Most MCP servers run on stdio. If you have connected Claude Desktop or Claude Code to a local server, you used stdio whether you realized it or not. It is the default transport for the Model Context Protocol, and it handles the vast majority of MCP connections in production today.

Here is what it actually does, how it works under the hood, and when you should reach for something different.

The Core Idea

Stdio stands for standard input/output. It is the oldest inter-process communication pattern in computing. One program writes to stdout. Another program reads from stdin. Messages flow back and forth through these pipes.

In MCP, the host application (Claude Desktop, Claude Code, or your own agent) launches the MCP server as a child process. The host sends JSON-RPC messages to the server through stdin. The server sends responses back through stdout. No network. No ports. No HTTP. Just two processes talking through pipes on your local machine.

That simplicity is the point.

How It Works Step by Step

When you add an MCP server to your Claude Desktop config, here is what happens:

  1. Claude Desktop reads your config and finds the server command (like npx @modelcontextprotocol/server-filesystem).
  2. It spawns that command as a child process.
  3. The host sends an initialize request over the child’s stdin.
  4. The server responds over stdout with its capabilities: what tools it exposes, what resources it provides, what prompts it offers.
  5. From that point on, every tool call and response flows through the same stdin/stdout pipes.
  6. When you close the connection, the host terminates the child process.

All messages use JSON-RPC 2.0, encoded as UTF-8. Each message is a single line of JSON. The server must not write anything else to stdout. Logging and debug output go to stderr, which the host can capture separately.

Why Stdio Is the Default

Three reasons stdio dominates MCP transport:

Zero configuration. No ports to open. No TLS certificates. No DNS. No firewall rules. You point it at a command, and it works. For developers experimenting with MCP for the first time, this removes every barrier except installing the server.

Security through isolation. A stdio server only talks to the process that spawned it. There is no network socket listening for connections. No attack surface beyond what the server binary itself does. The operating system enforces the boundary.

Speed. Pipes are fast. There is no TCP handshake, no HTTP overhead, no serialization beyond the JSON-RPC message itself. For local operations like reading files, querying a database, or running shell commands, stdio adds almost zero latency.

In the AgentNDX directory, 277 out of 296 servers use stdio transport. That ratio tells you where the protocol lives today: on developer machines, running locally, serving a single client.

The Tradeoffs

Stdio works until it does not. Here is where it falls short:

Single client only. A stdio server handles one connection. If two applications need the same server, you run two instances. There is no multiplexing, no shared sessions.

Local only. Stdio requires the host and server to run on the same machine. You cannot connect to a stdio server over a network. If your server needs to run on a remote machine or serve multiple users, stdio is the wrong choice.

No horizontal scaling. You cannot put a load balancer in front of stdin. If the server process dies, the connection dies. There is no reconnection logic built into the transport.

Process lifecycle coupling. The server lives and dies with the host. If Claude Desktop restarts, every stdio server restarts too. Any in-memory state is gone.

For local development, single-user tools, and filesystem access, none of these tradeoffs matter. For production services, remote deployments, or multi-tenant use cases, they all matter.

When to Use Stdio vs HTTP

MCP supports two transport types: stdio and HTTP (Streamable HTTP, which replaced the older SSE transport).

StdioHTTP
DeploymentLocal, same machineLocal or remote
ClientsOneMany
SetupZero configRequires port, optional TLS
Use caseDev tools, file access, local DBsProduction APIs, shared services
ScalingSingle processHorizontal, stateless

Pick stdio when the server needs access to something on your machine: files, local databases, shell commands, git repos. Pick HTTP when the server is a service others connect to, or when it needs to survive independent of any single client.

A Quick Example

A minimal stdio server in Node.js looks like this:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new McpServer({ name: "my-server", version: "1.0.0" });

server.tool("hello", "Says hello", {}, async () => ({
  content: [{ type: "text", text: "Hello from stdio!" }]
}));

const transport = new StdioServerTransport();
await server.connect(transport);

That is the entire transport setup. Two imports, one instantiation, one connect call. The SDK handles all the JSON-RPC framing, message parsing, and pipe management.

FAQ

Q: Can I use stdio for a server that runs in Docker? A: Yes, if the host launches the Docker container as a child process and pipes stdin/stdout. The container replaces the local binary, but the transport mechanics are identical.

Q: What happens if my server writes to stdout accidentally? A: The host will try to parse it as JSON-RPC and fail. Use stderr for all logging and debug output. Most MCP SDKs enforce this, but custom implementations need to be careful.

Q: Is stdio going away? A: No. The 2026 MCP roadmap focuses on improving HTTP transport for production use, but stdio remains the standard for local servers. The two transports serve different needs and will coexist.

Q: Can I switch a server from stdio to HTTP later? A: Yes. The tool definitions, resources, and prompts are transport-independent. You swap the transport layer without changing your server logic. Both the Node.js and Python MCP SDKs make this a one-line change.