欢迎
本教程将指导您使用Node.js编写自己的MCP服务器,并将其连接到您的AI代理。 我们将专门将其连接到OpenAI代理,但它可以连接到任何接受Streamable HTTP MCP的代理。 此项目可以轻松扩展以适应您的用例,您将学习如何添加代理可能需要的任何新工具。
项目设置和依赖关系
首先创建一个新项目并安装依赖项。
mkdir my-awesome-node-mcp-server
cd my-awesome-node-mcp-server
npm init -y一定要设置 type: "module" 在你的 package.json 以避免每次运行服务器时都出现恼人的警告消息。
构建mcp服务器所需的包称为 @modelcontextprotocol/sdk. 我们还将使用 @zod/3 指定工具参数的约束。
npm i @modelcontextprotocol/sdk zod@3我喜欢做的另一件事,虽然不是绝对必要的,是安装 nodemon 用于在文件更改时自动重新启动。
npm i nodemon --save-dev然后将此添加到您的 package.json 在...之下 scripts.
"dev": "nodemon server.js"我们很快就会创建server.js,但现在只要你想启动服务器,你只需键入:
npm run dev我们要做的最后一件事是创建 server.js 文件,我们可以在其中开始构建新的MCP服务器。
vi server.js进口
我们需要在服务器脚本中使用以下导入。
/* imports */
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { z } from "zod";
import { createMcpExpressApp } from '@modelcontextprotocol/sdk/server/express.js';创建MCP服务器
接下来,我们将创建MCP服务器。您可以选择任何您喜欢的名称和版本号。这主要是用于语言模型的元数据。
/* create the MCP server */
const getServer = () => {
const server = new McpServer(
{
name: 'my-awesome-mcp-server',
version: '1.0.0'
}
);
return server;
};注册工具
接下来,我们将添加一个通用工具。我选择了确定两点之间的距离,但你可以用任何你希望你的代理人能够调用的实用程序来代替它。 在服务器定义之后添加此项。
/* register a tool for our MCP server */
server.registerTool(
'calculate-euclidean-distance',
{
description: 'Find the euclidean distance between 2 two-dimensional points',
inputSchema: {
x1: z.number().describe('x coordinate of first point'),
y1: z.number().describe('y coordinate of first point'),
x2: z.number().describe('x coordinate of second point'),
y2: z.number().describe('y coordinate of second point'),
}
},
async ({ x1, y1, x2, y2 }) => {
console.log(`'calculate-euclidean-distance' was called with : `, { x1, y1, x2, y2 });
/* do other operations you may need here */
let eucDist;
try {
eucDist = calculateEuclideanDistance({ p1: { x: x1, y: y1 }, p2: { x: x2, y: y2 } });
} catch (error) {
console.log(`'calculate-euclidean-distance' error : `, error);
return false;
}
console.log(`'calculate-euclidean-distance' returned : `, eucDist);
return { content: [ { type: 'text', text: eucDist.toString() } ] };
}
);然后,您可以在同一文件中定义函数,也可以从其他文件导入函数。
/* helpers */
function calculateEuclideanDistance(p1, p2) {
const eucDist = Math.sqrt(((p1.x - p2.x) ** 2) + ((p1.y - p2.y) ** 2));
return eucDist;
}我们现在只有一个工具,就有了一个最小的MCP服务器定义。我们现在将创建一个应用程序,该应用程序将运行并公开我们的MCP服务器。
运行MCP服务器
我们将使用 express 库来创建我们的应用程序。
/* create an app to expose our MCP server */
const app = createMcpExpressApp();接下来,我们将添加一个 post 端点位于 /mcp 它将实际处理我们的MCP服务器请求。您可以添加GET和DELETE端点,但这不是严格必需的。 它对防御和人类可读性很好。
/* create a POST route */
app.post('/mcp', async (req, res) => {
const server = getServer();
try {
const transport = new StreamableHTTPServerTransport();
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
res.on('close', () => {
transport.close();
server.close();
});
} catch (error) {
console.error('Error handling MCP request:', error);
if (!res.headersSent) {
res.status(500).json({
jsonrpc: '2.0',
error: {
code: -32603,
message: 'Internal server error'
},
id: null
});
}
}
});服务器启动和关闭
我们最不希望做的就是启动服务器并定义关机行为。 有可能 PORT 8000 如果您正在运行其他web应用程序,则可能已在使用中。如果是这样的话,只需使用其他端口即可。
/* start the server */
const PORT = 8000;
app.listen(PORT, error => {
if (error) {
console.error('Failed to start server:', error);
process.exit(1);
}
console.log(`My Awesome MCP Streamable HTTP Server listening on port ${PORT}`);
});
/* handle server shutdown */
process.on('SIGINT', async () => {
console.log('Shutting down server...');
process.exit(0);
});希望您能看到一条消息,表明您的服务器正在运行。
使用代理测试我们的服务器
现在,我们终于可以试用我们的MCP服务器了。我们将使用OpenAI的Agent SDK创建一个代理,但您可以连接任何接受的代理 将HTTP MCP服务器流式传输到新服务器。
我们需要安装以下依赖项:
npm i @openai/agents dotenv创建 .env 文件并设置您的OpenAI API密钥,如下所示:
OPENAI_API_KEY=*注意:如果您正在分享您的 git 你应该为你的 .env 归档 .gitignore 以避免您的API密钥泄露。*
我们将创建一个名为的新文件 agent.js.
vi agent.jsimport { Agent, run, MCPServerStreamableHttp } from '@openai/agents';
import dotenv from 'dotenv';
dotenv.config();
async function main() {
const mcpServer = new MCPServerStreamableHttp({
url: 'http://localhost:8000/mcp',
name: 'My Awesome MCP Server'
});
const agent = new Agent({
name: 'MCP Assistant',
instructions: `
Use the tools to respond to user requests. Always dump the output from the tool verbatim, no processing, no rounding.
`,
mcpServers: [mcpServer],
});
try {
await mcpServer.connect();
const result = await run(agent, "What is the distance between origin and (13.21235, 15.1565)?");
console.log(result.finalOutput);
} catch (error) {
console.error(error);
} finally {
await mcpServer.close();
}
}
main().catch(console.error);然后,你可以用(*确保您的MCP服务器正在运行,无论是作为前台进程还是作为系统服务*):
node agent.js你应该在你的 server.js 日志:
My Awesome MCP Streamable HTTP Server listening on port 8000
'calculate-euclidean-distance' was called with : { x1: 0, y1: 0, x2: 13.21235, y2: 15.1565 }
'calculate-euclidean-distance' returned : 20.106856660664292以及您的代理人在回复中的正确答案, 表明代理能够成功地找到并使用该工具。
结论和下一步行动
您已在Node.js中成功构建了一个可流式HTTP MCP服务器,并使用Node.js SDK构建了连接并调用工具的OpenAI代理 从您的MCP服务器。
从这一点开始,您可以添加更多工具,以及更复杂的工具,例如调用命令行脚本或运行其他库中的函数。你 还可以构建更多的OpenAI代理,使其成为一个会话助手,可以在需要时从MCP调用工具。
