outsystems-mcp-relay
outsystems-mcp-relay
Ein leichtgewichtiges, generisches stdio → Remote-MCP-Relay mit OAuth, plus einem RFC-9207-Issuer-Override für Remote-Server, deren veröffentlichte OAuth-Metadaten nicht mit der Autorisierungsantwort übereinstimmen. Keine Laufzeitabhängigkeiten. Eine einzige Datei.
stdio (your MCP client) ⇄ outsystems-mcp-relay ⇄ remote MCP server (Streamable HTTP)Warum es das gibt
Einige Remote-MCP-Bereitstellungen sind ein Reverse-Proxy vor Keycloak (das OutSystems Developer Cloud MCP-Gateway ist eines davon). Sie veröffentlichen OAuth-Metadaten, deren issuer die Proxy-URL ist (z. B. https://<tenant>/mcp), aber der Autorisierungsserver stempelt seinen echten Issuer in den iss-Parameter der Autorisierungsantwort (z. B. https://<tenant>/auth/realms/<realm>).
RFC-9207-konforme Clients müssen diese Abweichung ablehnen, daher schlägt der OAuth-Login auf jeder Plattform fehl — Claude Code, pi, Cursor, Codex, um nur einige zu nennen. Dieses Relay ermöglicht es dir, iss gegen den echten Backend-Issuer zu validieren, während alle anderen OAuth-Prüfungen streng bleiben. Für normale Server verhält es sich wie ein einfaches Relay.
Related MCP server: mcp-auth-proxy
Wann man es verwenden sollte
Probiere zuerst die offizielle direkte Verbindung aus — richte deine Plattform direkt auf die Remote-MCP-URL aus, ohne Relay dazwischen. Greife nur dann zu diesem Relay, wenn das mit dem obigen RFC-9207-Issuer-Mismatch-Fehler fehlschlägt.
Das existiert ausschließlich, um diesen einen serverseitigen Bug zu umgehen. Es macht nichts besser als der offizielle Weg, sobald der Bug nicht mehr vorhanden ist — also wenn OutSystems es mandantenweit behebt oder dein Mandant das Problem nie hatte, entferne das Relay und verbinde dich direkt. Das Relay teilt dir mit, wann das der Fall ist: Bei einem erfolgreichen Login prüft es, ob eine Issuer-Korrektur tatsächlich nötig war, und wenn nicht, gibt es einen Hinweis auf stderr aus. Warte nicht auf eine „Wird das noch gebraucht?"-Überprüfung — wenn du diesen Hinweis siehst, wechsle sofort zurück zur offiziellen direkten Verbindung.
Installation
Erfordert Node.js ≥ 20. Keine Abhängigkeiten — nur die Datei.
npm install -g outsystems-mcp-relay # recommended
# or, without a global install:
npx outsystems-mcp-relay <remote-url> ...Du musst dieses Repo nicht klonen, um das Relay zu nutzen. Installiere es über npm (oder verwende npx) und fertig. Klone es nur, wenn du den Quellcode (eine einzelne Datei mit ~500 Zeilen) prüfen oder dazu beitragen möchtest.
Verwendung
outsystems-mcp-relay <remote-url> [options]
--as-metadata-url <url> OAuth AS metadata URL (default: discover from remote-url)
--expected-issuer <url> Override the RFC 9207 expected issuer (the proxy fix)
--client-id <id> Pre-registered client id (skips dynamic registration)
--bearer <token> Static bearer token mode (skips OAuth entirely)
--force Ignore cached tokens and re-authenticate
--no-open Print the authorization URL instead of opening a browser
--help Show helpGenerisches Beispiel (normaler Remote-Server)
// mcp.json
{
"mcpServers": {
"my-remote": {
"command": "outsystems-mcp-relay",
"args": ["https://api.example.com/mcp"]
}
}
}OutSystems-Beispiel (Issuer-Mismatch)
{
"mcpServers": {
"outsystems": {
"command": "outsystems-mcp-relay",
"args": ["https://<tenant>.outsystems.dev/mcp"]
}
}
}Kein --expected-issuer nötig — das Relay erkennt automatisch den echten Autorisierungsserver-Issuer aus der Autorisierungs-Weiterleitung (Keycloak-Realm-Setups). Füge nur dann
--expected-issuer https://<tenant>.outsystems.dev/auth/realms/<realm-id> hinzu, wenn die automatische Erkennung fehlschlägt (ein Nicht-Keycloak-Server): Die OAuth-Fehlermeldung gibt den Realm aus — der empfangene Wert ist der zu verwendende Wert. Die automatische Erkennung übernimmt einen Cross-Origin-Kandidaten nur, wenn dessen Issuer durch die eigenen Metadaten des Realms bestätigt wird (über die Origin-Allowlist erreichbar); für einen wirklich separaten IdP-Host übergib --expected-issuer (oder --as-metadata-url, um ihn vorab auf die Allowlist zu setzen).
Beim ersten Aufruf öffnet das Relay einen Browser zur Anmeldung (oder gibt die URL mit --no-open aus). Tokens werden zwischengespeichert und automatisch aktualisiert.
Installation über eine KI (diesen Text einfügen)
Füge dies in Claude Code, pi, Cursor oder eine beliebige KI-Plattform ein:
Install the OutSystems MCP fix (outsystems-mcp-relay). The official OutSystems
MCP fails OAuth on every AI harness with an RFC 9207 issuer mismatch — a
server-side bug in the gateway's Keycloak setup.
Step 1: run `npm install -g outsystems-mcp-relay`.
Step 2: ask me for my OutSystems tenant hostname (something like
`mycompany.outsystems.dev`).
Step 3: when I tell you, replace the broken server:
`claude mcp remove outsystems`
`claude mcp add -s user --transport stdio outsystems -- outsystems-mcp-relay https://<my-tenant>/mcp`
(substitute my actual tenant. No other flags needed — the relay auto-detects
the real authorization-server issuer; if auto-detection can't, ask me to paste
the OAuth error and use its "received" URL as `--expected-issuer`.)
Step 4: tell me to restart Claude Code, then ask anything OutSystems-related.
The first tool call opens a browser for sign-in (or prints the URL with
`--no-open`).Claude-Code-Schnellstart (OutSystems-Issuer-Mismatch)
Der Fehler, den du siehst, sieht so aus:
Issuer mismatch in authorization response (RFC 9207):
expected "https://<tenant>.outsystems.dev/mcp",
received "https://<tenant>.outsystems.dev/auth/realms/<realm-id>"In einem Terminal (nicht innerhalb von Claude Code):
npm install -g outsystems-mcp-relay
# 1. remove the broken HTTP entry
claude mcp remove outsystems
# 2. add the relay as a local stdio server — no other flags needed: it
# auto-detects the real authorization-server issuer
claude mcp add -s user --transport stdio outsystems -- \
outsystems-mcp-relay \
https://<tenant>.outsystems.dev/mcpStarte dann Claude Code neu. Beim ersten OutSystems-Toolaufruf öffnet das Relay einen Browser zur Anmeldung (füge --no-open hinzu, wenn du die URL lieber selbst einfügen möchtest). Tokens werden zwischengespeichert, sodass spätere Sitzungen die Anmeldung überspringen. Überprüfe mit /mcp (der Server sollte verbunden sein) und einem einfachen „list my environments".
Du musst den Realm-Issuer nicht selbst ermitteln. Das Relay erkennt ihn automatisch aus der Autorisierungs-Weiterleitung. Falls die automatische Erkennung nicht funktioniert (ein Nicht-Keycloak-Server), gibt die Fehlermeldung den empfangenen Wert aus — dieser ist der
--expected-issuer-Wert.
So funktioniert es
Protokollagnostische Durchreichung: liest zeilenweise JSON-RPC von stdin, sendet jeden Frame unverändert per POST an den Remote-Server und schreibt die JSON-RPC-Antwort zurück nach stdout. Keine Tool-Semantik hier — funktioniert für Tools, Ressourcen, Prompts, alles.
Behandelt Streamable-HTTP-Details:
Mcp-Session-Id-Echo, direkte JSON-Antworten und202/text/event-stream-Antworten (SSE-Zusammenführung).OAuth: ermittelt die Autorisierungsserver-Metadaten, registriert dynamisch einen öffentlichen Client (PKCE S256), öffnet den Browser, validiert
stateundiss, tauscht den Code aus und aktualisiert Tokens bei 401.--expected-issuerlegt den Issuer fest, gegen denissvalidiert wird — die Lösung für Proxy/Keycloak-Mismatches.Anfragen werden serialisiert (keine verschachtelten Antworten auf stdout).
Sicherheit
RFC 9207 durchgesetzt:
isswird nur validiert, wenn der Autorisierungsserver es tatsächlich sendet (fehlt es = der AS implementiert RFC 9207 nicht, keine Prüfung; vorhanden = strikter String-Vergleich gegen den erwarteten Issuer).--expected-issuerermöglicht einen anderen erwarteten Wert — es deaktiviert niemals die Validierung.Origin-Allowlist: Das Relay kontaktiert nur die konfigurierte Remote-Origin (und eine explizit angegebene
--as-metadata-url). Weiterleitungen werden manuell durchlaufen und jeder Hop ist auf der Allowlist (307/308 erhalten den Request-Body; 301/302/303 wechseln gemäß HTTP-Semantik zu GET), undAuthorization/Cookiewerden entfernt, wenn eine Weiterleitung die Origin wechselt (wie beim nativen fetch). Kein SSRF.PKCE S256 + zufälliger
state(validiert) + Callback-Server nur auf localhost mit einem ephemeren Port.Protokolliert niemals Geheimnisse: Tokens und Autorisierungscodes erscheinen nie in der Ausgabe (alle Diagnosen gehen nach stderr; stdout transportiert nur Protokollnachrichten).
Tokens werden unter
~/.mcp-auth/outsystems-mcp-relay-<sha1(url)>.jsonmit0600-Berechtigungen gespeichert — die Ökosystem-Konvention (gleiche Speicherstruktur wiemcp-remote). OS-Keychain-Speicherung ist eine geplante Erweiterung; siehe Nicht-Ziele.
Testen
npm test # mock-server protocol test (passthrough, session-id, SSE, 401)
npm run test:e2e -- <remote-url> --expected-issuer <issuer> # real-tenant round tripFehlerbehebung
Symptom | Lösung |
| Normalerweise erledigt die automatische Erkennung das ohne zusätzliche Flags. Falls nicht, übergib die empfangene URL als |
| Das zwischengespeicherte Token ist abgelaufen und die Aktualisierung fehlgeschlagen. Führe es mit |
Browser öffnet sich nicht | Füge |
Dynamische Client-Registrierung schlägt fehl | Der Registrierungs-Endpunkt des Servers ist eingeschränkt (z. B. durch Keycloaks Trusted-Hosts-Richtlinie). Falls es das OutSystems-Proxy ist, sollte das nicht passieren; andernfalls registriere einen Client selbst und übergib |
Etwas anderes | Öffne ein Issue mit dem vollständigen Fehlertext (alle Diagnosen gehen nach stderr — schwärze alle Tokens). |
Nicht-Ziele (v1)
OS-Keychain-Token-Speicherung (derzeit Datei mit 0600-Berechtigungen)
Multi-Server-Aggregation / -Verwaltung (verwende dafür ein Gateway)
Vom Server initiierte Benachrichtigungs-Streams über die Durchreichung hinaus
Benutzerdefinierte CA-Flags
Lizenz
MIT
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
- AlicenseNot gradedqualityDmaintenanceLocal stdio proxy for Uno MCP Gateway that enables MCP clients without OAuth support to securely connect to authenticated remote servers.1MIT
- FlicenseNot gradedqualityDmaintenanceBridges stdio-based LLM harnesses to OAuth-protected remote MCP servers via Streamable HTTP, handling PKCE browser login and token refresh automatically.9
- FlicenseNot gradedqualityDmaintenanceEnables AI clients like Claude to interact with Cartena tools via MCP, supporting remote OAuth or local stdio authentication.
- AlicenseNot gradedqualityAmaintenanceA local stdio MCP server that authenticates to remote OAuth-protected MCP servers using the client_credentials grant, handling token acquisition and request forwarding.251Apache 2.0
Related MCP Connectors
Access Kernel's cloud-based browsers and app actions via MCP (remote HTTP + OAuth).
StremAI MCP: shared memory for AI coding agents. Connected agents can recall. OAuth + local stdio.
Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.
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/izambasiron/outsystems-mcp-relay'
If you have feedback or need assistance with the MCP directory API, please join our Discord server