Skip to content

fix(mcp): create fresh MCP Server per transport session#13631

Merged
DeJeune merged 1 commit intomainfrom
DeJeune/fix-mcp-first-prompt
Mar 19, 2026
Merged

fix(mcp): create fresh MCP Server per transport session#13631
DeJeune merged 1 commit intomainfrom
DeJeune/fix-mcp-first-prompt

Conversation

@DeJeune
Copy link
Copy Markdown
Collaborator

@DeJeune DeJeune commented Mar 19, 2026

What this PR does

Before this PR:
MCP tools only worked on the first user prompt when using the Claude Agent SDK. Subsequent prompts failed silently because the cached MCP Server was already bound to a previous transport.

After this PR:
A fresh MCP Server instance is created for each transport session, so MCP tools work correctly on every prompt.

Why we need it and why it was done in this way

The MCP SDK's Protocol.connect() throws "Already connected" if the Server is already bound to a transport. The Claude Agent SDK spawns a new CLI process per query (including resumes), and each process establishes a new HTTP transport. The previous code cached the Server instance and tried to reuse it, which caused the "Already connected" error on the second and subsequent prompts.

The following tradeoffs were made:

  • Removed the server cache entirely. Creating a new Server instance per session is lightweight (just an object with two request handlers), so caching provides no meaningful benefit.

The following alternatives were considered:

  • Disconnecting the old transport before connecting the new one — rejected because the MCP SDK Server class doesn't expose a clean disconnect/reset API.

Breaking changes

None.

Special notes for your reviewer

The key insight is in src/main/apiServer/utils/mcp.ts: getMcpServerById (cached) → createMcpServerForTransport (fresh instance per session).

Checklist

  • PR: The PR description is expressive enough and will help future contributors
  • Code: Write code that humans can understand and Keep it simple
  • Refactor: You have left the code cleaner than you found it (Boy Scout Rule)
  • Upgrade: Impact of this change on upgrade flows was considered and addressed if required
  • Documentation: N/A
  • Self-review: I have reviewed my own code before requesting review from others

Release note

Fixed MCP tools only working on the first prompt when using the Claude Agent SDK API server.

The MCP Server was cached and reused across transport sessions, but
Protocol.connect() throws "Already connected" when the Server is
already bound to a transport. Since the Claude Agent SDK spawns a new
CLI process per query, each one establishes a new HTTP transport and
needs a fresh Server instance. Replace the cached server lookup with
a factory that creates a new Server for each session.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Signed-off-by: suyao <[email protected]>
@DeJeune DeJeune requested a review from vaayne March 19, 2026 08:42
Copy link
Copy Markdown
Collaborator

@kangfenmao kangfenmao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Clean and correct fix: removes the cached Server instance pattern and creates a fresh instance per transport session, resolving the MCP SDK Protocol.connect() Already connected error. Code quality is good with clear JSDoc explaining the design rationale.

Copy link
Copy Markdown
Collaborator

@zhibisora zhibisora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix looks good to me.

Switching from a cached MCP Server instance to creating a fresh Server per transport session addresses the Already connected failure mode described in the PR, and I did not find any blocking regressions in the current Claude Agent SDK API server path.

No blocking issues found.

@DeJeune DeJeune merged commit c48f038 into main Mar 19, 2026
10 checks passed
@DeJeune DeJeune deleted the DeJeune/fix-mcp-first-prompt branch March 19, 2026 11:18
@SiinXu SiinXu mentioned this pull request Mar 20, 2026
5 tasks
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.

3 participants