Skip to content
Wiki

MCP Streamable HTTP uses one POST endpoint, and Mcp-Session-Id sessions end with 2026-07-28

DrFritzi · Reviewed · Updated 28 Sept 2026 · Markdown

Answer

A Streamable HTTP server exposes one MCP endpoint. The client sends every JSON-RPC message as its own POST with Accept: application/json, text/event-stream. The server answers a request with either Content-Type: application/json or an SSE stream (text/event-stream), and answers an accepted notification with 202 Accepted and no body. In MCP 2025-03-26 to 2025-11-25, a server could also issue an Mcp-Session-Id and offer a GET stream. The latest revision, 2026-07-28, removes both: every request is self-contained. This page covers both eras and marks which is which.

Details

Rules in every revision

  • One endpoint path, for example https://example.com/mcp.
  • The client MUST send an Accept header that lists both application/json and text/event-stream. The client MUST handle either response type.
  • When a server replies with SSE, it may send notifications about that request (such as progress) before the final response. The response SHOULD end the stream.
  • Since 2025-06-18, clients send an MCP-Protocol-Version request header. An unsupported value gets 400 Bad Request.
  • Servers MUST validate Origin and MUST answer an invalid Origin with 403 Forbidden. Local servers SHOULD bind to 127.0.0.1, and all servers SHOULD authenticate. These rules defend against DNS rebinding.

Sessions in 2025-11-25 (legacy)

  1. The server MAY return MCP-Session-Id on the HTTP response that carries the InitializeResult. The value must be visible ASCII (0x21–0x7E) and SHOULD be cryptographically secure.
  2. The client MUST then send that header on every later request. A server that requires it SHOULD answer requests without it with 400.
  3. Once a session ends, the server MUST answer that ID with 404 Not Found. The client MUST then start over with a new initialize and no session ID.
  4. A client that is finished SHOULD send DELETE with the header. The server MAY answer 405.

The optional GET opened a standalone SSE stream for messages the server starts itself. A server that does not offer that stream MUST answer 405 Method Not Allowed. Streams could resume with Last-Event-ID.

Stateless vs stateful (legacy era)

The TypeScript SDK v1 makes this a single option. sessionIdGenerator: () => crypto.randomUUID() gives a stateful server that issues IDs and returns 404 for unknown ones. sessionIdGenerator: undefined gives a stateless server with no session header. The v1 source warns that a stateless transport cannot be reused across requests. Create a new one for each request, or two clients' message IDs can collide.

What 2026-07-28 changed

Legacy (up to 2025-11-25) Modern (2026-07-28)
Optional Mcp-Session-Id, ended with DELETE No protocol sessions. State goes in server-issued handles passed as tool arguments
GET opens a server-to-client stream GET is removed. Long-lived notifications use a subscriptions/listen POST
Server may send JSON-RPC requests on SSE Server returns InputRequiredResult, and the client sends the request again with inputResponses
Resumable via Last-Event-ID Not resumable. The client sends a broken request again with a new ID
Only MCP-Protocol-Version Also Mcp-Method (every request) and Mcp-Name (tools/call, resources/read, prompts/get), which must match the body. A mismatch gets 400 with error -32020
Cancel with notifications/cancelled Close the request's response stream

A server that speaks only 2026-07-28 SHOULD answer GET and DELETE with 405. It SHOULD ignore Mcp-Session-Id and Last-Event-ID. An unknown method gets 404 with JSON-RPC error -32601. That body tells it apart from a 404 sent by an old HTTP+SSE server.

Example modern request

POST /mcp HTTP/1.1
Content-Type: application/json
Accept: application/json, text/event-stream
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/list

{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{
  "io.modelcontextprotocol/protocolVersion":"2026-07-28",
  "io.modelcontextprotocol/clientCapabilities":{}}}}

Practical takeaway

If you design a new server today, make it stateless. That is the only shape 2026-07-28 allows, and it scales horizontally without sticky sessions. Keep session handling only where you must still serve 2025-era clients.

See also

Sources