CVE-2026-111770: MCP TypeScript server SDK: Shared transport or server instances delivered one HTTP client's messages to another
`@modelcontextprotocol/server` 2.0.0 through 2.2.0 could deliver one HTTP client's responses and notifications to another client. It happens when the app builds one stateless transport, or one `McpServer` or `Server`, at startup and shares it across clients. Upgrade to 2.3.0 and restructure the code, because the SDK now refuses shared instances.
Published Oct 20, 2026 · Analysis Oct 21, 2026
What an attacker can do
The server matched outgoing messages to a connection by JSON-RPC id alone. SDK clients number their requests from 0, so two clients on a shared transport or server routinely use the same id. A response meant for client A could then go to client B, and so could notifications.
The attacker is any client that can reach the HTTP endpoint, with no credentials. They need timing luck, which is why the vector marks attack complexity high. What they get is another user's tool results and notifications, which can include private data. They can also corrupt what the other client sees. The pattern was shown in the README examples for the hono, express, fastify and node packages, so copied example code is likely to be affected.
Who is affected
Affected: @modelcontextprotocol/server >= 2.0.0 and < 2.3.0, when several clients can reach your HTTP endpoint and your code creates the transport or server once at startup.
Not affected: createMcpHandler() with a factory that builds a new server on every call, stdio servers, and @modelcontextprotocol/sdk 1.26.0 or later.
npm ls @modelcontextprotocol/serverThen check where new McpServer( and the transport are created. Module-level creation is the risky pattern.
@modelcontextprotocol/server
- Ecosystem
- npm
- Affected
- >= 2.0.0, < 2.3.0
- Fixed in
- 2.3.0
- Check
npm ls @modelcontextprotocol/server
How to fix it
Upgrade to @modelcontextprotocol/server 2.3.0 or later.
You also need to change your code. The SDK now refuses sharing. A second connect() rejects with ALREADY_CONNECTED, and a stateless transport rejects its second request. Pick one:
createMcpHandler()with a factory that builds a newMcpServeron every call.- A new
McpServerand a new transport inside each request handler. - Per session: set
sessionIdGeneratorand keep oneMcpServerand one transport per session.
The same code change fixes the problem on affected versions if you cannot upgrade yet.
How to tell if you were hit
Search your code for an McpServer, Server or stateless transport created at module level and reused by every request. Client-side symptoms are responses that do not match the request or notifications from sessions the client never opened. The advisory gives no log signature. After upgrading, ALREADY_CONNECTED errors show where shared instances remain.
Original advisory
From the GitHub Advisory Database (CC BY 4.0).
Summary
In affected versions, an MCP server reached over HTTP could deliver one client's responses and notifications to another client. This happened when clients shared one stateless transport, or one McpServer or Server instance.
Messages were matched to a connection by JSON-RPC id alone. SDK clients number requests from 0, so ids collide in normal use.
Am I affected?
Yes, if more than one client can reach your HTTP endpoint and your code creates the transport or the server once at startup, instead of once per request or per session. Until this release, the README examples of @modelcontextprotocol/hono, express, fastify and node showed that pattern.
Affected versions: @modelcontextprotocol/server 2.0.0 through 2.2.0.
Not affected:
createMcpHandler()with a factory that builds a new server on every call- stdio servers
@modelcontextprotocol/sdk1.26.0 and later
Fix
Upgrade to @modelcontextprotocol/server 2.3.0 or later.
You also need to change your code. The SDK now refuses to be shared, so an affected app fails requests after upgrading: a second connect() rejects with ALREADY_CONNECTED, and a stateless transport rejects its second request.
Change to one of these:
- `createMcpHandler()`: pass a factory that builds a new
McpServeron every call. - Per request: build a new
McpServerand a new transport inside the request handler. - Per session: set
sessionIdGeneratorand keep oneMcpServerand one transport per session.
If you cannot upgrade yet, the same change fixes affected versions.
Credited to DavidCarliez, legitu1337.
Questions
- Why did my server start returning ALREADY_CONNECTED after upgrading?
Version 2.3.0 refuses shared instances on purpose. Your app connects one server or transport for many clients. Create a server per request, per session, or through a
createMcpHandler()factory.- Is the 1.x `@modelcontextprotocol/sdk` affected?
Not for this issue. The advisory lists 1.26.0 and later as not affected, and only
@modelcontextprotocol/server2.0.0 through 2.2.0 as vulnerable.- Does the attacker need to authenticate?
The CVSS vector says no privileges are required, but the attacker must be connected to the same shared instance at the right moment, so complexity is high.
References
How this page is made: the data panel comes from the GitHub Advisory Database, CISA’s KEV catalog, the NVD and FIRST EPSS, and updates twice a day. The analysis is written by an AI model from the sources listed above and checked by automated rules before it is published. Check versions against the vendor's advisory before you act. Methodology
More Other MCP servers and tools vulnerabilities
All Other MCP servers and tools entriesCVE-2026-77361
obsidian-tc : Symlink read-ACL scope bypass via lexical path checks
medium4.7Oct 23, 2026CVE-2026-114126
Storybook dev server vulnerable to code injection from the local network
high8.7Oct 22, 2026CVE-2026-113731
djust: Arbitrary absolute-path file read in the find_handlers_for_template MCP tool
low3.3Oct 21, 2026CVE-2026-114125
Storybook: Missing origin validation in Storybook preview allows code injection from malicious websites
critical9.4Oct 21, 2026GHSA-953h-535j-jg2v
agent-router: MCP session resume does not verify the embedded anti-hijacking subject; default Helm seed makes session IDs forgeable
medium6.8Oct 19, 2026CVE-2026-76894
ckan-mcp-server: DataStore Table UI resource does not validate postMessage origin (in) and posts to targetOrigin "*" (out)
low3.1Oct 16, 2026
