Skip to main content
Glama
R0Wi

mcp-gateway

by R0Wi

MCP Gateway

Ein leichtgewichtiges, selbstgehostetes MCP-Aggregator-Gateway: ein öffentlicher MCP-Endpunkt vor beliebig vielen geschützten Backend-MCP-Servern, mit einem spezifikationskonformen OAuth-2.1-Autorisierungsserver, der dem MCP-Client zugewandt ist – das Element, das den meisten vorhandenen Gateways fehlt.

Claude Code / Claude.ai ──OAuth 2.1 (DCR/CIMD + PKCE)──▶ MCP Gateway ──own credentials──▶ GitHub MCP
                                                          │                              ▶ Microsoft Learn MCP
                                                          └── /mcp (Streamable HTTP)      ▶ …more backends

Entwickelt mit FastAPI + FastMCP, konfiguriert über eine einzelne YAML-Datei, speichert seinen Zustand in einer einzigen verschlüsselten SQLite-Datenbank und wird als ein kleiner, eigenständiger Container ausgeliefert – kein Reverse-Proxy erforderlich, man kann jedoch einen davor setzen, wenn TLS benötigt wird.

Funktionen

Client-seitig (MCP-Autorisierungsspezifikation, 2025-11-25):

  • OAuth-2.1-Autorisierungscode-Ablauf mit verpflichtendem PKCE (S256)

  • Dynamische Client-Registrierung (RFC 7591) unter /registerclaude mcp add funktioniert ohne vorab geteilte Zugangsdaten

  • Client-ID-Metadaten-Dokumente (CIMD) – HTTPS-URLs als Client-IDs, einschließlich private_key_jwt-Client-Authentifizierung, bekanntgegeben über client_id_metadata_document_supported: true

  • Autorisierungsserver-Metadaten (RFC 8414) + OIDC-Discovery-Alias

  • Metadaten der geschützten Ressource (RFC 9728); 401-Antworten enthalten WWW-Authenticate: Bearer resource_metadata="…", wie es der Connector von Claude verlangt

  • Ressourcenindikatoren (RFC 8707) werden akzeptiert und an die ausgegebenen Token gebunden

  • Kurzlebige, undurchschaubare Zugriffstokens, rotierende Refresh-Tokens, einmalig nutzbare Autorisierungscodes – alle nur gehasht gespeichert; Client-Datensätze im Ruhezustand verschlüsselt

  • Loopback-Weiterleitungs-URIs werden portunabhängig abgeglichen (die Claude-Code-CLI registriert einen Port und autorisiert mit einem anderen); Nicht-Loopback-URIs erfordern die exakte Registrierung

  • Schlanke Svelte-5-Benutzeroberfläche für Login und Zustimmung (eine einzige lokale Identität aus der Konfigurationsdatei)

Backend-seitig:

  • none – öffentliche Server (z. B. Microsoft Learn MCP)

  • bearer – statische Token-Injektion (Authorization: Bearer …, z. B. PATs)

  • headers – beliebige statische Header (API-Schlüssel)

  • oauth – vollwertiger OAuth-Client nach der MCP-Spezifikation: Metadaten-Discovery, CIMD, sofern das Upstream-AS dies unterstützt (das Gateway hostet sein eigenes Client-Metadaten-Dokument), DCR-Fallback, PKCE, automatisches Refresh. Einmal über den Browser verbunden; Token werden verschlüsselt (Fernet) in SQLite gespeichert.

  • Das Gateway-Token des Clients wird nie weiter übergeben an den Upstream (kein Token-Passthrough, wie von der Spezifikation gefordert); Backends sehen ausschließlich Zugangsdaten, die das Gateway hält.

Aggregation:

  • Tools/Ressourcen/Prompts werden pro Backend namespacediert: github_create_issue, msdocs_microsoft_docs_search, …

  • Live-Proxy über Streamable HTTP; ein heruntergefahrenes oder noch nicht verbundenes Backend entfernt nur seine eigenen Tools, anstatt das Gateway zu beeinträchtigen

  • Integriertes gateway_status-Tool

Related MCP server: MCP OAuth Test

Schnellstart

cp config.example.yaml config.yaml
$EDITOR config.yaml                                   # set public_url, users, backends
cp .env.example .env
$EDITOR .env                                           # set MCP_GATEWAY_ENCRYPTION_KEY (openssl rand -base64 32)
docker compose up -d

Das Gateway läuft eigenständig und lauscht auf :8000; docker compose übernimmt MCP_GATEWAY_ENCRYPTION_KEY automatisch aus .env. Platzieren Sie es hinter einem Reverse-Proxy Ihrer Wahl für TLS oder legen Sie den Port direkt offen.

Erzeugen Sie einen Passwort-Hash für die Konfigurationsdatei:

docker compose run --rm mcp-gateway mcp-gateway hash-password

Claude Code verbinden (CLI)

claude mcp add --transport http gateway https://mcp.example.com/mcp

Claude Code entdeckt den Autorisierungsserver des Gateaways, registriert sich über DCR oder seine CIMD-Client-ID und öffnet Ihren Browser: Melden Sie sich mit einem Benutzer aus config.yaml an, genehmigen Sie alles, fertig. Keine Token müssen eingefügt werden.

Claude.ai / Claude Code Web verbinden (benutzerdefinierter Connector)

Fügen Sie https://mcp.example.com/mcp als benutzerdefinierten Connector hinzu. Die Browser-Weiterleitung an https://claude.ai/api/mcp/auth_callback durchläuft denselben Login-/Zustimmungsablauf.

OAuth-Backends verbinden

Öffnen Sie https://mcp.example.com/ui/backends, melden Sie sich an und drücken Sie Verbinden bei jedem OAuth-Backend (z. B. GitHub MCP). Sie werden genau einmal zum Autorisierungsserver des Backends umgeleitet; anschließend erneuert das Gateway Token automatisch.

Konfiguration

Alles befindet sich in einer YAML-Datei (siehe config.example.yaml). Werte unterstützen ${ENV_VAR} beziehungsweise ${ENV_VAR:-default}-Erweiterung.

server:
  public_url: https://mcp.example.com   # behind your reverse proxy

auth:
  encryption_key: ${MCP_GATEWAY_ENCRYPTION_KEY}   # encrypts secrets at rest
  users:
    - username: admin
      password_hash: "$2b$12$…"          # mcp-gateway hash-password
  access_token_expiry_seconds: 3600
  refresh_token_expiry_seconds: 2592000

storage:
  path: /data/gateway.db                 # SQLite; the only state

backends:
  github:                                # → tools namespaced github_*
    url: https://api.githubcopilot.com/mcp/
    auth:
      type: oauth
      # GitHub's authorization server supports neither CIMD nor DCR, so
      # register a GitHub OAuth App and provide its credentials directly:
      client_id: ${GITHUB_OAUTH_CLIENT_ID}
      client_secret: ${GITHUB_OAUTH_CLIENT_SECRET}
  microsoft-docs:                        # → tools namespaced microsoft-docs_*
    url: https://learn.microsoft.com/api/mcp
    auth: { type: none }
  something-with-a-pat:
    url: https://example.com/mcp
    auth: { type: bearer, token: "${SOME_PAT}" }

Das Hinzufügen eines Backends ist reine Konfiguration – keine Codeänderungen.

Backend-Authentifizierungsreferenz

Typ

Felder

Verhalten

none

keine Zugangsdaten gesendet

bearer

token

Authorization: Bearer <token> bei jeder Anforderung

headers

headers: {Name: value}

statische Header (API-Schlüssel usw.)

oauth

scopes, prefer_dcr, client_id, client_secret

vollwertiger OAuth-Client: CIMD → DCR-Fallback, PKCE, Refresh, verschlüsselter Speicher

Bei oauth-Backends hostet das Gateway sein eigenes Client-ID-Metadaten-Dokument unter <public_url>/oauth/client-metadata.json und verwendet es als Client-ID, sobald der Upstream-AS CIMD-Unterstützung bewirbt (dann ist eine HTTPS-public_url erforderlich). Andernfalls wird die Dynamische Client-Registrierung (DCR) verwendet. Wenn nicht der das Upstream-AS keines von beiden unterstützt (z. B. der von GitHub), setzen Sie client_id (und client_secret, falls die App vertraulich ist), um einen vorregistrierten OAuth-Client zu verwenden – CIMD/DCR werden dann vollständig übersprungen.

Logging

Das Gateway protokolliert nach stdout/stderr (docker logs, docker compose logs -f), on standard INFO: Start/Herunterfahren, Konfigurationsübersicht, Anmeldeversuche, OAuth-Autorisierung-/Einwilligung/Token-Ausgabe, Backend-Verbindung/Trennung sowie den Mount-Status der Backends. DEBUG fügt feinkörniger Details hinzu (Client-Konstruktion, Token-Rotation, CIMD-Aktualisierung, Haushaltsführung des Speichers). Zu keiner Protokollstufe werden jemals Zugangsdaten oder Token protokolliert.

Legen Sie die Stufe über die Umgebungsvariable MCP_GATEWAY_LOG_LEVEL fest (debug, info, warning, error oder critical):

# .env (picked up by docker compose)
MCP_GATEWAY_LOG_LEVEL=debug
# or inline
docker compose run --rm -e MCP_GATEWAY_LOG_LEVEL=debug mcp-gateway

docker-compose.yml übergibt diese Variable jetzt bereits an die Entiät; wenn keine gesetzt ist, wird standardmäßig info verwendet.

Außerhalb von Docker funktioniert --log-level bei mcp-gateway run genauso und hat Vorrang vor der Umgebungsvariable:

mcp-gateway run -c config.yaml --log-level debug

Endpunkte

Pfad

Zweck

/mcp

MCP-Endpunkt (Streamable-Web)

/.well-known/oauth-protected-resource[/mcp]

Metadaten der geschützten Ressource (RFC 9728)

/.well-known/oauth-authorization-server

Autorisierungsserver-Metadaten (RFC 8414) + OIDC-Alias

/authorize, /token, /register, /revoke

OAuth-2.1-Endpunkte (PKCE, DCR, Widerruf)

/ui/authorize

Login / Zustimmung (Svelte 5)

/ui/backends

Backend-Verbindungsstatus / verbinden / trennen

/oauth/client-metadata.json

eigener CIMD-Dokument des Gateways (Upstream-Strecke)

/oauth/connect/<backend>, /oauth/callback

Upstream-OAuth-Verbindungsablauf

/healthz

Liveness-Check

Sicherheitshinweise

  • PKCE (S256) ist verpflichtend; Autorisierungscodes sind einmalig nutzbar und verfallen nach 5 Minuten.

  • Refresh-Tokens rotieren bei jeder Verwendung (Anforderung für öffentliche Clients in OAuth 2.1).

  • Zugriffs-, Refresh-Tokens und Autorisierungscodes werden ausschließlich als SHA-256-Hashes gespeichert.

  • Registrierte Client-Datensätze und Upstream-Zugangsdaten werden im Ruhezustand mit Fernet verschlüsselt (auth.encryption_key; Passphrasen werden mit scrypt und pro Datenbank Salt abgeleitet).

  • Der Zustimmungsbildschirm nennt den Client und das exakte Umleitungsziel und warnt bei Loopback-Weiterleitungen (gemäß CIMD-Vorgaben zur Vermeidung von Localhost-Impersonation).

  • Tokens, die an MCP-Clients ausgegeben werden, werden niemals an Backends weitergeleitet; Backend-Zugangsdaten erreichen nie MCP-Clients.

  • Sitzungen sind signiert (itsdangerous), HttpOnly, SameSite=Lax, Secure bei HTTPS.

  • Zugangsdaten werden nicht protokolliert.

Entwicklung

uv venv && uv pip install -e ".[dev]"     # or: pip install -e ".[dev]"
(cd ui && npm install && npm run build)   # build the Svelte UI
pytest                                    # 35 tests incl. full e2e OAuth flows
mcp-gateway run -c config.yaml

Die Testsuite startet echte Gateways (und eine zweite Instanz, die als OAuth-geschützter Upstream dient) und durchläuft vollständige DCR/CIMD- und PKCE-Abläufe über HTTP.

Architektur

  • src/mcp_gateway/oauth_server.py – der client-zugewandte OAuth-AS. Er baut auf den Autorisierungsserver-Handlern der MCP-SDK und dem CIMD-Manager von FastMCP auf, statt Protokollcode von Hand zu schreiben; das Gateway ergänzt SQLite-Persistenz, den Login-/Zustimmungs-Transaktions Flow und die Richtlinie für Token-Ausgabe/-Rotation.

  • src/mcp_gateway/upstream.py – Backend-Clients. OAuth-Backends verwenden den offiziellen OAuthClientProvider des SDK (Discovery, CIMD/DCR, Refresh) mit verschlüsseltem SQLite-Tokenspeicher und einem über Browser gesteuerten Verbindungsablauf.

  • src/mcp_gateway/gateway.py – FastMCP-Server; jedes Backend wird als Live-Proxy unter seinem Namespace eingebunden.

  • src/mcp_gateway/app.py / web.py – FastAPI-App: JSON-API für die UI, Upstream-Callback, CIMD-Dokument, statische Svelte-App; die FastMCP-App (MCP-Endpunkt + OAuth-Routen + Well-Known) wird im Root-Verzeichnis gemounted.

  • ui/ – Svelte 5 + Vite SPA (Anmeldung, Zustimmung, Backends).

Bewusst als Ein-Instanz-Design (SQLite + In-Memory-Verbindungsabläufe). Läuft eigenständig; Sie können es hinterbringen vorhandenen Reverse-Proxy für TLS-Terminierung und sichern eine einzige Datei.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

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
    B
    maintenance
    Multi-tenant MCP server with OAuth 2.1 authorization, enabling tenant-scoped tool access and audit logging.
  • A
    license
    A
    quality
    C
    maintenance
    A federated MCP gateway that consolidates multiple plain-HTTP backends into a single, OAuth-protected MCP server, enabling agents to access diverse tools through one endpoint with centralized authentication and audit.
    5
    10
    MIT

View all related MCP servers

Related MCP Connectors

  • Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.

  • MCP Hub: AI service discovery, per-user OAuth, and multi-service workflow orchestration

  • An authenticated remote MCP server for user-owned devices and one-shot capability invocation.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/R0Wi/mcp-gateway'

If you have feedback or need assistance with the MCP directory API, please join our Discord server