Skip to main content

Stdio-to-HTTP gateway — connects MCP clients to remote HTTP MCP servers

Project description

mcp-stdio

English | 日本語

Stdio-to-HTTP gateway — connects MCP clients to remote HTTP MCP servers.

Overview

MCP clients like Claude Desktop and Claude Code see mcp-stdio as a locally running self-hosted MCP server, while it relays all requests to a remote MCP server with support for various authentication methods:

flowchart BT
    A[Claude<br>Desktop/Code] <-- stdio --> B(mcp-stdio)
    B <== "<b>HTTPS</b><br>Streamable HTTP / SSE<br>Bearer Token<br>Header<br>OAuth" ==> C[Remote<br>MCP Server]
    B -. "OAuth 2.1<br>(PKCE)" .-> D[Authorization<br>Server]
    D -. callback .-> B
    style B fill:#4a5,stroke:#333,color:#fff

Bearer tokens, custom headers, and OAuth 2.1 credentials are forwarded to the remote server.

Features

  • Both MCP transports supported — Streamable HTTP (current spec, default) and SSE (MCP 2024-11-05 legacy), selectable with --transport. SSE parser follows the WHATWG Server-Sent Events spec.
  • OAuth 2.1 client — built-in authorization code flow with PKCE, dynamic client registration, token refresh, and secure token persistence. Implements the full MCP authorization spec at the section level:
    • RFC 9728 Protected Resource Metadata
      • §3 discovery of authorization servers via /.well-known/oauth-protected-resource
      • §3 resource field validation — warn on mismatch, continue
    • RFC 8414 Authorization Server Metadata
      • §3 well-known URL construction, including path insertion for issuers with path components
      • §3 issuer validation — warn on mismatch, continue
    • RFC 8707 Resource Indicators
      • §2 resource parameter in authorization, token exchange, and refresh requests
    • RFC 7636 PKCE
      • §4.1–4.2 S256 code_challenge_method with a 96-char code_verifier
    • RFC 7591 Dynamic Client Registration
      • §3 client registration request (public client with token_endpoint_auth_method: none)
      • §3.2.1 client_secret_expires_at handling — auto re-register on expiry
    • RFC 6750 Bearer Token usage
      • §2.1 Authorization: Bearer <token> request header
  • Retry with backoff — retries up to 3 times on connection errors
  • Streaming resilience — streams SSE responses in real time; auto-reconnects on mid-stream disconnect
  • Session recovery — resets MCP session ID on 404 and retries
  • Token refresh on 401 — automatically refreshes expired OAuth tokens mid-session
  • Bearer token auth — via --bearer-token flag or MCP_BEARER_TOKEN env var
  • Custom headers — pass any header with -H / --header
  • Graceful shutdown — handles SIGTERM/SIGINT
  • Proxy support — respects HTTP_PROXY, HTTPS_PROXY, NO_PROXY env vars via httpx
  • Minimal dependencies — only httpx; OAuth uses stdlib only

Install

pip install mcp-stdio

Or with uv:

uv tool install mcp-stdio

Or run directly without installing:

uvx mcp-stdio https://your-server.example.com:8080/mcp

Or with Homebrew:

brew install shigechika/tap/mcp-stdio

Quick Start

mcp-stdio https://your-server.example.com:8080/mcp

With Bearer token authentication:

# Recommended: use env var (token is hidden from `ps`)
MCP_BEARER_TOKEN=YOUR_TOKEN mcp-stdio https://your-server.example.com:8080/mcp

# Or pass directly (token is visible in `ps` output)
mcp-stdio https://your-server.example.com:8080/mcp --bearer-token YOUR_TOKEN

With custom headers:

mcp-stdio https://your-server.example.com:8080/mcp --header "X-API-Key: YOUR_KEY"

With OAuth 2.1 authentication (for servers that require it):

mcp-stdio --oauth https://your-server.example.com:8080/mcp

# With a pre-registered client ID (skips dynamic registration)
mcp-stdio --oauth --client-id YOUR_CLIENT_ID https://your-server.example.com:8080/mcp

For legacy MCP servers using the 2024-11-05 SSE transport:

mcp-stdio --transport sse https://your-server.example.com:8080/sse

Check connectivity before use:

mcp-stdio --check https://your-server.example.com:8080/mcp

Claude Desktop Configuration

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "my-remote-server": {
      "command": "mcp-stdio",
      "args": ["https://your-server.example.com:8080/mcp"],
      "env": {
        "MCP_BEARER_TOKEN": "YOUR_TOKEN"
      }
    }
  }
}

Config file locations:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

Claude Code Configuration

claude mcp add my-remote-server \
  -e MCP_BEARER_TOKEN=YOUR_TOKEN \
  -- mcp-stdio https://your-server.example.com:8080/mcp

Usage

mcp-stdio [OPTIONS] URL

Arguments:
  URL                    Remote MCP server URL

Options:
  --bearer-token TOKEN   Bearer token (or set MCP_BEARER_TOKEN env var)
  --oauth                Enable OAuth 2.1 authentication
  --client-id ID         Pre-registered OAuth client ID (or set MCP_OAUTH_CLIENT_ID)
  --oauth-scope SCOPE    OAuth scope to request
  -H, --header 'Key: Value'  Custom header (can be repeated)
  --transport {streamable-http,sse}
                         Transport type (default: streamable-http)
  --timeout-connect SEC  Connection timeout (default: 10)
  --timeout-read SEC     Read timeout (default: 120)
  --check                Check connection and exit
  -V, --version          Show version
  -h, --help             Show help

Workarounds

Claude Code

Works around known issues in Claude Code's HTTP transport:

  • Bearer token not sent — Claude Code ignores Authorization header on tool calls (#28293, #33817)
  • Missing Accept header — servers return 406, misinterpreted as auth failure (#42470)
  • OAuth fallback loop — Claude Code enters OAuth discovery even when not needed (#34008, #39271)
  • Session lost after disconnect — mcp-stdio recovers MCP sessions automatically on 404 (#34498, #38631)
  • OAuth scope omitted — Claude Code sends no scope parameter in authorization requests, causing strict OAuth servers to reject the flow (#4540); mcp-stdio sends scopes via --oauth-scope
  • Proxy settings ignored — Claude Code does not respect NO_PROXY (#34804); mcp-stdio inherits proxy settings from httpx

mcp-remote

  • OAuth discovery fails for auth server with path — mcp-remote does not implement the RFC 8414 §3 path insertion rule, causing OAuth metadata discovery to fail when the authorization server URL contains a path component (e.g. multi-tenant or realm-based servers) (mcp-remote#207); mcp-stdio constructs the correct well-known metadata URL.

How It Works

  1. If --oauth is set, obtains an access token (cached → refresh → browser flow)
  2. Reads JSON-RPC messages from stdin (sent by Claude Desktop/Code)
  3. Relays them over HTTPS to the remote MCP server
  4. Parses responses and writes them to stdout
  5. On 401, refreshes the OAuth token and retries

Transport details:

  • Streamable HTTP (default) — each stdin message is a single POST; session state is tracked via the Mcp-Session-Id header and re-initialized automatically on 404.
  • SSE (MCP 2024-11-05 legacy) — a persistent GET stream delivers responses and the initial endpoint event containing the POST URL; the stream auto-reconnects on disconnect.

OAuth tokens are stored in ~/.config/mcp-stdio/tokens.json (permissions 0600).

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_stdio-0.4.3.tar.gz (48.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_stdio-0.4.3-py3-none-any.whl (20.2 kB view details)

Uploaded Python 3

File details

Details for the file mcp_stdio-0.4.3.tar.gz.

File metadata

  • Download URL: mcp_stdio-0.4.3.tar.gz
  • Upload date:
  • Size: 48.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_stdio-0.4.3.tar.gz
Algorithm Hash digest
SHA256 e11fac585a24361ef69ff327d8d970e8faf4d6beb8acc32455e29b9f9f654597
MD5 b73382cfdbbfed3a6cf55c11ccba526d
BLAKE2b-256 75d4c81726af35975039d68ac7b8cc6e92d6d318b08584063b0bb0ae4fca30ef

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_stdio-0.4.3.tar.gz:

Publisher: release.yml on shigechika/mcp-stdio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mcp_stdio-0.4.3-py3-none-any.whl.

File metadata

  • Download URL: mcp_stdio-0.4.3-py3-none-any.whl
  • Upload date:
  • Size: 20.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_stdio-0.4.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ec5b3f43aefa22eb6e80132470866b088d1c6f6a6af6b3e009e2a57c23a5940c
MD5 d9602db03bae27a63f86d1ef48e2f96c
BLAKE2b-256 01079b95b0d5e75962836ca4eb913ae6c3b53a11245fe1e1ae668753b4dc514c

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_stdio-0.4.3-py3-none-any.whl:

Publisher: release.yml on shigechika/mcp-stdio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page