MCP(Model Context Protocol)已成为连接AI助手与外部工具和数据的核心协议之一。其架构的每一次演进都旨在提升效率与兼容性。自2025年3月发布的协议版本起,MCP用全新的Streamable HTTP传输机制取代了原先的HTTP+SSE组合,这标志着协议底层通信方式的一次重大升级。

为什么MCP需要专门的传输协议?
MCP协议基于JSON-RPC 2.0格式在客户端(如AI助手)与服务器(如工具、数据库)间进行通信。传统的HTTP请求-响应模型对于需要连续、低延迟数据交换的AI场景来说效率低下,因为频繁建立连接会引入过高开销。
因此,MCP从一开始就采用了更适合实时数据推送的传输机制。最初,它依赖HTTP+SSE来实现服务器到客户端的流式传输。然而,这种组合在实践中暴露出一些局限性:
- 不支持连接中断后的流恢复。
- 要求服务器为每个客户端维护一个长期存活的连接,消耗资源。
- 通信方向受限:数据仅能通过SSE从服务器流向客户端,客户端需使用额外的HTTP POST通道发送请求。

Streamable HTTP 的引入正是为了解决上述问题。它支持无状态通信,并可按需升级到SSE以进行流式推送,从而提高了与现代云原生基础设施的兼容性,确保了更稳定、高效的通信体验。目前,主流MCP库在支持新协议的同时,仍保持对旧版HTTP+SSE的向后兼容。
深入剖析被替代的HTTP+SSE
服务器发送事件(SSE)是一种允许Web客户端通过一个持久HTTP连接接收服务器自动更新的技术。与双向的WebSocket不同,SSE是单向的,专用于服务器到客户端的消息推送。
在MCP的旧版实现中,一个典型的HTTP+SSE服务架构要求服务器提供两个端点:
- 一个 SSE (GET) 端点:用于客户端建立连接并接收服务器消息流。
- 一个 RPC (POST) 端点:用于客户端向服务器发送JSON-RPC请求。
当客户端连接到SSE端点时,服务器会立即通过该连接发送一个特殊的endpoint事件,告知客户端其专属的RPC端点URI。此后,所有客户端的请求都通过向该URI发送POST请求来完成,而服务器的响应则通过原先的SSE连接流式传回。
以下是一个简化的Node.js与浏览器代码示例,展示了HTTP+SSE模式下的基本交互:
服务器端 (Node.js with Express)
const express = require("express");
const app = express();
const PORT = 3000;
let clients = new Map(); // 存储客户端连接
// SSE连接端点
app.get("/sse", (req, res) => {
const clientId = Date.now().toString();
res.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
});
// 为客户端分配唯一的RPC端点
const rpcEndpoint = `/rpc/${clientId}`;
res.write(`event: endpoint\ndata: {"uri": "${rpcEndpoint}"}\n\n`);
clients.set(clientId, { res });
req.on("close", () => clients.delete(clientId));
});
// 动态RPC端点
app.post("/rpc/:clientId", (req, res) => {
const { clientId } = req.params;
const client = clients.get(clientId);
if (!client) return res.status(404).json({ error: "Client not found" });
// 处理请求并通过SSE连接返回响应
const response = { jsonrpc: "2.0", id: req.body.id, result: "pong" };
client.res.write(`data: ${JSON.stringify(response)}\n\n`);
res.json({ status: "received" });
});
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
客户端 (Browser JavaScript)
let eventSource;
let rpcEndpoint = null;
function connectSSE() {
eventSource = new EventSource("/sse");
eventSource.addEventListener("endpoint", (event) => {
rpcEndpoint = JSON.parse(event.data).uri;
});
eventSource.onmessage = (event) => {
console.log("Server response:", JSON.parse(event.data));
};
}
function sendPing() {
if (!rpcEndpoint) return;
fetch(rpcEndpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", method: "ping", id: 1 })
});
}
window.addEventListener("load", connectSSE);
HTTP+SSE的优缺点总结:
- 优点:支持流式传输大结果;允许服务器主动推送事件;基于标准HTTP协议,实现相对简单。
- 缺点:本质是单向通信,需要双通道;长连接对服务器资源消耗大;不支持断线重连后的流恢复。
新一代方案:Streamable HTTP 是什么?
Streamable HTTP是一种更灵活的数据流传输方法,它基于纯HTTP协议,无需强制建立长连接即可实现实时通信。虽然它仍可可选地使用SSE来支持流式推送,但这不再是必选项。这使得MCP服务器可以设计为无状态的,彻底摆脱维护大量持久连接的开销。
MCP选择Streamable HTTP而非WebSocket,主要基于以下考虑:
- 协议开销:对于无状态RPC调用,WebSocket显得过于重量级。
- 协议友好性:SSE和标准HTTP工具(如curl)更易调试和集成,而WebSocket则不然。
- 灵活性:WebSocket的升级机制仅适用于GET请求,使得基于POST的流程复杂化。
在Streamable HTTP模式下,服务器只需暴露一个统一的HTTP端点(支持POST和GET)。通信流程变得更加简洁和高效:
- 客户端请求:通过HTTP POST发送JSON-RPC请求。
- 服务器响应:可以直接在POST响应体中返回结果(简单RPC),也可以通过返回一个“流ID”并建议客户端使用SSE GET来订阅流式结果(复杂或持续响应)。

为了支持流恢复,服务器会为每个流分配唯一ID,客户端可以凭此ID重新连接并获取中断后的消息。
Streamable HTTP的核心优势:
- 无状态友好:服务器无需维护会话状态,易于水平扩展。
- 基础设施兼容:完美兼容HTTP负载均衡器、代理和所有主流托管平台。
- 纯HTTP:减少对特定协议(SSE)的依赖,使用标准HTTP工具即可进行测试和调试。
- 向后兼容:易于从HTTP+SSE架构平滑迁移。
- 灵活流式传输:可按需升级到SSE,实现真正的双向流式通信。
目前,官方MCP SDK(@modelcontextprotocol/sdk)已内置了对Streamable HTTP的完整支持。开发者无需手动处理底层通信细节,可以专注于实现业务逻辑。以下是一个使用官方SDK创建支持流式响应工具的示例:
import { McpServer, createStream } from "@modelcontextprotocol/sdk/server/mcp.js";
const server = new McpServer({ name: "streaming-demo", version: "1.0.0" });
// 注册一个流式工具
server.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;
if (name === "streamEcho") {
return createStream(async (stream) => {
const message = args?.message || "Hello";
for (let i = 0; i < message.length; i++) {
// 发送部分结果,形成流式响应
await stream.partial({
content: [{ type: "text", text: message[i] }],
});
await new Promise((r) => setTimeout(r, 200)); // 模拟延迟
}
// 发送最终结果
await stream.final({
content: [{ type: "text", text: `Echo: ${message}` }],
});
});
}
throw new Error(`Unknown tool: ${name}`);
});
// 启动服务器,SDK会自动处理Streamable HTTP传输
server.listen();
总结:从HTTP+SSE到Streamable HTTP的演进,反映了MCP协议为适应大规模、云原生AI应用场景所做的努力。新的传输机制通过拥抱无状态设计和纯标准HTTP协议,提供了更好的兼容性、可扩展性和开发者体验,为AI智能体与广阔数字世界的连接奠定了更稳固的基础。
参考资料
- Antonello Zanini. 《SSE vs Streamable HTTP: The Transport Technologies Behind MCP》
- MDN Web Docs. 《Using server-sent events》