MCP 最新 RFC 更新! 从状态服务器切换为无状态、可恢复的纯 HTTP 实现!

MCP 的可流式 HTTP 传输提案

本文翻译并整理自 GitHub Pull Request #206,介绍了 Model Context Protocol (MCP) 的可流式 HTTP 传输方案。这一方案旨在解决当前 HTTP+SSE 传输的局限性,同时保留其优势。

特别感谢 @atesgoral@topherbullock(Shopify)、@samuelcolvin@Kludex(Pydantic)、@calclavia、Cloudflare、LangChain、Vercel、Anthropic 团队以及 MCP 社区的众多成员!本提案得以成型离不开 GitHub 讨论 中收到的宝贵反馈。


简要概述 (TL;DR)

与当前的 HTTP+SSE 传输 相比,新提案:

  1. 移除 /sse 端点;
  2. 所有客户端到服务器的消息通过 /message(或类似)端点发送;
  3. 所有客户端到服务器的请求可由服务器升级为 SSE,用于发送通知或请求;
  4. 客户端在请求头中提供会话 ID(Mcp-Session-Id),服务器可根据需要处理;
  5. 客户端可通过空的 GET 请求到 /message 发起 SSE 流。

此方法支持向后兼容,并允许服务器实现完全无状态设计。


动机

当前远程 MCP 使用 HTTP+SSE 传输,存在以下问题:

  • 不支持断点续传;
  • 要求服务器维持高可用性的长连接;
  • 仅能通过 SSE 传递服务器消息。

优势

  • 支持无状态服务器:不再需要高可用性的长连接;
  • 纯 HTTP 实现:无需 SSE 即可在普通 HTTP 服务器上实现 MCP;
  • 基础设施兼容性:仅使用标准 HTTP,与中间件和基础设施无缝兼容;
  • 向后兼容性:是对现有传输的渐进式改进;
  • 灵活升级路径:服务器可选择在需要时使用 SSE 进行流式响应。

示例用例

无状态服务器

完全无状态、不支持长连接的服务器可按以下方式实现:

  1. 始终确认初始化请求(无需持久化任何状态);
  2. 对任何 ToolListRequest 返回单一 JSON-RPC 响应;
  3. 处理 CallToolRequest,执行工具,完成后以单一 CallToolResponse 作为 HTTP 响应体。

支持流式的无状态服务器

无状态服务器仍可利用流式设计。例如,在工具调用期间发送进度通知:

  1. 当收到 CallToolRequest 的 POST 请求时,服务器指示响应将使用 SSE;
  2. 服务器开始执行工具;
  3. 在工具执行期间,通过 SSE 发送任意数量的 ProgressNotification;
  4. 工具执行完成后,通过 SSE 发送 CallToolResponse;
  5. 服务器关闭 SSE 流。

有状态服务器

有状态服务器的实现与当前类似。主要区别在于服务器需处理 Mcp-Session-Id 请求头,并利用它在消息总线上路由消息。例如,在水平扩展部署中,POST 消息可能到达任意服务器节点,需通过服务器端持久存储(如 Redis)连接到现有会话。


为什么不使用 WebSocket?

核心团队深入讨论了将 WebSocket 作为主要远程传输(替代 SSE)并使其支持断开和续传的可能性,但最终决定暂不采用,原因如下:

  1. 如果将 MCP 用作"类 RPC"方式(例如,仅暴露基本工具的无状态服务器),每次调用都使用 WebSocket 会带来不必要的运营和网络开销;
  2. 在浏览器中,无法为 WebSocket 附加头信息(如 Authorization),且第三方库无法从头实现 WebSocket(不像 SSE);
  3. 只有 GET 请求可透明升级为 WebSocket(其他 HTTP 方法不支持升级),这意味着 POST 端点需两步升级流程,增加复杂性和延迟。

我们也避免将 WebSocket 作为规范中的额外选项,以限制官方指定的传输协议数量,避免客户端与服务器间的组合兼容性问题。(不过,这不妨碍社区非标准地采用 WebSocket 传输。)

本提案不排除未来进一步探索 WebSocket,如果 SSE 效果不佳。


待办事项

  • 将会话 ID 责任移交至服务器端

    • 定义会话 ID 的有效范围
    • 确保会话 ID 可被中间件/WAF 检查
  • 明确取消机制

  • 要求集中式 SSE GET 用于服务器到客户端的请求和通知

  • 将续传功能转化为按流概念

  • 支持批量客户端到服务器消息

  • 设计主动"结束会话"的方式

  • "如果客户端持有授权令牌,应在每个 MCP 请求中包含它"


补充说明

如果客户端持有授权令牌(auth token),它应当在每个 MCP 请求中包含该令牌,以确保安全性与身份验证的连续性。这一要求将进一步明确并纳入规范。


MCP 最新 RFC 更新! 从状态服务器切换为无状态、可恢复的纯 HTTP 实现! 感觉这一波兼容性又拉大了,肉眼可见会小起飞一波 以上内容整理自提案原文,旨在清晰传达其核心思想与技术细节。如需更深入探讨,欢迎参考原始文档或参与讨论!

相关推荐
Dm_dotnet5 小时前
使用Avalonia/C#构建一个简易的跨平台MCP客户端
mcp
Captaincc6 小时前
MCP在AI驱动UI设计中的应用
mcp
耿玉10 小时前
大模型应用中我们为什么需要MCP
前端·deepseek·mcp
敲代码的小霖10 小时前
UML-MCP-Server -cursor适用
uml·cursor·mcp
ivygeek14 小时前
MCP:基于Java SDK 实现一个 Mcp Server
后端·mcp
伊织code19 小时前
MCP 开放协议
github·协议·模型·mcp
Captaincc1 天前
Why MCP Won-为什么MCP 可以✌️胜利
mcp·ai 编程
Captaincc1 天前
1 次搭建完胜 1 亿次编码,MCP 硅谷疯传!Anthropic 协议解锁智能体「万能手」
mcp·ai 编程
Captaincc1 天前
什么是模型上下文协议(MCP)?它如何比传统 API 更简单地集成 AI?
mcp·ai 编程