Bidirectional stdio ↔ HTTP gateway for MCP servers — connect clients to remote servers or publish local servers
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
claude mcp add mcp-stdio -- python -m mcp-std{
"mcpServers": {
"mcp-stdio": {
"command": "python",
"args": ["-m", "mcp-std"]
}
}
}MCP Servers overview
<!-- mcp-name: io.github.shigechika/mcp-stdio -->
# mcp-stdio
English | [日本語](README.ja.md)
A stdio↔HTTP MCP gateway that works in **both directions** — the same
binary is both an MCP-over-HTTP **client** gateway and, via `serve` mode, a
full MCP-over-HTTP **server** (with an optional embedded OAuth 2.1
Authorization Server), so it can sit on either end of an MCP connection.
📖 **New here? Start with the [user guide](https://shigechika.github.io/mcp-stdio/)** — task-oriented docs for connecting a client or publishing a server. This README is the full reference.
## Overview
**Client gateway (default mode) — stdio → HTTP.** [MCP](https://modelcontextprotocol.io/) 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:
```mermaid
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.
**Reverse gateway (`mcp-stdio serve`) — HTTP → stdio.** The mirror image: takes a
local stdio MCP server (any language, any framework) and exposes it as a
Streamable HTTP endpoint, with optional bearer-token or embedded-OAuth-2.1
authentication, per-user backend isolation when OAuth is enabled, and a
restart-durable token store —
see [Reverse gateway: `serve` mode](#reverse-gateway-serve-mode) below. This
is how mcp-stdio can stand in for a framework's own HTTP/OAuth hosting layer
(e.g. instead of depending on a Python web framework's built-in server for
just that part) when the tool definitions themselves already run fine over
stdio.
## 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](https://html.spec.whatwg.org/multipage/server-sent-events.html).
- **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](https://www.rfc-editor.org/rfc/rfc9728) Protected Resource Metadata
- §3 discovery of authorization servers via `/.well-known/oauth-protected-resource`
- §3.1 path-aware well-known URL construction for path-based reverse-proxy deployments, with host-root fallback; preserves the resource URL's query component on the constructed metadata URL
- §3.3 `resource` field validation — warn on mismatch, continue
- §5.1 `WWW-Authenticate: Bearer resource_metadata=` hint — probes the server before discovery so servers that publish PRM at a non-standard URL are found without well-known path guessing
- [RFC 8414](https://www.rfc-editor.org/rfc/rfc8414) Authorization Server Metadata
- §3.1 well-known URL construction, including path insertion for issuers with path components
- §3.3 `issuer` validation — reject a cross-origin issuer (AS mix-up guard), warn on a same-origin mismatch (trailing slash / path / case) and continue
- §3 OpenID Connect Discovery 1.0 fallback — when the OAuth well-known 404s, probe `/.well-known/openid-configuration` (path-append and path-insertion) for ASes that expose only the OIDC form (Auth0, Okta, Azure AD, Google)
- [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707) Resource Indicators
- §2 `resource` parameter in authorization, token exchange, **and refresh** requests
- [RFC 7636](https://www.rfc-editor.org/rfc/rfc7636) PKCE
- §4.1–4.2 S256 `code_challenge_method` with an 86-char `code_verifier`
- [RFC 8628](https://www.rfc-editor.org/rfc/rfc8628) Device Authorization Grant
- §3.1 device authorization request with `resource` indicator (RFC 8707)
- §3.4–3.5 token polling with `authorization_pending` / `slow_down` (interval +=5 s) / `expired_token` / `access_denied` handling
- DCR registers `urn:ietf:params:oauth:grant-type:device_code` in `grant_types` (RFC 7591 §2)
- [RFC 7591](https://www.rfc-editor.org/rfc/rfc7591) Dynamic Client Registration
- §3 client registration request; `token_endpoint_auth_method` chosen from `token_endpoint_auth_methods_supported` in AS metadata (prefers `none` → `client_secret_post` → `client_secret_basic`)
- §3.2.1 `client_secret_expires_at` handling — auto re-register on expiry
- `application_type: "native"` in DCR ([RFC 8252](https://www.rfc-editor.org/rfc/rfc8252) §8.4 / MCP SEP-837): the loopback auth-code and headless device flows are native clients, so the loopback redirect is not rejected as the RFC 7591 default `"web"`
- [Client ID Metadata Documents](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#client-id-metadata-documents) (MCP 2025-11-25 / [draft-ietf-oauth-client-id-metadata-document-00](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-00))
- `--client-metadata-url` presents an operator-hosted HTTPS document URL as `client_id`, skipping Dynamic Client Registration; honoured when set even if the AS metadata does not (yet) advertise `client_id_metadata_document_supported` (warns instead of silently falling back), and outranked by a pre-registered `client_id` (`--client-id` or `MCP_OAUTH_CLIENT_ID`) (#60)
- the hosted document's `redirect_uris` must include mcp-stdio's loopback callback **without a port** (`http://127.0.0.1/callback`) — the actual callback binds a fresh ephemeral port every run, and the AS must accept any port for a loopback redirect URI ([RFC 8252](https://www.rfc-editor.org/rfc/rfc8252) §7.3 / §8.4)
- [RFC 6749](https://www.rfc-editor.org/rfc/rfc6749) OAuth 2.0
- §2.3.1 `client_secret_basic`: `Authorization: Basic` header with percent-encoded credentials (applied to code exchange, token refresh, and Device Authorization Grant polling)
- [RFC 6750](https://www.rfc-editor.org/rfc/rfc6750) Bearer Token usage
- §2.1 `Authorization: Bearer <token>` request header
- **Works with MCP 2026-07-28 servers** — add `--protocol-era auto` and mcp-stdio asks the server which protocol it speaks and adapts; your MCP client needs no changes. Without the flag nothing changes, so upgrading is safe. `mcp-stdio serve` answers both old and new clients on the same address automatically — or only the newer ones with `--modern-only`, and `--modern-idle-ttl` reclaims idle backends. Newer clients can also hold one connection open and hear when your server's tool, prompt or resource lists change, or when a specific resource they named is updated (mcp-stdio subscribes on their behalf when your server declares `resources.subscribe`). Verified end to end against python-sdk v2.0.0 in both directions. → [Working with MCP 2026-07-28 servers](https://shigechika.github.io/mcp-stdio/modes/#protocol-eras)
- **Retry with backoff** — retries up to 3 times on connection errors; after a transport error that may follow delivery (e.g. a read timeout on a slow `tools/call`), only known replay-safe methods (read-only or idempotent, such as `tools/list` or `resources/read`) are retried, so such an error never re-executes a `tools/call`
- **HTTP 429 / 503 handling** — honours `Retry-After` (delta-seconds or HTTP-date) up to a 60-second cap on both 429 (Too Many Requests) and 503 (Service Unavailable) — the two spec-sanctioned Retry-After carriers (RFC 9110 §10.2.3) — then surfaces the status so the client can decide (cf. modelcontextprotocol/typescript-sdk#1892)
- **Auto-pagination** (Streamable HTTP transport) — transparently follows `nextCursor` for `tools/list` / `resources/list` / `resources/templates/list` / `prompts/list` and merges the pages into one response, so clients that drop pages beyond the first still see the full list (cf. anthropics/claude-code#39586)
- **Streaming resilience** — streams SSE responses in real time; auto-reconnects on mid-stream disconnect
- **Line-separator safety** — escapes raw `U+2028` / `U+2029` (legal in JSON, but JavaScript line terminators) in upstream responses so clients that treat them as line breaks cannot mis-frame the output; lossless (cf. modelcontextprotocol/typescript-sdk#2155)
- **Argument normalization** — rewrites a `tools/call` request whose `arguments` is `null` to `{}` so strict servers that reject the null form accept the call; on by default, opt out with `--no-normalize-arguments` (cf. modelcontextprotocol/typescript-sdk#2012)
- **`Mcp-Param-*` headers** — against a 2026-07-28 server, mirrors every tool argument the server marks with `x-mcp-header` into the `Mcp-Param-*` header the spec requires (python-sdk v2 servers reject a `tools/call` without it), hides tools whose annotations are invalid, and on a `-32020` re-lists the tools once and retries the call; `--mcp-param-headers always` does the same on an older-protocol session for servers that still require the headers there (GitHub's hosted MCP server), `off` opts out (#459)
- **Cancellation-aware filtering** — tracks request ids cancelled via `notifications/cancelled` on stdin and drops any late upstream response carrying one of those ids before it reaches the client, per the MCP cancellation spec; on by default (60 s TTL), opt out with `--no-cancel-filter` (cf. anthropics/claude-code#51073)
- **SSE in-flight error synthesis** — on the legacy SSE transport, replies arrive only on the long-lived GET stream; when that stream drops, requests already POSTed would otherwise hang forever. mcp-stdio tracks the ids in flight on the current stream and synthesizes a JSON-RPC `-32000` error for each on a drop — so the client can retry instead of hanging — while auto-reconnecting; cancelled ids are skipped (cf. anthropics/claude-codWhat people ask about mcp-stdio
What is shigechika/mcp-stdio?
+
shigechika/mcp-stdio is mcp servers for the Claude AI ecosystem. Bidirectional stdio ↔ HTTP gateway for MCP servers — connect clients to remote servers or publish local servers It has 8 GitHub stars and its last recorded update is dated 2026-10-06.
How do I install mcp-stdio?
+
You can install mcp-stdio by cloning the repository (https://github.com/shigechika/mcp-stdio) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is shigechika/mcp-stdio safe to use?
+
Our security agent has analyzed shigechika/mcp-stdio and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.
Who maintains shigechika/mcp-stdio?
+
shigechika/mcp-stdio is maintained by shigechika. The last recorded GitHub activity is dated 2026-10-06, with 5 open issues.
Are there alternatives to mcp-stdio?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy mcp-stdio to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/shigechika-mcp-stdio)<a href="https://claudewave.com/repo/shigechika-mcp-stdio"><img src="https://claudewave.com/api/badge/shigechika-mcp-stdio" alt="Featured on ClaudeWave: shigechika/mcp-stdio" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
The fastest path to AI-powered full stack observability, even for lean teams.