Skip to content

fix(agent-core-v2): reconnect dropped MCP servers on tool call failure - #1991

Merged
7Sageer merged 6 commits into
mainfrom
fix/mcp-lazy-reconnect
Jul 21, 2026
Merged

fix(agent-core-v2): reconnect dropped MCP servers on tool call failure#1991
7Sageer merged 6 commits into
mainfrom
fix/mcp-lazy-reconnect

Conversation

@7Sageer

@7Sageer 7Sageer commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — the problem is explained below. Related: #1168 (asks for MCP status/manual control; this PR only adds automatic recovery, it does not resolve that request).

Problem

MCP servers connect once when a session starts. If a connection drops mid-session (the stdio process exits, a remote server restarts, etc.), the next call to one of its tools fails outright, and the server's tools disappear from the tool list for every later turn. There was no automatic recovery: the model saw a failed tool call and permanently lost the capability for the rest of the session.

What changed

When an MCP tool call throws because the transport died, the tool now reconnects its server once and retries the call on the fresh client, so a dropped connection surfaces as a slow call instead of a failed turn. This fits the existing lifecycle: the session-scoped connection manager already owns reconnects and status events, so the adapter only bridges the failing call to that path.

  • Parallel tool calls failing on the same dead server share a single reconnect instead of restarting it once per call.
  • User aborts bypass the retry, so cancellation stays responsive.
  • If the reconnect itself fails, the tool reports both the original error and the reconnect failure; existing failed/disconnected status events and tool-list updates are unchanged.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

When an MCP transport dies mid-session (e.g. the stdio process exits),
the wrapped tool now reconnects the server once and retries the call on
the fresh client, so a dropped connection surfaces as a slow call
instead of a failed turn. Concurrent failing calls on the same server
share a single reconnect, and abort errors bypass the retry.
@changeset-bot

changeset-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 02bbfa7

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 21, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@02bbfa7
npx https://pkg.pr.new/@moonshot-ai/kimi-code@02bbfa7

commit: 02bbfa7

7Sageer added 5 commits July 21, 2026 12:14
Widen the tool-call recovery trigger from the ConnectionClosed error code
to any transport-level failure: an McpError means the server answered (or
the request timed out) and is not retried, while raw transport errors
(fetch failures, "Not connected" on an already-closed client) now trigger
one reconnect-and-retry. This covers remote HTTP/SSE servers restarting
and batched calls dispatched after the close was processed.

Reconnect through the session-scoped connection manager with join
semantics (reconnectAndJoin) instead of a per-agent dedupe map: parallel
failing calls across agents now share one reconnect instead of preempting
each other through attemptId, and a call that fails after the server was
already healed retries on the resolved client without restarting it again.
…ll failure

Classify an ambiguous tool-call failure by probing the client with a
short-timeout ping instead of guessing from the error type:

- The server answered (a JSON-RPC error, or a result that failed
  client-side CallToolResultSchema validation) is rethrown as-is;
  reconnecting would not change the answer and previously restarted the
  stdio server on every such call.
- The probe succeeding means the failure was transient, so the call is
  retried once in place instead of paying a full reconnect.
- Only a measured-dead transport (the SDK's onclose, or a failed probe)
  goes through reconnectAndJoin and retries on the fresh client, still
  capped at one reconnect per call.

MCPClient gains ping() for the probe; retries remain at-least-once,
now documented in the adapter's module header.
A server whose transport dies between turns no longer loses its tools:
failed/pending status events no longer unregister them, so the next
call reaches the adapter and its reconnect-and-retry path heals the
connection instead of failing with "tool not found".
A server whose connection dies between turns no longer loses its tools from the tool list — they stay available and the next call heals the connection instead of failing with 'tool not found'.

Signed-off-by: 7Sageer <7sageer@djwcb.cn>
@7Sageer
7Sageer merged commit 92576e4 into main Jul 21, 2026
14 checks passed
@7Sageer
7Sageer deleted the fix/mcp-lazy-reconnect branch July 21, 2026 09:56
@github-actions github-actions Bot mentioned this pull request Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant