MCP Transport Layers: Stdio vs SSE
Standardizing how LLMs talk to external tools is great, but the actual plumbing—the transport layer—is where things get messy in production. In the Node.js ecosystem, you're basically choosing between Stdio and Server-Sent Events (SSE), and that choice changes everything from your security model to how you actually deploy the thing.
Stdio: Local Process Piping
Stdio is the "no-fuss" approach. The host just spawns the MCP server as a child process. Communication happens via stdin and stdout.
- How it works: The host writes a JSON-RPC request to the server's
stdin; the server reads it, does the work, and pipes the response back throughstdout. - The Upside: It's incredibly fast because there's no TCP/IP overhead. No ports to manage, no firewall headaches, and no DNS. If the host process crashes, the OS just cleans up the child process. It's the gold standard for local developer tools.
SSE: Network-Based Streaming
SSE moves the conversation to the network stack. This is where you go when your tools can't live on the same machine as your agent.
- The Architecture: It's a split system. The client sends requests via standard HTTP
POSTcalls, but it listens for responses via a long-lived HTTP connection using thetext/event-streamheader. - The Upside: Decoupling. Your MCP server can be a standalone microservice in a K8s cluster or a remote SaaS. You get the ability to scale the server independently of the agent host.
Real-world Trade-offs
When my team started implementing this, we noticed the operational difference immediately.
- Latency: Stdio is nearly instant. SSE introduces network jitter and HTTP overhead.
- Complexity: Stdio is "plug and play." SSE requires handling CORS, authentication headers, and connection timeouts.
- Lifecycle: With Stdio, the server is a disposable child. With SSE, the server is a persistent entity that needs its own health checks and monitoring.
All Replies (3)
SSE is a game changer for remote setups. Anyone else notice a speed boost over stdio?
Does SSE handle auto-reconnects natively, or is that something I need to code from scratch?
I'm worried about SSE timing out during long-running tasks. Has anyone actually scaled this in production?