最近在做一个基于 MCP 的 Agent 小项目,本地起了一个 stdio 的 MCP server,暴露了五六个工具。大部分时候调用正常,但偶尔会出现工具调用没有返回、Agent 那边一直卡住的情况,日志里也看不到明显报错。重启 server 后又好了,但过一段时间又可能出现。我怀疑是连接复用或者超时设置的问题,但不太确定该怎么排查。想问下大家有没有踩过类似的坑?一般怎么定位这种偶发的静默失败?
MCP 工具调用偶尔静默失败,有人遇到过吗?
全部回复
共 5 条stdio 模式偶发卡死我也碰过,多半是 server 那边 stdout 被日志污染或者阻塞了,建议先查输出流。
这个坑我太熟了,之前做 MCP agent 的时候被折磨了快两周。stdio 模式下的静默卡死,八成是子进程的 stdout/stderr 缓冲区满了没人读,server 端 write 阻塞住,Agent 这边就一直等,看起来就像工具调用没返回。你可以在 server 里加个心跳日志或者把 stderr 单独重定向到文件,看看卡住那一刻进程是不是还活着但没输出。另一个常见原因是 JSON-RPC 的消息边界处理有问题,多条消息粘在一个 chunk 里或者一条消息被拆成两个 chunk,解析器没处理好就会默默吞掉请求。连接复用的话,MCP 的 stdio 其实没有真正的连接池概念,但如果你自己封了一层 client 复用逻辑,要留意 request id 有没有冲突或者响应被错配到别的 pending 请求上。排查建议先加超时和 request id 日志,每个请求发出去和收到响应都打点,卡住时看哪个 id 没回来。如果确认是 buffer 问题,可以在 server 侧对 stdout 的写入做非阻塞处理,或者定期 flush。还有个偏门情况是 server 里某个工具调用了同步阻塞的库,把整个事件循环堵死了,这种只能靠 profiling 或者二分注释工具来定位。
这个坑我踩过,大概率是 stdio 的读写卡住了,不是超时那么简单。你可以先看下 server 进程还在不在,有时候子进程已经挂了但父进程还在傻等。我之前遇到过类似情况,加了个心跳和调用超时兜底之后就好多了,至少不会一直卡死。建议你在工具调用前后都打点日志,看看是请求没发出去还是响应没回来,这样定位会快很多。
stdio 的锅,八成是子进程卡死或管道堵了,加个心跳超时试试。
stdio 的坑我也踩过,八成是管道缓冲满了卡死的,加个心跳或者超时重连基本能救回来。