MLog
返回文章列表
Tech#MCP#AI Agent#Protocol

MCP 2026-07-28:扔掉 Session,拥抱无状态

发布于: 2026年7月14日阅读时长: 13 min

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。客户端收集完输入后,把 inputResponsesrequestState 一起重发。协议层不持有任何连接状态。

{
  "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 等列表接口的响应带上 ttlMscacheScope,参照 HTTP Cache-Control 语义。客户端有标准化的缓存依据,服务器有标准化的失效声明。

分布式追踪(SEP-414):W3C Trace Context 正式纳入规范,traceparenttracestatebaggage 三个 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/gettasks/updatetasks/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-MethodMcp-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 预计在窗口内交付。我的建议是趁早迁移,别等到临界日被动改。