MCP 传输机制深度解析:stdio、SSE 与 Streamable HTTP
深入分析 Model Context Protocol 的三种传输机制的工作原理、性能特点和适用场景,指导开发者选择最佳通信方案。
MCP 的传输层决定了 Client 和 Server 之间如何交换消息。选择合适的传输机制直接影响系统的延迟、可扩展性和部署复杂度。这篇文章将深入解析 MCP 支持的三种传输机制。
MCP 传输层概述
MCP 使用 JSON-RPC 2.0 作为消息格式,传输层负责将这些消息在 Client 和 Server 之间传递。协议设计了清晰的分层,使得传输层可以灵活替换。
┌─────────────────┐
│ MCP 协议层 │
│ (JSON-RPC 2.0) │
├─────────────────┤
│ 传输层 │
│ (stdio/SSE/HTTP)│
├─────────────────┤
│ 网络层 │
│ (TCP/Unix) │
└─────────────────┘
stdio 传输
stdio 是 MCP 最基础的传输方式,通过标准输入输出进行进程间通信。
工作原理
Client 启动 Server 作为子进程,通过 stdin 发送请求,从 stdout 读取响应。stderr 用于日志输出,不参与协议通信。
Client Server (子进程)
│ │
│──── stdin (JSON-RPC) ────>│
│ │
│<─── stdout (JSON-RPC) ────│
│ │
│<─── stderr (日志) ────────│
代码示例
Server 端:
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new McpServer({ name: 'my-server', version: '1.0.0' });
// 添加工具...
const transport = new StdioServerTransport();
await server.connect(transport);
// Server 开始监听 stdin,响应写入 stdout
Client 端:
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
const transport = new StdioClientTransport({
command: 'node',
args: ['server.js'],
env: { NODE_ENV: 'production' },
});
const client = new Client({ name: 'my-client', version: '1.0.0' });
await client.connect(transport);
优势
零网络配置——不需要开放端口、配置防火墙或设置反向代理。
操作系统隔离——进程级别的隔离提供了天然的安全边界。
低延迟——进程间通信的延迟通常在微秒级别,远低于网络通信。
局限
本地限制——只能用于同一台机器上的进程间通信。
单客户端——一个 Server 进程通常只能服务一个 Client。
生命周期绑定——Server 进程随 Client 的启动而启动,随 Client 的退出而终止。
SSE 传输
Server-Sent Events(SSE)是一种基于 HTTP 的单向流式通信机制。MCP 使用 SSE 传输实现远程 Server 的访问。
工作原理
Client 通过 HTTP GET 建立 SSE 连接接收 Server 推送的消息,通过 HTTP POST 发送请求到 Server。
Client Server
│ │
│──── GET /sse ────────────────>│ (建立 SSE 连接)
│<─── SSE: endpoint URL ───────│
│ │
│──── POST /messages ──────────>│ (发送 JSON-RPC 请求)
│<─── SSE: JSON-RPC response ──│ (通过 SSE 流返回)
│ │
│──── POST /messages ──────────>│
│<─── SSE: JSON-RPC response ──│
代码示例
Server 端:
import express from 'express';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
const app = express();
const server = createMcpServer();
app.get('/sse', (req, res) => {
const transport = new SSEServerTransport('/messages', res);
server.connect(transport);
});
app.post('/messages', express.json(), (req, res) => {
// SSE transport 自动处理消息路由
});
app.listen(3000);
Client 端:
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
const transport = new SSEClientTransport(
new URL('http://localhost:3000/sse')
);
const client = new Client({ name: 'remote-client', version: '1.0.0' });
await client.connect(transport);
优势
远程访问——Client 和 Server 可以位于不同的机器上。
Web 兼容——基于标准 HTTP 协议,可以穿过大多数防火墙和代理。
流式响应——SSE 支持流式推送,适合长时间运行的操作。
局限
单向推送——SSE 只支持 Server 到 Client 的推送,Client 到 Server 需要额外的 HTTP POST。
连接管理——需要处理 SSE 连接的断开和重连。
并发限制——浏览器对同一域名的 SSE 连接数有限制(通常 6 个)。
Streamable HTTP 传输
Streamable HTTP 是 MCP 最新引入的传输方式,基于 HTTP 的完整双向通信。
工作原理
所有消息都通过 HTTP POST 传递,响应可以是普通的 JSON 响应或 SSE 流。Client 可以选择接收流式或非流式响应。
Client Server
│ │
│──── POST /mcp ───────────────>│ (请求)
│<─── 200 OK (JSON) ───────────│ (普通响应)
│ │
│──── POST /mcp ───────────────>│ (流式请求)
│<─── 200 OK (SSE stream) ─────│ (流式响应)
代码示例
Server 端:
import express from 'express';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
const app = express();
app.use(express.json());
app.all('/mcp', async (req, res) => {
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => crypto.randomUUID(),
});
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
});
app.listen(3000);
Client 端:
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
const transport = new StreamableHTTPClientTransport(
new URL('http://localhost:3000/mcp')
);
const client = new Client({ name: 'http-client', version: '1.0.0' });
await client.connect(transport);
优势
完全兼容 HTTP——可以利用现有的 HTTP 基础设施(负载均衡、CDN、认证)。
灵活的响应模式——可以根据需要选择流式或非流式响应。
无连接限制——不受 SSE 的连接数限制。
会话管理——内置会话标识,支持多客户端并发。
如何选择
本地开发和简单集成
选择 stdio。零配置、低延迟,适合本地工具集成和开发调试。
远程服务和 Web 部署
选择 Streamable HTTP。兼容现有 HTTP 基础设施,适合生产环境部署。
需要服务端推送
选择 SSE 或 Streamable HTTP。两者都支持服务端推送,但 Streamable HTTP 更加灵活。
性能敏感场景
选择 stdio,其次是 Streamable HTTP。stdio 的进程间通信延迟最低。
常见问题(FAQ)
可以同时支持多种传输方式吗?
可以。你可以在同一个 Server 中同时暴露 stdio 和 HTTP 端点,让不同的 Client 选择不同的连接方式。
SSE 传输的安全性如何保障?
使用 HTTPS 加密传输,配合标准的 HTTP 认证机制(Bearer Token、OAuth 等)。
传输层的选择会影响 MCP 协议的使用吗?
不会。传输层是透明的——无论使用哪种传输方式,MCP 协议层的 API(listTools、callTool 等)保持完全一致。
总结
stdio 适合本地集成,Streamable HTTP 适合远程部署,SSE 是两者之间的过渡方案。在实际项目中,你可能需要同时支持多种传输方式,以适应不同的部署环境和使用场景。