2026 年 7 月 28 日,MCP 协议发布了自诞生以来最大的一次版本更新。核心从「双向有状态」改为「无状态」,握手与会话机制被移除。
关键词:
-
• 无状态:移除 initialize 握手和 Mcp-Session-Id
-
• MRTR:多轮往返请求,替代 Elicitation、Sampling、Roots
-
• 扩展框架:新能力走扩展,不必改核心协议
目前 MCP SDK 月下载量突破 4 亿次 ,连接器目录收录超过 950 个服务器。
一、旧架构的问题
有状态设计的代价
MCP 最早是双向有状态的协议:

这套设计在早期够用,但生产环境问题不少:
| 问题 | 影响 | | --- | --- | | 粘性路由 | 同一个会话必须打到同一台实例 | | 共享存储 | 需要 Redis 等外部存储维护会话状态 | | 网关复杂 | 限流、鉴权需要解析 JSON 请求体 | | 双向流依赖 | 服务端反向请求依赖长期保持的连接 |
结果是:MCP 服务器没法像普通 HTTP 服务那样,直接扔到 Serverless 或边缘节点上扩容。
社区对有状态架构有不少吐槽:
Figma(VP of Engineering):「用的人越多,我们的无状态架构越能跟着扩。」
Netlify(VP of Applied AI):「新规范让 MCP 第一次成为『一等 HTTP 工作负载』。」
二、握手没了,会话也没了
核心变化
2026-07-28 版本最大的变化:initialize/initialized 握手被移除,Mcp-Session-Id 请求头一并退休。
旧模式(已废弃):
bash
HTTP Request 1: POST /initialize → 返回 sessionId
HTTP Request 2: GET /sse (带 sessionId) → 建立双向流
HTTP Request 3: POST /tools/call (带 sessionId)
新模式(无状态):
bash
HTTP Request: POST /mcp
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"search","arguments":{"q":"otters"},
"_meta":{"io.modelcontextprotocol/clientInfo":{"name":"my-app","version":"1.0"}}}}
每个请求自描述:协议版本、客户端身份、客户端能力,全部塞进 _meta 字段。任何请求都可以随便落到负载均衡后面的任意实例,不需要共享存储。
状态何去何从
无状态不代表服务器不能「记事」。如果业务需要跨调用保留状态,官方方案是:
服务器主动返回一个显式的 handle,模型在后续调用里把这个 handle 传回去。
模型能看见这个 handle,可以显式传递,比藏在传输层里的隐式会话状态更清晰。
配套改动
还有三处调整:
| 改动 | 说明 | | --- | --- | | 请求头路由 | Streamable HTTP 必须携带 Mcp-Method 和 Mcp-Name 请求头,网关可直接路由和鉴权,不用再解析 JSON | | 列表结果可缓存 | tools/list、resources/list 等接口现在带 ttlMs 和 cacheScope 字段 | | 错误码对齐 | 「资源未找到」错误码从 -32002 改成 JSON-RPC 标准的 -32602 |
三、MRTR:多轮往返请求
旧问题:服务端如何反向请求客户端?
MCP 有不少场景需要服务器「反过来」问客户端要东西:
| 旧机制 | 用途 | 典型场景 | | --- | --- | --- | | Elicitation | 向用户请求结构化输入 | 删除数据前请求确认 | | Sampling | 请求客户端调用 LLM | 服务端需要文本生成但不带模型 | | Roots | 告知服务端可访问的目录 | 限制服务端文件访问范围 |
过去,这三个机制都依赖一条长期保持的双向流(SSE)。
MRTR 是什么
MRTR(Multi Round-Trip Requests) 的思路是:服务端不再「反向发起请求」,而是把问题放在响应里,让客户端带着答案重试。

关键点:
-
• 每个步骤都是独立的 HTTP 请求,任何实例都能处理
-
•
requestState在重试时原样返回,服务端凭此恢复上下文 -
• 统一替代 Elicitation、Sampling、Roots 三种旧机制
四、扩展框架
协议演进的核心矛盾是:想加功能就得改核心协议,每次大版本都伤筋动骨。这次推出了扩展框架来解决问题。
扩展的工作方式
每个扩展是一个带版本号的独立命名空间,服务端声明支持哪些扩展,客户端按需调用:
bash
// 服务端声明
{
"capabilities": {
"extensions": {
"io.modelcontextprotocol/mcpapps": "1.0.0",
"io.modelcontextprotocol/tasks": "1.0.0"
}
}
}
// 客户端调用
{
"method": "mcpapps/render",
"params": { "component": "confirm-dialog", "data": {...} }
}
扩展 vs 核心协议
| | 核心协议 | 扩展 | | --- | --- | --- | | 稳定性 | 高,只增不改 | 快速迭代,验证后可能并入核心 | | 破坏性变更 | 影响全局 | 只影响使用该扩展的客户端 | | 生命周期 | 长期稳定 | 可独立演进 |
已有的扩展
| 扩展 | 命名空间 | 说明 | | --- | --- | --- | | MCP Apps | io.modelcontextprotocol/mcpapps | 服务器可在对话内渲染交互式 UI | | Tasks | io.modelcontextprotocol/tasks | 处理长时间运行的后台任务,基于轮询 | | 企业级鉴权 | io.modelcontextprotocol/ema | 对接 Entra、Okta 等企业身份系统 |
五、MCP vs CLI
本质差异
MCP 和 CLI 不是非此即彼的关系,理解两者的本质差异更重要:
| | MCP | CLI | | --- | --- | --- | | 心智模型 | 从预定义工具集里选,确定性、schema驱动 | 模型生成命令,靠「猜测→执行→观察→纠正」循环 | | 类比 | 填空题 | 问答题 | | 关键词 | 「消除不确定性」 | 「管理不确定性」 |
-
• MCP 本质是 RPC 协议:有明确的工具定义,客户端按 schema 调用,结果可预期
-
• CLI 本质是自然语言到命令的翻译:模型理解意图,生成命令,从执行结果中学习
CLI 的优势
Token 成本
MCP 需要把完整工具 schema 塞进每个请求,CLI 只需要一条命令字符串。
| 接口 | Token 消耗 | | --- | --- | | MCP tools/call | 每次请求携带完整 schema(20 个工具 ≈ 10万+ token) | | CLI | 命令字符串本身,几百 token 顶天 |
实测:CLI 比 MCP 少 4-32× token。
模型熟悉度
git、docker、kubectl、gh 在互联网上的语料太丰富了,模型天然知道这些工具怎么用。MCP 服务器是自定义的,模型没见过,只能靠 schema「猜」。
探索式迭代
CLI 可以把复杂 pipeline 压缩进一条命令:
bash
# 一条命令搞定复杂操作
docker run --rm -v $(pwd):/app -w /app gcc:latest sh -c "gcc -o app main.c && ./app"
# MCP 要拆成多个工具调用
docker_run() → docker_exec() → docker_cp()
结论
接口强弱取决于模型和任务,前沿模型基本抹平了差距。关键在于任务性质:
-
• 探索式、容错迭代 → CLI 优势明显
-
• 正确性优先、不可试错 → MCP 优势明显
CLI 适合个人开发者,MCP 更适合企业场景。
六、思考
Token 效率
规范本身没有解决 token 膨胀问题。客户端层面的机制(如 Tool Search)可节省约 85% token,但这不是协议层的变化。
未来方向
| 方向 | 说明 | | --- | --- | | 协议层渐进式加载 | 规范可能会加入「按需加载工具」原语,从根本上解决 token 膨胀 | | 扩展框架成熟 | MCP Apps、Tasks 等扩展验证后会并入核心 | | Serverless 原生 | 无状态化后,MCP 在边缘计算场景潜力巨大 |
MCP 的定位
MCP 可以类比为 Agent 时代的 USB-C------统一了 AI Agent 接入外部工具的接口,让「即插即用」成为可能。
总结
新版 MCP 堵上了架构类的老问题(无状态化、MRTR、扩展框架),但 token 膨胀和协议安全这两个问题只是缓解,不是根治。
参考:
-
• MCP 官方博客
-
• Anthropic 官方说明
-
• SEP-2322: MRTR