10.1 三种客户端传输的接入细节 本节摘要:第 9 章用了 的三种构造形态,本节深入客户端侧三种传输的接入细节——stdio 客户端(连本地子进程)、流式 HTTP 客户端(连远程服务)、SSE 客户端(连旧版服务,现状与限制)。每种传输的客户端接入有不同的关键参数与陷阱,本节用对照表讲透,让你在生产里选对、配对。 一、stdio 客户端:连本地子进程 stdio 客户端用于「宿主连本地服务端子进程」——这是 Claude Desktop、IDE 这类本地宿主的标准模式。用 配置子进程: 关键参数: 参数 | 作用 | 注意 | 启动命令(如 、 ) | 要在 PATH 里能找到 | 命令参数(服务端文件等) | 第一个通常是文件路径 | 环境变量 | 必须显式注入(回顾第 8.
本节摘要:第 9 章用了
Client的三种构造形态,本节深入客户端侧三种传输的接入细节——stdio 客户端(连本地子进程)、流式 HTTP 客户端(连远程服务)、SSE 客户端(连旧版服务,现状与限制)。每种传输的客户端接入有不同的关键参数与陷阱,本节用对照表讲透,让你在生产里选对、配对。
stdio 客户端用于「宿主连本地服务端子进程」——这是 Claude Desktop、IDE 这类本地宿主的标准模式。用 StdioServerParameters 配置子进程:
from mcp.client.stdio import stdio_client, StdioServerParameters params = StdioServerParameters( command="python", # 启动命令 args=["server.py"], # 参数 env={ # 环境变量(白名单注入) "DATABASE_URL": "...", } ) async with stdio_client(params) as (read, write): async with Client(read, write) as client: result = await client.call_tool("add", {"a": 1, "b": 2})
关键参数:
| 参数 | 作用 | 注意 |
|---|---|---|
command |
启动命令(如 python、node) |
要在 PATH 里能找到 |
args |
命令参数(服务端文件等) | 第一个通常是文件路径 |
env |
环境变量 | 必须显式注入(回顾第 8.2 节白名单) |
⚠️ 注意:stdio 客户端的环境变量不会自动继承宿主。回顾第 8.2 节,子进程默认只拿白名单变量。如果你的服务端依赖
DATABASE_URL等,必须显式传env,否则服务端拿不到。
流式 HTTP 客户端用于「连远程 MCP 服务」——这是生产部署的标准模式。最简形态是 Client(url):
async with Client("http://example.com/mcp") as client: result = await client.call_tool("add", {"a": 1, "b": 2})
但生产场景常需要更多控制(认证头、超时、自定义传输),这时用底层的 streamable_http_client:
from mcp.client.streamable_http import streamable_http_client async with streamable_http_client( "http://example.com/mcp", headers={"Authorization": "Bearer ..."}, # 认证头 timeout=30, # 超时 ) as (read, write): async with Client(read, write) as client: ...
关键参数:
| 参数 | 作用 |
|---|---|
| URL | 服务端端点(如 http://example.com/mcp) |
headers |
自定义请求头(认证、客户端标识) |
timeout |
连接/请求超时 |
SSE 客户端用于「连旧版 SSE 服务」——新代码别用,但维护老服务时可能遇到:
from mcp.client.sse import sse_client async with sse_client("http://old-server.com/sse") as (read, write): async with Client(read, write) as client: ...
SSE 客户端的限制(对应第 8.4 节):
| 限制 | 说明 |
|---|---|
| 已弃用 | 官方不推荐,未来可能移除 |
| 双连接 | 底层是双连接模型,行为与流式 HTTP 不同 |
| 兼容性 | 仅用于连老服务,新服务用流式 HTTP |
把三种客户端传输放一起对照:
| 维度 | stdio 客户端 | 流式 HTTP 客户端 | SSE 客户端 |
|---|---|---|---|
| 连接对象 | 本地子进程 | 远程 HTTP 服务 | 旧版 SSE 服务 |
| 关键参数 | command/args/env | URL/headers/timeout | URL |
| 配置复杂度 | 中(配子进程) | 低(一个 URL) | 低 |
| 生产适用 | ✅ 本地宿主 | ✅ 远程生产 | ❌ 弃用 |
| 环境变量 | 显式注入 | 通过 headers | 通过 headers |
stdio 客户端有几个高频陷阱,值得单独列:
| 陷阱 | 原因 | 解决 |
|---|---|---|
| 子进程启动失败 | command 不在 PATH、文件路径错 | 用绝对路径、检查 PATH |
| 服务端拿不到环境变量 | 默认白名单不传 | 显式传 env |
| Windows 下编码问题 | 默认编码非 UTF-8 | 服务端设 UTF-8 输出 |
| stdout 被污染 | 服务端 print 到 stdout | 服务端调试用 stderr(第 8.2 节) |
| 子进程僵尸 | 异常退出未清理 | 用 async with 确保清理 |
💡 技巧:「我的 stdio 客户端连不上」排查四步:1)command/args 对不对(手动跑下命令);2)env 是否注入(服务端 print 环境变量到 stderr 看);3)stdout 是否被污染(服务端别 print 到 stdout);4)Windows 编码(设 UTF-8)。这四步覆盖 90% 的 stdio 问题。
流式 HTTP 客户端的陷阱:
| 陷阱 | 原因 | 解决 |
|---|---|---|
| 连接超时 | 网络问题、服务端没起 | 检查 URL、服务端状态 |
| DNS 重绑定防护 | 服务端默认只允许 localhost | 配置 allowed_hosts(第 8.5 节) |
| 认证失败 | 缺少或无效 token | 配 headers 加认证 |
| 反代问题 | 反代不兼容 SSE 流 | 配置反代支持长连接 |
| 大响应截断 | 请求体大小上限 | 调 max_request_body_size |
把传输选型浓缩成一个决策:
你的客户端连什么? │ ├─ 本地子进程(Claude Desktop 式)→ stdio 客户端 │ ├─ 远程 HTTP 服务(生产)→ 流式 HTTP 客户端 │ └─ 旧版 SSE 服务(维护)→ SSE 客户端(规划迁移)
绝大多数生产场景用流式 HTTP;本地工具用 stdio;SSE 仅过渡。第 11 章会讲,流式 HTTP 客户端连公网服务时,还要配 OAuth 认证。
StdioServerParameters 配子进程,关键参数 command/args/env(必须显式注入)。Client(url) 简单,或用 streamable_http_client 控制 headers/timeout。传输接入清楚了,下一节讲会话组——编排多个服务端的利器。