Skip to content

fix(opencode): reconnect MCP transport on session-expiration error and retry once#25135

Open
iggerask wants to merge 1 commit intoanomalyco:devfrom
iggerask:fix/mcp-session-recovery
Open

fix(opencode): reconnect MCP transport on session-expiration error and retry once#25135
iggerask wants to merge 1 commit intoanomalyco:devfrom
iggerask:fix/mcp-session-recovery

Conversation

@iggerask
Copy link
Copy Markdown

@iggerask iggerask commented Apr 30, 2026

Issue for this PR

Closes #25137.

Type of change

  • Bug fix

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 with Error POSTing to endpoint: {"error":"Session not found"} until the user manually disconnects and reconnects.

This wraps client.callTool in convertMcpTool with a one-shot recovery: on a session-expired error, call the existing createAndStore() 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 in session-recovery.test.ts).
  • Live repro against a streamable-HTTP MCP server I control: invalidated the session mid-conversation, saw the mcp session expired, reconnecting log line and the next tool call succeeded. Pre-fix, every call after that failed.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions
Copy link
Copy Markdown
Contributor

Hey! Your PR title mcp: reconnect transport on session-expiration error and retry once doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Apr 30, 2026
…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
@iggerask iggerask force-pushed the fix/mcp-session-recovery branch from d132b39 to 57e2337 Compare April 30, 2026 17:31
@iggerask iggerask changed the title mcp: reconnect transport on session-expiration error and retry once fix(opencode): reconnect MCP transport on session-expiration error and retry once Apr 30, 2026
@github-actions github-actions Bot removed needs:title needs:compliance This means the issue will auto-close after 2 hours. labels Apr 30, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@github-actions
Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

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.

MCP streamable-HTTP transport: 'Session not found' from server permanently breaks tool calls (no auto-reconnect)

1 participant