Skip to main content
Glama

MCP Gateway

A self-hosted control plane for Model Context Protocol servers. Define every MCP server you use in one place, manage them from a web GUI, and give your agents a single endpoint — per server or for a whole group of servers with namespaced tools.

 Claude Code · Claude Desktop · Cursor · VS Code · your agent
        │  Streamable HTTP  /mcp/servers/<id>   /mcp/groups/<id>      (+ API key)
        ▼
 ┌────────────────────── MCP Gateway ──────────────────────┐
 │  web GUI  ·  admin REST API  ·  sessions  ·  logs        │
 │  groups: namespaced tools  pg-analytics__execute_sql …   │
 │  upstream manager: start/stop, restart w/ backoff,       │
 │  health checks, idle stop, tool filters & renames        │
 └───────┬──────────────────┬──────────────────┬───────────┘
   stdio (npx/uvx/docker)   Streamable HTTP     legacy SSE
   Postgres, filesystem…    remote MCP servers  older servers

Scenario. An agent needs two Postgres databases. You add pg-analytics and pg-orders in the GUI (from the PostgreSQL (DBHub) template), put them in a group databases, and point the agent at http://gateway:8808/mcp/groups/databases. The agent sees pg-analytics__execute_sql and pg-orders__execute_sql; the gateway owns the processes, credentials, restarts and logs. A complete, runnable version lives in examples/postgres-scenario.

Features

  • Any upstream transport — stdio processes (npx, uvx, docker run, anything), Streamable HTTP and legacy SSE remotes with bearer/basic/header auth.

  • Lifecycle management — auto/lazy start, idle stop, restart with exponential backoff and a cap, health-check pings, startup/request/tool-call timeouts, captured stderr.

  • Groups — several servers behind one endpoint; tools and prompts namespaced (prefix__tool, . or -), or pass-through with conflict handling; per-member filters; combined instructions; implicit all group.

  • Tool policy — include/exclude globs, hide, rename and re-describe tools per server.

  • Full MCP proxying — tools, resources (+templates, subscriptions), prompts, completions, logging, progress, cancellation, list_changed propagation, and server→client sampling / elicitation / roots routed back to the originating session.

  • Downstream transports — Streamable HTTP (stateful with resumable streams, or stateless), legacy SSE, plus mcp-gateway-connect, a stdio bridge for clients such as Claude Desktop.

  • Security — API keys (hashed, scoped to servers/groups, expiring), admin token for the GUI/API, secret redaction, ${ENV} interpolation so secrets never have to be written to the config, DNS-rebinding protection, CORS allow-list.

  • GUI — dashboard, server catalog with 16 templates (Postgres ×3, MySQL, SQLite, filesystem, GitHub, Playwright, Context7, fetch, memory, …), tabbed editor with Test connection, tool explorer with Try it, resources/prompts browsers, live logs, metrics, per-client connect snippets, sessions, settings, import/export (Claude Desktop / Cursor / VS Code mcpServers files).

Related MCP server: Multi-MCP Hub

Screenshots

The dashboard — running servers, groups, active sessions and a live event feed:

MCP Gateway dashboard

The server catalog, with transport, status, tool counts and restart counts at a glance:

Server list

A server's detail view — runtime and endpoint facts, plus the tool explorer for calling tools straight from the GUI:

Server detail and tool explorer

Quick start

Requirements: Node.js ≥ 20 (plus npx/uvx/docker for whichever upstream servers you run).

git clone <this repo> mcp-gateway && cd mcp-gateway
npm install
npm run build
npm start                     # → http://127.0.0.1:8808

Then in the GUI: Servers → Add server → PostgreSQL (DBHub) → paste a DSN → Test connectionCreate server. Open the server's Connect tab and copy the snippet for your client, e.g.

claude mcp add --transport http pg-analytics http://127.0.0.1:8808/mcp/servers/pg-analytics

Development mode (Vite with hot reload on :5173, gateway on :8808): npm run dev.

Docker

docker compose up -d --build              # GUI on http://localhost:8808, data in ./data

The image ships node/npx, uvx and git, so npm- and Python-based MCP servers can be launched inside the container. Set GATEWAY_ADMIN_TOKEN in the environment when the port is reachable by others. To pre-load a configuration, mount a file and set GATEWAY_SEED_CONFIG=/path/to/config.json — it is copied to the data volume on first start.

How it fits together

Concept

What it is

Server

One upstream MCP server definition: transport, lifecycle, tool policy, forwarding options. Endpoint /mcp/servers/<id>.

Group

An ordered set of servers exposed as one virtual MCP server with namespaced tools/prompts and merged resources. Endpoint /mcp/groups/<id>. The implicit group all contains every enabled server.

API key

Bearer token for /mcp/* (hashed at rest, scoped to servers/groups, optional expiry). Enforced when Require API key is on.

Session

One connected downstream client (Streamable HTTP or SSE). Visible and closable in the GUI.

Admin token

Protects the GUI and /api/*. Set via GATEWAY_ADMIN_TOKEN or Settings.

Configuration is a single JSON file (data/config.json, mode 0600, atomic writes, .bak kept) — see docs/CONFIG.md for every field. Client setup for each tool is in docs/CLIENTS.md; the full design is in docs/SPEC.md. The GUI also has a built-in Docs page (/docs, next to Settings) that walks through how the gateway works and how to add, customize and connect servers.

CLI

mcp-gateway serve [--host 127.0.0.1] [--port 8808] [--data-dir ./data] [--config <file>] [--public-url <url>] [--log-level info]
mcp-gateway import <file> [--format gateway|mcpServers] [--mode merge|replace]    # into the config file (restart to apply)
mcp-gateway export [--format gateway|mcpServers] [--secrets] [--out <file>]
mcp-gateway hash-token <token>                                                     # sha256 for settings.auth.adminTokenHash
mcp-gateway connect <url> [--api-key K] [--header 'Name: v'] [--sse]              # stdio ⇄ HTTP bridge
mcp-gateway-connect <url> …                                                        # same bridge as a standalone package (@mcp-gateway/connect)

Environment: GATEWAY_HOST, GATEWAY_PORT, GATEWAY_DATA_DIR, GATEWAY_CONFIG, GATEWAY_ADMIN_TOKEN, GATEWAY_PUBLIC_URL, GATEWAY_LOG_LEVEL, GATEWAY_REQUIRE_API_KEY, GATEWAY_WEB_DIR, GATEWAY_SEED_CONFIG (Docker). Precedence: CLI flags > environment > config.json > defaults.

Endpoints

Path

Purpose

POST/GET/DELETE /mcp/servers/:id · /mcp/groups/:id

Streamable HTTP MCP endpoints

GET /mcp/servers/:id/sse + POST …/messages?sessionId= (same for groups)

legacy HTTP+SSE

GET /api/health

liveness (unauthenticated)

/api/servers, /api/groups, /api/keys, /api/sessions, /api/logs, /api/settings, /api/templates, /api/config/{export,import}, /api/connect/:kind/:id

admin REST API (JSON; Authorization: Bearer <admin token> when set)

GET /api/events

Server-Sent Events feed (status, logs, sessions, metrics) used by the GUI

/

the web GUI

The complete route list with request/response shapes is in docs/SPEC.md §7.

Security notes

  • With no admin token the GUI/API are open: keep the default loopback bind, or set GATEWAY_ADMIN_TOKEN.

  • Turn on Require API key before exposing /mcp beyond localhost; scope keys to the servers/groups each agent needs.

  • Secrets: prefer ${VAR} references over literal values; values under secret-looking keys are redacted in API responses and exports (?secrets=1 / with secrets export includes them).

  • Put a TLS-terminating reverse proxy in front for anything internet-facing (needed for the Anthropic API MCP connector).

  • The gateway executes the commands you configure — anyone with admin access can run arbitrary processes on the host.

Development

npm run dev          # gateway (tsx watch) + Vite dev server
npm run typecheck    # all workspaces
npm test             # vitest: shared unit tests, server integration tests (real stdio/HTTP fixtures), bridge tests
npm run build        # server bundle (esbuild), connect bundle, web (vite)

Layout: packages/shared (zod config schema, DTOs, templates, naming helpers — browser-safe), packages/server (Express 5 + @modelcontextprotocol/sdk: upstream manager, proxy server, sessions, REST/MCP routes, CLI), packages/web (React 19 + Vite), packages/connect (stdio bridge), examples/postgres-scenario (docker-compose demo).

Limitations / roadmap

  • OAuth to upstream servers is not implemented (use bearer/basic/header auth); OAuth for downstream clients is not implemented (API keys instead).

  • Resources are not namespaced in groups — URIs are routed to their owning server; identical URIs across members resolve to the first member.

  • No rate limiting; put a reverse proxy in front if you need it.

  • Single-process, in-memory sessions and logs (a restart drops sessions; clients re-initialize).

License

Apache License 2.0 — see LICENSE and NOTICE.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Aggregates multiple MCP servers behind a single, secure endpoint with unified tool/resource discovery, OAuth authentication, and resilient request routing. Enables users to manage and interact with multiple MCP backends through one centralized interface with load balancing and circuit breakers.
    2
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    A centralized gateway and router that integrates multiple MCP servers into a single endpoint with built-in policy enforcement and secret management. It features a Web GUI for managing tool access, audit logs, and multi-environment configurations across various sub-servers.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Aggregates multiple MCP servers into a single HTTP endpoint with tool namespacing, dashboard, and REST API for management.
    16 npm
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Aggregates multiple MCP servers into a single unified endpoint with hot-plugging, multi-protocol support, and management via web and CLI.
    26 npm
    -