Understanding MCP Stdio Transport: Beyond HTTP APIs

3 minute read

Published:

If you’re familiar with building HTTP APIs, you might be curious about how MCP (Model Context Protocol) servers work, especially when using stdio transport. Let me break this down using your existing API knowledge as a foundation.

What You Already Know: HTTP APIs

When you build a typical web API, the flow is straightforward:

// Your Express server
const express = require('express');
const app = express();

app.post('/api/css-concepts', (req, res) => {
  // Handle request
  res.json({ success: true });
});

app.listen(3000); // Server listens on port 3000

The HTTP Flow:

  1. Server starts and listens on port 3000
  2. Client makes HTTP request to http://localhost:3000/api/css-concepts
  3. Server processes request and sends HTTP response
  4. Client receives response

Stdio Transport: A Different Approach

Instead of HTTP, stdio transport makes your server work like a command-line program:

// css-tutor-server.js (stdio version)
process.stdin.on('data', (data) => {
  const request = JSON.parse(data.toString());
  
  // Process the request (same logic as HTTP handler)
  const response = handleRequest(request);
  
  // Send response back via stdout
  process.stdout.write(JSON.stringify(response));
});

How MCP Client Uses Your Server

Instead of making HTTP calls, the MCP client:

  1. Starts your server as a child process:
    node css-tutor-server.js
    
  2. Sends requests by writing to the process’s stdin:
    // MCP client internally does something like:
    serverProcess.stdin.write(JSON.stringify({
      method: "read_from_memory",
      params: {}
    }));
    
  3. Receives responses by reading from stdout:
    serverProcess.stdout.on('data', (data) => {
      const response = JSON.parse(data.toString());
      // Handle response
    });
    

Visual Comparison

HTTP API:

Claude → HTTP Request → :3000 → Your Server → HTTP Response → Claude

Stdio MCP:

Claude → MCP Client → stdin → Your Server Process → stdout → MCP Client → Claude

Key Differences

HTTP APIStdio MCP
Server listens on portServer runs as child process
HTTP requests/responsesJSON messages via stdin/stdout
Always runningStarted when needed
Network overheadDirect process communication
curl can test itOnly MCP client can use it

Why Choose Stdio Transport?

Performance: No network stack overhead - direct process communication is faster than HTTP calls.

Simplicity: No HTTP parsing, routing, or middleware - just JSON messages via stdin/stdout.

Security: No network exposure means only the parent process can access your server.

Automatic Management: The MCP client handles process lifecycle - starting, stopping, and restarting as needed.

MCP Transport Options

MCP supports multiple transport methods:

  1. Stdio transport - Process communication via stdin/stdout (no network port needed)
  2. HTTP transport - Traditional HTTP server on a specific port
  3. WebSocket transport - WebSocket connections for real-time communication

Practical Example

Here’s how you might configure an MCP server using stdio transport:

{
  "mcpServers": {
    "css-tutor": {
      "command": "node",
      "args": ["path/to/css-tutor-server.js"],
      "transport": "stdio"
    }
  }
}

When a function is called, the MCP client launches your server process and communicates through stdin/stdout pipes instead of making network requests.

Conclusion

Think of stdio transport as turning your server into a “smart command-line tool” instead of a web service. It’s particularly well-suited for MCP servers that need fast, secure, local communication without the overhead of network protocols.

Whether you choose HTTP or stdio transport depends on your specific needs - HTTP for network accessibility and stdio for performance and simplicity in local environments.