MCP 连不上,先分型再动手。本地 stdio 由客户端直接拉起一个进程,压根不经过网络;远程 HTTP/SSE 才会撞上代理、长连接被切、证书和企业网关。这两类的原因几乎没有交集,混在一起查就会陷入「改一个变量试一次」的循环。
分型只看一个信号:报错是进程没起来(命令找不到、依赖缺失),还是网络没通(超时、握手后无数据)。前者翻客户端启动日志,后者才轮到 Clash。Agent 侧用法见如何使用 Claude Code、如何使用 Codex CLI;统一多上游见 9Router 配置。
两种传输,两种病
| 本地 stdio | 远程 HTTP / SSE | |
|---|---|---|
| 怎么跑 | 客户端启动本地命令,走标准输入输出 | 客户端向一个 URL 发请求,服务端流式回传 |
| 典型失败 | 命令找不到、依赖缺失、权限不足、路径写错 | 超时、握手后无数据、会话莫名断开 |
| 和代理有关吗 | 基本无关 | 强相关 |
| 先看什么 | 客户端日志里的启动报错 | 能否出站、有没有增量数据 |
远程连不上:按这个顺序查
-
出站通不通。端点在境外时,先确认运行客户端的进程能出海:开 Tun,或在启动客户端的终端里设
HTTPS_PROXY。改完重开终端或重启客户端再试。 -
回环有没有被误代理。本地起的 MCP 服务用
127.0.0.1访问,代理变量却把它一起代理走,就会出现「服务明明在跑却连不上」。把回环写进NO_PROXY。 - 是不是握手成功但没数据。这最能说明问题:连接建立了,工具列表却一直空着,八成是流被中间层缓冲住了,而不是网络不通。
- 会话是不是被定时掐断。用几分钟就断、每次断的间隔还挺规律,通常是某一层的读超时或空闲超时在起作用。
- 证书与网关。公司网络里的 TLS 中间盒会让客户端拒绝连接;这类要么让 IT 放行,要么换网络验证。
自建服务端时,最常踩的一组配置
如果远程 MCP 是你自己放在 VPS 上、前面挂了 Nginx,那么「连上但不返回」几乎总是缓冲问题:反向代理默认会把响应攒够一批再发,而 SSE 需要边产生边送。对应的做法是在该 location 上关掉缓冲与缓存、保持 HTTP/1.1 长连接、不要压缩,并把读超时放长:
location /mcp {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
proxy_cache off;
gzip off;
proxy_read_timeout 86400s;
}
更省事的方向是换传输:MCP 规范里的 Streamable HTTP 把长连接拆成一次次独立请求,网络抖动时单次失败可重试,不会整段会话报废,反代配置也回归常规。新部署优先选它,SSE 更适合本机或内网。
另外,别把 MCP 服务裸奔在公网。它常常握着文件系统或内部 API 的操作能力,至少要有 TLS 与鉴权;把工具权限收敛到只读也是有效的减面手段。
网络抖动是常态,不是故障
合盖休眠、从 Wi-Fi 切到热点、代理换节点重连——这些都会打断长连接。合理预期是「需要重连」,而不是每次都去翻配置。经常在移动场景用远程 MCP 的人,选 Streamable HTTP 的收益比调超时更大。相关:休眠唤醒后断网、代理开了却打不开。
最小复现
- 只留一个 MCP 服务,其它先禁用。
- 在命令行直连端点,看数据是逐条到达还是最后一次性吐出——后者就是缓冲。
- 确认代理方式只启用一种(Tun 或变量)。
- 成功后再逐个加回其它服务,每加一个跑一次最小请求。