
This page is part of our MCP specification reference, a plain-English guide to the Model Context Protocol spec (version 2026-07-28), within The MCP Guide. Building a server? See MCP development.
Streamable HTTP is the MCP transport for remote servers. The server exposes one web address, called the MCP endpoint, and the client sends every JSON-RPC message to it as its own HTTP POST. The server answers each request with either a single JSON object or a short-lived Server-Sent Events (SSE) stream for that request.
Status in the 2026-07-28 spec: core
It is the transport behind hosted MCP servers from SaaS vendors. The 2026-07-28 release reshaped it, removing sessions and adding routing headers. This page follows the Streamable HTTP page of the 2026-07-28 specification, checked on 28 October 2026.
Key Takeaways
- The server provides a single MCP endpoint, such as
https://example.com/mcp, that accepts POST. - Each client message is a separate POST, and the server replies with JSON or a request-scoped SSE stream.
- Every POST must carry
MCP-Protocol-VersionandMcp-Method, plusMcp-Namefor tool, resource and prompt requests. - Servers must validate the
Originheader and return HTTP 403 for an invalid one, to block DNS rebinding. - The 2026-07-28 spec removed sessions (
Mcp-Session-Id), the GET stream and stream resumability.
Why Streamable HTTP exists
A remote server must handle many clients, work with load balancers and gateways, and support sign-in. The first remote transport, HTTP+SSE, needed two endpoints and a long-lived connection. Streamable HTTP "was introduced in protocol version 2025-03-26 as a replacement" for it, the spec notes.
The 2026-07-28 version went further. The release announcement says "any request can now land on any server instance behind a plain round-robin load balancer without needing shared storage."
How it works
Sending messages
The spec's rules for clients:
- "The client MUST use HTTP POST to send JSON-RPC messages."
- The
Acceptheader must list bothapplication/jsonandtext/event-stream. - The body is a single JSON-RPC request or notification, never a response.
For a notification the server accepts, it returns 202 Accepted with no body. For a request, it returns either application/json or text/event-stream, and "the client MUST support both."
Receiving replies
If the server opens an SSE stream, it may send notifications such as notifications/progress before the final response. Those must relate to the original request. The server "MUST NOT send independent JSON-RPC requests" on the stream. The final response "SHOULD terminate the stream."
Long-lived change notifications, such as "the tool list changed," arrive on the response stream of a subscriptions/listen request. See resource subscriptions and change notifications.
Required headers
Streamable HTTP mirrors key body fields into headers so "intermediaries (load balancers, gateways, observability tooling) can route and inspect requests without parsing the body." This is the spec's own example:
POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: get_weather
The body of that POST:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": { "location": "Seattle, WA" },
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": { "name": "ExampleClient", "version": "1.0.0" },
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}
Mcp-Method is required on all requests. Mcp-Name is required for tools/call, resources/read and prompts/get. Servers must reject requests where headers and body disagree, with 400 Bad Request and error code -32020 (HeaderMismatch). The spec explains why: it stops "a load balancer routing on the header value while the MCP server executes based on the body value."
Servers may also mark tool parameters with x-mcp-header. Clients "MUST support this feature," copying the value into an Mcp-Param-{name} header. Values that are not plain ASCII are Base64-encoded.
Status codes worth knowing
| Situation | Server response |
|---|---|
| Notification accepted | 202 Accepted, no body |
Invalid Origin header | 403 Forbidden |
| Header and body mismatch | 400 with HeaderMismatch (-32020) |
| Unsupported protocol version | 400 with UnsupportedProtocolVersionError |
| Unknown method | 404 with JSON-RPC error -32601 |
| GET or DELETE from an older client | 405 Method Not Allowed (SHOULD) |
Cancellation
There is no cancel message. "Closing the SSE response stream MUST be treated by the server as cancellation of that request." See cancelling MCP requests.
Security rules
The spec lists three: servers "MUST validate the Origin header" to prevent DNS rebinding; local servers "SHOULD bind only to localhost (127.0.0.1)"; and servers "SHOULD implement proper authentication." For authentication, see MCP authorization: what the spec requires. For the attack itself, see DNS rebinding and local MCP servers.
What changed across spec versions
| Version | Change |
|---|---|
| 2025-03-26 | Streamable HTTP introduced, with optional Mcp-Session-Id sessions and resumable streams |
| 2025-06-18 | MCP-Protocol-Version header required after negotiation, per the 2025-06-18 changelog |
| 2025-11-25 | 403 required for invalid Origin; servers may disconnect SSE streams so clients poll |
| 2026-07-28 | Sessions, the GET stream, server-sent requests and Last-Event-ID resumability removed |
| 2026-07-28 | Mcp-Method and Mcp-Name required; x-mcp-header added |
The 2026-07-28 changelog says a broken response stream now loses the in-flight request, and clients "MUST re-issue it as a new request with a new request ID."
A server that supports only 2026-07-28 should answer older clients this way: 405 for GET or DELETE, and ignore any Mcp-Session-Id or Last-Event-ID header. Our stateless protocol explainer covers the bigger picture.
Common mistakes
- Still minting session IDs. 2026-07-28 servers should not mint or echo them.
- Relying on resumable streams. They are gone. Retry the request with a new ID instead.
- Letting a proxy buffer SSE. The spec says servers "SHOULD include the
X-Accel-Buffering: noheader" so proxies such as nginx deliver events immediately. - Routing on headers without checking the version. Intermediaries should reject requests with an old or missing
MCP-Protocol-Versionrather than trust unvalidated headers. - Skipping Origin validation on a local HTTP server. That opens the door to DNS rebinding.
Next step
Most remote servers need sign-in. Read MCP authorization: what the spec requires next, or talk to our MCP development team about building a compliant endpoint.
Frequently asked questions
Does Streamable HTTP still use Server-Sent Events?
Yes, but only per request. A server may answer a POST with an SSE stream that carries progress notifications and then the final response. The long-lived standalone GET stream was removed in 2026-07-28.
What happened to Mcp-Session-Id?
The 2026-07-28 spec removed protocol-level sessions and the Mcp-Session-Id header. Servers that need state across calls pass explicit handles as normal tool arguments, according to the changelog.
Why are Mcp-Method and Mcp-Name required?
They let gateways, rate limiters and firewalls route and authorize requests without reading the JSON body. Servers must reject requests where these headers do not match the body.
Can one endpoint serve old and new clients?
Yes. The spec describes how dual-era clients and servers detect each other. A modern server can also keep hosting the deprecated HTTP+SSE endpoints alongside the MCP endpoint for very old clients.
Is Streamable HTTP required for remote servers?
It is the standard remote transport in 2026-07-28. Custom transports are allowed, but clients built for the standard will expect Streamable HTTP.











