Skip to content

MCP Streamable HTTP 传输协议详解

Model Context Protocol(MCP)是一种开放标准,旨在为 AI 应用提供统一的上下文交互接口。2025 年 3 月,MCP 规范迎来了重要更新:引入了 Streamable HTTP 传输协议,取代了之前的 HTTP+SSE 传输方式。本文将深入介绍 Streamable HTTP 的原理、特性和优势,帮助开发者理解这一新的传输机制。

1. MCP 传输协议概述

MCP 使用 JSON-RPC 编码消息,所有消息必须使用 UTF-8 编码。当前协议定义了两种标准传输机制:

  1. STDIO(标准输入输出):通过标准输入和输出流进行通信,客户端将 MCP 服务器作为子进程启动
  2. Streamable HTTP:服务器作为独立进程运行,使用 HTTP POST 和 GET 请求处理多个客户端连接

在规范版本 2025-03-26 中,Streamable HTTP 正式取代了协议版本 2024-11-05 中的 HTTP+SSE 传输方式。这一变化标志着 MCP 从开发者本地工具向「MCP 服务即服务」(MCP Servers as a Service)的企业级应用迈进。

2. Streamable HTTP 核心原理

2.1 基本架构

在 Streamable HTTP 传输模式下,服务器作为独立进程运行,能够处理多个客户端连接。服务器必须提供一个单一的 HTTP 端点路径(称为 MCP 端点),同时支持 POST 和 GET 方法。例如,端点 URL 可能是 https://example.com/mcp

2.2 消息发送机制

客户端向服务器发送的每个 JSON-RPC 消息都必须是一个新的 HTTP POST 请求。具体规则如下:

  1. 客户端必须使用 HTTP POST 向 MCP 端点发送 JSON-RPC 消息
  2. 客户端必须包含 Accept 头,列出 application/jsontext/event-stream 作为支持的内容类型
  3. POST 请求体必须是单个 JSON-RPC 请求、通知或响应

对于不同类型的输入,服务器的响应方式也有所不同:

输入类型服务器响应
JSON-RPC 响应或通知返回 HTTP 202 Accepted(无响应体)
JSON-RPC 请求返回 text/event-stream(SSE 流)或 application/json(单个 JSON 对象)

2.3 服务器消息监听

客户端可以通过 HTTP GET 请求打开 SSE 流,允许服务器主动向客户端发送消息,而无需客户端先通过 POST 发送数据。这种机制支持:

  • 服务器主动推送 JSON-RPC 请求和通知
  • 实时事件流传输
  • 双向通信能力

3. 会话管理机制

MCP 会话由客户端和服务器之间的逻辑相关交互组成,从初始化阶段开始。Streamable HTTP 提供了完整的会话管理能力:

3.1 会话 ID 分配

服务器在初始化时可以通过 Mcp-Session-Id 头分配会话 ID:

text
HTTP/1.1 200 OK
Content-Type: application/json
Mcp-Session-Id: a1b2c3d4-e5f6-7890-abcd-ef1234567890

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-11-25",
    "capabilities": { ... }
  }
}

会话 ID 的要求:

  • 必须是全局唯一且加密安全的(如安全生成的 UUID、JWT 或加密哈希)
  • 只能包含可见 ASCII 字符(范围从 0x210x7E
  • 客户端必须以安全方式处理会话 ID

3.2 会话生命周期

会话管理遵循以下流程:

  1. 会话创建:服务器在初始化响应中返回 Mcp-Session-Id
  2. 会话维持:客户端在后续所有 HTTP 请求中包含该会话 ID
  3. 会话终止:服务器可随时终止会话,之后必须对包含该会话 ID 的请求返回 HTTP 404
  4. 会话删除:客户端可发送 HTTP DELETE 请求显式终止会话

4. 可恢复性与消息重传

Streamable HTTP 的一个重要特性是支持断线恢复和消息重传,这对于生产环境中的可靠性至关重要。

4.1 事件 ID 机制

服务器可以为 SSE 事件附加 id 字段,遵循 SSE 标准:

text
id: evt-12345
event: message
data: {"jsonrpc":"2.0","method":"tools/progress","params":{...}}

事件 ID 必须在会话内的所有流中全局唯一,并且应该编码足够的信息来识别来源流。

4.2 断线恢复流程

当客户端需要在断线后恢复时:

  1. 客户端向 MCP 端点发送 HTTP GET 请求
  2. 请求中包含 Last-Event-ID 头,指示最后接收到的事件 ID
  3. 服务器可以使用此头重放断线后本应发送的消息
  4. 恢复始终通过带有 Last-Event-ID 的 HTTP GET 进行

5. 安全性考虑

5.1 DNS 重绑定防护

服务器必须验证所有传入连接的 Origin 头以防止 DNS 重绑定攻击:

python
def validate_origin(request):
    origin = request.headers.get('Origin')
    if origin and origin not in ALLOWED_ORIGINS:
        return Response(status=403, body={
            "jsonrpc": "2.0",
            "error": {
                "code": -32600,
                "message": "Invalid origin"
            }
        })

5.2 安全最佳实践

措施说明
Origin 验证必须验证 Origin 头,无效时返回 HTTP 403
本地绑定本地运行时应只绑定到 localhost(127.0.0.1)
身份验证应为所有连接实现适当的身份验证
HTTPS生产环境中必须使用 HTTPS

6. 与 STDIO 传输的对比

理解 Streamable HTTP 和 STDIO 传输的区别有助于选择合适的传输方式:

特性STDIOStreamable HTTP
通信媒介本地进程 STDIN/STDOUTHTTP/HTTPS 端点
延迟非常低(本地进程通信)中等(网络 + HTTP 开销)
部署仅限本地机器远程/云端/Web
多客户端支持否(1:1 客户端-服务器)是(并发连接)
可扩展性有限(单进程)高(水平扩展)
网络暴露无(仅本地)是(需要安全措施)
会话管理进程生命周期可选的 Mcp-Session-Id
流恢复不适用支持 Last-Event-ID
适用场景CLI 工具、IDE、本地开发云服务、API、SaaS

7. Streamable HTTP 的核心优势

7.1 企业级可扩展性

Streamable HTTP 使 MCP 能够支持企业级应用场景:

  • 负载均衡:可以部署在负载均衡器后面,实现流量智能分发
  • 水平扩展:支持多服务器部署,满足高并发需求
  • 会话持久性:通过会话管理确保用户体验的连续性

7.2 灵活的响应模式

服务器可以根据请求特性选择合适的响应方式:

  1. 简单 JSON 响应:适用于快速、一次性的请求
  2. SSE 流式响应:适用于长时间运行的任务或需要实时更新的场景
javascript
// 服务端示例:根据请求类型选择响应模式
async function handleRequest(request) {
  const isLongRunning = estimateExecutionTime(request) > 5000;

  if (isLongRunning) {
    // 返回 SSE 流,支持进度更新
    return new Response(sseStream, {
      headers: { 'Content-Type': 'text/event-stream' }
    });
  } else {
    // 返回简单 JSON 响应
    return new Response(JSON.stringify(result), {
      headers: { 'Content-Type': 'application/json' }
    });
  }
}

7.3 可靠的断线恢复

通过事件 ID 和 Last-Event-ID 机制,客户端可以在网络中断后无缝恢复,确保消息不丢失。这对于以下场景特别重要:

  • 移动网络环境下的不稳定连接
  • 长时间运行的 AI 任务
  • 关键业务流程的可靠性保障

7.4 向后兼容性

规范提供了完整的向后兼容性指南:

服务器端:可以同时托管旧传输方式的 SSE 和 POST 端点,以及新的 Streamable HTTP 端点。

客户端:可以通过以下流程自动检测服务器类型:

  1. 尝试向服务器 URL POST InitializeRequest
  2. 如果成功,假定为支持 Streamable HTTP 的服务器
  3. 如果返回 400/404/405 错误,回退到旧的 HTTP+SSE 传输

8. 协议版本头

使用 HTTP 时,客户端必须在所有后续请求中包含 MCP-Protocol-Version 头:

text
MCP-Protocol-Version: 2025-11-25

这允许 MCP 服务器根据协议版本做出适当响应。如果服务器未收到此头,且无其他方式识别版本,应假定协议版本为 2025-03-26

9. 总结

Streamable HTTP 传输协议的引入是 MCP 发展的重要里程碑。它为协议带来了以下关键能力:

  1. 可扩展性:支持企业级部署和多客户端并发
  2. 可靠性:内置断线恢复和消息重传机制
  3. 灵活性:支持简单响应和流式响应两种模式
  4. 安全性:提供完整的安全防护指南
  5. 兼容性:平滑过渡,支持旧版本客户端和服务器

对于开发者而言,选择传输方式应基于具体需求:

  • 本地开发、CLI 工具、IDE 集成 → 选择 STDIO
  • 云服务、Web 应用、多用户 SaaS → 选择 Streamable HTTP

随着 MCP 生态系统的不断发展,Streamable HTTP 将成为构建下一代 AI 应用的关键基础设施,为 AI Agent 与外部工具和数据源的集成提供标准化、可靠的通信方式。

参考资料