大家好,我是一名 Node.js 开发者。最近 MCP(Model Context Protocol)协议爆火,作为 Anthropic 推出的模型上下文协议,它能标准化大模型与外部工具、数据的连接,只要开发一个 MCP 服务,就能让 Claude、Cursor 等主流 AI 客户端拥有自定义能力------比如调用本地接口、操作数据库、解析文件等,相当于给 AI 装了个"自定义插件"。
之前很多小伙伴问我,Node.js 怎么开发 MCP 服务,网上相关教程要么零散,要么偏向 Python 版本,今天就给大家带来一篇从零到上线、可直接复制运行 的 Node.js 版 MCP 开发全指南,全程 30 分钟,新手也能轻松上手,最后还会讲解客户端对接和生产环境部署,干货拉满!
一、先搞懂:MCP 服务到底是什么?
在动手之前,先简单理清核心概念,避免盲目开发。MCP 采用客户端-服务端架构,核心是"让 AI 能调用我们自定义的功能",关键角色分为 3 个:
- MCP 服务端(我们要开发的):暴露工具(可执行函数)、资源(只读数据)、提示词(预定义模板)给 AI 客户端调用;
- MCP 客户端:Claude Desktop、Cursor、Cline 等支持 MCP 协议的 AI 应用;
- 传输层:负责两者通信,常用两种方式------本地开发用 STDIO(进程间直接通信,无网络开销),远程部署用 HTTP + SSE(支持公网访问)。
简单说:我们开发的 Node.js MCP 服务,就是 AI 客户端的"能力扩展插件",你想让 AI 做什么,就开发对应的工具/资源,比如让 AI 帮你读取本地文件、调用公司接口,都能通过 MCP 实现。
二、前置准备:3 分钟搭好开发环境
开发 Node.js 版 MCP 服务,不需要复杂框架,只需要两个基础环境,新手也能快速搞定:
1. 环境要求
- Node.js:≥ 20(推荐 LTS 版本,避免兼容性问题);
- 包管理器:npm、yarn、pnpm 任意一个(本文用 npm 演示)。
检查环境是否合格,终端输入以下命令:
bash
node -v # 输出 ≥ v20.0.0 即可
npm -v # 输出任意版本均可
2. 核心依赖(必装)
MCP 官方提供了 Node.js SDK,还有一个参数校验工具(官方推荐,避免参数异常导致服务崩溃),终端执行以下命令安装:
bash
# 核心 MCP SDK(官方包,处理协议通信)
npm install @modelcontextprotocol/sdk
# 参数校验工具(Zod,官方推荐,必装)
npm install zod
这里不需要额外安装 Express、Koa 等 Web 框架,纯原生 Node.js 就能跑通,极大降低开发成本。
三、核心开发:30 分钟写出可运行的 MCP 服务
我们采用"最小可用原则",先开发一个包含「工具 + 资源」的基础 MCP 服务,支持本地 STDIO 通信,能直接对接 Claude 客户端,后续再扩展远程部署和更多功能。
1. 项目结构(极简,不冗余)
不用复杂的目录结构,一个入口文件 + 配置文件就够了,新手也能快速理清逻辑:
bash
node-mcp-server/ # 项目根目录
├── index.js # 服务入口(核心代码)
└── package.json # 依赖和配置
2. package.json 配置(关键,避免运行报错)
新建 package.json 文件,复制以下内容,重点注意 type: "module"(必须加,支持 ES 模块导入):
json
{
"name": "node-mcp-server",
"version": "1.0.0",
"type": "module", // 关键:支持 ES 模块,否则 import 会报错
"main": "index.js",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.0",
"zod": "^3.22.4"
},
"scripts": {
"start": "node index.js", // 启动命令
"dev": "node --watch index.js" // 开发热更新(Node.js 18+ 支持)
}
}
3. 完整核心代码(可直接复制运行)
新建 index.js 文件,这是整个 MCP 服务的核心,包含服务初始化、工具注册、资源注册、服务启动四个步骤,每一行都加了注释,新手也能看懂:
javascript
// 导入核心依赖
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
// 1. 初始化 MCP 服务实例
// name:服务名称(自定义),version:版本号(自定义)
const mcpServer = new McpServer({
name: 'node-mcp-demo',
version: '1.0.0',
});
// 2. 注册工具(核心功能:让 AI 能调用的可执行函数)
// 示例1:两数相加工具(简单演示,可替换成你的业务逻辑)
mcpServer.tool(
'addNumbers', // 工具唯一标识(AI 调用时会用到)
// 参数校验规则(用 Zod 定义,避免传入非数字导致报错)
{
a: z.number().describe('需要相加的数字 A'),
b: z.number().describe('需要相加的数字 B'),
},
// 工具执行逻辑(async 函数,支持异步操作,比如调用接口、查数据库)
async ({ a, b }) => {
// 返回结果给 AI 客户端,格式必须是 { content: [{ type: 'text', text: '结果' }] }
return {
content: [{ type: 'text', text: `两数相加结果:${a + b}` }],
};
}
);
// 示例2:获取本地应用配置(模拟业务场景,可替换成读取本地文件、数据库)
mcpServer.tool(
'getAppConfig',
{}, // 该工具无需参数,传空对象即可
async () => {
// 模拟从数据库/配置文件获取数据
const config = {
appName: 'Node.js MCP 服务',
version: '1.0.0',
author: '掘金开发者',
enable: true
};
return {
content: [{ type: 'text', text: `应用配置:\n${JSON.stringify(config, null, 2)}` }],
};
}
);
// 3. 注册资源(只读数据,给 AI 提供上下文,比如配置、静态数据)
mcpServer.resource(
'config://appInfo', // 资源唯一 URI(AI 获取时会用到)
'应用基础配置信息(只读)', // 资源描述
async () => {
return {
contents: [
{
uri: 'config://appInfo', // 与上面的资源 URI 一致
text: JSON.stringify({
version: '1.0.0',
updateTime: '2026-05-08',
desc: 'Node.js 开发的 MCP 服务示例,用于对接 Claude 客户端'
}, null, 2)
}
]
};
}
);
// 4. 启动 MCP 服务(本地模式:STDIO 传输,适合开发调试)
async function startServer() {
// 初始化 STDIO 传输(本地进程间通信)
const transport = new StdioServerTransport();
// 连接传输层并启动服务
await mcpServer.connect(transport);
// 注意:MCP 服务只能用 console.error 打印日志(避免占用 STDIO 通信通道)
console.error('✅ Node.js MCP 服务启动成功(STDIO 模式)');
console.error('📌 可对接 Claude/Cursor 客户端进行测试');
}
// 启动服务并捕获错误
startServer().catch(error => {
console.error('❌ MCP 服务启动失败:', error.message);
process.exit(1);
});
4. 本地运行测试(1 分钟验证)
终端进入项目根目录,执行以下命令启动服务:
sql
npm start
如果终端输出以下内容,说明服务启动成功(STDIO 模式会保持进程运行,等待 AI 客户端连接):
css
✅ Node.js MCP 服务启动成功(STDIO 模式)
📌 可对接 Claude/Cursor 客户端进行测试
注意:不要关闭终端,关闭终端会终止 MCP 服务。
四、关键步骤:对接 Claude 客户端(实测可用)
服务启动后,我们需要配置 Claude 客户端,让它能连接到我们的 MCP 服务,这里以 Claude Desktop(Mac/Windows)为例,步骤超简单:
1. 找到 Claude 配置文件
- Mac 路径:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows 路径:
%APPDATA%\Claude\claude_desktop_config.json
如果找不到文件,可先启动一次 Claude 客户端,会自动生成配置文件。
2. 配置 MCP 服务路径
打开配置文件,添加 mcpServers 字段,替换成你的项目 index.js 路径(绝对路径):
json
{
"mcpServers": {
"node-mcp-demo": { // 服务名称(自定义,便于识别)
"command": "node",
"args": ["/Users/xxx/node-mcp-server/index.js"] // 替换成你的 index.js 绝对路径
}
}
}
3. 测试 AI 调用 MCP 工具
重启 Claude 客户端,在对话框中输入以下内容,测试工具调用:
调用 addNumbers 工具,a=10,b=20;再调用 getAppConfig 工具,获取应用配置。
如果 Claude 能正确返回相加结果和应用配置,说明对接成功!至此,你的 Node.js MCP 服务已经能正常工作了。
五、进阶:远程部署(公网可访问)
本地 STDIO 模式只能在自己的电脑上使用,如果想让其他人也能通过 AI 客户端调用你的 MCP 服务,需要改成 HTTP + SSE 传输模式,部署到服务器上。
1. 修改启动代码(替换传输层)
修改 index.js 中的启动逻辑,替换成 SSE 传输,添加 HTTP 服务:
javascript
// 导入 SSE 传输和 http 模块
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
import http from 'http';
// 替换原来的 startServer 函数
async function startServer() {
// 1. 创建 HTTP 服务器
const httpServer = http.createServer();
// 2. 初始化 SSE 传输(指定接口路径 /sse)
const transport = new SSEServerTransport('/sse', httpServer);
// 3. 绑定请求处理器
httpServer.on('request', transport.handler);
// 4. 启动 HTTP 服务(监听 3000 端口,可自定义)
httpServer.listen(3000, () => {
console.error('✅ Node.js MCP 远程服务启动成功');
console.error('📌 服务地址:http://localhost:3000/sse');
});
// 5. 连接 MCP 服务和传输层
await mcpServer.connect(transport);
}
2. 部署到服务器(简单演示)
- 将项目上传到服务器(推荐用 Git 或 FTP);
- 服务器安装 Node.js ≥ 20,执行
npm install安装依赖; - 用 pm2 守护进程(避免服务崩溃):
npm install -g pm2 `` pm2 start index.js # 启动服务 ``pm2 list # 查看服务状态 - 开放服务器 3000 端口(防火墙放行);
- 客户端配置修改为远程地址:
{ `` "mcpServers": { `` "node-mcp-remote": { `` "url": "http://你的服务器IP:3000/sse" `` } `` } ``}
六、生产环境必备:避坑指南 + 优化建议
如果要将 MCP 服务用于生产环境,以下 4 点一定要注意,避免踩坑:
1. 日志规范
MCP 服务的 STDIO 通道用于与客户端通信,绝对不能用 console.log 打印日志,必须用 console.error,否则会占用通信通道,导致客户端连接失败。
2. 错误捕获
所有工具和资源的执行逻辑中,必须添加 try/catch 捕获异常,避免单个工具报错导致整个 MCP 服务崩溃,示例:
javascript
mcpServer.tool(
'getAppConfig',
{},
async () => {
try {
const config = await fetchConfigFromDB(); // 模拟从数据库获取配置
return {
content: [{ type: 'text', text: JSON.stringify(config, null, 2) }]
};
} catch (error) {
// 捕获异常,返回错误信息给 AI 客户端
return {
content: [{ type: 'text', text: `获取配置失败:${error.message}` }]
};
}
}
);
3. 鉴权(远程服务必加)
远程服务暴露在公网后,必须添加鉴权(比如 API Key),防止被恶意调用,可通过拦截 HTTP 请求实现:
javascript
// 在启动 HTTP 服务时,添加鉴权拦截
httpServer.on('request', (req, res) => {
// 从请求头获取 API Key
const apiKey = req.headers['x-api-key'];
// 验证 API Key(替换成你的密钥)
if (req.url === '/sse' && apiKey !== 'your-secret-api-key') {
res.writeHead(401, { 'Content-Type': 'text/plain' });
res.end('Unauthorized: Invalid API Key');
return;
}
// 鉴权通过,交给 transport 处理
transport.handler(req, res);
});
4. 进程守护
生产环境不要用 node index.js 直接启动,必须用 pm2 等进程守护工具,确保服务崩溃后能自动重启,避免服务中断。
七、总结:Node.js 开发 MCP 服务的核心要点
其实开发 Node.js 版 MCP 服务一点都不复杂,核心就 4 个关键点,记住就能快速上手:
- 环境:Node.js ≥ 20 + 两个核心依赖(官方 SDK + Zod);
- 核心:McpServer 实例 + 工具/资源注册;
- 传输:本地用 STDIO(开发调试),远程用 HTTP + SSE(部署上线);
- 对接:修改 AI 客户端配置,即可调用自定义工具/资源。
MCP 协议的核心价值,就是让我们能轻松扩展 AI 的能力,不用依赖 AI 厂商的接口限制,自己开发服务,让 AI 适配我们的业务场景------比如对接公司内部系统、操作本地文件、调用第三方 API 等。
本文的代码可以直接复制运行,如果你有具体的业务场景(比如让 AI 调用数据库、解析 PDF、操作本地文件),可以在评论区留言,后续会补充对应的实现教程。
最后,如果你觉得这篇文章对你有帮助,麻烦点个赞、收藏一下,关注我,后续会分享更多 Node.js 和 AI 相关的实战教程~
附:常见问题排查
- 服务启动报错:检查 Node.js 版本是否 ≥ 20,package.json 是否添加
type: "module"; - Claude 无法调用工具:检查配置文件中的 index.js 路径是否正确,服务是否正常运行;
- 远程服务无法访问:检查服务器端口是否开放,鉴权配置是否正确。