1. 为什么需要远程传输
MCP 最初以本地为主:客户端(Claude Desktop 等)直接 spawn 服务器子进程,通过 stdio 通信。但真实场景很快要求远程:服务器跑在云端、多个客户端共享一个服务器、浏览器/移动端访问。远程传输让 MCP 从"本机插件"进化成"网络服务"。
# 传输演进
# 本地: stdio(子进程管道)——单客户端、零配置
# 局域网/进程内: InMemory、Unix Socket
# 远程: HTTP(Streamable HTTP / SSE)——跨网络、多客户端
# 选型: 场景决定,本地优先 stdio,共享/云端用 HTTP
1.1 三种主要传输对比
| 传输 | 连接 | 特点 | 适用 |
|---|---|---|---|
| stdio | 子进程管道 | 零配置、单客户端、随进程生命周期 | 本机桌面客户端 |
| Streamable HTTP | HTTP POST/GET | 远程、可流式、鉴权标准 | 公网/云端服务器 |
| SSE | EventSource | 单向服务器推送 | 旧式实时推送 |
1.2 从 stdio 到 HTTP 的取舍
# stdio 优势: 无网络、无鉴权、随用随起
# stdio 局限: 只能本机、只能单客户端、无标准鉴权
# HTTP 优势: 跨网络、多客户端、可托管可共享、可加网关
# HTTP 代价: 需要鉴权、会话管理、防滥用
# 决策: 给本机工具用 stdio;给团队/公网服务用 HTTP
2. Streamable HTTP 传输
2.1 设计思想
Streamable HTTP 用两个 HTTP 端点表达双向通信:
# 客户端 → 服务器: POST /(请求/通知)
# 服务器 → 客户端: POST 的响应体(同步返回)
# 流式场景: 服务器开 SSE 流(增量/进度/长期响应)
# 会话: 可选 session id(无状态则无会话)
# 优点: 兼容标准 HTTP 中间件、CDN、网关
2.2 非流式 vs 流式响应
# 非流式: 一次性 POST → 完整响应体(简单请求)
# 流式: 服务器分块返回(SSE),适合
# - 长任务进度
# - 增量结果(大工具输出)
# - 实时通知
# 客户端要能区分: 响应是"完整结果"还是"流的开始"
2.3 会话与无状态
# 无状态(默认): 每次请求独立,服务器不记忆客户端
# 优点: 可水平扩展、可挂负载均衡
# 代价: 复杂交互(进度/订阅)需额外机制
# 有状态: session id 关联客户端状态
# 适用: 需要服务器记住会话的复杂交互
# 实践: 尽量无状态,必要状态用客户端携带/显式会话
3. SSE 传输模式
3.1 SSE 的角色
SSE(Server-Sent Events)是 MCP 远程传输的早期方案,现在多被 Streamable HTTP 取代,但理解它有助于兼容旧服务器:
# SSE 模式
# 客户端: GET /sse(打开事件流,服务器推送)
# 客户端: POST /messages(发送请求,响应经 SSE 流回)
# 特点
# - 服务器单向推送天然(SSE 就是单向流)
# - 无内置鉴权规范(需自定义)
# - 长连接资源占用
# 结论: 新服务器优先 Streamable HTTP;维护旧服务器才用 SSE
3.2 何时仍需 SSE
# 1) 已有基于 SSE 的 MCP 服务器(向后兼容)
# 2) 需要"持续推送通知"的特定场景
# 3) 受限环境只允许 EventSource
# 否则: 用 Streamable HTTP(更现代、鉴权更标准)
4. 远程服务器的鉴权与安全
4.1 鉴权层
# 远程 MCP 必须鉴权(公网裸奔 = 工具被滥用)
# 方案
# 1) Bearer token: 简单,适合单客户端/受信环境
# 2) OAuth 2.1: 标准流程,适合多用户 SaaS
# 3) 网关鉴权: 由 API 网关统一处理(与 MCP 解耦)
# 安全基线
# - 传输加密(TLS)
# - 鉴权必选(至少 Bearer token)
# - 敏感工具再叠加工具级权限
4.2 服务器识别与发现
# 远程服务器的可发现性
# 1) 服务器 URL + 信息: name/version/description 对客户端展示
# 2) 能力声明: 客户端连接后 capabilities 协商
# 3) 目录/注册表: 统一入口列举可用服务器(见发布生态)
# 4) 客户端应"先看信息再决定连接"
4.3 防滥用
# 公网 MCP 服务器风险
# 1) 无限调用(成本/算力)→ 配额 + 限流
# 2) 恶意工具参数 → 输入校验 + 沙箱执行
# 3) 信息泄露 → 只暴露该客户端有权的工具
# 4) 审计 → 每次调用记录(谁、何时、什么工具、参数)
5. 服务器托管与网关
5.1 托管形态
# 托管方式
# 1) 裸进程: 云 VM/容器跑服务器进程(简单,需自己管)
# 2) 无服务器: 按请求计费的托管(适合低频)
# 3) 网关托管: 网关统一路由多个 MCP 服务器(团队共享)
# 4) 平台即服务: 托管 MCP 平台(省心,生态见发布篇)
# 决策: 团队内共享用网关,对外商业用平台/无服务器
5.2 网关路由多个服务器
# 场景: 一个 URL 背后多个工具域
# 架构
# 客户端 → 网关 → 路由(按工具域)→ 各 MCP 服务器
# 好处
# 1) 客户端只配一个地址
# 2) 统一鉴权、限流、审计
# 3) 服务器独立部署、独立扩展
# 实现: 网关聚合各服务器的 tools/list,tools/call 路由到对端
5.3 高可用与扩展
# 远程服务器生产化
# 1) 无状态 → 可水平扩展 + 负载均衡
# 2) 流式长任务 → 任务状态外置(Redis/DB),可跨实例恢复
# 3) 监控 → 调用量、延迟、错误率、工具成功率
# 4) 故障转移 → 多个副本 + 健康检查
6. 传输选择决策
# 决策树
# 本机桌面客户端 → stdio
# 进程内(测试/插件) → InMemory
# 局域网工具 → Unix Socket / 简单 HTTP
# 团队共享(多个开发者/应用) → 网关 + Streamable HTTP
# 公网 SaaS/商业 → Streamable HTTP + OAuth + 配额
# 原则: 先本地后远程,远程必鉴权
6.1 客户端兼容策略
# 客户端应支持多传输(退让)
# 1) 优先 stdio(本地)
# 2) 远程走 Streamable HTTP
# 3) 旧服务器回退 SSE
# 客户端测试: 对同一服务器逻辑,跨传输验证行为一致
7. 常见陷阱
- 公网不鉴权:裸跑 HTTP,工具被任何人调用。
- 无状态硬套有状态交互:进度/订阅没设计,长任务体验差。
- 混用 SSE 与 Streamable:旧客户端连新服务器,端点不匹配。
- 忽略流式区分:把"流开始"当"完整结果",客户端解析错。
- 网关把鉴权外包却不校验:网关放行但工具级无权限。
8. 总结
MCP 远程传输的工程要点是按场景选传输、远程必鉴权、尽量无状态:本地用 stdio、共享/云端用 Streamable HTTP、旧服务器兼容 SSE。生产化远程服务器还要叠加网关路由、配额限流、审计与高可用。传输层选对,MCP 就能从"本机插件"平滑变成"可托管、可共享、可对外的网络服务"。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。