Running it for a team
Over stdio, each person’s agent starts its own server. For a team, run one server on a shared machine and let everyone’s agents connect to it over Streamable HTTP: one set of mirrors, one configuration, one token to the code hosts — and nothing to install on people’s computers.
export REPO_READER_MCP_TOKEN=… # the bearer token clients will sendexport GITHUB_TOKEN=… # the read-only token for the code host, as over stdiorepo-reader-mcp --config config.yaml --http 0.0.0.0:8000repositories: - github: acme/shop-* token_env: GITHUB_TOKEN
http: token_env: REPO_READER_MCP_TOKEN # every request carries `Authorization: Bearer <its value>`The server answers at /mcp on that address (--http 8000 alone listens on 127.0.0.1). It lists groups and syncs
mirrors in the background, as over stdio; every person’s agent reads the same mirrors.
Who may call
Section titled “Who may call”- A bearer token —
http.token_envnames the variable that holds it. A request without it, or with another, is answered401and nothing else. The token is compared in constant time, so how long a refusal takes tells nothing about it. - A gateway in front —
http.behind_gateway: truewhen your organisation’s gateway (an MCP gateway, a proxy with single sign-on) checks who calls and only it can reach the server.
On any address other than exactly 127.0.0.1, ::1 or localhost one of the two is required: the server refuses to
start open to anyone who can reach its port. On those three no token is needed — that is one person’s computer — and
the server answers only requests addressed to it by those names, so a web page can’t reach it through a crafted domain
name.
The server speaks plain HTTP. Put TLS in front of it — a reverse proxy (nginx, Caddy, Traefik) or your gateway — and
route /mcp to it without a redirect: clients don’t follow one that leaves the address they were given. A proxy on the
same machine may forward to 127.0.0.1 with its own host name (code.example.com): with a token or
behind_gateway: true the server answers any host name — the token, or the gateway, is what keeps others out.
Connecting an agent
Section titled “Connecting an agent”Any MCP client that takes a URL and a header connects:
claude mcp add --transport http repo-reader https://code.example.com/mcp \ --header "Authorization: Bearer $REPO_READER_MCP_TOKEN"or, in a client’s JSON configuration:
{ "mcpServers": { "repo-reader": { "type": "http", "url": "https://code.example.com/mcp", "headers": { "Authorization": "Bearer <the token>" } } }}Checked with Claude Code and with the MCP Inspector
(npx @modelcontextprotocol/inspector --cli https://code.example.com/mcp --transport http --header "Authorization: Bearer …" --method tools/list).
How it answers
Section titled “How it answers”- No session between requests. Each request is answered on its own — the server keeps nothing about a client — so it can be restarted, or run as several copies behind a load balancer, without clients noticing.
- Plain JSON answers, not event streams: what gateways and proxies pass through unchanged.
- Request ids as strings or numbers, answered as they were sent — gateways often send strings.
Not yet
Section titled “Not yet”One token for everyone (no per-person tokens or access rights per repository), no published container image and no
health endpoint: they come with the release (dev/PLAN.md).