Skip to content
DocumentationPricingBlogCommunityAboutGitHub

Expose a stdio MCP server as a public Streamable HTTP URL

Use "kind": "stdio" when your MCP server is a command mcpwarp should spawn itself and talk to over stdin/stdout.

Web clients like claude.ai and ChatGPT can’t spawn a process on your machine, so a stdio server needs two things before they can use it: a bridge that turns HTTP requests into stdio messages, and a public URL that points at that bridge. Usually that means running supergateway or mcp-proxy plus a separate tunnel. mcpwarp does both in one step: it spawns your command, bridges it to Streamable HTTP locally, and gives it a public URL.

~/.mcpwarp/config.json
{
"servers": [
{
"name": "blender",
"kind": "stdio",
"command": "uvx",
"args": ["blender-mcp"],
"env": { "BLENDER_PATH": "/Applications/Blender.app" }
}
]
}
  • command — the executable to run.
  • args — arguments passed to it.
  • env — extra environment variables for the child process.
  • name — must match ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$, 1–30 characters, and be unique in your config. It’s also the public URL slug. Renaming a server mints a brand-new URL; the old one lingers offline in the dashboard until you delete it.
Terminal window
mcpwarp status # validate the config first
mcpwarp up

mcpwarp up spawns the command, speaks MCP over its stdin/stdout, and gives it a public URL:

NAME KIND URL
blender stdio https://blender-anatoly.tunnel.mcpwarp.io/mcp

Each stdio server gets a small local HTTP endpoint that turns Streamable HTTP requests into newline-delimited JSON-RPC on the child process’s stdin/stdout. It classifies messages by shape, so it supports both session-based MCP and the stateless 2026-07-28 generation of the protocol.

  • No SSE resumability — there’s no Last-Event-ID or replay, so a client has to re-issue a request if a stream drops.
  • On Windows, process cleanup is best-effort and only the direct child is killed.
  • On Windows, .cmd/.bat shims aren’t launched directly — point command at the underlying .js file via node instead.
  • If the child crashes 10 times in a row without a 60-second healthy run, mcpwarp stops restarting it and requests get a 502 with “local server ‘<name>’ is not running”. Run with --verbose to see why it’s crashing.

See also: Use a stdio MCP server in claude.ai and ChatGPT without deploying it, which compares this with supergateway, mcp-proxy, mcptunnels and OpenAI’s tunnel.