outsystems-mcp-relay
{"type": "text"}# outsystems-mcp-relay
軽量で汎用的な stdio → リモート MCP リレー。OAuth 対応、さらにリモートサーバーの公開 OAuth メタデータが認可応答と一致しない場合の RFC 9207 発行者オーバーライド機能を備えています。ランタイム依存関係ゼロ。単一ファイル。
stdio (your MCP client) ⇄ outsystems-mcp-relay ⇄ remote MCP server (Streamable HTTP)なぜこれが存在するのか
一部のリモート MCP デプロイメントは Keycloak の前段にリバースプロキシを置いています(OutSystems Developer Cloud MCP ゲートウェイもその一つ)。それらは issuer がプロキシ URL(例: https://<tenant>/mcp)である OAuth メタデータを公開しますが、認可サーバーは認可応答の iss パラメータに実際の発行者(例: https://<tenant>/auth/realms/<realm>)をスタンプします。
RFC 9207 準拠のクライアントはその不一致を拒否しなければならないため、Claude Code、pi、Cursor、Codex など、あらゆるハーネスで OAuth ログインが失敗します。このリレーは、他のすべての OAuth チェックを厳格に保ちながら、iss を実際のバックエンド発行者に対して検証できるようにします。通常のサーバーに対しては、単なるリレーとして動作します。
Related MCP server: mcp-auth-proxy
いつこれを使うべきか
まず公式の直接接続を試してください — ハーネスをリモート MCP URL に直接向け、リレーを挟まないでください。上記の RFC 9207 発行者不一致エラーで失敗した場合にのみ、このリレーに手を伸ばしてください。
これは、そのサーバー側のバグを回避するためだけに存在します。バグが存在しない場合、公式パスより優れたことは何もありません。したがって、OutSystems がテナント全体で修正した場合、またはテナントがそもそもこの問題に遭遇しなかった場合は、リレーをやめて直接接続してください。リレーは、そのような場合にそれを通知します。ログイン成功時に、発行者補正が実際に必要だったかどうかを確認し、不要だった場合は stderr にその旨のメモを出力します。「まだ必要か」のレビューを待つ必要はありません。そのメモが表示されたら、すぐに公式の直接接続に戻してください。
インストール
Node.js ≥ 20 が必要です。依存関係なし — ファイルだけです。
npm install -g outsystems-mcp-relay # recommended
# or, without a global install:
npx outsystems-mcp-relay <remote-url> ...このリポジトリをクローンする必要はありません。 npm からインストールするか(または npx を使用)、それで完了です。ソース(単一の ~500 行のファイル)を監査するため、または貢献する場合にのみクローンしてください。
使い方
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 help一般的な例(通常のリモートサーバー)
// mcp.json
{
"mcpServers": {
"my-remote": {
"command": "outsystems-mcp-relay",
"args": ["https://api.example.com/mcp"]
}
}
}OutSystems の例(発行者不一致)
{
"mcpServers": {
"outsystems": {
"command": "outsystems-mcp-relay",
"args": ["https://<tenant>.outsystems.dev/mcp"]
}
}
}--expected-issuer は不要です — リレーは認可リダイレクト(Keycloak レルム設定)から実際の認可サーバー発行者を自動検出します。自動検出が失敗した場合(Keycloak 以外のサーバー)にのみ、--expected-issuer https://<tenant>.outsystems.dev/auth/realms/<realm-id> を追加してください。OAuth エラーにはレルムが表示されます — その受信値が使用する値です。自動検出は、発行者がレルム自身のメタデータ(オリジン許可リスト経由で到達可能)によって確認された場合にのみ、クロスオリジンの候補を採用します。真に別の IdP ホストの場合は、--expected-issuer(または事前に許可リストに追加する --as-metadata-url)を渡してください。
最初の呼び出しで、リレーはサインイン用のブラウザを開きます(--no-open で URL を表示)。トークンはキャッシュされ、自動的に更新されます。
AI アシスタント経由でインストール(これを貼り付け)
Claude Code、pi、Cursor、または任意の AI ハーネスに貼り付け:
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 クイックスタート(OutSystems 発行者不一致)
表示されるエラーは次のようになります:
Issuer mismatch in authorization response (RFC 9207):
expected "https://<tenant>.outsystems.dev/mcp",
received "https://<tenant>.outsystems.dev/auth/realms/<realm-id>"ターミナルで(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/mcpその後、Claude Code を再起動します。最初の OutSystems ツール呼び出しで、リレーはサインイン用のブラウザを開きます(URL を貼り付けたい場合は --no-open を追加)。トークンはキャッシュされるため、以降のセッションではサインインがスキップされます。/mcp(サーバーが接続されているはず)と簡単な「環境一覧」で確認してください。
レルム発行者を探す必要はありません。 リレーは認可リダイレクトから自動検出します。自動検出ができない場合(Keycloak 以外のサーバー)、エラーメッセージに表示されます。エラー内の受信値が
--expected-issuerの値です。
仕組み
プロトコル非依存のパススルー: stdin から改行区切りの JSON-RPC を読み取り、各フレームをそのままリモートサーバーに POST し、JSON-RPC 応答を stdout に書き込みます。ツールのセマンティクスはここにはありません — ツール、リソース、プロンプト、何でも動作します。
Streamable HTTP の詳細を処理:
Mcp-Session-Idエコー、直接 JSON 応答、202/text/event-stream応答(SSE 再アセンブリ)。OAuth: 認可サーバーのメタデータを検出し、パブリッククライアント(PKCE S256)を動的登録し、ブラウザを開き、
stateとissを検証し、コードを交換し、401 でトークンを更新します。--expected-issuerはissが検証される発行者を設定します — プロキシ/Keycloak 不一致の修正です。リクエストは直列化されます(stdout にインターリーブされた応答はありません)。
セキュリティ
RFC 9207 を強制:
issは、認可サーバーが実際に送信する場合にのみ検証されます(不在 = AS が RFC 9207 を実装していない、チェックなし。存在 = 期待される発行者との厳密な文字列一致)。--expected-issuerは異なる期待値を選択します — 検証を無効にすることはありません。オリジン許可リスト: リレーは設定されたリモートオリジン(および明示的に指定された
--as-metadata-url)にのみ接続します。リダイレクトは手動で追跡され、すべてのホップが許可リストに登録されます(307/308 はリクエストボディを保持。301/302/303 は HTTP セマンティクスに従って GET にダウングレード)。また、リダイレクトがオリジンを変更する場合、Authorization/Cookieは削除されます(ネイティブ fetch と一致)。SSRF はありません。PKCE S256 + ランダムな
state(検証済み)+ エフェメラルポート上の localhost のみのコールバックサーバー。シークレットをログに記録しない: トークンと認可コードが出力に表示されることはありません(すべての診断は stderr に。stdout はプロトコルメッセージのみ)。
トークンは
~/.mcp-auth/outsystems-mcp-relay-<sha1(url)>.jsonに0600パーミッションで保存されます — エコシステムの慣例(mcp-remoteと同じストア形状)。OS キーチェーンストレージは計画中の拡張です。非目標を参照してください。
テスト
npm test # mock-server protocol test (passthrough, session-id, SSE, 401)
npm run test:e2e -- <remote-url> --expected-issuer <issuer> # real-tenant round tripトラブルシューティング
症状 | 修正 |
| 通常は自動検出がフラグなしで処理します。できない場合は、受信 URL を |
長時間アイドル後の | キャッシュされたトークンの有効期限が切れ、更新に失敗しました。 |
ブラウザが開かない |
|
動的クライアント登録が失敗する | サーバーの登録エンドポイントが制限されています(例: Keycloak の Trusted-Hosts ポリシー)。OutSystems プロキシの場合は発生しないはずです。それ以外の場合は、自分でクライアントを登録し、 |
その他 | 完全なエラーテキスト(すべての診断は stderr に出力されます — トークンは編集してください)を添えて issue を開いてください |
非目標(v1)
OS キーチェーントークンストレージ(当面は 0600 パーミッションのファイル)
マルチサーバー集約/管理(その場合はゲートウェイを使用)
パススルーを超えたサーバー開始通知ストリーミング
カスタム CA フラグ
ライセンス
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