fix(agent-core-v2): reconnect dropped MCP servers on tool call failure - #1991
Merged
Conversation
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 detectedLatest commit: 02bbfa7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
commit: |
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.