Skip to content

Web-standard SSE responses override the HTTP server keep-alive lifetime #2553

Description

@colinaaa

Problem

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-alive
Keep-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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions