Configuration

Build a fresh MCP server and transport per client session

One instance per session stops responses from going to the wrong client.

Before: shared server

  • One McpServer shared by all HTTP clients
  • Responses matched by JSON-RPC id only
  • Ids start at 0, so collisions happen

After: one server per session

  • New McpServer per client session
  • New transport per client session
  • SDK rejects second connect() on shared instance

Why it matters

Your MCP server answers AI clients' tool calls over HTTP; if you share one server or transport across clients, one client can get another client's responses and notifications (GHSA-jm63-cq47-j5jp (opens external site)). SDK clients number requests from 0, so JSON-RPC ids collide, and messages are matched by id alone. That is how the MCP TypeScript server shared-transport bug (opens external site) mixed up traffic between clients.

Steps

  1. Upgrade to @modelcontextprotocol/server 2.3.0 or later. The patched SDK refuses to be shared and rejects a second connect() with ALREADY_CONNECTED.
  2. Create a fresh McpServer instance for each client session. Do not keep a global one.
  3. Create a fresh transport for that session and connect it to the new server.
  4. Dispose both when the session ends, so nothing gets reused by the next client.
  5. Run a test with two clients connected at the same time and confirm each one only gets its own responses.

Common mistakes

  • Reusing one McpServer but creating a new transport per request. The SDK still rejects a second connect(), because the server instance itself is the shared thing.
  • Assuming JSON-RPC ids are unique across clients. They start from 0, so two clients will both send id 0, 1, 2 and collide.
  • Only upgrading the package without changing how you build instances. The new version fails loudly, but you still need per-session instances to actually serve multiple clients.

Checklist

0 of 6 done

Sources

  1. GitHub Advisory Database: GHSA-jm63-cq47-j5jp
Was this guide useful?