Claude Academy
intermediate14 min

MCP Transport Types: stdio vs HTTP vs SSE

Learning Objectives

  • Understand the three MCP transport types
  • Know when to use each transport
  • Configure user-level vs project-level MCP servers
  • Pass environment variables securely to MCP servers

Transport Types

MCP servers communicate with Claude Code through a transport — the mechanism for sending requests and receiving responses. There are three transport types, each suited to different scenarios.

stdio — Local Process

stdio (standard input/output) is the most common and recommended transport. The MCP server runs as a local process on your machine, and Claude Code communicates with it through stdin/stdout.

claude mcp add github \

-e GITHUB_TOKEN=ghp_xxx \

--transport stdio \

npx -y @modelcontextprotocol/server-github

How It Works

1. Claude Code spawns the MCP server as a child process

2. Claude sends requests to the server's stdin (as JSON)

3. The server processes the request and writes responses to stdout (as JSON)

4. Claude reads the response

Claude Code ─── stdin ──→ MCP Server Process

←── stdout ──

Advantages

  • Fast: No network overhead — direct process communication
  • Secure: No network exposure — the server only talks to Claude Code
  • Simple: No ports, no URLs, no certificates
  • Reliable: No network failures possible

When to Use

stdio is the right choice for:

  • Most MCP servers (GitHub, databases, Slack, etc.)
  • Any server that runs locally on your machine
  • Development and personal use

HTTP — Remote Server

HTTP transport connects to an MCP server running on a remote machine via HTTP(S).

claude mcp add company-tools \

--transport http \

--url https://mcp.company.com/tools \

--header "Authorization: Bearer ${COMPANY_TOKEN}"

How It Works

1. The MCP server runs on a remote host and exposes an HTTP endpoint

2. Claude Code sends HTTP POST requests with the MCP payload

3. The server processes and returns HTTP responses

Claude Code ─── HTTPS ──→ Remote MCP Server

←── HTTPS ── (company.com)

Advantages

  • Remote access: Server can be anywhere — different machine, cloud, corporate network
  • Shared: Multiple developers can use the same server instance
  • Managed: IT/DevOps team can maintain the server centrally

When to Use

HTTP is the right choice for:

  • Company-hosted MCP servers (internal tools, proprietary data)
  • Cloud-based MCP services
  • Shared infrastructure across a team
  • Servers that need to be on a different machine

Authentication

HTTP servers typically require authentication via headers:

claude mcp add internal-api \

--transport http \

--url https://mcp.internal.company.com/v1 \

--header "Authorization: Bearer $INTERNAL_TOKEN" \

--header "X-Team-ID: backend"

SSE — Server-Sent Events (Legacy)

SSE (Server-Sent Events) is a streaming transport that was used in earlier versions of MCP. It's being phased out in favor of HTTP with streaming support.

claude mcp add legacy-server \

--transport sse \

--url https://old-server.company.com/events

When to Use

Only use SSE if you're connecting to an older MCP server that hasn't been updated to support HTTP transport. For new setups, always prefer stdio or HTTP.

Choosing the Right Transport

| Scenario | Transport | Why |

|---|---|---|

| GitHub, databases, Slack | stdio | Local, fast, secure |

| Company internal tools | HTTP | Remote, shared |

| Cloud-hosted services | HTTP | Not running locally |

| Personal tools and scripts | stdio | Simple setup |

| Legacy servers | SSE | Backward compatibility |

| Most situations | stdio | Default choice |

Rule of thumb: Use stdio unless the server must run remotely. Then use HTTP.

Configuration Scopes

MCP server configs can be stored at two levels, controlling who has access:

User-Level: ~/.claude.json

Servers available in all your projects:

{

"mcpServers": {

"github": {

"transport": "stdio",

"command": "npx",

"args": ["-y", "@modelcontextprotocol/server-github"],

"env": {

"GITHUB_TOKEN": "ghp_xxxx"

}

}

}

}

Good for:

  • Personal tools (GitHub with your token)
  • Cross-project utilities
  • Personal productivity servers

Project-Level: .mcp.json

Servers specific to this project, committed to git:

{

"mcpServers": {

"project-db": {

"transport": "stdio",

"command": "npx",

"args": ["-y", "@modelcontextprotocol/server-postgres"],

"env": {

"DATABASE_URL": "postgresql://reader:pass@localhost:5432/project_dev"

}

},

"project-sentry": {

"transport": "http",

"url": "https://mcp.company.com/sentry",

"headers": {

"Authorization": "Bearer ${SENTRY_TOKEN}"

}

}

}

}

Good for:

  • Project-specific databases
  • Team-shared integrations
  • Standardizing tools across the team

Scope Flag

When using claude mcp add, control where it's stored:

# User-level (default) — available everywhere

claude mcp add github -e GITHUB_TOKEN=ghp_xxx --transport stdio npx -y @modelcontextprotocol/server-github

# Project-level — committed to git

claude mcp add project-db --scope project -e DATABASE_URL=$DB_URL --transport stdio npx -y @modelcontextprotocol/server-postgres

Environment Variables: Secure Patterns

Never hardcode secrets in config files that are committed to git. Use these patterns instead:

For User-Level Config

Hardcoding is acceptable in ~/.claude.json since it's not committed to git:

{

"env": {

"GITHUB_TOKEN": "ghp_actual_token_here"

}

}

For Project-Level Config

Reference environment variables that each developer sets in their shell:

{

"env": {

"DATABASE_URL": "${DATABASE_URL}",

"API_KEY": "${PROJECT_API_KEY}"

}

}

Each developer sets DATABASE_URL and PROJECT_API_KEY in their shell profile. The .mcp.json references the variables without containing the actual values.

Document Required Variables

In your CLAUDE.md or project README, document what variables team members need:

## MCP Setup

Set these environment variables before using MCP servers:

  • DATABASE_URL — PostgreSQL connection string for local dev DB
  • SENTRY_TOKEN — Sentry API token (get from 1Password vault)

On-Demand Loading

An important optimization: MCP servers only load their tool definitions when connected. If you configure a server but don't connect it in a session, it doesn't consume tokens.

This means you can configure many servers and only activate the ones you need per session. The token savings are significant — tool definitions for inactive servers don't exist in your context.

Key Takeaway

MCP supports three transports: stdio (local, recommended for most cases), HTTP (remote servers), and SSE (legacy). Use stdio by default and HTTP only when the server must run remotely. Store personal servers in ~/.claude.json (user-level) and team-shared servers in .mcp.json (project-level). Never hardcode secrets in project configs — reference environment variables instead. Only connect the servers you need per session to manage token costs.