What is mcp-hub?
mcp-hub serves many Model Context Protocol servers from one container, published over HTTPS for Claude Web custom connectors, Claude Code and any other Streamable-HTTP MCP client — behind a built-in OAuth 2.1 authorization server protected by a single password.
The problem
Most MCP servers are stdio programs. They read JSON-RPC on stdin and write it on stdout, and they assume a client that starts them as a child process. That works beautifully on a laptop and not at all for a hosted client: Claude Web connectors speak HTTP and expect OAuth.
The usual fix is to wrap each stdio server in its own auth proxy. That works, but the cost per server is real:
- a container image and a compose stack,
- a hostname and a TLS certificate,
- an OAuth authorization server with its own client registrations and its own state directory,
- a firewall rule, a log stream, a monitoring entry and a backup path.
Nine servers means nine of each. Every one of them has to be updated, scanned and re-authorized separately, and every one is a place where an authorization bug can hide.
What mcp-hub does instead
One Node process holds all of it:
What you get
Your existing config works. /config/mcp.json uses exactly Claude Code's mcpServers schema, ${VAR} expansion included. Copy entries across without translating them. The one extra field, "hub": false, is ignored by Claude Code, so the file stays interchangeable.
Path-based routing. Each server is reachable at /<name> and /<name>/mcp. Register the ones you reach for daily as their own connectors.
The /hub aggregate. Registering nine connectors means nine servers' worth of tool schemas in the model's context before a single question is asked. /hub is one connector that exposes four meta-tools — list_servers, list_tools, get_tool_schema, call_tool — and lets the model page in only the schema it actually needs. Four schemas instead of N×tools.
Real supervision. Children start at boot, get pinged every 60 seconds and are restarted with exponential backoff when they die. A server that is down answers 503 on its path and shows up in /health — it does not hang.
Hot reload. Editing mcp.json starts, stops or restarts exactly the servers whose entries changed. Everything else keeps its connections.
Stateless transport. No session state is kept between requests, so a client that reconnects without closing its previous session — which claude.ai does, roughly every five minutes — cannot leak processes or memory.
No database. State is one JSON file plus an Ed25519 key under /data.
What it is not
- Not a sandbox. Every stdio server configured in the hub container runs as the same operating-system user as the hub and can read its mounted files and environment. Only run stdio packages you trust; put anything else in its own container and connect it as a remote server. See Security.
- Not a notification bridge. The stateless transport delivers request/response traffic in full, but server-initiated messages (
listChanged, subscriptions, sampling) are not forwarded to clients. - Not a multi-user system. There is one password. Anyone who has it can approve a client and reach every server the hub exposes.
Next
- Getting started — a working deployment
- Configuration — writing your
mcp.json - Architecture — what happens inside
- Comparison — when something else fits better