MCP Streamable HTTP 传输协议详解
Model Context Protocol(MCP)是一种开放标准,旨在为 AI 应用提供统一的上下文交互接口。2025 年 3 月,MCP 规范迎来了重要更新:引入了 Streamable HTTP 传输协议,取代了之前的 HTTP+SSE 传输方式。本文将深入介绍 Streamable HTTP 的原理、特性和优势,帮助开发者理解这一新的传输机制。
1. MCP 传输协议概述
MCP 使用 JSON-RPC 编码消息,所有消息必须使用 UTF-8 编码。当前协议定义了两种标准传输机制:
- STDIO(标准输入输出):通过标准输入和输出流进行通信,客户端将 MCP 服务器作为子进程启动
- 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 请求。具体规则如下:
- 客户端必须使用 HTTP POST 向 MCP 端点发送 JSON-RPC 消息
- 客户端必须包含
Accept头,列出application/json和text/event-stream作为支持的内容类型 - 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:
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 字符(范围从
0x21到0x7E) - 客户端必须以安全方式处理会话 ID
3.2 会话生命周期
会话管理遵循以下流程:
- 会话创建:服务器在初始化响应中返回
Mcp-Session-Id - 会话维持:客户端在后续所有 HTTP 请求中包含该会话 ID
- 会话终止:服务器可随时终止会话,之后必须对包含该会话 ID 的请求返回 HTTP 404
- 会话删除:客户端可发送 HTTP DELETE 请求显式终止会话
4. 可恢复性与消息重传
Streamable HTTP 的一个重要特性是支持断线恢复和消息重传,这对于生产环境中的可靠性至关重要。
4.1 事件 ID 机制
服务器可以为 SSE 事件附加 id 字段,遵循 SSE 标准:
id: evt-12345
event: message
data: {"jsonrpc":"2.0","method":"tools/progress","params":{...}}事件 ID 必须在会话内的所有流中全局唯一,并且应该编码足够的信息来识别来源流。
4.2 断线恢复流程
当客户端需要在断线后恢复时:
- 客户端向 MCP 端点发送 HTTP GET 请求
- 请求中包含
Last-Event-ID头,指示最后接收到的事件 ID - 服务器可以使用此头重放断线后本应发送的消息
- 恢复始终通过带有
Last-Event-ID的 HTTP GET 进行
5. 安全性考虑
5.1 DNS 重绑定防护
服务器必须验证所有传入连接的 Origin 头以防止 DNS 重绑定攻击:
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 传输的区别有助于选择合适的传输方式:
| 特性 | STDIO | Streamable HTTP |
|---|---|---|
| 通信媒介 | 本地进程 STDIN/STDOUT | HTTP/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 灵活的响应模式
服务器可以根据请求特性选择合适的响应方式:
- 简单 JSON 响应:适用于快速、一次性的请求
- SSE 流式响应:适用于长时间运行的任务或需要实时更新的场景
// 服务端示例:根据请求类型选择响应模式
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 端点。
客户端:可以通过以下流程自动检测服务器类型:
- 尝试向服务器 URL POST
InitializeRequest - 如果成功,假定为支持 Streamable HTTP 的服务器
- 如果返回 400/404/405 错误,回退到旧的 HTTP+SSE 传输
8. 协议版本头
使用 HTTP 时,客户端必须在所有后续请求中包含 MCP-Protocol-Version 头:
MCP-Protocol-Version: 2025-11-25这允许 MCP 服务器根据协议版本做出适当响应。如果服务器未收到此头,且无其他方式识别版本,应假定协议版本为 2025-03-26。
9. 总结
Streamable HTTP 传输协议的引入是 MCP 发展的重要里程碑。它为协议带来了以下关键能力:
- 可扩展性:支持企业级部署和多客户端并发
- 可靠性:内置断线恢复和消息重传机制
- 灵活性:支持简单响应和流式响应两种模式
- 安全性:提供完整的安全防护指南
- 兼容性:平滑过渡,支持旧版本客户端和服务器
对于开发者而言,选择传输方式应基于具体需求:
- 本地开发、CLI 工具、IDE 集成 → 选择 STDIO
- 云服务、Web 应用、多用户 SaaS → 选择 Streamable HTTP
随着 MCP 生态系统的不断发展,Streamable HTTP 将成为构建下一代 AI 应用的关键基础设施,为 AI Agent 与外部工具和数据源的集成提供标准化、可靠的通信方式。
参考资料
- MCP 官方规范:https://modelcontextprotocol.io/specification/2025-11-25/basic/transports
- AWS Builder 技术文档:https://builder.aws.com/content/35A0IphCeLvYzly9Sw40G1dVNzc/mcp-transport-mechanisms-stdio-vs-streamable-http
- Cloudflare Agents 文档:https://developers.cloudflare.com/agents/model-context-protocol/transport/