传输层与通信机制
问题
MCP 支持哪些传输方式?stdio、SSE 和 Streamable HTTP 有什么区别?
答案
一、传输方式对比
| 传输方式 | 适用场景 | 特点 |
|---|---|---|
| stdio | 本地进程通信 | 最简单,Client 启动 Server 子进程 |
| SSE(已弃用) | 远程 HTTP 通信 | 单向流,需两个端点 |
| Streamable HTTP | 远程 HTTP 通信 | 推荐,双向流,单端点 |
二、stdio 传输
Client 将 Server 作为子进程启动,通过 stdin/stdout 双向通信:
// Client 端:启动 Server 子进程
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
const transport = new StdioClientTransport({
command: "node",
args: ["./my-server.js"],
env: { DATABASE_URL: "postgres://..." }
});
const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(transport);
何时用 stdio
- 本地开发和调试
- Claude Desktop、VS Code 等桌面应用
- Server 代码在本地运行
三、Streamable HTTP 传输
MCP 推荐的远程传输方式,使用单个 HTTP 端点:
关键设计:
- 单端点(
/mcp)处理所有请求 - Session ID:通过
Mcp-Session-IdHeader 维护会话 - 双向通信:Client 用 POST 发消息,GET 开 SSE 流接收 Server 推送
- 无状态可选:简单场景可不用 SSE,直接 POST 请求-响应
// Server 端:Streamable HTTP
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import express from "express";
const app = express();
const server = new McpServer({ name: "my-server", version: "1.0.0" });
// 注册工具...
app.all("/mcp", async (req, res) => {
const transport = new StreamableHTTPServerTransport("/mcp");
await server.connect(transport);
await transport.handleRequest(req, res);
});
app.listen(3000);
四、SSE 传输(已弃用)
已弃用
SSE 传输在 MCP 2025-03-26 版本中被标记为弃用,推荐使用 Streamable HTTP 替代。
SSE 使用两个端点:
GET /sse:建立 SSE 流(Server → Client)POST /messages:发送消息(Client → Server)
五、传输层选择
常见面试问题
Q1: stdio 和 Streamable HTTP 分别在什么场景用?
答案:
- stdio:本地桌面应用(Claude Desktop、VS Code),Server 作为子进程运行
- Streamable HTTP:远程部署的 Server,多用户共享,需要 HTTP 接入
Q2: 为什么 SSE 传输被弃用了?
答案:
- SSE 需要两个端点(/sse + /messages),增加复杂度
- 无法在单一请求中完成初始化和通信
- Streamable HTTP 用单端点解决了双向通信,更简洁
- Streamable HTTP 还支持无状态模式,更适合 Serverless 部署