MCP Gateway
MCP Gateway — Phase 1 (KLIP, schreibgeschützt)
Ein einzelner sicherer Dienst, der autorisierten Energi-Up-Mitarbeitern ermöglicht, KLIP in natürlicher Sprache über Claude abzufragen, ohne die Anwendung zu öffnen. Streng schreibgeschützt.
Bereitstellungsziel (PRD Q3, inzwischen geschlossen): <gateway-hostname> -> <gateway-public-ip>
(ECS-MCP, ap-southeast-5). Beachten Sie, dass der Hostname mcp-gw lautet, nicht mcp.example.com,
wie in den v0.9-Dokumenten angenommen; das PRD/TSD sollte entsprechend aktualisiert werden.
Dokumente: PRD v0.9 · TSD v0.9 · Implementierungsleitfaden · Design-Review · Bereitstellungs-Runbook
1. Fixierte Versionen (T-1)
Die MCP-Spezifikationsrevision und die SDK-Version sind hier fixiert. Wo die SDK-eigene Dokumentation von den Designdokumenten abweicht, gewinnt das SDK — es definiert die exakte API.
Komponente | Fixiert | Anmerkungen |
| 1.30.0 (exakt, ohne Caret) | Veröffentlicht am 27. Juli 2026. Liefert den OAuth-AS, den Streamable-HTTP-Transport und |
MCP-Protokollrevision | 2025-11-25 implementiert; Drahtformat kompatibel mit | Revision |
Node.js | 22 LTS ( | |
TypeScript | 5.9.3, | |
express | 5.2.1 | Gegenüber dem 4.x des TSD angehoben: Das SDK hängt von |
zod | 4.4.3 | Gegenüber dem 3.x des TSD angehoben: Die Typdefinitionen des SDK zielen auf zod 4. Beachten Sie, dass |
jose | 6.2.9 | RS256-Gateway-Tokens. |
| 2.1.0 | Ersetzt |
axios | 1.19.0 | KLIP-Client, hinter der Methoden-Sperre. |
pg | 8.23.0 | |
PostgreSQL | 16 (Container) | |
nginx | nginx.org mainline | Konfiguration in |
Related MCP server: Snowflake MCP Server
2. Aufbau
src/
core/ config, logger, db, audit, cache, rateLimit, semaphore, migrate, errors
adapters/klip/ routes(APPENDIX A) · fields(APPENDIX A) · client(guard) · session · paginate · normalize
tools/klip/ 9 tool definitions + shared parameter plumbing
mcp/ server, envelope, runner
auth/ keys, hub(OIDC RP), users, clients, tokens, provider, loginPage
http/ app, consent(Hub + break-glass), health, origin, clientIp
migrations/ idempotent SQL (001 schema, 002 Hub OIDC)
deploy/ nginx config, backup sidecar
test/ 120 tests + mock KLIP and mock Hub fixturesSchichtungsregel (T-3): tools → adapters → core. Nichts importiert http/ außer dem
Einstiegspunkt. Die gesamte Geschäftsnormalisierung liegt in adapters/klip/normalize.ts, das
nichts importiert und daher isoliert unit-testbar ist.
3. Authentifizierung — Downstream Hub OIDC
Pilotbenutzer melden sich mit Downstream Hub (OIDC) an. Das Gateway bleibt der
Autorisierungsserver, mit dem Claude spricht; der Hub ist ein Schritt innerhalb seines eigenen
/authorize-Flusses.
Wir verwenden bewusst nicht den ProxyOAuthServerProvider des SDK. Ein Proxy würde
Claude ein Hub-Token aushändigen, was die RFC-8707-Audience-Bindung brechen, Claude
umfassendere Hub-Scopes als klip:read geben und die Token-Ausstellung unserer Kontrolle
entziehen würde, sodass der S8-Notausschalter laufende Sitzungen nicht mehr ungültig machen könnte.
Claude ──/authorize──▶ gateway ──302──▶ Downstream Hub ──302──▶ /authorize/hub/callback
│ │
│ validate id_token (sig/iss/aud/nonce) │
│ check the pilot ALLOWLIST │
◀──────────────────────────────────────────────┘
└──302 code──▶ Claude ──/token──▶ gateway token (klip:read)Authentifizierung ist keine Autorisierung. Der Hub beweist, wer jemand ist; die
users-Tabelle entscheidet, ob sie den Connector verwenden dürfen. Phase 1 verwendet ein
gemeinsames KLIP-Dienstkonto, sodass jeder zugelassene Benutzer alles lesen kann, was MCP_READONLY
lesen kann (Review H8) — die Pilotmitgliedschaft ist die Datenzugriffskontrolle. Ein Hub-Konto,
das nicht auf der Liste steht, erhält eine 403, und das <= 15-Limit wird durch user:add durchgesetzt.
Im Ablauf laufen zwei PKCE-Austausche; verwechseln Sie diese nicht. Claudes eigenes
code_challenge schützt den Abschnitt Claude→Gateway (vom SDK behandelt); ein separater
Verifier, den das Gateway serverseitig aufbewahrt, schützt den Abschnitt Gateway→Hub.
Welcher Hub-Client? Der eigene des Gateways — nicht der von KLIP
Registrieren Sie einen neuen OIDC-Client für das MCP Gateway. Verwenden Sie nicht die Hub-Registrierung von KLIP wieder, auch wenn KLIP bereits im Test-DWS-Hub registriert ist.
Der Hub berührt nur eine der beiden Vertrauensgrenzen:
Grenze | Anmeldedaten | Hub beteiligt? |
Claude → Gateway (welcher Mensch fragt) | eigener Hub-Client des Gateways + die Pilot-Allowlist | ja |
Gateway → KLIP (Daten lesen) |
| nein — PRD §7 schließt dies explizit aus |
Die Wiederverwendung des KLIP-Clients bricht die erste Grenze auf konkrete Weise. Das Gateway
validiert die aud des ID-Tokens gegen seine eigene HUB_CLIENT_ID; die gemeinsame Nutzung
der KLIP-Client-ID bedeutet, dass ein während einer KLIP-Anmeldung ausgestelltes ID-Token vom
Gateway akzeptiert würde, was die Confused-Deputy-Form darstellt. Getrennte Clients sind es,
die die beiden vertrauenden Parteien unterscheidbar machen. Es hält außerdem die Redirect-URI-Allowlists,
Client-Geheimnisse, Rotationspläne, Hub-SSO-Audit-Einträge und Deaktivierungsschalter
unabhängig — das Deaktivieren des Hub-Clients des Connectors darf die KLIP-Anmeldung nicht beeinträchtigen.
Keines davon erfordert Änderungen auf der KLIP-Seite. K1–K4 bleiben unberührt.
Zwei Hub-Instanzen, zwei Registrierungen
Registrieren Sie das Gateway separat in jedem Hub und kombinieren Sie sie mit dem passenden KLIP:
Stufe | KLIP_ENV | HUB_ISSUER | Client |
4–6 (Build, Staging-UAT) |
| Test-DWS-Hub | Gateway-Client im Test-Hub |
7+ (Produktionsumstellung) |
| Produktions-Hub | ein separater Gateway-Client im Produktions-Hub |
Die Zuordnung wird beim Start erzwungen, denn ein Fehler in einer Richtung ist gefährlich statt nur unsauber:
KLIP_ENV=production+ ein Test-HUB_ISSUER→ das Gateway weigert sich zu starten. Jeder, der ein Test-Hub-Konto erstellen kann, würde sonst auf echte kommerzielle Daten zugreifen.KLIP_ENV=staging+ der Produktions-HUB_ISSUER→ warnt und fährt fort.
hub:check gibt die erkannte Zuordnung aus, sodass die Umstellung überprüfbar ist:
pairing: KLIP staging <-> Hub testingWas DWS Hub erfordert (es ist kein Standard-OIDC)
Gemäß Docs/SSO-TARGET-APP-INTEGRATION.md. Vier davon weichen von den Standardeinstellungen ab, die
eine OIDC-Client-Bibliothek annimmt, und drei würden sofort fehlschlagen:
DWS Hub | |
Client-Typ | public, PKCE S256 — |
Discovery |
|
Token-Body | JSON; formularcodiert liefert |
Scopes | nur |
| in der Token-Anfrage obligatorisch und bytegenau |
Daher wird HUB_DISCOVERY_URL explizit konfiguriert, HUB_CLIENT_SECRET ist optional,
und HUB_TOKEN_BODY standardmäßig auf json gesetzt, mit einem einmaligen Fallback auf Formular bei
unsupported_grant_type (mit Protokollierung, welches funktioniert hat, damit es fixiert werden kann).
Einrichtung
Registrieren Sie das Gateway als OIDC-Client im Hub mit der Redirect-URI
<PUBLIC_URL>/authorize/hub/callback. Es ist ein public client — fragen Sie nicht nach einem Geheimnis.Tragen Sie
HUB_ISSUER,HUB_DISCOVERY_URLundHUB_CLIENT_IDin/opt/mcp/.envein.Verifizieren Sie, bevor ein Pilotbenutzer es versucht:
docker compose exec -T gateway node dist/cli.js hub:checkDies gibt die zu registrierende Redirect-URI aus, führt Discovery aus und warnt, wenn der Hub kein S256-PKCE bewirbt. Das Gateway prüft Discovery auch beim Start und meldet es in
/healthzalshub_oidc.Fügen Sie Pilotbenutzer hinzu (keine Passwörter — der Hub authentifiziert sie):
docker compose exec -T gateway node dist/cli.js user:add someone@example.com "Their Name"
Das Notfall-Konto
Genau ein lokales Passwortkonto ist zulässig, für den Fall, dass der Hub ausgefallen oder fehlkonfiguriert ist:
docker compose exec -T gateway node dist/cli.js user:add-break-glass it-emergency@example.comEs ist hinter einem Hinweis auf der Anmeldeseite verborgen, erzwingt eine Passwortänderung bei
der ersten Verwendung, und jede Anmeldung darüber wird mit break_glass: true bei hoher
Schwere protokolliert. Ein Hub-authentifizierter Benutzer kann den Passwortpfad überhaupt nicht
nutzen, sodass das Abschalten des Hubs kein Weg ist, auf ein Passwort zurückzugreifen, das niemand gesetzt hat.
Setze BREAK_GLASS_ENABLED=false, sobald der Hub-Pfad in der Produktion bewiesen ist, um die Passwort-Oberfläche vollständig zu entfernen.
Optionale Gruppen-Gate — nicht verfügbar auf DWS Hub
HUB_REQUIRED_GROUP fügt eine zweite Prüfung gegen einen Gruppen-Anspruch hinzu. DWS Hub stellt keinen aus (es bewirbt nur openid profile email), daher würde die Festlegung jeden Benutzer ablehnen. hub:check warnt, wenn du es tust. Die Zulassungsliste in der users-Tabelle bleibt die Autorisierungskontrolle.
IdP-initiiertes Login
Der Hub kann einen Benutzer direkt von seiner Dashboard-Kachel zu einem Callback pushen. Das kann für einen Connector nicht funktionieren: Der Callback existiert, um eine Autorisierungsanfrage abzuschließen, die Claude gestartet hat. Wenn also jemand ohne eine solche ankommt, bleibt nichts übrig, gegen das ein Code ausgestellt werden kann. Das Gateway erkennt dies und meldet „start from Claude instead", anstatt als „sign-in expired" zu scheitern.
4. Schnellstart (lokal)
npm ci
docker run -d --name mcpgw-devdb -e POSTGRES_DB=gateway -e POSTGRES_USER=gateway \
-e POSTGRES_PASSWORD=devpassword -p 127.0.0.1:55432:5432 postgres:16-alpine
cp .env.example .env.dev # then edit: PUBLIC_URL=http://localhost:8787, DATABASE_URL=...55432...
npx tsx test/fixtures/mockKlip.ts 5099 & # mock KLIP, behaves like the real one
set -a; . ./.env.dev; set +a
npm run migrate
npx tsx src/index.tsErstelle einen Pilotbenutzer (funktioniert mit TTY-Eingabe oder Pipeline-Eingabe):
printf 'a-strong-password\na-strong-password\n' | npx tsx src/cli.ts user:add you@example.com "Your Name"5. Tests
npm testSuite | Abdeckung |
| Die Incoterm × Null-Matrix, kg→MT, Rundungsreihenfolge, negative offene Menge, WIB-Zeitstempel |
| Erschöpfende Methode/Pfad-Tabelle für T-6, Traversal- und Herkunfts-Ausweichpfade |
| T-5-Umschlag, Kürzung von |
| Ein begrenzter Abruf veröffentlicht |
| Alle 9 Tools gegen Mock-KLIP; kein Nicht-GET erreicht KLIP; 401 erneutes Anmelden; |
| RFC-8707-Zielgruppenbindung: nur die kanonische Ressource dieses Servers wird akzeptiert |
| S5-Redaktion — aggressiv bei Zeichenketten, inert bei Zahlen |
| Hub-OIDC gegen einen Mock-Provider: Discovery-Aussteller-Mismatch, fremder Signaturschlüssel, falscher Aussteller/Zielgruppe, abgelaufenes Token, fehlende und wiedergegebene Nonce, keine E-Mail-Anspruch |
|
|
| Produktions-KLIP hinter einem Test-Hub weigert sich zu starten; die normalen Paarungen tun dies nicht |
| Token-Endpunkt-Authentifizierungsmethode aus Discovery gewählt, einschließlich Nur-POST- und Public-Client-Hubs |
| DWS Hub exakt modelliert: |
Der Mock-Hub ist ein funktionierender Mini-OIDC-Provider — echtes Discovery-Dokument, echte JWKS, echte RS256-ID-Tokens und PKCE-Verifikation am Autorisierungscode — mit jedem Drehknopf, der nötig ist, um ein schlechtes Token zu fälschen, denn die negativen Fälle sind der Punkt.
Die Mock-KLIP-Fixture reproduziert absichtlich die Eigenheiten des echten Systems: Kilogramm als MT bezeichnet, gemischtsprachige Status, ein Incoterm außerhalb der Standard-Vier, Null-Mengen, eine übererfüllte Lieferung, ein limit, das stillschweigend auf 100 geklemmt wird, und ein Vertragskommentar, der eine Prompt-Injection-Nutzlast trägt.
6. Bereitstellung
Vollständige host-spezifische Anleitung, mit der echten IP, Hostname und Sicherheitsgruppen-Tabelle: deploy/RUNBOOK.md.
# on ECS-MCP
cd /opt/mcp && git pull
docker compose build gateway && docker compose up -d
curl -fsS http://127.0.0.1:8787/healthzAdmin-CLI — beachte, dass dies innerhalb des Containers läuft, denn der Host installiert nur Docker und hat kein Node.js:
docker compose exec -T gateway node dist/cli.js user:list
docker compose exec -T gateway node dist/cli.js audit:summary --days 7
docker compose exec -T gateway node dist/cli.js audit:export --from 2026-08-01 --to 2026-09-01 --out /tmp/audit.csv
docker compose exec -T gateway node dist/cli.js routes:verify # probes KLIP, reports Appendix A gapsKill-Schalter (S8) — Ziel unter 5 Minuten:
docker compose exec -T gateway node dist/cli.js tokens:revoke-all --reason "incident 2026-xx"
docker compose stop gatewayNotfallzugriff, wenn der App-Container nicht gesund ist:
docker compose exec -T db psql -U gateway -d gateway -c "UPDATE oauth_tokens SET revoked_at=now() WHERE revoked_at IS NULL;"7. Anhang A ist ein hartes Tor
src/adapters/klip/routes.ts und src/adapters/klip/fields.ts enthalten jeden KLIP-Pfad, Abfrageparameternamen, Seitenlimit-Obergrenze, Antwortfeldnamen und Enum-Wert, den der Adapter abhängt. Jeder Eintrag ist derzeit unverifiziert.
Das Tor ist ausführbar, nicht bürokratisch: Mit KLIP_ENV=production weigert sich der Prozess zu starten, solange irgendeine Route unverifiziert ist. Führe routes:verify gegen Staging aus, protokolliere die Ergebnisse, setze verified: true pro Route und enums.verified = true.
Zwei Felder sind wichtiger als der Rest:
maxLimit— das größtelimit, das KLIP tatsächlich akzeptiert. Wenn es stillschweigend auf 100 klemmt, verwandelt einKLIP_PAGE_SIZEvon 1000 eine Seite in zehn und bricht das Latenzziel.enums.*— die kanonischen Status- und Incoterm-Werte. Alles, was nicht zugeordnet ist, wird aus den Summen ausgeschlossen, mit einem Datenqualitätshinweis, niemals standardmäßig übernommen.
8. Abweichungen von TSD v0.9
Jede stammt aus dem Design-Review und ist an ihrer Aufrufstelle kommentiert.
# | Änderung | Warum |
B3 | Origin nur abgelehnt, wenn vorhanden und ungültig | Die Spezifikation verlangt 403 nur für eine vorhandene und ungültige Origin. Claude ruft den Connector Server-zu-Server auf und sendet möglicherweise keine; das Ablehnen einer fehlenden Origin würde jeden Tool-Aufruf mit 403 beantworten. |
B4 |
| RFC 8707 Audience-Bindung. |
B5 | Zustandsloser Transport; Identität aus dem Token pro Anfrage | Revision 2026-07-28 entfernte Protokollsitzungen. T-4 ist durch Konstruktion erfüllt — es gibt keine Sitzung, die gekapert werden könnte. |
B6 | Kill-Switch führt | Der Host hat kein Node.js, daher könnte |
B7 | nginx ist die Anti-Missbrauchs-Basis; pro-Benutzer-Limitierung mit Schlüssel auf dem OAuth- | Der gesamte Datenverkehr kommt aus dem gemeinsamen Egress-Bereich von Anthropic, daher würde eine IP-basierte Limitierung die gesamte Pilotphase in einen einzigen Bucket stecken. |
H1 | OAuth basierend auf dem SDK- | Das SDK liefert den AS, einschließlich Widerruf und Standard-Ratenbegrenzung. Nur Speicherung und Benutzerauthentifizierung sind unsere. |
H2 | Downstream-Hub-OIDC ist der Login-Pfad, mit einem Break-Glass-Lokalkonto | Aus Phase 2 vorgezogen. Der Hub authentifiziert; die Benutzertabelle bleibt die Pilot-Allowlist. |
H3 | nginx-Allowlist-Gerüst für Anthropics | Anthropic veröffentlicht stabile Egress-Bereiche und empfiehlt Allowlisting; |
H4 | Abgeschnittene Ergebnisse veröffentlichen | Vier verschiedene Wege zu einer selbstsicheren falschen Zahl. |
H5 | Kurzer TTL-Cache; Seiten 2..N parallel abgerufen; Seitengröße auf | Zehn sequenzielle Round-Trips können P95 ≤ 5 s nicht erfüllen. |
H6 | Ein 9. Tool hinzugefügt, | Ohne dieses würde ein falsch geschriebener Pflanzname eine leere Menge zurückgeben, die als „nichts ist offen" gelesen wird. |
H7 |
| Der angegebene hartcodierte String „KLIP production" hätte jede Staging-UAT-Antwort behaupten lassen, Produktion zu sein. |
H9 |
| Aufbewahrung durch Partitions-Drop ist das Einzige, was der Append-only-Trigger erlaubt; U5s Export hatte keine Implementierung; Client-IPs wären alle als 127.0.0.1 protokolliert worden. |
H10 | Backup-Sidecar, Container-Healthcheck, | Im TSD spezifiziert, aber im Leitfaden nie implementiert, daher wäre es zum Go-Live nicht vorhanden gewesen. |
— | Unbekannte Tool-Parameter abgelehnt über | PRD 8.1 verlangt Ablehnung; ein einfaches |
— | Tools geben | Typisierte Daten statt JSON in Prosa — weniger Übertragungsfehler, was M1 misst. |
9. Noch offen
Anhang-A-Abgleich (P1) — blockiert die Produktion, beim Start erzwungen.
KLIP-seitige K1–K4 — die
MCP_READONLY-Rolle, dassvc-mcp-Konto, die Sicherheitsgruppenregel.Off-Host-Backup-Synchronisierung und ein getesteter Restore — der Sidecar schreibt nur lokal.
Echte Unternehmens-Egress-CIDRs in
deploy/nginx/mcp.conf, dann die beiden auskommentiertenreturn 403-Zeilen aktivieren.Lasttest bei der NFR von 30 gleichzeitigen Benutzern.
Hub-Client-Registrierung — die eigene des Gateways, zuerst im Test-DWS-Hub:
HUB_ISSUER, Client-ID und -Geheimnis, mit Redirect-URI<PUBLIC_URL>/authorize/hub/callback, Hub-seitig registriert. Die E-Mail- und Gruppen-Claim-Namen des Hubs bestätigen, dannhub:checkausführen. Eine zweite, separate Registrierung im Produktions-Hub ist in Stufe 7 erforderlich.Entscheiden, ob
HUB_REQUIRED_GROUPgesetzt werden soll und obBREAK_GLASS_ENABLED=falsegesetzt werden soll, nachdem der Hub-Pfad in der Produktion bewiesen ist.
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
- FlicenseAqualityBmaintenanceEnables read-only querying of the gong-nl-db Postgres database through natural language via Claude Desktop.9
- AlicenseNot gradedqualityDmaintenanceEnables natural language queries against Snowflake Gold-layer tables through Claude Desktop, allowing users to ask business questions in plain English without SQL knowledge.MIT
- AlicenseNot gradedqualityCmaintenanceGives Claude live access to your Observe tenant, enabling natural language queries about errors, logs, and metrics without writing OPAL pipelines.17MIT
- FlicenseNot gradedqualityBmaintenanceEnables natural language interaction with Kintone data via Claude, allowing listing apps, field definitions, querying and modifying records.
Related MCP Connectors
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.
Connect Claude to Fathom meeting recordings, transcripts, and summaries
Garmin data in Claude & ChatGPT via the Garmin Health API. OAuth sign-in, no password sharing.
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/dwsitproject-hub/MCP-Gateway'
If you have feedback or need assistance with the MCP directory API, please join our Discord server