Back to Library
Architecture

WebSocket vs SSE for Agent Communication: Why MCP Chose Neither

Last updated: September 11, 2026

Key takeaways

  • The MCP 2026-07-28 specification deprecated HTTP+SSE and replaced it with Streamable HTTP — not WebSocket — because stateless servers work with standard HTTP infrastructure (WAFs, load balancers, auth proxies) without persistent connection management (MCP specification).
  • A2A uses JSON-RPC 2.0 over HTTP with SSE for streaming task output — the transport is plumbing; the protocol semantics (task lifecycle, INPUT_REQUIRED state) are what make agent-to-agent communication work (A2A protocol).
  • CVE-2026-16496 (CVSS 10.0) in Terraform MCP exploited the stateful SSE transport mode — a stolen session ID let an attacker execute tool calls with another user's credentials. Stateless transport eliminates the attack surface at the architecture level, not the patch level (NVD).
  • WebSocket is available as a custom MCP transport but adds session management complexity that the spec authors deliberately avoided — the protocol is transport-agnostic, but the standard transports (stdio, Streamable HTTP) cover the production cases (MCP specification).
  • The AGNTCon+MCPCon Europe session "Stateless: The Future of MCP Transports" on September 17, 2026 is the first major conference validation of the stateless transport direction — presented by Google and Hugging Face, the MCP Transport Working Group maintainers (Linux Foundation).

The transport question sounds like infrastructure plumbing, and it is — but the choice has security, scalability, and operational consequences that show up in production. When the Model Context Protocol deprecated HTTP+SSE on July 28, 2026 and replaced it with Streamable HTTP, the spec authors made a deliberate engineering decision: stateless servers over persistent connections, standard HTTP over custom protocols, and a single endpoint over the dual-endpoint SSE model. They did not choose WebSocket, even though WebSocket is bidirectional and SSE is not. The reason is not that WebSocket is wrong — it is that for the specific workload MCP serves (tool calls between an agent and a data source), the bidirectional capability is not worth the session management overhead.

This article maps the three transport options — SSE, WebSocket, and Streamable HTTP — against the two agent protocols that use them (MCP and A2A), with a decision matrix for B2B agent deployments. The AGNTCon session on September 17 makes the timing concrete: the stateless transport is moving from specification to conference validation, and teams running the deprecated SSE transport have a 12-month migration window that is already two months elapsed.

The three transports, and what each one does

SSE (Server-Sent Events) — the deprecated default

SSE is a unidirectional protocol: the server pushes data to the client over a long-lived HTTP connection, and the client cannot send messages back over the same connection. Every client action — cancelling a generation, steering an agent mid-task, approving a tool call — requires a separate HTTP POST request (WebSocket.org).

MCP used SSE in its 2024-11-05 specification as the transport for remote servers. The model required two endpoints: an SSE endpoint for server-to-client messages and a separate POST endpoint for client-to-server messages. The server maintained session state across both connections. Three limitations drove the deprecation: no support for resumable streams, the requirement for long-lived highly-available connections, and server messages delivered only via SSE (MCP specification PR #206).

A2A still uses SSE for its streaming mode. The SendStreamingMessage method delivers task updates as SSE events — token deltas, artifact chunks, status transitions. This is the right choice for A2A because the streaming is one-directional (server to client) and the client's control messages (cancel, subscribe) go through separate JSON-RPC calls (A2A protocol). SSE is simple, works over standard HTTP, and does not require WebSocket's session management for a workload that is fundamentally server-push.

WebSocket — the bidirectional option that MCP did not standardize

WebSocket provides a persistent, bidirectional connection between client and server. After an HTTP upgrade handshake, the connection stays open and both sides can send messages at any time. This is the right primitive for applications that need true bidirectional communication on a single channel: chat, collaborative editing, multiplayer games, trading dashboards (Ably).

For AI agents, the bidirectional case is real. Agent workflows need client-to-server messages during execution: cancelling a generation, steering an agent mid-task, approving or rejecting a tool call, sending follow-up context. With SSE, each of these is a separate HTTP request. With WebSocket, they ride on the same connection as the token stream (WebSocket.org).

The MCP specification does not standardize WebSocket. It is available as a custom transport — the spec says "clients and servers MAY implement additional custom transport mechanisms" as long as they preserve the JSON-RPC message format — but the standard transports are stdio (for local servers) and Streamable HTTP (for remote servers) (MCP specification). A GitHub issue (#493) proposed adding WebSocket as a standard transport to simplify the HTTP model; it was closed without adoption, and the spec moved to Streamable HTTP instead (GitHub).

The reason MCP did not standardize WebSocket is operational, not technical. WebSocket requires the server to maintain persistent connections, manage session health, handle reconnection logic, and deal with broken connections. This is the same stateful-connection burden that made SSE a liability. The MCP authors wanted stateless servers — any instance can handle any request, no shared session store, plain round-robin load balancing — and WebSocket's persistent connection model works against that goal.

Streamable HTTP — what MCP chose instead

Streamable HTTP is the MCP spec's answer to the SSE-vs-WebSocket question. The server exposes a single HTTP endpoint (e.g., https://example.com/mcp) that handles both POST and GET. The client sends every JSON-RPC message as a POST. The server can respond with a plain JSON body or upgrade the response to an SSE stream if the result is long-running. The key design choice: the server does not need to maintain a persistent connection. Every request is self-contained (MCP specification).

This gives MCP the streaming capability of SSE without the long-lived connection requirement, and it gives MCP the bidirectional capability of WebSocket without the session management overhead. The client sends messages via POST (standard HTTP), the server streams responses via optional SSE (standard HTTP), and the server can be stateless (standard HTTP infrastructure) (Bright Data; Auth0).

The security argument is concrete. Auth0's analysis: with Streamable HTTP, "we can stamp a standard Authorization: Bearer header on every single envelope. The mailroom checks the stamp on every message, not just the first one." With the old SSE transport, the auth token was established once at connection time and the persistent connection carried all subsequent messages — including messages from an attacker who stole the session ID (Auth0).

The decision matrix

Criterion SSE (deprecated) WebSocket (custom) Streamable HTTP (MCP standard)
Direction Server → client only Bidirectional Client → server via POST; server → client via optional SSE
Connection model Long-lived, persistent Long-lived, persistent Per-request (stateless)
Server state Stateful (session per connection) Stateful (session per connection) Stateless (no session between requests)
Load balancing Sticky sessions required Sticky sessions required Plain round-robin
Scaling Limited (connection per client) Limited (connection per client) High (any HTTP infrastructure)
Auth At connection time At handshake time Per-request (Bearer on every POST)
Resumability No No No (but stateless means no session to resume)
Infrastructure Needs SSE-aware proxy Needs WebSocket-aware proxy Standard HTTP (WAFs, LBs, CDN, auth proxies)
Security surface Session ID theft (CVE-2026-16496) Session hijacking on persistent connection None at transport layer (no session to steal)
MCP status Deprecated, 12-month sunset Custom transport (not standardized) Standard remote transport since 2026-03-26
A2A status Used for streaming mode Not used Not used (A2A uses JSON-RPC over HTTP + SSE)
Best for Simple server-push (A2A task streaming) True bidirectional (chat, collaboration) Agent-to-tool calls (MCP)

The table answers the question most B2B teams ask: if your agent needs to call a tool on a remote MCP server, use Streamable HTTP. If your agent needs to stream task output to another agent, use A2A's SSE streaming mode. If you are building a real-time collaborative interface where the client sends messages as often as the server, WebSocket is the right primitive — but it is a custom transport, not a protocol standard.

The three transports compared:

WebSocket vs SSE vs Streamable HTTP for Agent Communication MCP deprecated SSE and chose Streamable HTTP. Neither WebSocket nor SSE won. SSE Server-Sent Events DEPRECATED in MCP 12-month sunset (ends Jul 2027) Direction Server → client only Connection Long-lived, persistent Server state Stateful (session per connection) Load balancing Sticky sessions required Auth At connection time only Security surface Session ID theft (CVE-2026-16496) Used by A2A streaming (still valid) BEST FOR A2A task progress streaming WebSocket Bidirectional, persistent CUSTOM TRANSPORT in MCP Not standardized; spec allows it Direction Bidirectional (full duplex) Connection Long-lived, persistent Server state Stateful (session per connection) Load balancing Sticky sessions required Auth At handshake time Security surface Session hijack on persistent conn. Used by Custom agent implementations BEST FOR True bidirectional: chat, collab Streamable HTTP MCP standard since 2026-03-26 MCP STANDARD TRANSPORT Stateless, single endpoint Direction POST (client→server) + optional SSE Connection Per-request (stateless) Server state Stateless (no session between req.) Load balancing Plain round-robin Auth Per-request (Bearer on every POST) Security surface None at transport layer Used by MCP (all remote servers) BEST FOR Agent-to-tool calls (MCP) MCP chose Streamable HTTP — not WebSocket, not SSE — for stateless servers. CVE-2026-16496 (CVSS 10.0) proved the stateful transport was a security liability.

The security dimension — why stateless matters

The CVE that validated the stateless transport choice is CVE-2026-16496, a CVSS 10.0 authorization bypass in HashiCorp's Terraform MCP Server. The vulnerability affected the stateful streamable-HTTP transport mode: a user who obtained another user's MCP session ID could have their tool calls executed using that user's Terraform credentials. The attack vector exists only because the server holds a session state that an attacker can steal and reuse. A stateless server has no session to steal (NVD; The Hacker News).

This is the production evidence that the stateful transport mode is a security liability, not just an operational complexity. The 12-month SSE deprecation window is now a security deadline, not just an operational one. The 1,227 servers still running the deprecated HTTP+SSE transport are the population most affected — and the population carrying the session-hijacking attack surface.

For a deeper treatment of the stateless protocol and the explicit-handle pattern that replaces server-side session state, see MCP 2026-07-28: What the Stateless Protocol Means for B2B Agent Deployments.

What A2A does differently — and why it works

A2A uses SSE for streaming, not Streamable HTTP. The difference is workload. MCP tool calls are short request/response operations — query a database, fetch a record, run a calculation. The server processes the request and returns a result. Streaming is optional and rare. A2A tasks are longer-running operations with explicit lifecycle management — a pricing evaluation that takes two minutes, a compliance check that takes an hour. The streaming is the progress updates, not the result itself.

A2A's SSE streaming is server-push only, which is the correct direction for task progress: the agent working on the task sends updates to the calling agent. The calling agent's control messages (cancel, subscribe to updates) go through separate JSON-RPC calls. There is no need for bidirectional communication on the streaming channel because the control channel is a separate, standard HTTP request (A2A protocol; Google Developers Blog).

This is why the transport question is plumbing, not architecture. MCP and A2A use different transports because they have different workloads, but both are built on standard HTTP. The protocol semantics — MCP's stateless tool calls and A2A's stateful task lifecycle — are what make agent communication work. The transport carries the messages; it does not define them.

For the full protocol-level comparison (scope, transport, auth, state, human-in-the-loop), see A2A vs MCP: choosing the right protocol for agent communication.

When WebSocket is the right answer

WebSocket is not wrong. It is the right transport for specific workloads that MCP and A2A do not standardize:

  • Real-time collaborative interfaces where the client sends messages as often as the server — a shared agent dashboard where multiple operators steer the same agent simultaneously.
  • High-frequency bidirectional communication where HTTP request overhead per message is prohibitive — a trading agent that receives market data and sends orders on the same channel.
  • Custom MCP transports where the standard transports do not fit — the spec explicitly allows custom transports as long as they preserve JSON-RPC message format and lifecycle requirements (MCP specification).

The trade-off is operational complexity. Maintaining long-lived, bidirectional connections requires explicit logic for session health, retries, broken connections, and message protocols (Nimble Way). For most B2B agent deployments — an agent calling NetSuite, a procurement agent delegating to a pricing agent — this complexity is not justified by the workload.

The stateless trend

The industry direction is clear. MCP went stateless on July 28, 2026. A2A uses stateful task machines but stateless transport (HTTP + SSE, no persistent session on the server). The AGNTCon+MCPCon Europe session on September 17 — "Stateless: The Future of MCP Transports," presented by Kurtis Van Gent (Google) and Shaun Smith (Hugging Face, MCP Transport Working Group maintainer) — is the first major conference session dedicated to the stateless transport direction (Linux Foundation; sched.com).

Shaun Smith is also giving a keynote at the same conference: "Getting to Stateless MCP: In Production" — which signals that the stateless transport is moving from specification to production deployment guidance. For teams running the deprecated SSE transport, the 12-month migration window (ending July 2027) is the operational deadline. The security deadline is sooner: every day a server runs stateful SSE transport is a day it carries the session-hijacking surface that CVE-2026-16496 exploits.

The WebSocket vs SSE question, for agent communication, has a clear answer: neither, if you are building on MCP. Use Streamable HTTP. Use SSE if you are streaming A2A task output. Use WebSocket only when the workload is genuinely bidirectional and the operational complexity is justified. The transport is plumbing. The protocol semantics — stateless tool calls, stateful task lifecycles, explicit handles, human-in-the-loop states — are what make agent systems work in production.

Related reading


A mid-market distributor running NetSuite, BigCommerce, and three supplier catalogs deploys an MCP-based quoting agent. The agent calls NetSuite for tier pricing, checks supplier catalogs for availability, and holds stock with an expiry. Each of these is a stateless tool call over Streamable HTTP — no persistent connection, no session to manage, no sticky-session load balancer. When the agent delegates a complex multi-supplier negotiation to a pricing agent, that delegation crosses the A2A protocol boundary as a task with SSE streaming for progress updates. The transport choice was not WebSocket vs SSE — it was Streamable HTTP for tool calls and SSE for task streaming, with the protocol semantics doing the work that the transport does not need to.

Request a scoped build. One-week discovery. You get a system inventory, workflow map, and fixed scope — whether or not you build with us.

Want this built for your systems?

Every document here comes from real production work. If you have a target system and a workflow in mind, we can scope a build in one week.

Request a scoped build

One-week discovery. You get a system inventory, workflow map, and fixed scope — whether or not you build with us.