如果把一个网络协议比作一座房子,Model Context Protocol(MCP)这次更新几乎是把承重墙拆了重砌。5月21日,主要维护者冻结了候选版本,并预计7月28日发布最终规范。修订日志上最刺眼的一句是:会话和初始化握手将直接消失,同时还有三项核心功能被标记为弃用。任何一个接过分布式系统的人看到这句话,第一反应大概是:那服务器之间还怎么认得彼此?
答案恰恰藏在问题里:它们再也不需要刻意相认了。这一版修订的真正逻辑,是把MCP自己制造出来的分布式难题,重新交还给那些已经成熟运转的基础设施。对于运营者来说,这意味着一个远程MCP服务器终于可以像普通的无状态服务一样随意伸缩,不再需要专门为这个协议维护一套额外的状态管理装置。
![]()
消失的握手:MCP曾经对自己的用户征收的“税”
要理解为什么砍掉这些机制,得先理清原始设计和一个残酷现实之间的落差。MCP最早、也最广为人知的形态,是一个桌面应用通过标准输入输出与本地进程对话。在这种模式下,启动时的握手几乎是免费的——一个长时间、低延迟的持久连接上,互相通报一下能力、交换一个会话标识,再自然不过。那个时候,没有人觉得这是成本。
问题出在服务器搬家之后。当越来越多的MCP服务跑到远端,部署在水平扩展的集群里时,那张看似无害的会话标识——Mcp-Session-Id,立刻变成了一根钉在可伸缩性上的钉子。因为服务器一旦给客户端签发了这个ID,后续所有请求就必须落到当初签发它的那个实例上。要绕开这个限制,团队往往要在网关层做会话亲和性,或者维护一个所有实例都能访问的外部会话存储,再不然就是开发一套能解析JSON请求体、根据会话信息决定路由的MCP专用网关逻辑。
换句更直白的话说,一个团队在发布一个MCP服务器的时候,等于被迫去解决一个该协议自己凭空制造出来的分布式系统难题。他们本可以把精力花在工具逻辑本身,却不得不先给协议擦屁股。这种额外的工程负担,被一些开发者戏称为“MCP税”。
能力协商的代价同样不容忽视。原始设计中,双方的技能清单只在连接建立时交换一次。这意味着同一客户端与不同实例建立连接时,得到的能力列表很可能不一样。这个特性直接破坏了跨会话、跨中间件统一缓存的可能性,让任何试图加一层共享代理或缓存层的做法都变得非常难推理。而对于做平台的人来说,不能缓存就意味着更高的延迟、更低的吞吐和更高的成本。
无状态化:让每个请求都自己携带全部上下文
这一轮更新之所以值得单拿出来讲,是因为维护者没有采用打补丁的思路,而是直接推翻了旧有的状态模型。六份规范增强提案(Specification Enhancement Proposals)不约而同地指向同一个目标:让每一个请求都能独立站立。
实现这一点的手法相当干脆。协议版本号和客户端能力现在不再靠握手一次性完成交换,而是放进了一个名叫_meta的字段里,随着每一次调用一起搬运。客户端也被鼓励把自己的身份信息塞进这个_meta里。与此同时,新增的server/discover方法则让服务器的能力清单变成一个随时可以独立查询的资源——既可以在开始时查,也可以在需要的任何时候查。
维护团队在发布说明里给这种做法取了个名字,叫“按需付费的复杂性”。翻译成工程语言就是:核心永远保持瘦骨嶙峋,只有在功能真的需要状态时,状态才会冒出来。如果你只是想做最简单的工具调用,那些复杂的状态管理机制就跟你毫无关系。
有人可能立刻会反问:但很多服务器就是需要记住东西的啊,比如跨多个工具调用的上下文、用户偏好、会话历史,总不能每次都让模型重头开始讲吧?维护者对这个问题给出了一个毫不花哨的答案——显式句柄。这个模式已经在HTTP购物车系统里跑了二十年。一个工具创建资源时返回一个类似basket_id的句柄,模型再把这个句柄当成普通参数,在下一次调用时原样传回去。账户状态、资源锚点、多步任务的中间产物,都可以通过这种显式传递的方式在完全无状态的链路里穿梭。
这种处理方式最大的好处,是它把状态管理从协议层卸载到了应用层和基础设施层。一个普通的负载均衡器、一个常规的无状态容器编排系统,不需要知道任何MCP专属的逻辑,就能把流量均匀地分发给任意多个服务器副本。会话亲和性、共享存储、定制网关,这三样过去几乎标配的额外组件,在大多数场景下可以一并被删除。
从“连接即状态”到“调用即自足”
如果回顾这次更新的原始动机,会发现一个容易被忽略的微妙转向。早期的MCP更像一个面向本地对话的有状态通道,而维护者现在显然在把它重塑成一个面向互联网规模的无状态服务接口。这种转变不止是技术架构上的,也是对开发者心智模型的修正。
过去,当人们开发一个MCP服务器时,心里想的是“我和客户端之间有一个持续的生命周期,我们会先互相介绍自己,然后保持一个长久的连接,在这个连接上完成一系列相关操作”。这几乎就是一个迷你会话管理器的思路。而在新的规范下,这种思路被替换成了“每一个请求就是一个完整的世界,我可以随时随地查询彼此能做什么,任何需要延续的状态都由调用链路显式传递”。
这两种模型的差异,反映在工程实践上就是巨大的自由度的变化。以前,为了部署一个被多个客户端并发的远端MCP服务,团队需要自己实现一个类似反向代理但又能解析MCP握手消息的入口,或者必须使用支持MCP感知的网关产品。而现在,一个普通的HTTP负载均衡器就可以直接顶上,因为再也没有连接级的特殊初始化步骤需要被拦截和理解。
对于已经投入大量工程精力去打磨那些自定义的会话管理机制的团队来说,这次更新可能会带来短暂的不适应。但从长期看,把协议层的强制状态挪到应用设计的显式交互里,本身就是向成熟基础设施靠拢的标志。这种做法与曾经的Corba、早期的SOAP等协议追求“无所不包的中间件智能”的道路正好相反:MCP正在主动放弃这种智能,承认HTTP和其他底层基础设施在无状态请求路由、缓存和高可用方面的经验远比自己沉淀得多。
更有趣的是,这次改动的冲击波并不会只停留在服务器部署这一个环节。客户端同样会变得简单。过去客户端需要精心管理会话生命周期,处理可能出现的连接断开后重新握手的逻辑,甚至要配合服务器端实现重连时的状态恢复。在新的规范下,客户端可以把这些都抛掉,因为请求失败只需重试一次没有前置依赖的调用,而不必操心是否要重新走一遍握手。
同时,把能力查询从连接建立时的静态行为变成随时可调用的动态API,也为更智能的运行时优化打开了大门。一个客户端可以根据调用的工具动态决定是否需要再次拉取服务器的能力清单,不必在启动时就加载一个包含所有服务器全部能力的庞大列表,这对于那些需要同时对接数十个MCP服务的复杂应用场景来说,带来的内存和启动速度上的改善会非常明显。
旧机制的终结,也是新惯性的开始
任何大规模协议重构都会面临一个实际问题:社区里大量已经按照旧规范实现的服务器怎么办?此次更新候选版本冻结的消息同时附带了一个清晰的弃用时间线。三项核心功能——原始会话模型、初始化握手和能力协商——将在正式规范发布后进入弃用期,现有的实现不会被立刻抛弃,但所有后续更新的官方工具和参考实现都将基于新规范构建。
对于那些单纯依赖MCP工具链的团队来说,升级路径已经基本铺好。维护者在SDK层面封装了大多数从有状态到无状态的迁移细节。只要升级到新的SDK版本,旧的手动管理会话ID的代码可以被直接移除,_meta和server/discover的交互逻辑会被自动注入。
然而,对于自己从头实现了协议的团队,尤其是那些为了跨语言支持或定制化需求而手动处理JSON-RPC消息和TCP链接的团队来说,工作量并不小。他们需要自己消化新版规范文档,重新实现消息头的传递、_meta字段的构造、对server/discover的响应处理,以及将所有原本依赖服务端存储的状态切换到显式句柄模式。
但从社区的反应来看,多数长期维护者给出的反馈是积极的。原因在于,比起当年为了支持远程部署而在网关层和会话管理上投入的持续工程成本,这次一次性迁移的投资回报率是明确且可度量的。一个直接的证据就是,已经有团队提前试用了候选版本,并报告了移除自定义会话亲和层后,服务器集群的平均响应延迟下降了近三分之一——这里节省的时间,正是因为路由层不再需要解开负载来读取会话信息。
从更宏观的视角看,MCP这次更新相当于验证了一条规律:任何从本地对话起家的协议,当它演化到需要支撑大规模分布式交互时,迟早要对初始设计中隐含的状态绑定做手术。MCP的选择是,把手术刀向下挥,直接切掉病灶,而不是用绷带和支架凑合。对于所有正在观望或正在基于MCP构建服务的人来说,这无疑是一个值得关注的信号——未来的MCP生态,会更像是一组自由伸缩的无状态微服务,而不是一个需要细心呵护管理连接的繁重框架。
在技术历史上,主动解除自身复杂性的协议并不多见。MCP的做法不禁让人想起HTTP/2与HTTP/3之间的迭代,也同样是选择把底层传输交给更合适的协议,而不是在自己内部造一个万能的传输层。当协议设计者愿意承认“有些事不该我做”,往往意味着它的适用范围会扩展到一个更大的舞台。MCP这次的“减法”,很可能会成为它从集成工具链走向通用Agent互联协议过程中的一枚关键落子。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.