MCP Gateway
MCP Gateway — フェーズ 1(KLIP、読み取り専用)
認可されたEnergi-Upスタッフが、アプリケーションを開かずにClaudeを通じて自然言語でKLIPに問い合わせできるようにする、単一のセキュアなサービス。厳密に読み取り専用。
デプロイ先(PRD Q3、現在はクローズ済み): <gateway-hostname> -> <gateway-public-ip>
(ECS-MCP、ap-southeast-5)。ホスト名はmcp-gwであり、v0.9ドキュメントが想定していたmcp.example.comではないことに注意。PRD/TSDはこれに合わせて更新すべきである。
ドキュメント: PRD v0.9 · TSD v0.9 · 実装ガイド · 設計レビュー · デプロイランブック
1. 固定バージョン(T-1)
MCP仕様リビジョンとSDKバージョンはここで固定する。SDK自身のドキュメントが設計ドキュメントと矛盾する場合、SDKが優先される — SDKが正確なAPIを定義するからである。
コンポーネント | 固定バージョン | 備考 |
| 1.30.0(完全一致、キャレットなし) | 2026年7月27日公開。OAuth AS、Streamable HTTPトランスポート、 |
MCPプロトコルリビジョン | 2025-11-25を実装。ワイヤー形状は | リビジョン |
Node.js | 22 LTS( | |
TypeScript | 5.9.3、 | |
express | 5.2.1 | TSDの4.xから引き上げ: SDKは |
zod | 4.4.3 | TSDの3.xから引き上げ: SDKの型定義はzod 4を対象としている。 |
jose | 6.2.9 | RS256ゲートウェイトークン。 |
| 2.1.0 |
|
axios | 1.19.0 | KLIPクライアント。メソッドガードの背後にある。 |
pg | 8.23.0 | |
PostgreSQL | 16(コンテナ) | |
nginx | nginx.org mainline | 設定は |
Related MCP server: Snowflake MCP Server
2. レイアウト
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 fixturesレイヤリングルール(T-3): tools → adapters → core。エントリポイント以外でhttp/をインポートするものはない。すべてのビジネス正規化はadapters/klip/normalize.tsにあり、これは何もインポートしないため、単体でユニットテスト可能である。
3. 認証 — 下流Hub OIDC
パイロットユーザーはDownstream Hub(OIDC)でサインインする。ゲートウェイはClaudeが通信する認可サーバーのままであり、Hubはその独自の/authorizeフロー内の1ステップである。
SDKのProxyOAuthServerProviderは意図的に使用しない。プロキシすると、ClaudeにHubトークンが渡され、RFC 8707のオーディエンスバインディングが壊れ、Claudeにklip:readより広いHubスコープが付与され、トークン発行が当社の管理外に移るため、S8キルスイッチがライブセッションを無効化できなくなる。
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)認証は認可ではない。 Hubは誰であるかを証明し、usersテーブルがコネクタを使用できるかどうかを決定する。フェーズ1では共有のKLIPサービスアカウントを1つ使用するため、承認されたすべてのユーザーはMCP_READONLYが読み取れるすべてを読み取れる(レビューH8)— パイロットメンバーシップがデータアクセス制御である。リストにないHubアカウントは403を受け取り、<= 15の上限はuser:addによって強制される。
フローでは2つのPKCE交換が実行される。混同しないこと。Claude自身のcode_challengeはClaude→ゲートウェイ区間を保護し(SDKが処理)、ゲートウェイがサーバー側で保持する別のベリファイアがゲートウェイ→Hub区間を保護する。
どのHubクライアントか? ゲートウェイ自身のもの — KLIPのものではない
MCP Gateway用に新しいOIDCクライアントを登録すること。KLIPのHub登録を再利用しないこと。KLIPがテスト用DWS Hubにすでに登録されている場合でも同様である。
Hubは2つの信頼境界のうち1つにのみ関与する:
境界 | 資格情報 | Hub関与? |
Claude → ゲートウェイ(どの人間が質問しているか) | ゲートウェイ自身のHubクライアント + パイロット許可リスト | あり |
ゲートウェイ → KLIP(データの読み取り) | KLIPの | なし — PRD §7が明示的に除外している |
KLIPのクライアントを再利用すると、最初の境界が具体的な形で壊れる。ゲートウェイはIDトークンのaudを自身のHUB_CLIENT_IDに対して検証する。KLIPのクライアントIDを共有すると、KLIPログイン中に発行されたIDトークンがゲートウェイに受け入れられることになり、これは混乱した代理人(confused deputy)の形である。クライアントを分離することで、2つの証明書利用者(relying party)が区別可能になる。また、リダイレクトURI許可リスト、クライアントシークレット、ローテーションスケジュール、Hub SSO監査エントリ、無効化スイッチも独立して維持される — コネクタのHubクライアントをオフにしてもKLIPログインを停止させてはならない。
これにはKLIP側の変更は一切不要である。K1〜K4は影響を受けない。
2つのHubインスタンス、2つの登録
ゲートウェイを各Hubに個別に登録し、対応するKLIPとペアリングする:
ステージ | KLIP_ENV | HUB_ISSUER | クライアント |
4〜6(ビルド、ステージングUAT) |
| テスト用DWS Hub | テスト用Hubのゲートウェイクライアント |
7以降(本番カットオーバー) |
| 本番Hub | 本番Hubの別のゲートウェイクライアント |
ペアリングは起動時に強制される。間違った方向で設定すると、単なる不手際ではなく危険だからである:
KLIP_ENV=production+ テスト用HUB_ISSUER→ ゲートウェイは起動を拒否する。 テストHubアカウントを作成できる者は誰でも、実際の商用データに到達できてしまう。KLIP_ENV=staging+ 本番HUB_ISSUER→ 警告して続行する。
hub:checkは検出したペアリングを出力するため、カットオーバーは検証可能である:
pairing: KLIP staging <-> Hub testingDWS Hubが要求するもの(バニラOIDCではない)
Docs/SSO-TARGET-APP-INTEGRATION.mdによる。これらのうち4つはOIDCクライアントライブラリが想定するデフォルトと異なり、3つは完全に失敗する:
DWS Hub | |
クライアントタイプ | パブリック、PKCE S256 — |
ディスカバリ |
|
トークンボディ | JSON。フォームエンコードは |
スコープ |
|
| トークンリクエストで必須であり、バイト単位で完全一致である |
したがって、HUB_DISCOVERY_URLは明示的に設定され、HUB_CLIENT_SECRETはオプションであり、HUB_TOKEN_BODYはデフォルトでjsonとなり、unsupported_grant_typeの場合にフォームへのワンショットフォールバックがある(どちらが機能したかをログに記録し、固定できるようにする)。
セットアップ手順
リダイレクトURI
<PUBLIC_URL>/authorize/hub/callbackでゲートウェイをHubのOIDCクライアントとして登録する。これはパブリッククライアントである — シークレットを要求しないこと。HUB_ISSUER、HUB_DISCOVERY_URL、HUB_CLIENT_IDを/opt/mcp/.envに配置する。パイロットユーザーが試す前に検証する:
docker compose exec -T gateway node dist/cli.js hub:checkこれにより、登録するリダイレクトURIが出力され、ディスカバリが実行され、HubがS256 PKCEを宣伝していない場合に警告する。ゲートウェイは起動時にもディスカバリをプローブし、
/healthzでhub_oidcとして報告する。パイロットユーザーを追加する(パスワードなし — Hubが認証する):
docker compose exec -T gateway node dist/cli.js user:add someone@example.com "Their Name"
非常用(ブレークグラス)アカウント
Hubがダウンしているか誤設定されている場合に使用するため、ローカルパスワードアカウントは正確に1つだけ許可される:
docker compose exec -T gateway node dist/cli.js user:add-break-glass it-emergency@example.comこれはログインページの開示の背後に隠されており、初回使用時にパスワード変更を強制し、それを通じたすべてのサインインは高重大度でbreak_glass: trueとして監査される。Hub認証ユーザーはパスワードパスをまったく使用できないため、Hubをオフにしても、誰も設定していないパスワードにフォールバックする方法にはならない。
Hub パスが本番で実証されたら、BREAK_GLASS_ENABLED=false に設定して、パスワードの攻撃面を完全に削除してください。
オプションのグループゲート — DWS Hub では利用不可
HUB_REQUIRED_GROUP は、groups クレームに対する2番目のチェックを追加します。DWS Hub は groups クレームを発行しません(openid profile email のみをアドバタイズします)。そのため、これを設定するとすべてのユーザーを拒否することになります。設定した場合、hub:check が警告します。users テーブルのパイロット許可リストが、引き続き認可の制御となります。
IdP 開始ログイン
Hub はダッシュボードのタイルからユーザーをコールバックに直接送り込むことができます。これはコネクタでは機能しません。コールバックは Claude が開始した認可リクエストを完了させるために存在するため、リクエストなしでコールバックに到達しても、コードを発行する対象が何もありません。ゲートウェイはこれを検出し、「サインイン期限切れ」として失敗する代わりに「Claude から開始してください」と表示します。
4. クイックスタート(ローカル)
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.tsパイロットユーザーを作成します(TTY またはパイプ入力を使用可能):
printf 'a-strong-password\na-strong-password\n' | npx tsx src/cli.ts user:add you@example.com "Your Name"5. テスト
npm testスイート | 内容 |
| インコターム × ステータス × null のマトリクス、kg→MT、丸め順序、マイナスの未達、WIB タイムスタンプ |
| T-6 の網羅的なメソッド/パステーブル、トラバーサルとオリジンエスケープ |
| T-5 エンベロープ、 |
| 境界付きフェッチは |
| モック KLIP に対する全9ツール、非 GET が KLIP に到達することは決してありません、401 再ログイン、 |
| RFC 8707 オーディエンスバインディング:このサーバーの正規リソースのみが受け入れられます |
| S5 リダクション — 文字列には積極的、数値には作用しません |
| モックプロバイダーに対する Hub OIDC:ディスカバリーの発行者不一致、外部署名キー、誤った issuer/audience、期限切れトークン、nonce の欠落とリプレイ、email クレームなし |
|
|
| テスト用 Hub の背後にある本番 KLIP は起動を拒否します。通常のペアリングは起動を拒否しません |
| ディスカバリーから選択されるトークンエンドポイントの認証方式(post-only およびパブリッククライアントの Hub を含む) |
| DWS Hub を正確にモデル化: |
モック Hub は、実際のディスカバリードキュメント、実際の JWKS、実際の RS256 ID トークン、認可コードに対する PKCE 検証を備えた動作するミニ OIDC プロバイダーであり、不正なトークンを偽造するために必要なあらゆる設定項目を備えています。ネガティブケースこそが重要なのです。
モック KLIP フィクスチャは、実システムの癖を意図的に再現しています:MT とラベル付けされたキログラム、複数言語のステータス、標準の4つ以外のインコターム、null 数量、過剰納品された契約、暗黙に 100 にクランプされる limit、そしてプロンプトインジェクションペイロードを含む契約備考です。
6. デプロイ
実際の IP、ホスト名、セキュリティグループの表を含む、ホスト固有の完全な手順: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/healthz管理 CLI — これはコンテナ内で実行されることに注意してください。ホストには Docker のみがインストールされ、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 gapsキルスイッチ(S8) — 目標は5分未満:
docker compose exec -T gateway node dist/cli.js tokens:revoke-all --reason "incident 2026-xx"
docker compose stop gatewayアプリコンテナが異常な場合のブレークグラス:
docker compose exec -T db psql -U gateway -d gateway -c "UPDATE oauth_tokens SET revoked_at=now() WHERE revoked_at IS NULL;"7. 付録Aはハードゲートです
src/adapters/klip/routes.ts と src/adapters/klip/fields.ts には、アダプターが依存するすべての KLIP パス、クエリパラメータ名、ページサイズ上限、レスポンスフィールド名、enum 値が保持されています。現在、すべてのエントリは未検証です。
このゲートは事務的なものではなく、実行時に強制されます。KLIP_ENV=production の場合、いずれかのルートが未検証の間、プロセスは起動を拒否します。ステージングに対して routes:verify を実行し、結果を記録し、ルートごとに verified: true を設定し、enums.verified = true を設定します。
他のどのフィールドよりも重要な2つのフィールド:
maxLimit— KLIP が実際に受け入れる最大のlimit。暗黙に 100 にクランプされる場合、KLIP_PAGE_SIZEが 1000 だと1ページが10ページになり、レイテンシ目標を破ります。enums.*— 正規のステータス値とインコターム値。マッピングされていないものは、デフォルト値にされることはなく、データ品質メモ付きで合計から除外されます。
8. TSD v0.9 からの逸脱
それぞれは設計レビューに由来し、その呼び出し箇所でコメントされています。
# | 変更内容 | 理由 |
B3 | Origin は存在するが無効な場合のみ拒否 | 仕様では、存在するが無効な Origin に対してのみ 403 が要求される。Claude はコネクタをサーバー間で呼び出し、Origin を送信しない場合がある。存在しない場合を拒否すると、すべてのツール呼び出しが 403 になる。 |
B4 |
| RFC 8707 のオーディエンスバインディング。PRM ドキュメントに |
B5 | ステートレスなトランスポート。ID はリクエストごとにトークンから取得 | リビジョン 2026-07-28 でプロトコルセッションが削除された。T-4 は構造上満たされる。乗っ取るセッションが存在しないため。 |
B6 | キルスイッチは | ホストに Node.js がないため、 |
B7 | nginx が不正利用対策の最低限の防御。OAuth の | すべてのトラフィックは Anthropic の共有 egress レンジから到着するため、IP をキーにした制限ではパイロット全体が 1 つのバケットに入ってしまう。 |
H1 | SDK の | SDK には AS(認可サーバー)が同梱されており、失効とデフォルトのレート制限も含まれる。ストレージとユーザー認証のみが当社の実装である。 |
H2 | 下流の Hub OIDC がログインパスであり、緊急用のローカルアカウントが 1 つある | Phase 2 から前倒しされた。Hub が認証を行い、users テーブルはパイロットの許可リストのままである。 |
H3 | Anthropic の | Anthropic は安定した egress レンジを公開し、許可リスト化を推奨している。 |
H4 | 切り詰められた結果は | 自信を持って誤った数値に至る 4 つの異なる経路。 |
H5 | 短い TTL のキャッシュ。2..N ページ目は並行して取得。ページサイズは | 10 回のシーケンシャルなラウンドトリップでは P95 ≤ 5 秒を満たせない。 |
H6 | 9 番目のツール | これがないと、誤入力されたプラント名が空のセットを返し、「outstanding は何もない」と読めてしまう。 |
H7 |
| 指定されたハードコードの「KLIP production」文字列では、ステージングの UAT のすべての応答が本番であると主張することになっただろう。 |
H9 |
| パーティション削除による保持管理は、追記専用トリガーが許可する唯一の方法である。U5 のエクスポートには実装がなかった。クライアント IP はすべて 127.0.0.1 として記録されていただろう。 |
H10 | バックアップサイドカー、コンテナのヘルスチェック、 | TSD では指定されていたがガイドでは実装されておらず、本番稼働時には存在しなかっただろう。 |
— | 未知のツールパラメータは | PRD 8.1 は拒否を要求している。通常の |
— | ツールは | 散文に埋め込まれた JSON ではなく型付きデータ。転記エラーが減り、それが M1 が測定するものである。 |
9. 未解決事項
付録 A の整合性確認(P1)— 本番稼働をブロックし、起動時に強制される。
KLIP 側の K1–K4 —
MCP_READONLYロール、svc-mcpアカウント、セキュリティグループルール。ホスト外へのバックアップ同期とテスト済みのリストア — サイドカーはローカルのみに書き込む。
deploy/nginx/mcp.confの実際の企業 egress CIDR。その後、コメントアウトされた 2 つのreturn 403行を有効にする。30 同時ユーザーのキャパシティ NFR での負荷テスト。
Hub クライアント登録 — ゲートウェイ自身のものを、まずテスト用 DWS Hub に登録:
HUB_ISSUER、クライアント ID とシークレット、リダイレクト URI<PUBLIC_URL>/authorize/hub/callbackを Hub 側に登録する。Hub の email と groups クレーム名を確認してからhub:checkを実行する。Stage 7 では、本番 Hub への 2 つ目の個別登録が必要である。HUB_REQUIRED_GROUPを設定するかどうか、および Hub パスが本番で実証された後にBREAK_GLASS_ENABLED=falseにするかどうかを決定する。
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