用途:帮助为 MCP 服务器选择并正确实现传输层,适用于新建服务器选型、从已废弃的 SSE 迁移到 Streamable HTTP、排查“连接断开”“会话过期”错误,以及远程服务器水平扩容。
选型:stdio 适合本地工具、CLI 集成和单用户,零网络、进程可信、最简单,但仅限本地且一个服务器进程只服务一个客户端;Streamable HTTP 适合远程多用户,双向、可恢复、可负载均衡,但更复杂且需要会话层;SSE 为旧方案,已废弃,应迁移到 Streamable HTTP。
stdio 用法:服务器从 stdin 读、向 stdout 写 JSON-RPC、日志写 stderr,客户端负责启动进程。关键规则是绝不向 stdout 写入非 JSON 内容,console.log 会破坏协议,应使用 console.error 记录日志。示例:import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; const transport = new StdioServerTransport(); await server.connect(transport);
Streamable HTTP 用法:单一 HTTP 端点处理所有方法,长连接 GET 走 SSE 推送,POST 接收消息,通过 Mcp-Session-Id 头支持可恢复会话。服务端用 StreamableHTTPServerTransport,指定 sessionIdGenerator 并在 onsessioninitialized 中登记会话,客户端用 StreamableHTTPClientTransport 连接 https://mcp.example.com/mcp。会话生命周期:客户端不带会话头发起 initialize,服务端在 Mcp-Session-Id 响应头返回会话 ID,之后每个请求都携带该头,任一方可用 DELETE /mcp 加会话头终止。
恢复与扩展:SSE 长流可能因代理超时或 NAT 重绑定断开,客户端用 Last-Event-ID 重连,服务端从每会话缓冲区重放;需配置 eventStore(如 Redis,ttlSeconds 3600),否则重连会丢失在途工具结果,仅适合开发。多实例部署必须共享会话状态:负载均衡粘性会话、共享 Redis 存 transports 映射与事件存储,或按 Mcp-Session-Id 哈希做会话亲和;切勿配合内存会话状态做轮询,否则会出现“session not found”。
背压与迁移:客户端慢时可用高水位缓冲(如 1000 条),溢出则发送进度/取消通知并丢弃请求,同时输出缓冲深度指标告警。迁移时 POST /mcp 发请求、GET /mcp 开 SSE 流、DELETE /mcp 结束会话;可并行运行一个版本,把 SSE 客户端重定向到新端点后再移除旧路由,SDK 的 StreamableHTTPClientTransport 会自动协商。
调试:stdio 报“not valid JSON”说明有其他代码写了 stdout,需检查所有 console.log、print 和调试库;HTTP 400 “missing session id” 多为客户端已初始化但中间层剥离了头;重连丢状态是未配置事件存储;CPU 飙升可能是 SSE 写入未刷新,可用 res.flush() 或 X-Accel-Buffering: no。
限制:上述为通用实践,未提供具体版本兼容范围、性能基准或托管方案细节。