文章摘要
5月21日官方冻结MCP候选发布版本,7月28日发布最终版规范,这是其推出近两年后最大规模的更新,协议设计回归无状态模式。此次更新调整了底层架构,虽解决了运维痛点,但开发者评价不一。更新围绕让请求独立自洽的目标,带来多方面优化,但也有迁移成本。维护团队设置验证期、提供SDK,定义迁移路径助力适配。

Model Context Protocol(MCP)在推出近两年后,迎来了官方口中发布以来规模最大的一次更新,不过这次更新的方向却出人意料——协议设计回归了类似传统HTTP的无状态模式。官方于5月21日冻结了候选发布版本,并于7月28日发布了最终版的规范。

乍看之下,这份更新日志的改动幅度相当大:会话和初始化握手将被移除,三个核心功能将被弃用。但仔细分析后会发现,这次修订实际上是将原本需要协议自身承担的工作交还给行业已成熟的专用基础设施,从而大幅简化MCP本身。对于运维人员来说,这解决了长期存在的痛点:运行远程MCP服务器,本就不应该需要普通无状态服务不需要的专用复杂装置。

这次更新彻底调整了MCP的底层架构:移除了初始化握手流程,废除了会话粘滞机制,要求每个请求都必须独立携带完整的上下文信息。这意味着远程MCP服务器可以像普通无状态HTTP服务一样部署,直接使用轮询调度策略即可,无需配置会话亲和性规则。不过不少开发者对此评价两极,有人认为MCP好不容易从不够完善的SSE演进到成熟的WebSocket,这次改动又将协议拉回了早期的设计思路。

AgentStatus创始人Román Moskalenko在社交平台上直言:“看到MCP这次更新了吗?MCP刚刚实现了无状态化,这是发布以来最大的一次变动。不再需要握手,不再需要粘性会话,每个请求都携带自己的上下文。现代协议和旧版协议共存的阶段会非常混乱,故障率可能比现在还要高——我们已经做好了准备。”

MCP 带来的开销

要理解这次颠覆性的调整,需要先回顾MCP的设计演变与实际部署之间的差距。MCP最初作为桌面应用的本地通信协议,通过标准输入输出与本地进程交互,此时通过持久连接建立握手的成本极低。但随着远程部署和水平扩展成为主流,原有设计中的会话机制逐渐暴露出问题:服务器会生成Mcp-Session-Id将客户端与特定实例绑定,为了实现水平扩展,运维团队不得不配置会话亲和性、共享会话存储,或者开发具备MCP感知能力的网关来解析请求正文以确定路由,这无疑增加了部署的复杂度。此外,能力协商在连接建立时一次性完成,导致不同连接的能力列表存在差异,跨会话或中间件的缓存变得难以维护。

维护者的优化目标

这次六项规范增强提案都围绕着一个核心目标:让每个请求都能独立自洽。现在,协议版本和客户端能力信息会通过_meta字段在每次调用中传递,客户端还可以在其中携带身份信息。新增的server/discover方法允许服务器能力既可以在初始连接时查询,也可以在需要时单独获取,官方将这种设计称为“按需付费复杂度”原则:保持协议核心精简,仅在必要时才引入有状态逻辑。

不少开发者会质疑,很多服务器场景都需要保留状态信息,对此协议给出的主要解决方案是显式句柄。这和HTTP购物车的设计逻辑一致:工具生成一个唯一标识,将其包含在返回结果中,客户端在后续调用中作为普通参数传递回去。账户状态、资源URI、任务句柄和数据库标识符都可以采用这种模式。需要注意的是,这类句柄对模型是可见的,可以在不同工具和工作流步骤间传递,但必须将其绑定到经过身份验证的主体,每次使用时都要验证权限,不能直接将句柄作为授权凭证。

开发人员具体会得到什么

对于服务器开发者来说,这次调整最大的价值在于远程MCP服务器终于可以像传统无状态HTTP服务一样运维。采用轮询调度的多个服务器副本,无需配置会话亲和性,也不需要运行或维护协议会话存储。滚动部署不会再导致会话失效,客户端也不会被绑定到已下线的实例,虽然仍可能中断正在处理的请求和订阅流,但客户端可以通过新的请求ID重新发起请求。

对于平台团队来说,新增的Mcp-Method和Mcp-Name标头让网关无需解析请求正文就能按操作进行速率限制或授权,不过这需要遵循传输验证规则,后端会拒绝标头与正文不符的请求,中间节点也会拒绝无法保证该检查的旧版本协议。缓存机制也得到了优化,受影响的列表和读取结果现在需要包含ttlMs和cacheScope字段,参考HTTP Cache-Control规范,让客户端可以在指定时间内缓存目录信息而无需重新获取。

不过需要明确的是,协议层的无状态性仅带来了可路由性,而非确定性——两个相同版本的副本处理相同请求可能会返回不同结果,取决于它们读取的下游数据。

为什么要关心扩展

这次更新中,扩展机制的变化同样值得关注。现在扩展拥有了命名空间标识符,官方扩展使用io.modelcontextprotocol命名空间,第三方扩展则使用作者拥有的反向域名,各自拥有独立的存储库和发布周期。这种模式和Kubernetes自定义资源定义的设计一致,允许功能在核心发布流程之外独立迭代。

以任务功能为例,它最初作为实验性核心功能在2025年11月发布,但在生产环境中暴露了设计问题,随后被重新设计为扩展功能。将其移出核心虽然是破坏性变更,但后续迭代可以通过功能标志或版本控制来演进,无需强制整个生态同步升级。MCP应用现在也作为扩展纳入了正式的管理协商框架,替代了此前缺失的标准化流程。

弃用策略带来了什么

官方还为所有特性定义了完整的生命周期策略,分为“活跃”、“已弃用”和“已移除”三个状态。从特性被标记为“已弃用”的版本起,至少保留十二个月的过渡期,除非存在紧急安全风险,此时最短过渡期也不能少于90天。公共注册表会列出即将淘汰的特性和具体时间,只有当对应的测试用例被纳入符合性测试套件后,标准提案才能达到最终版状态。

对于开发者来说,这种明确的弃用策略让MCP集成的长期规划变得更加清晰,尤其是需要向平台评审委员会证明集成合理性的团队来说,书面的弃用保证比任何具体特性都更有价值。

本次更新的代价是什么

当然,这次更新并非没有成本。任何基于实验性Tasks API构建的系统都需要迁移到新的生命周期,曾向客户端发起独立请求的服务器也需要切换为多轮次请求模式:服务器返回需要的后续请求信息,客户端根据响应重试。服务器还需要对回显的requestState进行身份验证,确保其不会影响授权或业务逻辑,一次性工作流也需要独立的重放跟踪机制。

采样机制是最典型的迁移案例:使用客户端中介式采样的服务器不需要提供商凭证,也不会承担模型账单,但直接调用提供商API会让服务器成为凭证持有者、账单方和用户数据的独立处理者。日志记录也是如此,stderr和OpenTelemetry虽然解决了运维的可观测性问题,但无法为远程客户端提供以往结构化日志流的替代方案。需要明确的是,应用状态并没有消失,句柄、购物车、任务记录和幂等性密钥依然需要存储位置,协议不再管理状态,但不代表状态本身被移除。

未来展望

在协议推出不到两年的时间里就移除基础抽象,是一项经过深思熟虑的风险。维护团队通过设置十周的验证期,并提供Python、TypeScript、Go和C#的测试版SDK来对冲风险。他们还定义了清晰的迁移路径:客户端首先通过server/discover方法探测服务器支持的协议版本,遇到仅支持旧版协议的服务器时,自动回退到initialize流程。这种不强制同步升级的过渡方案,让生态系统可以逐步适配新协议。

发布候选窗口是梳理会话依赖和进行测试的最佳时机,待方案获得批准且SDK稳定后,就可以进行生产部署。从单个服务器开发者到平台团队,再到围绕协议构建网关和注册中心的服务商,最终都将在现有基础设施之上,获得一个可以兼容行业成熟运营体系的协议层。

以上内容不代表本平台立场,仅供读者参考