modelcontextprotocol / modelcontextprotocol/typescript-sdk
Bug/Feature Request: Node 26 fetch HTTP/2 SSE stream buffering hangs MCP connections
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 13.4k
- Forks
- 2.2k
- Avg merge
- 3d 15h
- Merged PRs (30d)
- 4
Description
Title
Bug/Feature Request: Node 26 fetch HTTP/2 SSE stream buffering hangs MCP connections
Body
(Note: This issue was investigated and drafted with the help of Google Antigravity / Gemini 3.1 Pro during a debugging session).
The Issue
When running MCP SDK clients (such as mcporter) on Node.js 26.4.0, all Server-Sent Events (SSE) connections fail to initialize and eventually time out with errors like Invalid response body, expected a web ReadableStream.
Root Cause Analysis
Node 26 upgraded its native fetch implementation (backed by undici) to enable HTTP/2 by default. There appears to be a stream buffering regression in undici when handling SSE over HTTP/2. As a result, the initial connection chunks (specifically the endpoint URI required by the MCP client) are buffered and never flushed to the client's ReadableStream, causing the connection handshake to stall indefinitely.
Evidence & Workaround
- Failure: On Node 26.4.0, standard MCP SSE connections hang completely.
- Success: By overriding the global
fetchdispatcher to force HTTP/1.1, the streams flow instantly and 100% of the MCP server connections succeed.
Here is the exact shim that resolves the issue locally:
import { setGlobalDispatcher, Agent } from "undici";
// Force HTTP/1.1 to bypass the Node 26 HTTP/2 SSE streaming bug
const agent = new Agent({
allowH2: false
});
setGlobalDispatcher(agent);
Proposed Solution
While the root cause lies upstream in Node.js / undici, the MCP SDK could protect its users from this breaking change:
- Enforce HTTP/1.1 for SSE: Explicitly configure the fetch transport layer to use HTTP/1.1 (
allowH2: false) when running in a Node.js environment, as SSE over HTTP/2 in Node is currently unstable. - Expose Transport Config: Alternatively, expose the underlying
fetchrequest initialization/dispatcher options in the SDK so users can inject customundiciagents when needed.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the SDK's SSE fetch transport and reproduce the connection hang on Node.js 26.4.0. Compare the current HTTP/2 behavior with the reported undici Agent workaround; done means MCP SSE connections initialize reliably or the transport exposes a way to configure the dispatcher.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100