考察点
小米三面考过这组传输层问题,属于 MCP 的深水区,面试官想区分「跑通过 demo」和「研究过协议规范」的人。三个子问题环环相扣:消息格式、传输方式选型、为什么不用 WebSocket。
参考答案
底层消息格式:JSON-RPC 2.0
MCP 的应用层消息是标准的 JSON-RPC 2.0:请求带 jsonrpc、id、method、params,响应带 result 或 error(code + message),还有不带 id 的 notification。方法命名如 initialize、tools/list、tools/call、resources/read。选 JSON-RPC 而不重新发明协议,是因为它足够简单、有成熟实现,且天然支持请求-响应和通知两种模式。
两种官方传输方式
stdio:Client 把 Server 作为子进程拉起,通过标准输入输出传 JSON-RPC 消息(换行分隔)。适合本地工具——读文件系统、操作本地 Git 仓库这类 Server 跟 Host 在同一台机器。优点是零网络配置、进程隔离天然安全、延迟极低;缺点是只能本地用,Server 的生命周期被 Host 管着。
Streamable HTTP:远程场景的标准方式(2025 年的协议版本取代了早期的 HTTP+SSE 双端点方案)。Client 向单一端点发 POST 请求携带 JSON-RPC 消息;Server 可以直接回 JSON,也可以把响应升级成 SSE 流持续推送,长任务进度通知、多部分结果都走这条流;Server 还能主动向 Client 发请求(比如 sampling)。会话用 session id 头管理,支持无状态模式——Server 不保存会话状态也能跑。
为什么不用 WebSocket 全双工
这是面试里最容易卡壳的一问,理由很实际:
- 基础设施兼容:HTTP 能直接穿过现有的负载均衡、API 网关、鉴权中间件、CDN,WebSocket 在很多企业网关和代理上需要特殊配置甚至根本不放行。企业落地时这是硬约束。
- Serverless 友好:WebSocket 要求长连接常驻,和 Lambda、Cloud Functions 这类按需拉起、用完即毁的计算模型天然冲突。Streamable HTTP 的无状态模式让每个 POST 可以是独立请求,Serverless 直接能扛;SSE 流只是在需要推送时才建立的临时增强。
- MCP 的交互模型本来就不是对等的:绝大多数流量是 Client 发起请求、Server 响应,真正的「全双工」需求(Server 主动推消息)占比很小,用 SSE 单向流补这个缺口就够了,犯不上为这点需求维护全双工连接。
早期 HTTP+SSE 方案的问题是拆成两个端点(POST 发请求、GET 挂 SSE 收响应),连接管理复杂、断线重连语义不清,Streamable HTTP 合并成单端点后解决了这个工程痛点。
选型实践
本地开发、桌面应用集成一律 stdio,简单粗暴不出错;跨团队共享的远程工具服务用 Streamable HTTP,配合 OAuth 鉴权,部署成无状态服务挂网关后面。
可能的追问
- stdio 模式有什么安全隐患? Server 子进程继承 Host 的权限,恶意 Server 能干的事很多。缓解:配置里明确列出可信 Server、对敏感目录做进程级隔离、优先用官方或审计过的实现。
- SSE 流断了怎么办? 协议支持断线重连和事件 id 续传(Last-Event-ID),Client 实现里要做自动重连和幂等处理,避免工具调用重复执行。
- 无状态模式牺牲了什么? 牺牲了会话级的状态保持和某些需要长连接的能力(如订阅类资源更新),换来水平扩展和 Serverless 兼容。按需选择,初始化时可以协商。