MCP — Model Context Protocol
什么是 MCP?
MCP(Model Context Protocol,模型上下文协议)是连接 AI 助手与外部工具、数据源和服务的开放标准。你的服务器暴露"工具" — 具有名称、描述和输入模式的函数 — AI 模型在对话中决定何时调用它们。MCP 由 Anthropic 在 2024 年末创建,现在被 Claude、ChatGPT、IDE 插件和不断增长的代理框架列表支持,它对 AI 起到的作用与 USB 对硬件起到的作用相同:一根电缆,适用于任何设备。
为什么 MCP 重要
在 MCP 之前,每个 AI 助手通过自定义"插件"或"function calling"代码连接到每个外部服务。每个 AI 供应商都有自己的格式。每个工具集成都必须按供应商重新编写 — 一次为 Claude,再一次为 ChatGPT,再一次为 Cursor,再一次为自定义代理。
MCP 标准化了接口。一个 MCP 服务器适用于所有兼容 MCP 的客户端。这意味着:
- 工具构建者写一次集成,而不是 N 次
- AI 客户端在新工具发布时立即拾取,无需更新客户端
- 代理可以在运行时发现、列出和调用工具 — 无需编译时配线
- 开源服务器可以被审计、分叉和自托管
就像专有打印机驱动程序和 IP 标准的区别。协议很无聊。在它上面标准化解锁了一个生态系统。
工作原理
所有通信都使用 JSON-RPC 2.0 通过 HTTP POST 到单个端点(例如 /mcp):
- 客户端发送
initialize来建立会话 - 服务器以其名称、版本和功能响应
- 客户端发送
tools/list来发现可用工具 - 服务器返回带描述和输入模式的工具列表
- 客户端发送
tools/call带有工具名称和参数 - 服务器执行工具并返回结果
MCP 与替代方案
| 方面 | OpenAI function calling | OpenAPI / Swagger | MCP |
|---|---|---|---|
| 供应商范围 | 单一供应商 | 供应商中立 | 供应商中立 |
| 设计目的 | LLM 工具调用 | REST API | AI 代理 |
| 发现 | 客户端硬编码 | 静态规范文件 | 通过 tools/list 运行时 |
| 流式传输 | 有限 | 无原生支持 | 内置(SSE / Streamable HTTP) |
| 有状态会话 | 否 | 否 | 是(initialize → 调用) |
| 认证 | 客户端密钥 | API 密钥、OAuth | OAuth、bearer、自定义 |
| 生态系统 | 仅 OpenAI | 成熟、广泛 | 新但快速增长 |
OpenAPI 在设计时描述 REST API。MCP 在运行时描述活动工具表面。两者互补 — 许多 MCP 服务器包装现有的 OpenAPI 服务并将其作为代理可调用工具公开。
实现示例
app.post('/mcp', (req, res) => {
const { method, params, id } = req.body;
if (method === 'initialize') {
return res.json({ jsonrpc: '2.0', id, result: {
protocolVersion: '2024-11-05',
capabilities: { tools: {} },
serverInfo: { name: 'my-service', version: '1.0' }
}});
}
if (method === 'tools/list') {
return res.json({ jsonrpc: '2.0', id, result: {
tools: [{
name: 'search',
description: 'Search for items',
inputSchema: {
type: 'object',
properties: { query: { type: 'string' } },
required: ['query']
}
}]
}});
}
if (method === 'tools/call') {
const { name, arguments: args } = params;
return res.json({ jsonrpc: '2.0', id, result: {
content: [{ type: 'text', text: 'Search results...' }]
}});
}
res.json({ jsonrpc: '2.0', id, error: { code: -32601, message: 'Method not found' }});
});
传输选项
MCP 支持三种传输 — 根据客户端运行位置选择:
- Streamable HTTP (远程服务器推荐):普通 HTTP POST 到一个端点。服务器返回 JSON 响应或为发出进度的工具返回 SSE 流。通过 CDN、负载均衡器和防火墙工作。这是 claude.ai web 和大多数托管客户端所期望的。
- SSE(Server-Sent Events):使用长连接 GET 用于服务器→客户端和 POST 用于客户端→服务器的较旧传输。仍受支持但 Streamable HTTP 在新服务器中取代了它。
- stdio:进程管道 — 客户端将你的服务器作为子进程启动并通过 stdin/stdout 通信。Claude Desktop 和 CLI 代理使用。无网络,无 CORS,但客户端必须能够在本地运行你的代码。
如果你想要一个 MCP 服务器同时与 Claude Desktop 和 Claude web 应用 和 ChatGPT 和 Cursor 工作,请发布 Streamable HTTP。现在几乎所有人都说它。
CORS — 基于浏览器的代理所需
越来越多的 MCP 客户端在浏览器中运行:Claude.ai web、ChatGPT 浏览器、浏览器扩展和嵌入式聊天小部件。当 claude.ai 上运行的 JavaScript 调用 fetch('https://yourdomain.com/mcp') 时,浏览器自己做两件事:
- 它实际上将请求发送到你的服务器。
- 它拒绝将响应交给请求它的 JavaScript — 除非你的服务器响应包含命名
claude.ai(或*)的Access-Control-Allow-Origin头。
因此没有 CORS 头时,你的服务器运行良好并返回 200,但浏览器选项卡中的 MCP 客户端看到网络错误,永远无法读取正文。这是浏览器在保护用户。像 Claude Desktop 或 MCP CLI 这样的服务器端客户端不受此限制。
为支持基于浏览器的 MCP 客户端,在每个 /mcp 响应上发送这些头,并处理 OPTIONS 预检:
app.use('/mcp', (req, res, next) => {
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.set('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization');
if (req.method === 'OPTIONS') return res.sendStatus(204);
next();
});
通配符 vs 特定来源
Access-Control-Allow-Origin: * 适用于公开、只读的 MCP 端点。如果你的 MCP 端点需要认证或为工具调用收费,返回特定来源(或将请求的 Origin 头与允许列表对比并回显)并设置 Access-Control-Allow-Credentials: true。根据 CORS 规范,通配符来源不能与凭证一起使用。
为什么预检很重要
对于"简单"请求 — 普通 GET 或 Content-Type: text/plain 的 POST — 浏览器只是发送它,只有响应被阻止。但是 MCP 使用 Content-Type: application/json 的 POST,浏览器认为这足够危险以先检查。在发送实际 POST 之前,浏览器发送 OPTIONS 请求询问:"你会接受来自此来源带这些头的 POST 吗?"
如果你的服务器没有用 2xx 状态和正确的 CORS 头响应 OPTIONS,浏览器完全取消 POST — 它永远不到达你的服务器。这就是为什么 CORS 中间件必须处理两者:OPTIONS 预检和实际 POST。
认证
对于公开只读服务器,无认证就可以。对于私有或付费工具,MCP 支持:
- Bearer 令牌在
Authorization头中(最简单) - OAuth 2.1 与 PKCE — 用户委托访问的标准;MCP 规范在
/.well-known/oauth-authorization-server定义元数据端点,以便客户端自动发现你的 OAuth 流程 - 按请求付款 通过 x402 — 返回带支付指令的 HTTP 402 而不是事先认证
如果是人类代表自己授权,OAuth 是正确的默认值。Bearer 令牌适合服务到服务。x402 适合付费且无状态的调用。
谁在使用 MCP
- Anthropic Claude — Claude Desktop、Claude.ai web 和 Claude API 中的原生 MCP 客户端
- OpenAI ChatGPT — 在 2025 年添加了 MCP 支持
- IDE 集成 — Cursor、Zed、Windsurf 和 JetBrains 插件都说 MCP
- 代理框架 — LangChain、LlamaIndex 和大多数代理 SDK 包含 MCP 传输
- 官方 MCP 注册表
registry.modelcontextprotocol.io列出数百个公开服务器 - Smithery
smithery.ai是最大的社区维护 MCP 市场
AgentGrade 发布自己的 MCP 服务器(com.agentgrade/mcp-server),用于希望从 MCP 感知客户端内部扫描站点的代理。
常见错误和调试
Method not found(-32601):客户端调用了你的服务器未实现的方法。始终为未知方法返回优雅的错误而不是抛出。- CORS 预检失败:OPTIONS 返回 404 或 405。添加上面所示的中间件。
- 客户端 UI 中工具列表为空:你的
tools/list响应格式良好,但客户端期望非空tools数组。确认至少注册了一个工具。 Invalid params(-32602):客户端发送的参数与你的inputSchema不匹配。查看 JSON Schema — 缺少必需字段或类型错误是通常的元凶。- Desktop 中工作,web 中失败:几乎总是 CORS。浏览器阻止响应;服务器日志显示 200s,但客户端看不到任何东西。
关键概念
- Tools:你的服务器暴露的函数(例如 "search"、"create_invoice")
- inputSchema:描述每个工具接受什么参数的 JSON Schema
- Resources:你的服务器可以交给模型的只读数据(文件、片段、查询结果)
- Prompts:服务器发布供客户端使用的可重用提示模板
- Streamable HTTP:推荐的传输 — 所有消息通过 POST 到一个端点
- SSE:Server-Sent Events — 较旧传输,为向后兼容保留
FAQ
MCP 是 Anthropic 协议还是开放标准?
它由 Anthropic 创建并作为开放规范发布。参考实现采用 MIT 许可。OpenAI、IDE 供应商和代理框架独立于 Anthropic 采用了它 — 它现在是社区标准,不是单一供应商协议。
MCP 与 OpenAI 的 function calling 有什么区别?
Function calling 是一个供应商 API 的特性。MCP 是任何客户端都可以说的传输层协议。使用 function calling,模型和工具定义存在于同一个 OpenAI 请求中;使用 MCP,模型存在于客户端,工具存在于你的服务器,它们通过定义的通信格式通信。
我应该将现有 REST API 公开为 MCP,还是只给 AI 我的 OpenAPI 规范?
两者都有效,但针对不同客户端。具有原生 MCP 支持的模型(Claude、Cursor)直接通过 MCP 调用工具。如果你只有时间做一个,发布 MCP — 大多数代理客户端更喜欢它用于运行时发现。
MCP 需要 WebSocket 吗?
不。当前标准是 Streamable HTTP — 到一个端点的普通 POST,内部可选 SSE 流。早期草案使用 WebSocket;那条路被放弃了,因为普通 HTTP 无需配置就能穿越 CDN、负载均衡器和企业防火墙。
MCP 服务器可以为工具调用收费吗?
可以。协议本身不包括支付,但你可以在上面叠加 x402:让你的服务器从 tools/call 返回 HTTP 402,直到代理附加有效的支付收据。这是代理生态系统中最活跃的模式之一。
我如何在注册表中列出我的 MCP 服务器?
向 registry.modelcontextprotocol.io 提交清单。Smithery.ai 镜像注册表并添加发现功能。列表是免费的,审核队列很短。
为什么我的 MCP 服务器很慢?
协议本身很便宜 — HTTP 上的 JSON-RPC。慢几乎总是(a)工具实现,或(b)无服务器冷启动。在责怪传输之前先分析 tools/call 处理程序。
我需要每个工具一个单独的服务器,还是一个带多个工具的服务器?
一个带多个工具的服务器是标准。按逻辑服务分组工具(例如,所有 GitHub 操作在一个服务器中)。客户端可以同时连接到多个服务器,所以只有当权限管理或托管需求不同时分割才有意义。
规范成熟度
正式规范。 MCP 由 Anthropic 维护,具有版本化规范。当前协议版本:2024-11-05。Claude、ChatGPT、Cursor 和大多数代理框架原生支持。Streamable HTTP 传输稳定,并被所有主要客户端使用。
了解更多
- modelcontextprotocol.io — 官方规范
- MCP TypeScript SDK — 参考实现
- 官方 MCP 注册表 — MCP 服务器的公开目录
- Smithery — 最大的社区市场
- MDN: CORS — 跨源资源共享参考
- 代理就绪度 — MCP 如何融入更广泛的代理 Web 格局