MCP 2026-07-28:扔掉 Session,拥抱无状态
MCP 即将迎来最大规模的一次协议修订——去掉 initialize 握手和 Session ID,转向无状态核心。聊聊这次变更意味着什么,以及迁移时要注意的三个坑。
MCP 2026-07-28:扔掉 Session,拥抱无状态
我手上有一个 MCP server,跑在 Kubernetes 上,两个副本,前面挂一个普通的负载均衡。
按说这是最标准的部署方式。但 MCP 2025-11-25 版本的协议有一个问题:它需要 session。
客户端先发 initialize,服务器回 initialized,然后给一个 Mcp-Session-Id。之后所有请求都要带上这个 ID,服务器在内存里维护 session 状态。如果请求被负载均衡分发到了另一个副本——session 不在那个副本上——请求就失败了。
所以我不得不加 sticky session、搭共享 session store、做深度包检测来路由。一个小服务,运维复杂度比业务逻辑还多。
这不是我一个人的问题。SEP-1442,2025 年 9 月由 Jonathan Hefner 等五位贡献者提出,就把这件事说得很直白:"一个简单的无状态负载均衡器没法用,因为它会把不同请求路由到不同的后端。"
2026 年 7 月 28 日,MCP 将正式发布新版本。这个问题终于被解决了。而且不止解决了这一个。
这一版到底改了什么
5 月 21 日锁定 RC 之后,社区已经讨论了两个多月。这次修订包含了 21 个以上的 SEP,可以归纳为五个核心变更:
| 支柱 | 核心内容 |
|---|---|
| 无状态核心 | 去掉 initialize 握手,去掉 Mcp-Session-Id,每个请求自包含 |
| 运维层 | Mcp-Method/Mcp-Name 路由头、ttlMs 缓存、W3C Trace Context |
| 扩展系统 | MCP Apps(沙箱 iframe UI)+ Tasks + 扩展框架 |
| 授权加固 | 6 个 SEP,对齐 OAuth 2.1 / OIDC,强制 iss 验证 |
| 弃用政策 | Roots / Sampling / Logging 弃用,12 个月宽限期 |
下面逐个说。
1. 无状态核心
这是这次修订最大的 Breaking Change,也是最重要的一个。
旧版 MCP 的工作流程:客户端先发 initialize 握手,拿到 Mcp-Session-Id,之后每个请求都带上。服务器在内存里存 session。session 丢了、重启了、被路由到另一个实例了——全崩。
新版把这个流程整个删掉。取而代之的是:每个请求自己携带所有需要的信息。
协议版本、客户端身份、能力声明(capabilities),全部放在每个请求的 _meta 字段里。客户端想知道服务器支持什么,调用新的 server/discover 方法——无状态、可缓存、不依赖任何共享状态。
服务器向客户端发起请求的模式也改了。以前依赖长连接 SSE 流,现在改用 Multi Round-Trip Requests(SEP-2322)。服务器返回 InputRequiredResult,包含 inputRequests 数组和一个不透明的 requestState。客户端收集完输入后,把 inputResponses 和 requestState 一起重发。协议层不持有任何连接状态。
{
"resultType": "input_required",
"inputRequests": {
"confirm": {
"type": "elicitation",
"message": "确定要删除这 3 个文件吗?",
"schema": { "type": "boolean" }
}
},
"requestState": "1a2b3c4d5e6f7g8h9i0j..."
}
说人话:以前需要 sticky session、共享 session store、深度包检测才能部署的东西,现在一个普通的轮询负载均衡就够了。
我觉得这个设计方向是对的。HTTP 二十年就是这么工作的——Cookie、Token、opaque handle,应用层状态跑在无状态传输层上,这是被验证过能 scale 的模式。MCP 联合创始人 David Soria Parra 今年 4 月接受 ShiftMag 采访时也说了:"2026 年的重点是确保 MCP 能够帮助人们将 agentic 系统投入生产。"这次修订就是这个承诺的技术落地。
2. 运维层:路由头、缓存、追踪
三个 SEP,让 MCP 流量从路由和可观测性的角度看,跟普通 HTTP API 没有区别。每一项都不花哨,但都解决了一类真实痛点。
必选路由头(SEP-2243):每个 Streamable HTTP 请求必须带 Mcp-Method(如 tools/call)和 Mcp-Name(工具名)。网关不用解析 JSON-RPC 请求体就能路由。在 2026 年 4 月的 AAIF MCP Dev Summit 上,Kong、Docker、Solo.io、Uber 内部平台都在同一件事——从请求体里逆向解析工具名来做路由。7 月 28 日之后这件事不再需要了。我觉得这是整个版本里最被低估的改动。
缓存元数据(SEP-2549):tools/list 等列表接口的响应带上 ttlMs 和 cacheScope,参照 HTTP Cache-Control 语义。客户端有标准化的缓存依据,服务器有标准化的失效声明。
分布式追踪(SEP-414):W3C Trace Context 正式纳入规范,traceparent、tracestate、baggage 三个 key 固定。OpenTelemetry 采集器直接看到 MCP 流量的端到端链路,零胶水代码。
一个 2026-07-28 版本的请求长这样:
POST /mcp HTTP/1.1
Host: server.example.com
Authorization: Bearer <token>
Mcp-Method: tools/call
Mcp-Name: search_issues
Mcp-Protocol-Version: 2026-07-28
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
{"jsonrpc":"2.0","id":"req-1","method":"tools/call",
"params":{"name":"search_issues","arguments":{"query":"crash"},
"_meta":{"clientInfo":{"name":"claude","version":"3.5"}}}}
3. 扩展系统:MCP Apps 和 Tasks
MCP 终于有了正式的扩展系统。扩展用反向 DNS 标识(如 io.modelcontextprotocol/tasks),放在独立 ext-* 仓库中独立维护,通过能力协商匹配,版本演进跟核心规范解耦。SEP 流程新增了正式的 Extensions Track。
首发两个官方扩展:
MCP Apps(SEP-1865):服务器可以声明 HTML 界面,客户端在沙箱 iframe 里渲染。工具的 UI 模板提前声明,客户端可以预取和安全审查。渲染出来的 UI 通过同样的 JSON-RPC 协议跟服务器通信——审计日志和同意流程保持统一。这跟 OpenAI 的 Apps SDK 是直接竞争关系。
Tasks:从核心规范的实验性功能迁移为扩展,围绕新的无状态模型重新设计。服务器通过 tools/call 的响应返回 task handle,客户端用 tasks/get、tasks/update、tasks/cancel 驱动。tasks/list 被移除了——因为没有 session,跨客户端列任务没有明确定义的作用域。
| 2025-11-25 | 2026-07-28 | |
|---|---|---|
| 定位 | 核心功能(实验性) | 扩展(正式) |
| 任务创建 | 客户端主导 | 服务器主导(作为 tools/call 响应返回) |
| 获取任务 | tasks/result(阻塞) |
tasks/get(轮询) |
| 任务输入 | 重发 tools/call |
tasks/update 发送 inputResponses |
tasks/list |
存在 | 移除 |
扩展框架是我认为这次修订第二重要的变更,仅次于无状态核心。它是治理层面的回答——Rich UI、持久化任务、Agent 交接这些需求不该放在一个 wire specification 里。MCP 灵感来源 Language Server Protocol 的经验是:规范只有把演化面限定好,才能长期保持可用。
4. 授权加固
六个 SEP,修补了 MCP 在 OAuth 2.1 / OIDC 部署中的多个细节问题。
最关键的是 SEP-2468:客户端必须验证授权响应中的 iss 参数(按 RFC 9207),防止 mix-up 攻击——即一个授权服务器的响应被重放到另一个。OAuth 的 mix-up 攻击从 2016 年起就在野外被武器化。MCP server 作为受保护资源,MCP client 继承了同样的威胁模型。利用成本低,因为攻击面小。这个 SEP 建议所有客户端在 8 月之前就实现。
其他几个:动态客户端注册时声明 application_type、客户端凭据绑定到颁发者、刷新令牌 scope 语义明确化、权限逐步升级时 scope 累积定义、.well-known discovery 后缀稳定化。
5. 弃用政策:删得慢比改得快更重要
Roots、Sampling、Logging 三项功能被标记为弃用(Deprecated),但不会被删除。新生命周期政策(SEP-2577 + SEP-2596)规定从 Deprecated 到 Removed 至少 12 个月。7 月 29 日调用 roots/list 依然能得到有效响应。
| 弃用功能 | 原因 | 迁移目标 |
|---|---|---|
| Roots | 与无状态设计不符 | 工具参数(inputSchema)、资源 URI |
| Sampling | 明确责任边界 | 客户端直接对接 LLM Provider API |
| Logging | 推荐行业标准工具 | stdio: stderr;结构化: OpenTelemetry |
这件事本身比弃用了什么更重要。社区历史上,非正式地移除东西往往引发几个月的争论。把规则写下来,弃用就变成了常规操作。
迁移时容易踩的三个坑
一、把 session 状态留在服务器进程里。 从有状态版本直接移植,没有重新考虑持久化。新契约要求你把所有 per-session 关心的东西(购物篮 ID、浏览器 ID、工作流 handle)外化为工具返回的不透明 handle,客户端下次请求时传回来。
二、忽略路由头。 Mcp-Method 和 Mcp-Name 不是可选的,是必选的。网关会拒绝缺少这些头的请求。如果你的客户端 SDK 是旧版,重新生成。
三、误解 requestState。 它不透明(客户端不能解析),但不是 secrets。服务器对它签名或加密,保证往返不丢失即可。不要把它当成 session token 来管理权限。
我的判断
这次修订做的事,比"修几个 bug 加几个功能"大得多。它重新定义了 MCP 的运行前提——从"需要一个有状态的连接"变成"可以在无状态 HTTP 上运行"。
对个人开发者来说是架构平权。以前要让一个 MCP server 扛住并发,要处理 sticky session、搭 session store、做深度包检测。现在一个普通轮询负载均衡后面挂几个无状态实例就能横向扩展。一个人能架起以前需要小团队维护的东西。
对平台和网关厂商来说,路由头让 MCP 流量从路由层面跟普通 API 无差别。这是生态基础设施化的关键一步。
MCP 4 月给出的 2026 年路线图承诺了四个方向:传输层可扩展性、Agent 通信、治理成熟度、企业就绪。这次 RC 全部覆盖。SDK 有 10 周验证窗口,Tier 1 SDK 预计在窗口内交付。我的建议是趁早迁移,别等到临界日被动改。