Skip to content

MCP stdio server 意外死亡后无自动重连,调用挂起至 toolTimeoutMs 而非快速失败 #2109

Description

@Yorha9e

摘要

当 stdio MCP server 进程意外死亡(崩溃、OOM、Windows 上 taskkill /F)时,kimi-code 能正确检测并把 server 标记为 failed——但从不尝试重连,且发往已死 server 的工具调用会一直挂到(可能很长的)toolTimeoutMs,而不是快速失败或尝试恢复。MCP server 是长驻边车进程,意外死亡是常态事件而非边缘情况——尤其在 Windows 上,强杀不会投递 SIGTERM。

复现

  1. 配置任意 stdio MCP server(最小例子:一个永不退出的 node 脚本)。
  2. 启动会话,/mcp 确认显示 connected
  3. 强杀 server 进程(Windows:taskkill /F /PID <pid>;POSIX:kill -9)。
  4. 调用它的任一工具。

观察到的行为

  • /mcp 显示 server 为 failed(检测正常)——但没有任何机制重连它;只有手动 /mcp 重连或新开会话才能恢复。
  • 在途工具调用一直阻塞到 toolTimeoutMs(默认分钟级;用户可能设得更大,例如长轮询 server 的 30 分钟),期间无任何诊断信息。

期望的行为

  • 意外关闭后按指数退避(有限次数)自动重连——瞬时崩溃是常见情况。
  • failed server 的调用应快速失败并给出明确错误(或在失败前内联尝试一次重连),而不是挂起。

证据(代码引用,0.29.0)

  • 死亡检测正常:packages/agent-core/src/mcp/connection-manager.ts —— watchForUnexpectedClose 把条目标记为 failed、记录 stderr、广播状态事件。
  • 手动重连存在:同文件 reconnect(name);RPC reconnectMcpServerpackages/agent-core/src/rpc/core-impl.ts)。
  • manager 中不存在任何自动重试。
  • 我们针对 @modelcontextprotocol/sdk 在 Windows 上做了两个独立复现:taskkill /FStdioClientTransport.onclose 约 0.5 秒触发;完整 Client 握手 + 强杀同样约 0.6 秒触发 onclose。SDK 层信号送达正常,缺的只是 kimi-code 的恢复策略。
  • 真实影响案例:一个长轮询 MCP server(toolTimeoutMs: 1800000)被强杀后,编排中的多个 agent 的调用静默挂起——因为失败面在 30 分钟后才出现,排查耗时巨大。插件形态的 server(插件同样是 stdio MCP server)走同一条路径——插件层没有独立于共享 connection-manager 的进程监管。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions