---
title: "MCP: Streamable HTTP Transport"
slug: "mcp-streamable-http"
category: "ai-agents"
tags: ["mcp", "ai-agents", "transports", "streamable-http", "sse", "http"]
status: "stable"
last_updated: 2026-08-14
summary: "Streamable HTTP is the current remote MCP transport: one endpoint, per-request metadata after the 2026-07-28 spec retired Mcp-Session-Id, resumable streams via Last-Event-ID, replacing HTTP+SSE."
related: ["[[ai-agents/mcp-transports]]", "[[ai-agents/mcp-protocol]]", "[[ai-agents/mcp-security]]", "[[ai-agents/mcp-servers]]", "[[ai-agents/claude-code-mcp]]", "[[ops/cloudflare]]"]
---

## Overview

Streamable HTTP is the standard remote transport for MCP, introduced in spec revision 2025-03-26 to replace the older HTTP+SSE transport. It runs on a single HTTP endpoint that the client POSTs to and that the server may upgrade to a request-scoped SSE stream when it needs to push messages. As of the 2026-07-28 spec revision, the transport is also stateless: the connection-scoped `Mcp-Session-Id` header from the 2025-03-26 through 2025-06-18 revisions is retired in favor of per-request metadata, described below. For the stdio-vs-remote choice, see [[ai-agents/mcp-transports]]; for the JSON-RPC framing that rides on top, see [[ai-agents/mcp-protocol]].

## Use one endpoint for both directions

Streamable HTTP exposes a single MCP endpoint, conventionally `/mcp`. The client sends every JSON-RPC message as an HTTP POST to that endpoint with an `Accept` header listing both `application/json` and `text/event-stream`.

- When the server can answer immediately, it returns a single JSON response.
- When the server needs to stream notifications, progress, or several messages, it answers the same POST with an SSE stream and closes it when the exchange is done.
- The client may also open a standalone GET to the endpoint to receive server-initiated messages outside any request.

There is no separate channel to keep alive. This is the key difference from the deprecated HTTP+SSE design.

## Carry protocol version and capabilities in the request body, not a session header

Under the current (2026-07-28) spec, every request carries its own protocol version and client capabilities in `_meta.io.modelcontextprotocol/*` fields in the JSON-RPC body. Streamable HTTP mirrors selected fields into HTTP headers so intermediaries can route without parsing the body, but the body remains the source of truth.

```http
POST /mcp HTTP/1.1
Content-Type: application/json
Accept: application/json, text/event-stream

{
  "jsonrpc": "2.0", "id": 2, "method": "tools/list",
  "_meta": { "io.modelcontextprotocol/clientCapabilities": {} }
}
```

For rate limiting and audit correlation, key state on a per-request identifier rather than a connection-scoped session; see [[ai-agents/mcp-security]] for the isolation rules. Servers that still speak the 2025-03-26 through 2025-06-18 revisions assign a session by setting `Mcp-Session-Id` on the `initialize` response, and the client echoes it on every subsequent request; treat that pattern as legacy when building new servers.

## Resume dropped streams with Last-Event-ID

Streamable HTTP supports resumable streams. When the server emits SSE events, it tags each with an `id`. If the connection drops mid-stream, the client reconnects and sends the last id it saw in the `Last-Event-ID` header. The server replays only the events after that id, so no message is delivered twice and none is lost.

Implement reconnection with exponential backoff. Resume by `Last-Event-ID` where the prior exchange was streaming; otherwise retry the request fresh, since there is no session to re-establish.

## Migrate off the deprecated HTTP+SSE transport, and off session-scoped state

The HTTP+SSE transport (spec revision 2024-11-05) is deprecated with a year-long offramp. Treat it as legacy:

- New servers implement Streamable HTTP only.
- Clients that must talk to old servers can negotiate by attempting Streamable HTTP first, then falling back to the two-endpoint SSE flow on failure.
- Do not build new integrations against the separate SSE-channel design; it carries the reconnection and load-balancer fragility that Streamable HTTP was created to fix.

Separately, new servers should not depend on `Mcp-Session-Id` for correctness. The 2026-07-28 revision removed the connection-scoped session model so requests can land on any server instance without shared state; design new deployments around per-request metadata from the start.

## Related

- [[ai-agents/mcp-transports]]
- [[ai-agents/mcp-protocol]]
- [[ai-agents/mcp-security]]
- [[ai-agents/mcp-servers]]
- [[ai-agents/claude-code-mcp]]
- [[ops/cloudflare]]
