Skip to content

fix(examples): create fresh McpServer per client in three examples#1610

Merged
mattzcarey merged 1 commit intomodelcontextprotocol:mainfrom
nielskaspers:fix/per-client-mcpserver-examples
Mar 2, 2026
Merged

fix(examples): create fresh McpServer per client in three examples#1610
mattzcarey merged 1 commit intomodelcontextprotocol:mainfrom
nielskaspers:fix/per-client-mcpserver-examples

Conversation

@nielskaspers
Copy link
Contributor

Summary

Fixes #1278

Three example files were sharing a single McpServer instance across all client connections. This can cause issues when multiple clients connect concurrently, as the server's internal state (tools, resources, sessions) becomes entangled between unrelated clients.

This PR updates the following examples to create a fresh McpServer per client connection using a getServer() factory function, matching the pattern already used by simpleStreamableHttp.ts and jsonResponseStreamableHttp.ts:

  • elicitationFormExample.ts — Wrapped McpServer creation and all three tool registrations (register_user, create_event, update_shipping_address) into getServer(), called on each new initialization request.
  • standaloneSseWithGetStreamableHttp.ts — Moved McpServer creation and initial resource registration into getServer(). The addResource helper now takes a server parameter. The periodic resource change interval adds resources to all active server instances. Added proper cleanup of both transports and servers maps on close/shutdown.
  • ssePollingExample.ts — Wrapped McpServer creation and long-task tool registration into getServer(), called when creating a new transport.

Test plan

  • Verify the three updated examples compile successfully (pnpm build:all)
  • Verify typecheck passes (pnpm typecheck:all)
  • Verify lint passes (pnpm lint:all)
  • Manual test: start each example server and connect multiple clients simultaneously to confirm they operate independently

Move McpServer creation and tool/resource registration into a
getServer() factory function that is called for each new client
connection, matching the pattern used by simpleStreamableHttp and
jsonResponseStreamableHttp.

Sharing a single McpServer instance across multiple clients can cause
issues with concurrent connections. The three updated examples are:

- elicitationFormExample.ts
- standaloneSseWithGetStreamableHttp.ts
- ssePollingExample.ts

Fixes modelcontextprotocol#1278
@nielskaspers nielskaspers requested a review from a team as a code owner March 1, 2026 11:58
@changeset-bot
Copy link

changeset-bot bot commented Mar 1, 2026

⚠️ No Changeset found

Latest commit: 3821275

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 1, 2026

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@1610

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@1610

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@1610

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@1610

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@1610

commit: 974123d

Comment on lines +148 to +158
// Close all active transports to properly clean up resources
for (const sessionId in transports) {
try {
console.log(`Closing transport for session ${sessionId}`);
await transports[sessionId]!.close();
delete transports[sessionId];
delete servers[sessionId];
} catch (error) {
console.error(`Error closing transport for session ${sessionId}:`, error);
}
}
Copy link
Contributor

@mattzcarey mattzcarey Mar 2, 2026

Choose a reason for hiding this comment

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

this shouldnt be necessary?

@mattzcarey mattzcarey merged commit 52186d1 into modelcontextprotocol:main Mar 2, 2026
12 checks passed
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.

Unclear guidance on whether McpServer can be shared between clients

2 participants