Repository navigation
Description
Is your feature request related to a problem? Please describe.
The current HTTP transport mechanisms for MCP (both HTTP+SSE and Streamable HTTP) introduce unnecessary complexity, state management challenges, and security concerns. As someone implementing an MCP server, I've encountered several issues:
-
Excessive Complexity: The current approach requires maintaining session state across multiple connections and offers too many ways to achieve the same outcomes (multiple session creation methods, SSE opening options, and response delivery methods).
-
Security and Scalability Concerns: Managing state across HTTP and SSE connections creates potential vulnerabilities and scalability challenges, particularly in enviorments with more then one node.
-
Poor Developer Experience: The current transport mechanisms don't follow established web standards, have a lot of corner cases and is making implementation unnecessarily difficult.
-
Implementation Burden: The server must maintain complex state management to "join" connections across calls, which significantly complicates any redundant/distributed deployment scenarios. Eg. The answer to a rpc POST coming in to one server in Europe might have to be returned through a SSE established to a server in the US.
-
Distributed System Challenges: The current approach forces implementations to maintain cross-server state for sessions. In a distributed environment (load balancers, multiple regions, autoscaling), this requires implementing complex shared session state management that could be entirely avoided with Websockets, where the state remains local to a single connection.
Describe the solution you'd like
I propose replacing the current HTTP+SSE and Streamable HTTP transports with two simpler, well-established alternatives:
-
Websockets for full-duplex communication,
GET /mcp:- Websockets provide a true socket-like experience similar to stdio but over HTTP
- They eliminate the need for complex session state management across multiple connections
- They're widely supported by all modern browsers, servers, and client libraries
- They follow established web standards and patterns
-
Simple HTTP request/response for stateless operations,
POST /mcp:- A straightforward REST-style API for single request/response interactions
- No session state to maintain
- Perfect for simple tool invocations or short interactions
- Follows standard HTTP patterns that developers already understand
- Some concessions probably have to be made in terms of the initial handshake of the MCP protocol
- On top of my head...
POST /mcp/capabilitiesmight return the standard initialize responsePOST /mcpcan contain initialize request and the rpc call
This approach would:
- Dramatically simplify the protocol
- Reduce implementation complexity
- Improve security by reducing the attack surface
- Make the protocol more accessible to developers
- Better align with the stdio transport model (Websockets are conceptually similar to stdio streams)
Describe alternatives you've considered
-
Refining the current Streamable HTTP approach: While Streamable HTTP could potentially be simplified and better documented, its fundamental design still introduces unnecessary complexity compared to Websockets, is a mismatch conceptually to stdio and will still forces state management over multiple sockets/threads/server/regions.
-
gRPC: While powerful for service-to-service communication, gRPC is overkill for this use case, doesn't really play nice in the browser and isn't as universally supported in browsers as Websockets.
Additional context
The current approach seems to be attempting to reinvent Websockets using a combination of SSE and HTTP requests, creating what is essentially a more complex, less standard, and less secure version of Websockets.
Addressing objections to Websockets (from PR #206)
I've reviewed the objections to Websockets stated in PR #206 and would like to address them, and the issue comment #206 (comment):
-
"RPC-like use would incur unnecessary overhead": This is incorrect. Websockets actually reduce overhead for RPC-like interactions by eliminating the need to establish new connections and perform TLS handshakes for each call. For stateless operations, a simple HTTP endpoint can be provided alongside Websockets, giving developers the best of both worlds if this turns out to be a real problem.
-
"Cannot attach headers like Authorization in browser Websockets": While true that headers can't be added after connection establishment, there are standard, well-established patterns for this:
- Authorization tokens can be passed during the initial connection as header, cookies or via query parameters
- Post-connection authentication can occur in the first or subsequent message
- Authorization can be part of the MCP protocol or a subprotocol. Eg. sending key-value pairs over the socket
-
"Only GET requests can be upgraded to Websocket": This is true as well but really does not matter. The Websocket standard specifies the use of GET, and this is not a limitation but simply how the protocol works. Every Websocket library handles this transparently. To do a GET and open a socket to then send down a rpc message over the socker doesn't introduce additional complexity or realy latency compared to the current approach in any mening full way.
-
Regarding compatibility concerns: Supporting both Websockets and a simple stateless HTTP API would simplify the compatibility matrix compared to the current complex state management across multiple HTTP connections and SSE streams.
State management advantages of Websockets
The current approach requires maintaining complex session state across multiple connections, which becomes particularly problematic in distributed environments:
- In a load-balanced environment, SSE connections and HTTP requests may be routed to different servers, requiring shared state.
- Session resurrection/resumption requires complex distributed state management and introduces a DoS risk since the cliend does not need to stick around.
- With Websockets, the entire session state remains local to a single connection, dramatically simplifying implementation.
- For redundancy, standard Websocket failover patterns are possible as well.
Websockets provide exactly the bidirectional message exchange in a standardized, widely-supported way that closely mimics the preferred stdio transport. As the specification itself notes:
"Clients and servers MAY implement additional custom transport mechanisms to suit their specific needs. The protocol is transport-agnostic and can be implemented over any communication channel that supports bidirectional message exchange."
But it does not seem that the standard way of doing things should be this complex
Activity
Marlinski commentedon May 13, 2025
Also supporting stateless transport! It would be very useful to facilitate MCP deployment in the cloud. Current transport (both SSE and Streamable HTTP) adds unnecessary complexities.
rev1si0n commentedon May 14, 2025
It’s unclear to me why HTTP+SSE was originally chosen as a communication method, given its awkward design. I’ve implemented an MCP SSE server myself, and I still feel that this approach seems more like something a novice programmer would come up with—especially considering that WebSocket is clearly a more suitable communication protocol.
rev1si0n commentedon May 14, 2025
Aside from the convenience of using GET/POST for firewall traversal and authentication, except for being easier to convert to stdio locally, it is unsuitable for use at network level. I can’t think of any other advantages. Moreover, if an MCP SSE server is deployed behind Nginx for load balancing, and a path prefix is added before the connection—such as proxy_pass example.com/route1/ -> mcp.server/sse—it leads to significant complications. I have to implement path rewriting within the MCP framework, and Nginx must also provide additional parameters like /route1/, since the
endpoint: /ssereturned by SSE also needs to be rewritten toendpoint: /route1/sse. All in all, it's a protocol with poor design considerations.Bit0r commentedon May 14, 2025
Because this protocol might be created by an LLM.
lmaccherone commentedon May 30, 2025
I agree with everything in this thread plus I'll add another reason for HTTP request/response + WebSockets... edge serverless. WebSockets have been around long enough that edge serverless vendors now have 1st class support for them. Cloudflare is a great example. They have hibernatable WebSocket support. The underlying infrastructure handles keepalive functionality while your serverless code can run and self-evict from memory at will. Their implementation allows one unit of serverless functionality (called a Durable Object) to have up to 32,000 hibernated WebSocket connections.
RoseSecurity commentedon Jun 6, 2025
The initial arguments against Websockets felt extremely brittle to me. I think this implementation will ultimately need to be addressed going forward to gain more community support as developers create MCP servers and have to battle the awkwardness of HTTP+SSE
Kludex commentedon Jun 12, 2025
I help maintain the MCP Python SDK, and I completely agree with this issue. I had previously suggested to use WebSockets as well, given that it seems the obvious choice for bidirectional message support.
Now that I see how complex the Python SDK has become due to the handling of session, streams and issues during development about long-lived HTTP connections (as web servers treat those differently than WebSockets) I can be even more sure about it.
Kludex commentedon Jul 25, 2025
It seems I can sponsor this idea if it becomes a SEP, which I'm willing to.
Anyone wants to write a draft for it? I'm happy to sponsor it.
lmaccherone commentedon Jul 28, 2025
I am willing to take a stab at drafting one. I have a reference implementation in the works so I can draw from that learning.
lmaccherone commentedon Jul 29, 2025
Question for everyone on this thread... @crholm's original suggestion was for both Websockets for full-duplex communication and Simple HTTP request/response for stateless operations. I'm working on the draft SEP right now, and I don't believe we need the latter as the Streamable HTTP transport already supports that. Server initiated notifications are optoinal in the main spec. The MCP server need only specify update capabilities (subscribe, listChanged). It also states that you can return
application/jsonfor simple HTTP request/response use.I think that's already covered and it strengthens the SEP to be simpler and focused on WebSockets.
Thoughts?
Kludex commentedon Jul 30, 2025
I honestly didn't even pay attention to the stateless HTTP proposal. I think it should be ONLY WebSockets.
It's far easy to reason about layers:
I also find it weird that you would restrict MCP operations like sampling.
crholm commentedon Jul 30, 2025
Nice to see that this is being picked up
I think you are correct to focus on the ws part. My initial suggestion was made a more suitable way forward to replace all the SSE/Streamable HTTP nonsens to address most of the needs in those transport options. But with Streamable HTTP not going away, adding websockets would be the focus imho.
lmaccherone commentedon Aug 2, 2025
OK. Here it is: #1288
Please provide feedback either to the PR review (if you have that permission) or comments here, to the PR, or the issue. Not sure which is the best place of those three, but I'll try to keep an eye on all three and respond accordingly.
localden commentedon Jun 26, 2026
Closing the loop here - thank you again folks for the discussion. Looks like this proposal hasn't been picked up. Additionally, the upcoming spec (
2026-07-28) will be moving to a stateless model.