04 传输方式与客户端接入
MCP的数据层使用JSON-RPC消息,传输层负责在Client和Server之间传递这些消息。当前常用的标准传输方式主要有两类:stdio和Streamable HTTP。
选择传输方式时,应根据Server运行位置、部署方式、安全要求和并发需求判断。
一、传输方式对比
| 传输方式 | 适用场景 | Server形态 | 特点 |
|---|---|---|---|
stdio | 本地工具、本地开发、桌面客户端插件 | Client启动的子进程 | 无需端口,启动简单,适合同机通信 |
| Streamable HTTP | 远程工具、团队共享服务、Web部署 | 独立HTTP服务 | 支持远程访问、认证、多个Client连接 |
两种传输方式承载的是同一套MCP协议语义。差异主要在连接建立、消息传递和部署运维方式。
二、stdio传输
stdio传输中,MCP Client会把Server作为子进程启动。Client通过Server的标准输入发送JSON-RPC消息,Server通过标准输出返回JSON-RPC消息。
MCP Client
├── 启动 Server 子进程
├── 写入 stdin
└── 读取 stdoutstdio适合以下场景:
- 本地文件系统工具
- 本地Git仓库工具
- 桌面客户端连接的本地Server
- 开发和调试阶段
- 不需要远程访问的内部工具
2.1 stdio启动示例
Python Server中可以这样启动:
def main():
mcp.run(transport="stdio")
if __name__ == "__main__":
main()客户端配置通常需要指定命令和参数:
{
"mcpServers": {
"docs": {
"command": "uv",
"args": [
"--directory",
"/ABSOLUTE/PATH/docs-mcp-server",
"run",
"server.py"
]
}
}
}配置要点:
- 使用绝对路径,避免Host工作目录不确定导致启动失败。
- 不要把业务日志写入
stdout。 - 需要的环境变量应显式配置。
2.2 环境变量配置
本地Host启动Server时,继承的环境变量可能有限。需要API Key、数据库地址等配置时,应在客户端配置中显式写入:
{
"mcpServers": {
"docs": {
"command": "uv",
"args": [
"--directory",
"/ABSOLUTE/PATH/docs-mcp-server",
"run",
"server.py"
],
"env": {
"DOCS_API_KEY": "your-api-key",
"DOCS_BASE_URL": "https://docs.example.com"
}
}
}
}生产环境中不建议把敏感信息直接提交到仓库,应使用客户端支持的安全配置方式或系统密钥管理方案。
三、Streamable HTTP传输
Streamable HTTP适合远程MCP Server。Server作为独立HTTP服务运行,Client通过HTTP POST发送JSON-RPC消息,也可以通过SSE接收流式消息或通知。
MCP Client
↓ HTTP POST /mcp
MCP Server
↑ application/json 或 text/event-streamStreamable HTTP适合以下场景:
- 团队共享的工具服务
- 企业内部统一MCP Server
- 需要认证和权限控制的远程服务
- 多个Host连接同一Server
- 需要部署到容器或云服务的场景
3.1 HTTP Server示例
不同SDK版本对HTTP启动参数可能略有差异。使用FastMCP时,常见配置方式如下:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP(
"docs-server",
host="127.0.0.1",
port=8000,
streamable_http_path="/mcp",
)
@mcp.tool()
def ping() -> str:
"""Health check tool."""
return "pong"
if __name__ == "__main__":
mcp.run(transport="streamable-http")对应的Server地址为:
http://127.0.0.1:8000/mcp本地开发时建议绑定127.0.0.1。如果绑定0.0.0.0,应确认网络访问范围、认证策略和防火墙配置。
3.2 HTTP客户端配置
远程Server通常通过URL接入:
{
"mcpServers": {
"docs": {
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer your-token"
}
}
}
}不同Host的配置格式可能不同,但核心信息通常包括:
- Server名称
- MCP endpoint URL
- 请求头
- 认证信息
- 超时或重试配置
四、stdio和HTTP如何选择
| 判断条件 | 推荐方式 |
|---|---|
| Server只在本机使用 | stdio |
| Server需要访问本地文件或本地Git仓库 | stdio |
| Server需要被多人共享 | Streamable HTTP |
| Server需要统一认证和审计 | Streamable HTTP |
| Server部署在容器或云服务中 | Streamable HTTP |
| 开发早期快速验证 | stdio |
可以先用stdio完成最小可用版本,再在需要共享或部署时改为HTTP服务。
五、连接生命周期
MCP连接建立后,会先进行初始化和能力协商。典型流程如下:
Client -> Server: initialize
Server -> Client: protocolVersion + capabilities + serverInfo
Client -> Server: notifications/initialized
Client -> Server: tools/list
Server -> Client: available tools初始化阶段会协商:
- 协议版本
- Client能力
- Server能力
- Server名称和版本
- 是否支持工具、资源、提示词、通知等
如果协议版本不兼容,Client和Server应终止连接或给出明确错误。
六、常见连接问题
| 问题 | 可能原因 | 处理方式 |
|---|---|---|
| Server无法启动 | 命令路径错误、依赖缺失、权限不足 | 使用绝对路径,单独运行命令验证 |
| Client看不到工具 | Server未声明工具能力,或初始化失败 | 用Inspector查看initialize和tools/list |
| stdio连接后立即断开 | Server向stdout打印日志,破坏JSON-RPC | 日志改写到stderr |
| HTTP连接失败 | URL错误、端口未开放、路径不一致 | 检查endpoint和网络访问 |
| 认证失败 | Token缺失或过期 | 检查请求头和服务端认证逻辑 |
| 参数错误 | 工具schema与调用参数不匹配 | 检查工具定义和模型输入 |
七、部署建议
7.1 本地Server
本地Server应关注:
- 使用绝对路径配置命令。
- 不向
stdout写业务日志。 - 限制文件系统访问范围。
- 对写入、删除类工具加入确认机制。
- 避免在配置文件中硬编码敏感信息。
7.2 远程Server
远程Server应关注:
- 使用HTTPS。
- 实现认证和授权。
- 校验
Origin头,防止DNS rebinding攻击。 - 本地调试服务绑定
127.0.0.1。 - 对高风险工具加入审计和人工确认。
- 记录工具调用日志和错误日志。
八、总结
MCP的传输层决定Server如何被Client连接。
| 传输方式 | 核心特点 |
|---|---|
stdio | Client启动Server子进程,通过标准输入输出通信 |
| Streamable HTTP | Server作为HTTP服务运行,支持远程连接和认证 |
本地工具优先使用stdio,共享服务优先使用Streamable HTTP。无论选择哪种方式,都应关注初始化、能力发现、日志输出和安全边界。