Build1 publisher3 min readPublished
The MCP transport your search results teach has been deprecated since March
HTTP+SSE, the two-endpoint transport from the 2024-11-05 revision, is deprecated and eligible for removal. Tutorials ranking today still teach it.
The Engineer · Build desk
Drafted by a language model from the sources cited here and checked against its claim ledger before publication. How we use AISend a correction
What happened
- The two-endpoint HTTP+SSE transport from the MCP 2024-11-05 revision has been deprecated since 2025-03-26; new implementations should not adopt it, and it is eligible for removal in a future revision.
- The author reports his own search data showed thirty-one different spellings of the stdio-vs-HTTP question, nearly three hundred impressions, several of them on page one, and zero clicks, because the site ranked for it by accident from other articles with no page answering it.
- Most of what you find on the MCP transport question, including the top results, describes a version of the protocol that has been replaced; this includes a fair number of tutorials published this year.
- Use stdio if a single client launches the server on the same machine and it touches local files, local databases or local tools; use Streamable HTTP if the server must be reachable over a network, serve more than one client, or run somewhere you deploy rather than somewhere you sit.
- Over stdio the client launches the server as a subprocess; the server reads JSON-RPC from stdin and writes JSON-RPC to stdout, one message per line, newline-delimited, and messages must not contain embedded newlines.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
The two-endpoint HTTP+SSE transport introduced in the Model Context Protocol's 2024-11-05 revision has been deprecated since 2025-03-26, new implementations are told not to adopt it, and it is eligible for removal in a future revision [1]. That is a problem for anyone wiring up a remote MCP server from search results, because according to a dev.to writeup by studiomeyer_io, most of what you find on the transport question, top results included, describes a version of the protocol that has been replaced [3].
The author's account of how the gap was found is worth noting as evidence of demand rather than of correctness: thirty-one different spellings of the same question, close to three hundred impressions, several of them on page one, and zero clicks, because the pages ranking for it were ranking by accident [2]. Whatever else that says about search, it says the query volume exists and the answer supply is stale. The deprecated transport was the current one for roughly 141 days [15]. Guides written in that window, and a fair number published since, are teaching it.
The decision itself is short. If one client launches the server on the same machine and the server touches local files, local databases or local tools, use stdio; if it has to be reachable over a network, serve more than one client, or run somewhere you deploy rather than somewhere you sit, use Streamable HTTP [4].
The stdio failure mode is the one to internalise. The server reads newline-delimited JSON-RPC from stdin and writes it to stdout, one message per line, with no embedded newlines [5], and the spec's requirement is that the server must not write anything to stdout that is not a valid MCP message [6]. Every print, every console.log, every stray debug line from an imported library lands in the message channel; symptoms range from a tool that never returns to a server that connects and then dies on the first call [7]. Logging goes to stderr, which the server may use freely and which the client should not treat as an error condition [8]. Shutdown is the client closing your input stream, so exit promptly on stdin EOF: per the spec that is the primary graceful shutdown signal and the only portable one [9]. If the process dies, the client should restart it, and because the protocol is stateless the in-flight requests are lost rather than replayed, so any retry is your caller's decision [10].
On the HTTP side, one endpoint accepts POST, each request or notification is its own POST, a request gets back either a single JSON object or an SSE stream scoped to that request, and an accepted notification gets a 202 with no body [11]. Clients must advertise both application/json and text/event-stream in Accept, must send a single request or notification and never a response, and must send the mandatory request metadata headers [12]. Long-lived server-to-client notifications now go through a subscriptions/listen request whose response stream stays open for the notification types you opted into, while progress and other request-scoped notifications stay on the stream of the request they belong to [13].
The change that invalidates the most existing code: protocol-level sessions are gone. The Mcp-Session-Id header, terminated by an HTTP DELETE, is not part of the current revision, and a server implementing only the new revision should ignore an incoming Mcp-Session-Id header entirely [14].
Watch for the revision that actually removes HTTP+SSE, and check whether your SDK version still ships the two-endpoint server helper by default. If your remote server is holding state keyed to a session header, that is now application state you own, not something the transport is doing for you [14].