先给结论:MCP(Model Context Protocol)不是另一种 Function Calling,也不是一个模型。它是 AI 应用(Host)和外部工具进程(MCP Server)之间的开放协议,报文是 JSON-RPC 2.0。大模型仍然走各家的 Tool Calling / Function Calling;Host 把 tools/list 译成模型的 tools 数组,再把模型的 tool_calls 译成 tools/call。三层叠在一起,才是 2026 年常见的 Agent 工具调用。
这篇按 2026 年 9 月 7 日写。当前规范是 2026-07-28:协议层无会话、无 initialize 握手,每条请求自带 _meta,发现能力用 server/discover。本站 8 月的《Agent JSON 数据流》仍用旧版 initialize 举例;读这份指南时以 7 月规范为准。迁移细节见《MCP 2026 迁移指南》。
MCP 是什么
Model Context Protocol 是一套给 AI 应用发现、读取和调用外部上下文的开放标准。Anthropic 在 2024 年 11 月发布,后来交到 Agentic AI Foundation 开源治理。它只规定「上下文怎么交换」,不规定你用哪家模型、怎么编排多步 Agent、怎么写业务代码。
可以记成 USB-C:插座形状统一,插头后面接硬盘、显示器还是电源,协议不管。MCP 统一的是 Host ↔ Server 的插座;后面接文件系统、GitHub、内部订单 API,还是本站这种 JSON 校验服务,都是 Server 自己的事。
| 说法 | 实际含义 | 常见误读 |
|---|---|---|
| MCP | Host 与工具进程之间的 JSON-RPC 协议 | 一个模型、一个 Agent 框架、或 OpenAI 的 Tools API |
| MCP Server | 对外暴露 tools / resources / prompts 的程序 | 必须部署在公网、或必须代替你的 REST API |
| MCP Client | Host 里连一台 Server 的连接管理器 | 等于大模型本身 |
| MCP Host | Cursor、VS Code、Claude Desktop 这类 AI 应用 | 等于 MCP 规范或 SDK |
协议分两层:数据层是 JSON-RPC 2.0(方法、参数、错误码、通知);传输层是怎么把这些 JSON 运过去——本机用 stdio,远程用 Streamable HTTP。换传输不换报文形状。这就是为什么调试 MCP 时,先分清「信封是 JSON-RPC,业务载荷也常是 JSON」。
Host、Client、Server
规范里的三角,不要和「客户端 / 服务器」口语混用:
- Host:用户打开的 AI 应用。它创建 Client、把工具 Schema 喂给模型、执行前做授权与校验、把结果写回对话。
- Client:Host 内部的一个连接对象。一台 Server 对应一个 Client。VS Code 同时连文件系统和 Sentry,运行时就是两个 Client。
- Server:提供上下文的程序。可以和 Host 同机(stdio),也可以在别的机器上(Streamable HTTP)。「Server」指角色,不指必须有一个公网域名。
模型不在这个三角里。GPT-5.5、Claude 4.8、Gemini 3.7 看见的是 Host 翻译好的 tools 数组,看不见 JSON-RPC,也看不见 Mcp-Session-Id(2026-07-28 已经去掉会话头)。把模型直接「对接 MCP」是产品话术;工程上永远隔着一层 Host。
JSON-RPC 2.0 报文怎么读
JSON-RPC 是一种用 JSON 做远程过程调用的约定,比 REST 更接近「调用一个函数」。MCP 选它,是因为方法名稳定(tools/list、tools/call)、请求/响应/通知三分法清楚,而且对模型友好——整份信封都是 JSON。
| 字段 | 谁用 | 含义 |
|---|---|---|
jsonrpc | 所有报文 | 固定 "2.0" |
id | 请求与响应 | 配对用;通知没有 id |
method | 请求 / 通知 | 如 tools/call、server/discover |
params | 请求 | 参数对象;2026-07-28 起常带 _meta |
result / error | 响应 | 二选一;成功走 result,失败走 error |
一次 tools/call(规范 2026-07-28)看起来像这样。注意:没有握手、没有 session 头,版本和客户端身份在 _meta 里,任何 Server 实例都能处理这一帧。
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "validate_json",
"arguments": {
"payload": {"orderId": "A-1001", "total": 42.5},
"schemaId": "order.v1"
},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "json-toolbox-host",
"version": "1.0.0"
}
}
}
}
成功响应同样是 JSON 信封。业务结果在 result.content 里,常见 type: "text",文本本身又可能是一段 JSON——外层是协议,内层是载荷。调试时先看 id 能否对上请求,再对内层做 Schema 校验。
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"content": [
{
"type": "text",
"text": "{\"valid\":true,\"schemaId\":\"order.v1\"}"
}
]
}
}
错误走 JSON-RPC 的 error 对象:code、message、可选 data。2026-07-28 把「资源不存在」从 MCP 自定义 -32002 改成标准 -32602(Invalid Params)。客户端若写死旧错误码,会漏判。通知(notification)没有 id,也不等响应,例如工具列表变化。
Tools、Resources、Prompts
Server 能对外暴露三类原语。Agent 日常用得最多的是 Tools;另外两类常被忽略,却能少浪费一轮模型猜测。
| 原语 | 发现 | 使用 | 干什么 |
|---|---|---|---|
| Tools | tools/list | tools/call | 可执行动作:查库、调 API、写文件、校验 JSON |
| Resources | resources/list | resources/read | 按 URI 读上下文:Schema 文件、日志切片、配置 |
| Prompts | prompts/list | prompts/get | 可复用的提示词模板,带可选参数 |
工具定义的核心是 name、description 和 inputSchema。inputSchema 是 JSON Schema(2026-07-28 起按 2020-12,根仍须 type: "object",允许 oneOf / $ref / $defs)。可选的 outputSchema 约束返回形状。Host 几乎是一对一把 inputSchema 填进模型 API 的 parameters / input_schema。
{
"name": "validate_json",
"title": "Validate JSON",
"description": "Check a JSON payload against a named schema. Returns valid and errors.",
"inputSchema": {
"type": "object",
"additionalProperties": false,
"properties": {
"payload": { "type": "object", "description": "Already parsed JSON object, not a raw string" },
"schemaId": { "type": "string", "description": "Stable schema id such as order.v1" }
},
"required": ["payload", "schemaId"]
}
}
Resources 适合「先读再想」:把 schema://order.v1 读进上下文,比让模型在对话里背一份 200 行 Schema 便宜。Prompts 适合团队固化的开场白。Roots、Sampling、Logging 在 2026-07-28 已弃用:工作区路径改用工具参数或资源 URI;Server 不要再向 Host 要一次补全;日志走 stderr 或 OpenTelemetry。
和 Tool Calling 怎么叠
三个名字经常被写成一回事。数据流上它们不在同一层——上一篇《Agent JSON 数据流》拆过每一跳,这里只记映射:
| 层 | 两端 | 典型报文 |
|---|---|---|
| Function Calling / Tool Calling | 模型 API ↔ Host | tools[] + tool_calls.arguments |
| MCP | Host ↔ Server | JSON-RPC tools/list、tools/call |
| JSON Schema | 契约,不是传输 | inputSchema / parameters |
Function Calling 是早期 OpenAI 的名字;Tool Calling 是后来更通用的叫法(Claude tools、Gemini Function Calling、OpenAI Tools API)。对开发者是同一套:Host 把 Schema 发给模型,模型返回带 JSON 参数的调用,Host 执行后再把 JSON 结果塞回对话。
MCP 不替代这一层。没有 MCP 时,Host 在进程内调本地函数也完全合法。有了 MCP,工具变成可发现、可跨进程、可换 Host 复用的 Server。企业 Agent 几乎总是两层叠用;脚本和演示可以只用 Tool Calling。
映射时有两处容易踩坑:模型 API 常把 arguments 做成字符串,MCP 的 params.arguments 是对象;以及 tools/list 的 name 必须原样传给模型和 tools/call,不要在中间改成「更友好」的别名。校验应发生在真正 tools/call 之前,见《Tool Calling 与 JSON Schema 验证》。
一次完整工具调用
用户说:「用 order.v1 校验这段订单 JSON。」按 2026-07-28,端到端是:
- Host → Server:
server/discover(可缓存)确认对方有 tools;或直接发后续请求,版本不对再重试。 - Host → Server:
tools/list拿到带inputSchema的清单,响应可带ttlMs/cacheScope。 - Host → 模型:把清单映射成
tools[].parameters(仍是 JSON Schema)。 - 模型 → Host:
tool_calls,name为validate_json,arguments多为字符串化 JSON。 - Host 校验:
JSON.parse后按inputSchema验;失败则把错误写成 tool 结果,不碰真实 Server。 - Host → Server:
tools/call,arguments为对象,_meta带协议版本。 - Server → Host:
result.content;Host 必要时再按outputSchema验一遍。 - Host → 模型:
role: tool的 JSON 字符串,模型再写成给用户的话,或继续下一轮工具。
用户自然语言
│
▼
Host ──JSON Schema──► LLM Tool Calling
│ │
│ ▼
│ arguments JSON
▼ │
MCP JSON-RPC ◄──── 校验通过才 tools/call
│
▼
result JSON ──► tool message ──► 模型最终答复
远程传输时,HTTP 头还要带 MCP-Protocol-Version、Mcp-Method、Mcp-Name,且必须与 body 一致,否则 Server 应拒。负载均衡可以只看头、不拆 JSON。本机 stdio 没有这些头,但 JSON-RPC 方法名相同。
2026-07-28 你要记住的
7 月规范是 MCP 上线以来最大的一次修订,7 月 28 日已作为正式版发布。对「MCP 是什么」只记下面几条;要不要改 Server 代码,仍看迁移文的决策树。
- 无握手、无协议会话:
initialize/initialized和Mcp-Session-Id已去掉。每条请求自包含。应用状态请自己用basket_id这类显式参数串起来,不要指望传输层帮你记。 - 发现改走
server/discover:可选,但能一次拿到支持的版本、capabilities、serverInfo。列表结果带ttlMs,不必靠长 SSE 才能知道工具变了。 - Schema 升到 JSON Schema 2020-12:输入根仍是 object,可用组合与引用;不要自动解外部
$ref。输出 Schema 不再限定为 object。 - 弃用 Roots / Sampling / Logging:一年窗口内方法还在;新 Server 不要再实现 Sampling 向 Host 要补全。
- Extensions:Tasks、MCP Apps 是官方扩展,不是核心必做。长任务用 task handle +
tasks/get,不要自己发明会话。
仍跑 2025-11-25 的 Host / Server 会继续用 initialize。混连时看双方协商出的版本,不要把这篇的无握手报文打给旧 Server。选型与生态见《2026 MCP Server 排名》。
现在该怎么用
- 先画三层,再写代码:模型 API 的 Tool Calling、Host 编排、MCP Server。只做脚本就停在前两层;要跨 IDE 复用工具,再写 Server。
- 用官方 SDK,不要手写 JSON-RPC 帧:
@modelcontextprotocol/sdk以及各语言官方包已经处理发现、传输和错误码。手写 SSE 或私有字段,是迁移文里「必须改代码」的典型原因。 - 把
inputSchema写成能独立校验的契约:additionalProperties: false、required、枚举、长度上限。模型会漏字段、会把数字写成字符串。执行前用同一份 Schema 挡一次。 - 本机 stdio,远程 Streamable HTTP:个人调试不必上 HTTP。团队共享、多客户端、要过网关时再上远程传输,并加 OAuth / 最小权限。
- 列表要缓存,结果要裁:尊重
ttlMs;工具返回不要把堆栈原文灌回模型。窗口再大,脏 JSON 也会污染下一轮——见《1M Token 上下文窗口》。 - 落地前在浏览器里对样例:把
inputSchema、正例 / 反例 arguments、Server 返回样例存成 JSON,用本站校验和 Diff。数据不上传。这和测 REST 契约同一习惯。
常见问题 FAQ
MCP 是模型还是框架?
都不是。MCP 是 Host 与外部工具进程之间的开放协议,报文为 JSON-RPC 2.0。模型仍由各家 API 提供;编排仍由 Host / Agent 运行时负责。没有「MCP 模型」这种东西。
有了 Tool Calling 还要 MCP 吗?
单进程、工具写死在 Host 里时,只要 Tool Calling。需要跨应用复用、跨进程隔离、动态发现工具时,再加 MCP。2026 年的 IDE Agent 默认两层都在;命令行一次性脚本常常没有 MCP。
JSON-RPC 和 REST 哪个才是 MCP?
数据层是 JSON-RPC 2.0,不是「每个工具一个 HTTP 路径」。远程传输可以走 Streamable HTTP,但 body 仍是 JSON-RPC 对象,方法名在 method 和 Mcp-Method 头里。不要按 REST 资源风格去拆 MCP。
2026-07-28 之后还要写 initialize 吗?
新规范不再有 initialize / initialized,也没有 Mcp-Session-Id。版本与客户端信息放在每条请求的 _meta。只对接 2025-11-25 的旧 Server 时,仍按旧握手。看双方实际协商的 protocolVersion,不要混用两套信封。
MCP 会取代 OpenAPI 吗?
不会。OpenAPI 描述 HTTP API;MCP 描述 Agent 运行时如何发现和调用工具。常见做法是 REST 继续用 OpenAPI,外面再包一个薄 MCP Server,把路径映射成 tools/call。
如何本地检查 MCP 用的 JSON?
把 inputSchema、模型 arguments 样例、tools/call 返回样例存成文件,用 JSON 工具箱在浏览器里做语法和结构校验,再用 Diff 对比两版 Schema。数据不离开浏览器。
总结
MCP 是 2026 年 Agent 的工具插座:JSON-RPC 2.0 在 Host 和 Server 之间搬运发现与调用;大模型侧仍然是 Tool Calling;JSON Schema 是两边共用的契约。它不是模型,不是框架,也不替代 OpenAPI。当前规范 2026-07-28 把会话从协议里拿掉了,请求必须自包含;Tools / Resources / Prompts 三类原语没变。
读这份指南只为建立正确的分层。每一跳的字节形状见数据流文,旧 Server 要不要改代码见迁移文,装哪些现成 Server 见评测文。动手前先把 Schema 和样例 JSON 在本地校验过——模型可以换,字段名和 required 不该变。