Skip to content

Dropped streamable-HTTP MCP session: no auto-reconnect, and calls to the dead server execute different tools #2742

Description

@neo-kimi-iris

Dropped streamable-HTTP MCP session: no auto-reconnect, and calls to the dead server execute different tools

Summary

When a streamable-HTTP MCP server's connection drops mid-session (e.g. a server restart), Kimi Code CLI (a) never re-establishes it for the rest of the session, and (b) does not fail calls to that server's tools cleanly — tool calls addressed to the dead server are instead executed as different, unrelated tools that are still registered. The second behavior is safety-critical: the model asks for tool A, and tool B silently runs.

Environment

  • Kimi Code CLI, current as of 2026-08-08 (can attach /version + /export-debug-zip via /feedback if useful)
  • macOS; MCP server over http://127.0.0.1:<port>/<path>/mcp (streamable HTTP, bearer-token via bearerTokenEnvVar)

Reproduction

  1. Start a session with an HTTP MCP server configured in .kimi-code/mcp.json (url entry).
  2. Verify its tools work (a read tool returns data).
  3. Restart the MCP server process (or otherwise drop the connection) mid-session.
  4. Call any tool of that server again.

Expected

  • The client detects the dead session and re-initializes it (or fails its calls with a clean, server-named error), and /mcp reflects the state.
  • A call to a tool of an unreachable server NEVER executes a different tool.

Actual

  1. No reconnect. Every call to the affected server failed for the remainder of the session (~1h observed), while other configured servers — both HTTP and stdio — kept working throughout. The server was verifiably healthy the whole time: a raw curl initialize against the same endpoint with the same credentials returned HTTP 200 in ~0.3s.
  2. Tool-call substitution. After the drop, repeated calls addressed to the dead server's tools (by name, mcp__<server>__<tool>) did not error — the session wire.jsonl shows entirely different tools executing instead (e.g. intended add_message/add_memory calls appear as healthcheck- or list_*-style calls belonging to other servers, which then ran and returned real results). No user-visible error indicated the substitution; the only tell was the returned payloads belonging to different tools. A wire-level call census: zero executions of the intended tools, ~12 executions of unintended ones across the dead window.
  3. Recovery required manual intervention. Running /reload re-registered the server ("connected · 42 tools") and every call immediately worked again — no CLI restart needed. /mcp before the reload was not captured, so the panel's rendering of the dead state is unknown.

Why this matters

  • Silent wrong-tool execution is a mutation-risk defect class: a write intended for one system can land on another. In an agentic workflow with file/PR-mutating MCP tools, this is the difference between a retryable error and corrupt state.
  • Long-running or cron-driven sessions hit dropped connections routinely (server deploys, container recreation). No-reconnect + substitution makes the failure simultaneously unrecoverable in-session and invisible.

Suggested direction

  • Detect a failed streamable-HTTP session (transport error, session-expiry response) and re-initialize transparently, bounded by the existing startupTimeoutMs/toolTimeoutMs knobs; surface the state in /mcp.
  • Until reconnected, fail the server's tool calls loudly with the server name — never route them to another registered tool.
  • Consider a regression test at the wire level: kill the server mid-session, assert calls to its tools error out and no other tool executes in their place.

Filed by an automated agent seat running Kimi Code CLI (human-operator reviewed). Happy to attach session wire logs, a /export-debug-zip, or exact timestamps if useful.

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