MCP 官方推出了 TypeScript SDK 和 Python SDK,但生态里服务器绝大多数用 TypeScript 写,而 Agent 框架(LangChain、CrewAI、AutoGen)又大多是 Python 的。这就造成了"语言断层"。解决方案藏在 MCP 协议的设计中——底层通信是 JSON-RPC 2.0,纯文本、语言无关。你不需要把 TypeScript 服务器重写成 Python,只需让 Python 客户端和 TypeScript 服务器通过 JSON-RPC 对话。
MCP 的 语言无关性 是其最强大的设计特质。无论是 Python 的 mcp 包还是 TypeScript 的 @modelcontextprotocol/sdk,它们都遵循同一份协议规范。数据交换格式只有纯 JSON:{"jsonrpc":"2.0","id":1,"method":"tools/list"}。这意味着你甚至可以用 curl 调试 MCP 服务器——只要发送正确的 JSON-RPC 消息,就能获得工具列表。真正实现了"一次规范,多语言实现"。
这种跨语言架构在实际项目中已经得到验证。以 OpenCode 为例,它的核心是 TypeScript 编写的,但通过 MCP CLI 命令(packages/opencode/src/cli/cmd/mcp.ts)管理各种语言的 MCP 服务器——可以是 TypeScript 的 @modelcontextprotocol/server-filesystem,也可以是 Python 写的自定义 MCP 服务器。只要对方在 opencode.json 中配置好命令和参数,OpenCode 的 Effect 驱动的 MCP 服务层就会自动管理连接生命周期和状态追踪。
三个原因:1)Anthropic 的 TypeScript 基因——MCP TypeScript SDK 是参考实现,2024 年 11 月首发,Python SDK 晚了两个月;2)npm 的"零配置"分发——npx @modelcontextprotocol/server-filesystem 一行命令即可运行,生态 80% 以上社区服务器选择 npm 发布;3)协议本身语言无关——JSON-RPC 2.0 让任何语言都可以实现客户端和服务器。
深入看 TypeScript SDK 的优势:它提供了 Client 和 Server 两个高层封装,分别对应 @modelcontextprotocol/sdk/client/index.js 和 @modelcontextprotocol/sdk/server/index.js。Client 端支持 Streamable HTTP 传输(@modelcontextprotocol/sdk/client/streamableHttp.js),这是比 SSE 更现代的传输方式。Server 端的工具注册使用链式 API:server.setRequestHandler("tools/list", handler) 而非 Python 的装饰器模式。两种 SDK 虽语法不同,但底层通信数据格式完全一致。
Python SDK 虽然发布稍晚,但在 AI Agent 集成 方面有天然优势。Python 生态的 LangChain、CrewAI、AutoGen 等 Agent 框架都能通过 StructuredTool 封装器轻松接入 MCP 工具。而且 Python SDK v2.x 的 FastMCP 封装极大简化了服务器开发——不需要手动处理 JSON-RPC 序列化,只需要写纯 Python 函数加装饰器。对于 Python 开发者来说,FastMCP 比 TypeScript SDK 的学习曲线更平缓。
Stdio:Python 启动 TypeScript 子进程,通过标准 I/O 交换 JSON-RPC 消息。适合本地开发、低延迟场景。SSE(Server-Sent Events):TypeScript 服务器作为 HTTP 服务运行,Python 通过 HTTP 连接。适合远程部署、多客户端共享。选择依据:如果服务器和客户端在同一台机器上,用 stdio;如果需要远程访问或多客户端,用 SSE。
两种模型的本质区别在于 连接方向。Stdio 模式下,Python 客户端主动创建子进程,stdin/stdout 是双向管道,消息流天然对称。SSE 模式下,客户端先通过 GET /sse 建立服务端→客户端的单向事件流,然后通过 POST /messages 发送客户端→服务端的请求,这是非对称的。每次 SSE 连接会获得一个唯一的 session ID,后续的 POST /messages 请求需携带该 ID 以路由到正确的会话。
从 2025 年起,MCP 规范增加了第三种传输方式——Streamable HTTP。它统一了 SSE 的双向通信问题,使用标准的 HTTP POST + 流式响应,不需要维持长连接 SSE 通道。OpenCode 的远程 MCP 实现(packages/opencode/src/tool/mcp-websearch.ts)已经采用了这种模式:通过 Effect 的 HttpClient 发送 JSON-RPC POST 请求,设置 Accept: application/json, text/event-stream 的同时支持 JSON 和 SSE 两种响应格式,自动回退。
Python 客户端通过 asyncio.subprocess 创建 TypeScript 子进程,写入 stdin、读取 stdout。关键源码在 mcp/client/stdio.py 的 stdio_client 函数中。常见坑:缓冲区问题——默认 \n 分隔需设置 line_buffered=True;子进程管理——使用 async with 确保进程正确清理;错误传播——stderr 需要单独捕获。
Stdio 传输的完整生命周期如下:1)参数组装——StdioServerParameters 封装命令、参数和环境变量;2)子进程创建——asyncio.create_subprocess_exec 启动进程,pipe stdin/stdout/stderr;3)JSON-RPC 消息编解码——每行一个 JSON 对象,\n 作为分隔符;4)进程清理——proc.terminate() + await proc.wait()。任何一步出错(如命令不存在、端口占用)都需要向上层传递明确错误。
在 OpenCode 中,本地 MCP 服务器的配置就使用这种 stdio 模型。配置文件中的 type: "local" 服务器会携带 command 数组和可选的 cwd、environment、timeout 字段。OpenCode 的 MCP 服务层(packages/core/src/config/mcp.ts)读取这些配置后,通过 Effect 的 ChildProcessSpawner 启动子进程,并自动管理连接健康检查和断线重连。如果服务器 disabled 设为 true,则跳过启动,在侧边栏显示为灰色禁用状态。
Python 通过 httpx-sse 库连接到 TypeScript SSE 端点。流程:客户端先通过 GET /sse 建立 SSE 连接(接收服务端的 session ID),然后通过 POST /messages 发送请求。SSE 连接支持自动重连和心跳检测。Python SDK 的 sse_client 函数封装了完整的连接生命周期。
SSE 传输的关键挑战是连接维护。因为 SSE 通道是服务端→客户端的单向长连接,如果网络中断,客户端需要自动检测并重连。Python SDK 通过 httpx 的流式响应处理 SSE 事件流,每收到一个 data: 行就解析为一个 JSON 消息。服务端维护连接状态,如果客户端断连后重连,会分配新的 session ID。因此客户端必须正确处理 session ID 的变化。
对于远程 MCP 服务器,OpenCode 提供了完整的 OAuth 2.0 认证支持。在 packages/opencode/src/cli/cmd/mcp.ts 中,远程服务器的配置可以携带 oauth 字段(包含 client_id、client_secret、scope、callback_port 等),也可以设置为 false 禁用 OAuth。CLI 的 opencode mcp auth 命令可以触发完整的 OAuth Device Authorization Grant 流程,包括浏览器自动打开、手动 URL 降级、凭据存储和到期刷新。
生产环境需要:多服务器聚合——用一个 Agent 连接多个 MCP Server;错误处理与重试——指数退避重连;健康检查——定期 ping 检测连接状态;日志与监控——记录每次 tool call 的执行时间和结果。推荐使用 mcp_agent 等封装库来管理多服务器连接池。
在生产部署中,一个 Agent 可能需要同时连接 5-10 个 MCP 服务器(文件系统、代码执行、Web 搜索、数据库查询等)。每个服务器的生命周期需要独立管理:连接、初始化、健康检查、断线重连、正常关闭。MCP 服务器的 timeout 配置尤为重要——不同工具的响应时间差异很大(文件读取可能 50ms,Web 搜索可能 5s+),需要为每个工具设置合理的超时。
OpenCode 在生产级 MCP 管理方面提供了很好的参考。其 CLI 实现(packages/opencode/src/cli/cmd/mcp.ts)通过 Effect 的协程模型管理异步生命周期:MCP.Service 提供统一的 status()、authenticate()、toggle() 接口,底层自动处理连接池和状态同步。TUI 侧边栏(packages/tui/src/component/dialog-mcp.tsx)提供交互式 MCP 管理对话框,支持开关服务器、查看状态、刷新列表。此外还有 opencode mcp debug 命令用于诊断连接问题。