You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Web-standard SSE responses override the HTTP server keep-alive lifetime #2553
WebStandardStreamableHTTPServerTransport sets Connection: keep-alive on each SSE Response, but it cannot know the lifetime of the underlying HTTP connection and does not provide a matching Keep-Alive lifetime.
Connection is a hop-by-hop header. The HTTP adapter or server owns that policy. On Node HTTP/1.1, the explicit SDK header suppresses Node automatic output such as:
Connection: keep-aliveKeep-Alive: timeout=5
Without the lifetime hint, a pooling client cannot retire an idle socket before the server does and can race a server FIN on a later MCP request. On HTTP/2, Connection is forbidden and must be removed by the adapter.
The header is currently present at three response sites on both main and v1.x.
Expected behavior
The web-standard transport should omit hop-by-hop connection policy. The concrete adapter can then describe the real transport:
Node HTTP/1.1 emits Connection: keep-alive and its configured Keep-Alive: timeout=... automatically.
HTTP/2 emits neither forbidden hop-by-hop header.
Other Fetch runtimes remain free to apply their own connection policy.
This does not disable persistent connections and does not require Connection: close. Nearby MCP requests can still reuse a socket, while clients that honor the advertised lifetime can retire it safely and continue the same Mcp-Session-Id on another socket.
Scope
This is separate from SSE comment heartbeats such as #2541. Heartbeats protect an open, temporarily silent SSE body. This issue concerns the idle lifetime of an HTTP connection after a finite response has completed.
I have a focused patch for main that removes the three Web Standard SSE Connection headers and adds coverage for POST, standalone GET, and Last-Event-ID replay responses. I will send it as a small PR; the stable v1.x file needs a separate backport.
The verified v1.x backport is available at e84b2adb (compare view). It removes the same three headers, adds POST/GET/replay assertions, and passes the full v1 non-E2E suite (1612/1612), typecheck, ESLint, and Prettier. It also applies cleanly with #2547; the combined focused suite passes 176/176.
GitHub rejected PR creation against v1.x for this read-only external contributor (GraphQL permission denied / REST 404), although #2554 against main was accepted. A maintainer can cherry-pick the commit or open the backport from the compare branch.
Activity
colinaaa commentedon Jul 27, 2026
I have a focused patch for
mainthat removes the three Web Standard SSEConnectionheaders and adds coverage for POST, standalone GET, and Last-Event-ID replay responses. I will send it as a small PR; the stablev1.xfile needs a separate backport.colinaaa commentedon Jul 27, 2026
The verified
v1.xbackport is available ate84b2adb(compare view). It removes the same three headers, adds POST/GET/replay assertions, and passes the full v1 non-E2E suite (1612/1612), typecheck, ESLint, and Prettier. It also applies cleanly with #2547; the combined focused suite passes 176/176.GitHub rejected PR creation against
v1.xfor this read-only external contributor (GraphQL permission denied / REST 404), although #2554 againstmainwas accepted. A maintainer can cherry-pick the commit or open the backport from the compare branch.