返回
Kevin Riedl

10 分钟 阅读 · 2026年7月31日

下一篇
图片在你的设备上生成,不连接 Instagram。文章链接会复制到剪贴板,供链接贴纸使用。

MCP 现在无状态了吗?你自己的 MCP 服务器需要改什么

是的。从 2026-07-28 规范开始,MCP 在协议层已经是无状态的。initialize 握手与 Mcp-Session-Id 被移除。每个请求自行携带协议版本、客户端身份与能力,因此远程请求无需粘性路由,也能由任意健康实例处理。

但这里有一个关键限定:无状态 MCP 不等于无状态软件。购物篮、浏览器任务、审批流程与已付款订单仍可能需要持久状态。区别在于,这些状态必须在应用层显式建模、寻址与保护,而不能隐藏在 MCP 传输会话中。

本文只解决传输与迁移问题。如果你需要权限与租户隔离方案,请阅读企业级 MCP 授权架构。如果你想知道安全控制究竟应放在哪里,请继续阅读为什么 MCP 不是完整的安全边界

需要迁移远程 MCP 服务器,同时避免破坏现有客户端?

 规划 MCP 架构审查

最直接的答案是什么?

MCP 2026-07-28 是一个由无状态、自包含请求组成的协议。协议状态消失了,应用状态仍然允许,而且经常不可缺少。

官方规范已把“无状态、自包含请求”和“按请求协商能力”列为基础协议特性。在 Streamable HTTP 中,每条消息都是一个新的 POST。响应可以是单个 JSON 对象,也可以是仅属于该请求的 SSE 流。旧版独立 GET 流、协议会话、Mcp-Session-Id 与 SSE 恢复机制都不属于本次修订。

MCP 2026-07-28 改了什么?

问题2025-11-25 及更早版本2026-07-28
启动流程initialize,然后发送 notifications/initialized不再握手;客户端可选调用 server/discover
协议会话服务器可以签发 Mcp-Session-Id没有协议会话,也没有会话 ID
请求上下文版本与能力只协商一次版本、client info 与能力在每个请求的 _meta 中传递
HTTP 路由可能需要会话亲和或共享 session store任意实例都能处理自包含请求
HTTP 元数据网关经常需要解析 JSON bodyMCP-Protocol-VersionMcp-Method 与部分请求的 Mcp-Name 为必填
向客户端索取输入服务器可以通过 SSE 发起请求返回 input_required;客户端携带 inputResponses 与可选 requestState 重试
长时间任务核心协议内的实验性 Tasks通过官方 Tasks 扩展与持久 task handle 完成
列表结果变更通知与轮询确定性顺序,并返回 ttlMscacheScope

MCP 2026-07-28 官方 changelog列出了完整的 breaking changes,其中还包括新的 resultType、取消流恢复、支持 JSON Schema 2020-12、新错误码,以及对 Roots、Sampling、Logging 和旧 HTTP+SSE 的弃用计划。

无状态 MCP 服务器还能保存数据吗?

可以。它只是不能让后续请求依赖不可见的协议会话内存。

假设一个工具打开浏览器,另一个工具继续同一次自动化。第一次响应可以返回随机且不透明的 browser_id。客户端在下一次调用时带回这个 handle。服务器检查调用者与过期时间后,再从 Durable Object、数据库或其他存储中解析它。这个工作流有状态,但每个 MCP 请求仍然自包含。

  • 单个请求:把状态保留在局部变量中,并直接返回最终结果。
  • 连续几轮输入:input_required 中返回受完整性保护的 requestState,并将其绑定到认证主体、原始操作与过期时间。
  • 长时间任务:使用MCP Tasks 扩展与持久 taskId
  • 业务实体:返回 order_idbasket_iddocument_id 等应用 handle,并在每次使用时重新授权。
  • 持续变更通知:使用 subscriptions/listen。打开的 SSE 响应只属于该请求,并不是协议会话。

不要把 secret 或可修改的业务状态直接放进可读的 bearer handle。应优先使用不透明 ID,或者经过认证与加密的状态 token,并严格限制大小、audience 与有效期。

所有 MCP 服务器都需要迁移吗?

每个实现都应接受审计,但工作量不同。

当前服务器可能需要的工作优先级
本地 stdio,不依赖会话功能升级 SDK、schema、按请求元数据与 discovery 行为
远程 Streamable HTTP,不存储会话增加现代 wire contract、请求头校验、result type、缓存元数据与兼容测试
使用 Mcp-Session-Id、粘性路由或 session map把业务状态外置,建立 dual-era 路径,待客户端迁移后再移除会话基础设施最高
旧 HTTP+SSE先迁移到 Streamable HTTP,再完成无状态切换最高
依赖 Sampling、Roots 或协议 Logging这些功能已弃用,需要设计替代方案

服务器可以在运行时无状态,却仍使用旧协议。它也可以支持新无状态协议,同时保存应用数据。请分别审计网络协议行为与数据生命周期。

你自己的 MCP 服务器应当改什么?

  1. 清点隐藏的连接状态。搜索 session map、sticky cookie、Mcp-Session-Id、跨请求复用的 transport、按连接变化的工具列表,以及 SSE event store。把每一项标记为协议状态、短期请求状态或持久业务状态。
  2. 实现现代 discovery。服务器必须支持 server/discover,并返回支持版本、能力、server info、instructions、ttlMscacheScope。不要用服务器自报信息做安全判断。
  3. 校验每个请求的元数据。_meta 中要求版本与客户端数据。HTTP 请求还需要 MCP-Protocol-VersionMcp-Method,以及适用时的 Mcp-Name。请求头与 body 不一致时,必须返回 HeaderMismatch
  4. 让结果符合新规范并可缓存。普通结果增加 resultType: "complete"。让 tools/list 保持确定顺序。尤其当授权会改变工具集合时,应正确设置 ttlMscacheScope
  5. 用显式 handle 代替隐式状态。Handle 必须难以猜测、绑定主体、限制权限且可撤销。修改操作必须幂等,避免断流重试造成重复扣款、发送或删除。
  6. 有计划地支持两个时代。Dual-era 服务器可以无状态处理现代请求,同时为旧客户端保留 initialize。隔离这条路径,监控使用量,并设定下线日期。
  7. 测试架构,而不只是 handler。在真实 round-robin 后把连续请求发送到不同实例。测试缺失与冲突请求头、不支持的版本、过期 handle、重放、取消、重试和跨租户访问。

Streamable HTTP 官方规范定义了请求头与 mismatch 行为。决定直接切换还是 dual-era 上线前,还应阅读版本与向后兼容矩阵

我们对 Wavect 自己的 MCP 做了哪些修改?

2026 年 7 月 31 日,我们用同一份清单审查了自己的 Cloudflare Pages Function。由于不需要保留旧客户端,我们直接完成了切换。

  • 进程与协议都已无状态:handler 没有内存 session map,现在只接受自包含的 2026-07-28 请求。
  • 业务状态已经显式化:commerce 工具使用 quote ID、order ID、access token 与 idempotency key,而不是传输会话。
  • 现代 discovery 已上线:server/discover 返回支持版本、capabilities、server info、instructions 与缓存元数据。
  • HTTP contract 已强制执行:请求必须携带 MCP-Protocol-VersionMcp-Method,工具调用还必须携带 Mcp-Name。服务器会校验请求头与 body 一致性,并显式验证 origin。
  • 响应已使用 2026 结构:discovery、列表与工具调用都包含 resultType;确定性列表还包含准确的缓存元数据。
  • 旧 lifecycle 已移除:initializepingnotifications/initialized 会返回 method not found,不再保留旧协议契约。

这说明“我们不保存 MCP session”并不是完整迁移结论。运行拓扑、协议版本和响应 schema 可能处于不同阶段。对我们的服务器而言,业务状态重构很小,wire contract、安全检查与 conformance test 才是主要工作。

Kevin Riedl

"无状态 MCP 移除的是隐藏的传输内存,不是持久工作流。让状态显式、经过认证,并且能够安全重试。"

生产迁移应该如何上线?

  1. 记录现有客户端版本、transport、会话功能与错误率。
  2. 在改变生产流量前,为现代请求与结果结构增加 conformance test。
  3. 根据你对客户端的控制程度,部署 dual-era endpoint 或独立现代 endpoint。
  4. 先迁移内部与 canary 客户端,并强制连续调用落到不同实例。
  5. 监控版本错误、header mismatch、重试、延迟、重复副作用与授权失败。
  6. 发布客户端迁移日期与 rollback window。不要因为一次 SDK 测试成功就删除旧存储。
  7. 只有当遥测证明旧流量与会话依赖已经消失,才能移除粘性路由与 session store。

Cloudflare 在MCP SDK v2 迁移指南中说明了无状态 handler 与有会话功能的分阶段迁移。即使你使用其他 runtime,这种区分协议状态与应用状态的方法仍然有效。

选择 MCP 开发伙伴时应问什么?

  • 生产服务器会支持哪些协议版本与客户端时代?
  • 哪些状态只属于请求,哪些是持久数据,哪些仍依赖传输会话?
  • Handle 如何绑定身份、tenant、操作与有效期?
  • 支付、写入与外部副作用如何通过幂等性避免重复执行?
  • 团队能否证明连续两个调用可以由不同实例完成?
  • 网关与 origin 如何把 HTTP 请求头和 JSON body 互相校验?
  • 哪些内容会缓存多久,私有工具列表是否可能进入共享缓存?
  • 仍有哪些弃用功能,它们的替代方案是什么?
  • 关闭旧路径需要哪些证据:遥测、客户端清单、rollback test 与下线日期?

如果方案只写“升级 SDK”,它还不完整。商业交付应包含状态清单、兼容决策、威胁模型、迁移测试、canary 证据与回滚计划。

常见问题

MCP 现在完全无状态吗?

2026-07-28 协议核心是无状态的。应用仍可通过显式 handle、storage、Tasks 与 request state 保存持久状态。

Streamable HTTP 还存在吗?

存在。它仍是标准远程 transport,但每条消息都是独立 POST,旧 GET stream 与协议会话已被移除。

还需要发送 initialize 吗?

现代请求不需要。请使用每次请求的元数据,并按需调用 server/discover。Dual-era 服务器仍可为旧客户端处理 initialize

还需要 Redis 或 Durable Objects 吗?

MCP 协议会话不再需要。Job、订单、浏览器实例、锁、rate limit 与其他应用状态仍可能需要持久存储。

可以立刻移除 sticky session 吗?

只有现代流量已在不同实例之间通过测试,并且遥测确认受支持客户端不再依赖旧路径时才可以。

最终思考

MCP 已在协议扩展性真正需要的地方变为无状态:没有 initialize 生命周期,没有 Mcp-Session-Id,也不需要隐藏连接状态来理解请求。你的产品仍可有状态。请把状态放在显式、经过授权的 handle 后面;实现 discovery、必填请求头、现代结果结构与缓存语义;保留可监控的兼容路径;并在删除旧基础设施前,用 round-robin 证明迁移结果。

一手资料

构建产品,而不只是 backlog

如果这篇文章对应的是一个真实产品决策,Wavect 可以用高级创始人级判断帮你界定范围、构建、加固或领导软件工作。

可选服务路径:

只收重要内容

关注与你相关的内容

每当我们发布新文章,你会收到一封简短邮件。你可以关注整个博客,也可以只选感兴趣的主题。

你希望接收哪些内容?
选择主题

免费、双重确认、不使用跟踪像素。

返回
Kevin Riedl

10 分钟 阅读 · 2026年7月31日

下一篇

通过邮件获取新文章

我们发布时给你一封简短邮件。免费,不做跟踪。

免费、双重确认、不使用跟踪像素。