---
title: "Deploy Junctio | (Just Updated) MCP Gateway, One Endpoint for All MCP Servers, Admin Token Set"
description: "Junctio MCP gateway: one endpoint for many MCP servers, REST API, API keys"
category: "AI/ML"
url: https://railway.com/deploy/junctio-or-just-updated-mcp-gateway-one-
---

# Deploy Junctio | (Just Updated) MCP Gateway, One Endpoint for All MCP Servers, Admin Token Set

Junctio MCP gateway: one endpoint for many MCP servers, REST API, API keys

**[Deploy Junctio | (Just Updated) MCP Gateway, One Endpoint for All MCP Servers, Admin Token Set on Railway](https://railway.com/template/junctio-or-just-updated-mcp-gateway-one-)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/junctio-or-just-updated-mcp-gateway-one-/manifest.json

- **Creator:** SuperSlowSloth
- **Category:** AI/ML

## Template content

### junctio

- **Image:** ghcr.io/k2so-dev/junctio:0.2.6@sha256:2fdd95f574744aa25aba8a33db4bdf6389b6d2b2d3d86c71c682cb0674e793d3
- **Start command:** `/bin/sh -c 'echo IyEvYmluL3NoCiMgUmFpbHdheSBib290IGZvciBKdW5jdGlvIChzZWxmLWhvc3RlZCBNQ1AgZ2F0ZXdheSkuIFJ1bnMgYXMgcm9vdCwgZHJvcHMgdG8gdWlkIDEwMDAxLgojCiMgVGhlIGltYWdlIHJ1bnMgYXMgdGhlIGp1bmN0aW8gdXNlciAodWlkIDEwMDAxKSBhbmQga2VlcHMgaXRzIFNRTGl0ZSBkYXRhYmFzZSBpbiAvZGF0YS4gUmFpbHdheQojIG1vdW50cyB0aGUgdm9sdW1lIHJvb3Qtb3duZWQsIHNvIHRoZSBnYXRld2F5IGNhbm5vdCB3cml0ZSB0aGVyZTogdGhpcyBzY3JpcHQgY2hvd25zIC9kYXRhIGFuZAojIHRoZW4gZHJvcHMgcHJpdmlsZWdlcyB3aXRoIHNldHByaXYuIFRoZSBpbWFnZSdzIG93biBFTlRSWVBPSU5UICh0aW5pKSBpcyByZXBsYWNlZCBieSBhIHN0YXJ0CiMgY29tbWFuZCwgc28gdGluaSBpcyBuYW1lZCBoZXJlIGFnYWluLgojCiMgTGl0ZXJhbHMgdGhhdCBhIHRlbXBsYXRlIHZhcmlhYmxlIGNhbm5vdCBjYXJyeSAoYSBsaXRlcmFsIGRlZmF1bHQgcHVibGlzaGVzIGFzIGEgYmxhbmsgcmVxdWlyZWQKIyBmaWVsZCkgbGl2ZSBoZXJlLiBKVU5DVElPX1RSVVNUX1BST1hZIHN0YXlzIGF0IGl0cyBkZWZhdWx0IChmYWxzZSk6IGl0IGtleXMgdGhlIHJhdGUgbGltaXRlciBvbiB0aGUKIyByaWdodC1tb3N0IHgtZm9yd2FyZGVkLWZvciBlbnRyeSwgd2hpY2ggb24gUmFpbHdheSBpcyB0aGUgZWRnZSBob3AgYW5kIHJvdGF0ZXMgcGVyIHJlcXVlc3QuCnNldCAtZXUKCjogIiR7SlVOQ1RJT19TRUNSRVQ6P0pVTkNUSU9fU0VDUkVUIG11c3QgYmUgc2V0fSIKOiAiJHtKVU5DVElPX0FETUlOX1RPS0VOOj9KVU5DVElPX0FETUlOX1RPS0VOIG11c3QgYmUgc2V0fSIKClZPTD0vZGF0YQpta2RpciAtcCAiJFZPTCIgL2NhY2hlL3RtcCAvY2FjaGUvbnBtIC9jYWNoZS9idW4gL2NhY2hlL3V2IC9jYWNoZS91di1weXRob24gL2NhY2hlL3NoYXJlCmNob3duIC1SIDEwMDAxOjEwMDAxICIkVk9MIiAvY2FjaGUKCmVjaG8gImp1bmN0aW8gYm9vdDogdWlkPSQoaWQgLXUpIGRhdGFfb3duZXI9JChzdGF0IC1jICV1OiVnICIkVk9MIikgZGF0YV93cml0YWJsZV9hZnRlcl9jaG93bj15ZXMgcG9ydD0ke1BPUlQ6LTMwMDB9IgoKZXhwb3J0IEhPU1Q9MC4wLjAuMApleHBvcnQgUE9SVD0iJHtQT1JUOi0zMDAwfSIKY2QgL2FwcApleGVjIHNldHByaXYgLS1yZXVpZCAxMDAwMSAtLXJlZ2lkIDEwMDAxIC0tY2xlYXItZ3JvdXBzIFwKICAvdXNyL2Jpbi90aW5pIC0tIGJ1biBhcHBzL2dhdGV3YXkvc3JjL2NsaS9pbmRleC50cyBzZXJ2ZQo= | base64 -d > /tmp/boot.sh; exec /bin/sh /tmp/boot.sh'`
- **Health check:** /health
- **Public domain:** Yes

## Documentation

# Deploy and Host Junctio on Railway

**Built for an LLM agent to deploy and use.** There is no setup form and nothing to fill in: the admin token is generated at deploy time, and the contract below lists every address, variable name and one script that creates an MCP endpoint, attaches a server to it and calls a tool through it.

Junctio is a self-hosted MCP gateway. You register your MCP servers once (stdio, HTTP or SSE), group them into namespaces, and publish each namespace as one authenticated endpoint at `/mcp/` plus the endpoint slug. Every client, such as Claude Code, Codex, Cursor or a custom agent, connects to that one URL instead of configuring each server by hand. It prefixes tool names per server, supports API keys and OAuth, and has a REST API and web UI.

## About Hosting Junctio

This template runs one service, the official `ghcr.io/k2so-dev/junctio` 0.2.6 image pinned by digest. State is a SQLite database in `/data` on an attached volume, so servers, namespaces, endpoints and API keys survive redeploys. The volume is root-owned on Railway, so the start command fixes ownership and then drops to the image's own user before launching the gateway.

`JUNCTIO_ADMIN_TOKEN` is the headless admin credential for `/api/v1/*`, and it is also what is required to choose the web UI admin password on a fresh install, so a stranger who finds the URL first cannot claim the instance. `JUNCTIO_SECRET` encrypts stored upstream credentials; keep it stable. Both are generated per deploy and stay the same across redeploys.

Stdio servers run inside this container. Use the `bunx` runtime for npm packages: the `npx` runtime fails on this image because its bundled npm cannot load its own cache module (`Class extends value undefined`). Stdio servers need outbound network access from the service and the first start of a server pays its download time. `JUNCTIO_TRUST_PROXY` is left off on purpose: on Railway the right-most `x-forwarded-for` entry is the edge hop, which changes per request, so trusting it would make the login rate limit useless.

### Agent contract

- Public URL: `JUNCTIO_BASE_URL` (`https://` plus the service's `RAILWAY_PUBLIC_DOMAIN`). Web UI at `/`, REST API at `/api/v1/`, endpoints at `/mcp/` plus the endpoint slug.
- Private URL: `http://junctio.railway.internal:8080`, exposed as `JUNCTIO_PRIVATE_URL`.
- Credentials: `JUNCTIO_ADMIN_TOKEN` (admin) and `JUNCTIO_SECRET` (encryption key, not for clients). Client API keys start with `jn_` and are minted through the REST API.
- Auth: admin calls send `Authorization: Bearer` followed by the admin token. MCP clients send `Authorization: Bearer` followed by an API key, or `X-API-Key`. Anonymous API calls get `401`.
- Health: `GET /health` returns 200 without credentials.
- Protocol: Streamable HTTP, stateless. A new endpoint accepts MCP revision `2026-07-28` and sends it in the request `_meta`, plus `Mcp-Method` and, for named calls, `Mcp-Name` headers.

```bash
# run with JUNCTIO_BASE_URL and JUNCTIO_ADMIN_TOKEN set (needs curl and jq)
AUTH="Authorization: Bearer $JUNCTIO_ADMIN_TOKEN"
JSON="Content-Type: application/json"
S=$(date +%s)
curl -s -o /dev/null -w "health: %{http_code}\n" "$JUNCTIO_BASE_URL/health"
curl -s -o /dev/null -w "anonymous api: %{http_code}\n" "$JUNCTIO_BASE_URL/api/v1/namespaces"
SRV=$(curl -s -H "$AUTH" -H "$JSON" -d "{\"name\":\"everything$S\",\"transport\":\"stdio\",\"runtime\":\"bunx\",\"args\":[\"@modelcontextprotocol/server-everything\"]}" "$JUNCTIO_BASE_URL/api/v1/servers" | jq -r .id)
NS=$(curl -s -H "$AUTH" -H "$JSON" -d "{\"name\":\"agents$S\"}" "$JUNCTIO_BASE_URL/api/v1/namespaces" | jq -r .id)
curl -s -o /dev/null -w "attach server: %{http_code}\n" -H "$AUTH" -H "$JSON" -d "{\"serverId\":\"$SRV\"}" "$JUNCTIO_BASE_URL/api/v1/namespaces/$NS/servers"
curl -s -o /dev/null -w "create endpoint: %{http_code}\n" -H "$AUTH" -H "$JSON" -d "{\"slug\":\"demo$S\",\"namespaceId\":\"$NS\",\"authMode\":\"api_key\"}" "$JUNCTIO_BASE_URL/api/v1/endpoints"
EP=$(curl -s -H "$AUTH" "$JUNCTIO_BASE_URL/api/v1/endpoints" | jq -r ".[] | select(.slug==\"demo$S\") | .id")
KEY=$(curl -s -H "$AUTH" -H "$JSON" -d "{\"name\":\"agent\",\"endpointId\":\"$EP\"}" "$JUNCTIO_BASE_URL/api/v1/api-keys" | jq -r .token)
META='"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientInfo":{"name":"curl","version":"1.0.0"},"io.modelcontextprotocol/clientCapabilities":{}}'
mcp() { curl -s -H "Authorization: Bearer $KEY" -H "$JSON" -H "Accept: application/json, text/event-stream" -H "MCP-Protocol-Version: 2026-07-28" -H "Mcp-Method: $1" ${3:+-H} ${3:+"Mcp-Name: $3"} -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"$1\",\"params\":{$2$META}}" "$JUNCTIO_BASE_URL/mcp/demo$S"; }
for i in 1 2 3 4 5 6 7 8 9 10 11 12; do TOOL=$(mcp tools/list "" | jq -r '.result.tools[0].name // empty'); if [ -n "$TOOL" ]; then break; fi; sleep 5; done
echo "first tool: $TOOL"
mcp tools/call "\"name\":\"${TOOL%%__*}__echo\",\"arguments\":{\"message\":\"hello junctio\"}," "${TOOL%%__*}__echo" | jq -r '.result.content[0].text'
```

A fresh deploy prints `health: 200`, `anonymous api: 401`, `attach server: 200`, `create endpoint: 201`, the first tool name (the first run waits while `bunx` downloads the example server) and `Echo: hello junctio`.

## Why Deploy Junctio on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying Junctio on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.

- **Agent-ready** - generated admin token, contract block and one working script; no setup form.
- **One URL for every MCP server** - clients connect once instead of configuring each server.
- **State survives redeploys** - servers, endpoints and keys live in SQLite on a volume.
- **Locked from the first request** - admin setup needs the token, endpoints need an API key or OAuth.
- **Public HTTPS endpoint** - claude.ai and Claude Desktop connectors can reach it with the built-in OAuth server.

## Common Use Cases

- **One MCP endpoint for a team of coding agents** - Claude Code, Codex and Cursor share the same tool set and the same keys.
- **Remote access to local-only MCP servers** - run stdio servers on the gateway and reach them over HTTPS.
- **Per-client access control** - one API key per endpoint, a rate limit per minute, and a request log of every call.

## Dependencies for Junctio Hosting

- One Railway volume mounted at `/data`, created by the template.

### Deployment Dependencies

- [Junctio repository](https://github.com/k2so-dev/junctio)


## Similar templates

- [Chat Chat](https://railway.com/deploy/-WWW5r) — Chat Chat, your own unified chat and search to AI platform.
- [Weaviate](https://railway.com/deploy/weaviate-1) — Vector database with hybrid search and an API key-protected API
- [Möbius v0.1 Personal AI OS](https://railway.com/deploy/mobius-v01-personal-ai-os) — Self-hosted AI agent that builds and runs apps for you, with memory.

Open this page in a browser: https://railway.com/deploy/junctio-or-just-updated-mcp-gateway-one-
