fix(opencode): reconnect MCP transport on session-expiration error and retry once#25135
fix(opencode): reconnect MCP transport on session-expiration error and retry once#25135iggerask wants to merge 1 commit into
Conversation
|
Hey! Your PR title Please update it to start with one of:
Where See CONTRIBUTING.md for details. |
…d retry once Closes anomalyco#23997. When a remote MCP server invalidates a streamable-HTTP session (server restart, idle timeout, or periodic rotation), the cached StreamableHTTPClientTransport keeps sending the now-stale mcp-session-id header and every tool call on that server fails with "Error POSTing to endpoint: {\"error\":\"Session not found\"}" until the user manually disconnects and reconnects. Wrap client.callTool in convertMcpTool with a single-retry recovery: on an error matching session-expiration ("session not found" / "invalid session" / "mcp-session-id"), trigger a reconnect via the existing createAndStore() machinery and replay the call against the fresh client. Bound to one retry to avoid hammering on persistent failures. The reconnect callback re-enters Effect-land from the AI SDK's plain async Tool.execute path by capturing the current Effect context inside tools() and using Effect.runPromiseWith(ctx). The resolver reads s.clients directly so it observes the post-reconnect client. Includes test/mcp/session-recovery.test.ts: - recovers from one-shot Session-not-found - propagates after exactly one retry on persistent failure (no loop) - non-session errors are not treated as recoverable
d132b39 to
57e2337
Compare
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
|
Automated PR Cleanup Thank you for contributing to opencode. Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions. This PR was closed because it matched the following cleanup criteria:
PRs created within the last month are not affected by this cleanup. If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate. Thanks again for taking the time to contribute. |
Issue for this PR
Closes #25137.
Type of change
What does this PR do?
When a remote streamable-HTTP MCP server invalidates a session (server restart, idle timeout), opencode keeps sending the stale
mcp-session-id. Every tool call after that fails withError POSTing to endpoint: {"error":"Session not found"}until the user manually disconnects and reconnects.This wraps
client.callToolinconvertMcpToolwith a one-shot recovery: on a session-expired error, call the existingcreateAndStore()to rebuild the transport, then replay the call once. Bounded to one retry — a fresh transport that fails again signals a real problem where retrying won't help.Doesn't touch the related
listTools()eviction path (#17099) or the desktop session-restore crash (#25131).How did you verify your code works?
bun --cwd packages/opencode test test/mcp/— 36/36 pass (3 new insession-recovery.test.ts).mcp session expired, reconnectinglog line and the next tool call succeeded. Pre-fix, every call after that failed.Checklist