Claude Code 的 MCP 工具跑一会儿就超时?根因与两个超时变量的解法(附 issue)

用 Claude Code(或 Claude Desktop)通过 MCP 工具跑耗时较长的命令时,常遇到命令在服务器上明明还在跑、却在大约一两分钟处被中止。这篇把现象、根因和解法整理清楚,附两条能对上号的 issue。

现象

通过 MCP 工具执行长命令(远程执行、测速、sleep、装包、大文件下载等),客户端报类似:

Error: MCP error -32001: Request timed out

命令并没有真的被取消,它在远端会继续跑完;后续调用也一切正常。

XPipe 的 issue #870 记录了完全一致的情况:MCP run_command 约 60–70 秒超时,远程命令照常完成,作者判断"这更可能是 MCP 客户端侧的限制,而不是 XPipe 直接控制的阈值",该 issue 最终被标为 not planned 关闭。也就是说:这不是 MCP 服务器或远程主机的问题,是 MCP 客户端(Claude Code)侧的超时在掐。

根因

  1. 很多 MCP 工具本身没有暴露 timeout 参数。给这类工具调用传 timeout 会被静默忽略——那个字段是 Claude Code 内置 Bash/PowerShell 工具的,对 MCP 工具不生效。

  2. Claude Code 侧管着 MCP 工具调用的两个超时,真正掐命令的往往是第二个:

    • MCP_TOOL_TIMEOUT —— 工具执行的总超时。
    • CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT —— 空闲超时:工具多久没有新输出就判定卡住并中止。很多 MCP 工具是"跑完才一次性返回结果",执行期间没有任何增量输出,在客户端看来就是一直空闲,于是到点被砍。这也解释了为什么"命令还在跑却被判超时"。
  3. 别和 MCP_TIMEOUT 混淆——那个是 MCP 服务器启动超时,跟工具执行无关。

解决

全局配置:在 ~/.claude/settings.jsonenv 里加(单位毫秒,示例 10 分钟):

{
  "env": {
    "MCP_TOOL_TIMEOUT": "600000",
    "CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT": "600000"
  }
}

CLAUDE_CODE_MCP_TOOL_IDLE_TIMEOUT 设为 0 可直接关闭空闲检测。

只想对单个服务器放宽:在该服务器的 MCP 配置(.mcp.json)条目里加 timeout 字段(毫秒),例如 "timeout": 600000。它会覆盖该服务器的 MCP_TOOL_TIMEOUT,并作为空闲超时的下限(需 Claude Code v2.1.203+)。

改完需要重启 Claude Code,env 在会话启动时注入,当前会话不即时生效。

另一种更稳的思路:不改超时,而是把长命令在服务器上后台跑、输出写日志文件,再分次轮询——这正是 XPipe issue #870 里给出的 workaround(setsid + 重定向日志 + 事后轮询)。这样每次 MCP 调用都秒回,不触发任何超时。两者不冲突,可以配合用。

顺带:同一类"隐形超时"

Claude Code 里不止这一个自动超时。anthropics/claude-code#73125 讲的是 AskUserQuestion 工具的 60 秒自动继续:在 2.1.198 里它默认开启,无人应答满 60 秒就自动带着当前选项继续,而且当时没文档、不可配,还会绕过需要用户确认的安全检查。维护者在 该 issue 的回复 里说明:2.100 起不再默认开启,改为在 /config 里可配的时间窗口(设置项 askUserQuestionTimeout,可选 60s/5m/10m/never,默认 never),且只在终端失焦时才计时、按任意键即取消。

它和 MCP 工具超时是两码事(一个是问答自动继续,一个是工具执行/空闲被中止),别把两者混为一谈。但它们属于同一类问题:Claude Code 有多个会自动中止/继续的超时,知道各自叫什么、在哪配,就不会被莫名其妙打断。

参考