MCP 变了:会话和握手都删了,你的服务器要在 2027 年 7 月前改完

多个并排的服务器实例整齐排列在一个环形负载均衡结构之下,每个请求化作独立自足的光点包裹着自身的标识,代表 MCP 无状态协议下任意实例都可响应的架构
内容摘要

MCP 出了史上最大一次改版:会话没了、初始化握手没了,每个请求自己带上协议版本和客户端能力,任意实例都能接。旧的根目录、采样、日志三项能力进入弃用期,最少还有十二个月。本文把每条破坏性变更、六步迁移路径,以及「什么样的服务器不值得迁」讲清楚。

如果你自己跑过一台 MCP 服务器,今天这篇文章是给你写的。

十月之前,一个远程 MCP 服务想水平扩展,得做三件麻烦事:粘性路由、共享会话存储、或者在网关上做深度包检测。原因很直白——协议本身是有状态的。客户端先 initialize,服务器回一个 Mcp-Session-Id,之后每个请求都必须落到这台机器上。

2026 年 7 月 28 日发布的 MCP 新规范把这个前提删掉了。官方自己的说法是「协议自发布以来最大的一次改版」。下面把它拆成能落地的部分。

一句话说清这次改了什么

协议核心从「有状态的双向流」换成了每个请求自描述。协议版本、客户端身份、客户端能力,以前只在连接建立时交换一次,现在跟着每个请求走。结果就是任意实例都能回任何请求,普通的轮询负载均衡器就够了。

官方原话的落地效果是:一个只处理 POST、答完就退出的函数,现在也算一个合法的 MCP 服务器。

逐条对照:老写法换新写法

这部分是迁移的真清单,建议对着自己的代码过一遍。

一、初始化握手没了。 initialize 和 notifications/initialized 移除(SEP-2575)。以前在连接时读一次的客户端能力和身份,现在放到每个请求的 _meta 里:io.modelcontextprotocol/protocolVersion、clientCapabilities,可选 clientInfo。

二、新增 server/discover,而且必须实现。 客户端用它查服务器支持的协议版本、能力声明和缓存提示。注意它不是新的握手,只是能力发现,不会建立协议层会话。用官方 v2 SDK 的话,这个方法是 SDK 帮你答的;手写的服务器得自己加 handler。

三、Mcp-Session-Id 移除(SEP-2567)。 所有按会话 ID 存的缓存、鉴权上下文、多步流程都要重做。替代方案是显式 handle:工具返回一个 basket_id、ticket_id 之类的标识,由模型在后续调用里当普通参数传回来。官方的说法是这比藏在校验层里的会话状态更好——因为模型能看见这个 handle,可以在工具之间穿梭。

四、路由头。 每个请求必须带 Mcp-Method(对应 JSON-RPC 方法名,如 tools/call);调 tools/call、resources/read、prompts/get 时必须带 Mcp-Name(对应目标名)。MCP-Protocol-Version 头继续沿用。网关、限流器、WAF 可以直接按头路由,不用解析请求体。而且头里的值必须和请求体一致,不一致服务器必须拒绝——这条容易被忽略,也是最容易被用作绕过的一处。

五、服务器反过来问客户端,改成多轮往返(MRTR)。 以前的 sampling/createMessage、elicitation/create、roots/list 是服务器在打开的流上推请求给客户端。现在改成:服务器返回 resultType: "input_required" 加一组 inputRequests,客户端补齐后带着 inputResponses 重试原来的调用,可选的 requestState 原样回传。顺带一提,每个结果都要带 resultType,普通结果也要。

六、列表结果带缓存提示(SEP-2549)。 tools/list、prompts/list、resources/list、resources/read 的结果要带 ttlMs 和 cacheScope,客户端据此决定什么时候重新拉。另外 tools/list 应该返回确定顺序的工具列表。

七、几处告别。 ping 和 logging/setLevel 移除,日志改成每个请求在 _meta 里带 io.modelcontextprotocol/logLevel,不带你就不发日志。HTTP GET 流和 resources/subscribe 换成 subscriptions/listen,每个客户端一条订阅流。SSE 的断线续传(Last-Event-ID)移除,客户端改为重新发起请求——所以工具调用要设计成可以重复执行。

八、错误码改了一个。 资源找不到从 -32002 改成标准的 -32602。跑新规范的服务器不能再返回 -32002;客户端里按老码做的处理会静默失效。

九、Tasks 移出核心,进扩展。 新位置是 io.modelcontextprotocol/tasks,生命周期改成轮询:tasks/get、tasks/update、tasks/cancel,tasks/list 移除。对已经按 2025-11-25 实验版 API 写过代码的项目,这是一次明确的破坏性变更。

十、鉴权收紧。 六个 OAuth 相关 SEP 落地,覆盖签发方校验、凭据绑定和 PKCE;动态客户端注册(DCR)弃用,改推客户端 ID 元数据文档(CIMD)。

谁会立刻踩到坑

这条很关键:同一台服务器,现在要同时答两个协议时代。

站内写过的 Claude Code 插件体系背后的客户端已经在用新规范了,而一些命令行 Agent 还停在旧版。具体表现是,一个只按新规范实现的服务器,会被旧客户端拒绝;一个只按老规范写的服务器,新客户端也不认。

官方的建议是两种路线并存:新开一条严格无状态的路径,保留原有的会话路径,把功能一项项搬过去,让活动会话自然耗尽,再在弃用期内删掉老路径。客户端侧反而简单,升级版本就行。

六步迁移

按官方和几份迁移指南的交集,顺序大概是这样:

  1. 升 SDK。 TypeScript 拆成了两个包(客户端与服务端分开,v2 线);Python 走 mcp-sdk>=2.0.0;Go 是 go-mcp/v2;C# 是 McpSdk 2.x。旧版 SDK 仍会为 2025 时代的服务器维护。
  2. 清掉会话假设。 网关或路由里凡是依赖 Mcp-Session-Id 的逻辑,全部重写;需要跨调用保留的状态,改成显式 handle。
  3. 补上头。 加 Mcp-Method(全量)和 Mcp-Name(按需),并确认服务器会拒绝头体不一致的请求。
  4. 迁 Tasks。 删掉 tasks/list 的用法,换成轮询三件套。
  5. 列表加 ttlMs。 新规范要求项,客户端靠它决定重新拉取的时机。
  6. 加固鉴权。 自己写鉴权的,重点看签发方校验和 PKCE 那几条。

再加一条测试建议:写一条「故意发一个缺 Mcp-Method 的请求,断言服务器拒绝」的集成测试,并且两个协议时代各跑一遍冒烟,任一边挂掉就让流水线失败。这样迁移过程中不会顾此失彼。

不想自己改的话:托管方案已经跟上了

Cloudflare 在这次改版里是深度参与者。他们把这个能力做进了 Agents SDK 的 createMcpHandler,并且这个 handler 已经升级进官方的 TypeScript SDK。对使用者来说最省事的一点是:/mcp 端点同时接受新协议和 2025 版 Streamable HTTP 的老客户端,大部分客户端不用改配置就能重连。

他们也给了一个自用的数据点:用这套方式的 Code Mode MCP 服务器,已经跑到每秒数千请求、累计服务数十亿次工具调用。另有团队把四台企业 MCP 服务器迁到无服务器运行时,报告 p95 延迟下降三到四成,纯粹来自去掉了会话粘性和随之而来的内存状态。

站内写过 Cloudflare 的决策模型,这次它在协议层的动作更值得关注——这家公司的路线一直是「把基础设施里最烦的那部分替你做了」。

什么情况下不值得迁

官方文档很诚实地列了几种「迁了也白迁」的情况,这几条反过来最有用:

  • 只有一台实例、流量很低。 没有会话要做粘性的时候,粘性路由一分钱不花。迁移只增加工作量。
  • 工具上下文 token 才是大头。 无状态不减少工具描述的 token 消耗。官方测过一个五服务器组合,58 个工具定义大约占 5.5 万 token,内部优化前甚至到 13.4 万。这部分要靠延迟加载工具来治,不是靠这次改版。
  • 工具真的需要状态。 handle 现在要走模型上下文、当参数传递。一个被丢掉或被改坏的 handle,会把「传输层的保证」变成「提示词层的可靠性问题」。
  • 依赖已弃用能力。 用了根目录、采样、日志或老 SSE 传输的服务器,等于要迁两次。

时间表:你有多少时间

新版写进了正式的弃用生命周期:被标记弃用的能力,至少要保留十二个月才可能移除。根目录、采样、日志和动态客户端注册,最早要等到 2027 年 7 月 28 日及之后某个版本才可能下线;老的 HTTP+SSE 传输走一套单独公布的时间表。

翻译过来的意思是:不急,但别拖。 客户端 SDK 已经在升级了,兼容层不会一直替你兜着。

老达点评

第一,这次改版的价值不在「新功能」,而在「少做三件麻烦事」。粘性路由、共享会话存储、网关深包检测,是每个自己部署 MCP 的人都会撞上的坎。协议层把坎填掉,价值远大于多几个方法。

第二,无状态把状态挪了位置,不是消掉了。以前状态藏在传输层,现在变成模型可见的 handle,跟着对话走。好处是透明、可审计、可回放;坏处是它变成了提示词可靠性问题——模型传错一个 ID,锅就从基础设施转移到模型身上。做 Agent 的人对这点要有预期。

第三,Tasks 移到扩展这件事,是企业侧真正的必做项。一个长任务可能在授权过期之后还在跑,所以每个任务要能单独标识、能中途撤销、能算清成本。这些扩展本身不提供,得自己加。

第四,最值得抄的其实是那句测试建议。头体和请求体不一致必须拒绝——如果只做路由不做校验,Mcp-Name 就从「路由信息」变成了「不需要和实际执行一致的授权表面」。这类不一致,恰恰是过去一年里 Agent 出事最多的那一类。站内写过 Agent 沙箱逃逸 和 插件热加载的边界,本质都是同一句话:你要相信的那一层,一定要能独立校验。

上手第一步

不用一次改完。最省事的第一步是拿 MCP Inspector 同时开两个协议时代,各跑一遍冒烟,把现在挂掉的地方列出来——通常你会发现真正需要改的只有会话假设和几个头。今天就把这条清单建起来,比等到 2027 年再动手从容得多。

想系统看 Agent 基础设施这条线的,可以从 AI 智能体与自动化专题 和 AI 编程工具专题 往下翻。

发表评论

您的电子邮箱地址不会被公开,必填项已标注 *