mcp-gateway
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 backendsEntwickelt 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
/register—claude mcp addfunktioniert ohne vorab geteilte ZugangsdatenClient-ID-Metadaten-Dokumente (CIMD) – HTTPS-URLs als Client-IDs, einschließlich
private_key_jwt-Client-Authentifizierung, bekanntgegeben überclient_id_metadata_document_supported: trueAutorisierungsserver-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 verlangtRessourcenindikatoren (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 -dDas 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-passwordClaude Code verbinden (CLI)
claude mcp add --transport http gateway https://mcp.example.com/mcpClaude 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 |
| – | keine Zugangsdaten gesendet |
|
|
|
|
| statische Header (API-Schlüssel usw.) |
|
| 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-gatewaydocker-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 debugEndpunkte
Pfad | Zweck |
| MCP-Endpunkt (Streamable-Web) |
| Metadaten der geschützten Ressource (RFC 9728) |
| Autorisierungsserver-Metadaten (RFC 8414) + OIDC-Alias |
| OAuth-2.1-Endpunkte (PKCE, DCR, Widerruf) |
| Login / Zustimmung (Svelte 5) |
| Backend-Verbindungsstatus / verbinden / trennen |
| eigener CIMD-Dokument des Gateways (Upstream-Strecke) |
| Upstream-OAuth-Verbindungsablauf |
| 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,Securebei 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.yamlDie 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 offiziellenOAuthClientProviderdes 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.
This server cannot be installed
Maintenance
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
- FlicenseNot gradedqualityNot gradedmaintenanceAggregates 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
- FlicenseNot gradedqualityBmaintenanceMulti-tenant MCP server with OAuth 2.1 authorization, enabling tenant-scoped tool access and audit logging.
- AlicenseAqualityCmaintenanceA 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.510MIT
- AlicenseNot gradedqualityCmaintenanceAuthenticating reverse proxy for MCP servers providing credential isolation, OAuth2 token management, and composite tool aggregation.BSD Zero Clause
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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