mcp-oauth-test
FastMCP OIDC Server
これは FastMCP を使用して作成された、OIDC ログインで保護された MCP server です。FastMCP の OIDCProxy を使用しており、MCP クライアントはサーバーが公開する OAuth メタデータを通じて認証を完了し、実際のログインと token exchange は QA OIDC provider に転送されます。
現在は QA MGT OpenAPI に接続されており、trainee、注文、商品、顧客、キャンパス採用、国際採用に関連する MCP tools が生成されています。
OIDC discovery アドレスはデフォルトで次のように設定されています:
https://auth-qa.drillinsight.com/.well-known/openid-configuration認証の準備
まず auth-qa.drillinsight.com で OAuth アプリを登録し、次のコールバックアドレスをホワイトリストに追加してください:
http://localhost:8000/auth/callback他のアドレスにデプロイする場合は、http://localhost:8000 を BASE_URL の値に置き換えてください。コールバックアドレスは FastMCP の BASE_URL と完全に一致している必要があります。
ローカルでの実行
cp .env.example .env
# 编辑 .env,至少填写 OIDC_CLIENT_ID 和 OIDC_CLIENT_SECRET
uv sync
uv run mcp-oidc-serverモジュールを直接実行することもできます:
uv run python -m oidc_mcp_server.serverサービスはデフォルトで http://127.0.0.1:8000 をリッスンします。MCP クライアントが他のマシンやコンテナで実行されている場合は、クライアントからアクセス可能な BASE_URL と適切な HOST(例:0.0.0.0)を設定してください。
Claude Code プラグイン
リポジトリにはプライベートな Claude Code marketplace と MCP プラグインが含まれています:
.claude-plugin/marketplace.json
└── plugins/mcp-oauth-test/
├── .claude-plugin/plugin.json
├── .mcp.json
└── README.mdプラグインは Claude Code をすでにデプロイ済みのリモート MCP サービスに接続するだけのもので、ローカルで Python サービスを起動することはありません。開発テスト時には直接ロードできます:
claude --plugin-dir ./plugins/mcp-oauth-testプラグインは開発環境の MCP Server に固定接続されています:
https://api-mcp-oauth-dev.beaconfireinc.com/mcpプライベート marketplace からインストールすることもできます:
/plugin marketplace add /path/to/mcp-oauth-test
/plugin install mcp-oauth-test@authsome-internal現在の marketplace のルートディレクトリはリポジトリのルートです。この marketplace は会社のプライベート GitHub リポジトリに保持し、公開 marketplace にはコミットしないでください。共有環境では HTTPS アドレスを使用し、会社の IdP と MCP Server 側で会社ユーザーのみにアクセスを制限してください。
OIDCProxy を使用する理由
上流の auth-qa.drillinsight.com は DCR や CIMD をサポートする必要はありません。OIDCProxy はまさにこのようなシナリオのためにあります:
ChatGPT ── MCP OAuth / CIMD ──> FastMCP OIDCProxy
│
└── 固定 client_id/client_secret ──> auth-qa.drillinsight.com上流に事前登録が必要なのは FastMCP という OAuth アプリのみで、${BASE_URL}/auth/callback を設定します。ChatGPT が使用する CIMD は FastMCP プロキシ層で処理され、上流の OAuth server には転送されません。
ChatGPT CIMD 設定
ChatGPT でカスタム MCP を作成する際、OAuth 詳細設定の「クライアント登録」では次を選択してください:
客户端标识元数据文档(CIMD)現在の ChatGPT コネクタが生成する情報は次のとおりです:
CIMD Client ID / 客户端元数据 URL:
https://chatgpt.com/oauth/0Buhw3sHVv1-/client.json
ChatGPT Callback URL:
https://chatgpt.com/connector/oauth/0Buhw3sHVv1-CIMD URL 自体が、ChatGPT が FastMCP OAuth プロキシにアクセスする際に使用する client_id です。これは上流の auth-qa.drillinsight.com に登録する必要はなく、登録すべきでもありません。
このプロジェクトには 2 層の異なる OAuth Client ID が存在します:
OAuth リンク |
| 設定場所 |
ChatGPT → FastMCP OIDCProxy |
| ChatGPT が自動提供、CIMD 選択後は手動入力不要 |
FastMCP OIDCProxy → |
| MCP Server の |
対応するデータフローは次のとおりです:
ChatGPT
│ client_id=https://chatgpt.com/oauth/0Buhw3sHVv1-/client.json
▼
FastMCP OIDCProxy
│ client_id=app_74a4b555-5b87-4212-9dda-d584fa78caf8
▼
auth-qa.drillinsight.comMCP Server の環境変数設定:
OIDC_CLIENT_ID=app_74a4b555-5b87-4212-9dda-d584fa78caf8
OIDC_CLIENT_SECRET=<上游 OAuth Server 颁发的客户端密钥>上流の OAuth Server は、その app_... アプリに対して FastMCP のコールバックアドレスのみを設定すればよいです:
https://heroic-verbally-crawdad.ngrok-free.app/auth/callbackChatGPT のコールバックアドレス https://chatgpt.com/connector/oauth/... を上流の OAuth Server に設定しないでください。このアドレスは FastMCP プロキシ層が認証完了後に使用します。
認証開始時、正常なログにはまず ChatGPT の CIMD Client ID が表示されるはずです:
CIMD document fetched and validated
GET /authorize?client_id=https://chatgpt.com/oauth/.../client.json ... 302その後、FastMCP が app_74a4b555-... を使用して上流の OAuth Server にリダイレクトします。
MCP クライアント設定
MCP アドレスを次のように設定します:
http://localhost:8000/mcpFastMCP は次の認証 discovery アドレスを提供します:
http://localhost:8000/.well-known/oauth-authorization-server
http://localhost:8000/.well-known/oauth-protected-resource/mcpクライアントはこれらの MCP/OAuth discovery endpoint を自動的に読み取る必要があります。ログイン成功後、2 つの保護されたツールを呼び出すことができます:
ping:ヘルスチェック。who_am_i:FastMCP が現在の認証 token から抽出したclient_id、scope、claims を返します。
設定項目
環境変数 | 必須 | デフォルト値 | 説明 |
| はい | - | 上流 OIDC クライアント ID |
| どちらか一方 | - | confidential client secret |
| どちらか一方 | - | public PKCE client または本番環境の FastMCP token 署名キー |
| いいえ | QA discovery URL | OIDC discovery アドレス |
| いいえ |
| MCP server のパブリックアドレス |
| いいえ |
| OAuth 認可リクエスト/デフォルト広告の scope。access token の scope 検証には使用しない |
| いいえ | OIDC discovery issuer | JWT |
| いいえ |
| カスタム token issuer の JWKS アドレス |
| いいえ | - | オプションの JWT |
| いいえ |
| リッスンアドレス |
| いいえ |
| リッスンポート |
| いいえ | QA MGT アドレス | MGT API の実際の呼び出し Base URL |
| いいえ |
| ローカル OpenAPI spec パス |
本番環境ではランダムな JWT_SIGNING_KEY を明示的に設定し、HTTPS の BASE_URL を使用してください。.env や client secret を Git にコミットしないでください。
カスタム Token Issuer
token の iss が OIDC discovery が返す issuer ではなく、auth middleware によってテナントアドレスに書き換えられている場合、例えば:
实际 token iss:
https://api-authsome-qa.drillinsight.com/auth-middleware/t_adecdb63-afab-4346-a1aa-b50bbbae7aee/次のように設定します:
OIDC_TOKEN_ISSUER=https://api-authsome-qa.drillinsight.com/auth-middleware/t_adecdb63-afab-4346-a1aa-b50bbbae7aee/
OIDC_JWKS_URI=https://auth-qa.drillinsight.com/oauth/jwksOIDC_CONFIG_URL は引き続き OAuth ログインと認可エンドポイントの discovery に使用されます。OIDC_TOKEN_ISSUER は JWT access token の iss 検証のみに使用されます。両者は異なっていても構いません。OIDC_TOKEN_ISSUER は末尾の / を含め、token 内の iss と完全に一致している必要があります。
現在のプロジェクトでは access token の scope や scp claim は検証されません。MGT の過去の Token が非標準の scope 形式を使用しているためです。OIDC_REQUIRED_SCOPES は引き続き OAuth 認可リクエストに使用されますが、標準の scope claim を持たない有効な Token をブロックすることはありません。署名、issuer、audience、有効期限、JWKS の検証は引き続き行われます。
QA MGT OpenAPI の統合
QA OpenAPI spec は次の場所に固定保存されています:
specs/mgt-qa-openapi.jsonMCP は実行時にオンラインの /api-docs にアクセスしないため、将来本番環境で API ドキュメントを公開しなくても動作に影響はありません。MGT_API_BASE_URL で実際の API アドレスを切り替えるだけです。Docker イメージは specs/mgt-qa-openapi.json を /app/specs/mgt-qa-openapi.json にコピーし、MGT_OPENAPI_SPEC_PATH を自動設定します。
最初のバージョンで公開される API 範囲:
/api/v1/user/current
/course/list
/batch/list
/batch/trainee/list
/equity/userequity/give
/api/v1/order/**
/api/v1/item/**
/api/v1/open/getSku*
/api/v1/customers
/api/v1/campus-recruitment/**(排除 export)
/api/v1/recruitment-info/**(排除 export)注文支払いリンク API は現在の要件に応じて統合されています:
/api/v1/order/queryPayLink
/api/v1/order/reGenaratePayLink返金、支払いコールバック、顧客データエクスポート API は引き続き除外されています:
/mall/v1/order/refund
/alipay/**
/stripe/**
/weixin/refund/**
/api/v1/customers/export
/api/v1/campus-recruitment/export
/api/v1/recruitment-info/exportMGT を呼び出すたびに、OpenAPI client は現在の FastMCP リクエストからユーザーの上流 OAuth access token を取得し、次のものを送信します:
Authorization: Bearer <user access token>
X-Application-Id: <token.app_id>ここで X-Application-Id は追加設定は不要で、検証済み JWT の app_id claim から直接読み取られます。app_id を持たない Token は拒否され、不完全なリクエストが MGT に送信されるのを防ぎます。
したがって、MGT は auth-qa.drillinsight.com が発行したユーザー Token を信頼し、ユーザー ID に基づいて権限制御を実行する必要があります。
ChatGPT CIMD timeout の調査
ログに次の内容が含まれる場合:
CIMD fetch failed for https://chatgpt.com/.../client.json: Timeout fetching
Unregistered client_id=https://chatgpt.com/.../client.jsonFastMCP が ChatGPT がホストするクライアントメタデータに直接アクセスできないことを意味します。現在のマシンが信頼できる送信プロキシ経由で外部ネットワークにアクセスする必要がある場合は、次のように設定してください:
FASTMCP_SSRF_TRUST_PROXY=true
HTTPS_PROXY=http://127.0.0.1:7897その後、サービスを完全に停止して再起動してください。プログラムは FastMCP をインポートする前にプロジェクトルートの .env を自動的にロードします。FastMCP はデフォルトで CIMD/JWKS リクエストに対して DNS 検証と IP 固定を行うため、通常のプロキシ環境変数は自動的に使用されません。このオプションを有効にすると、SSRF 防御の責任が指定したプロキシに委ねられ、NO_PROXY は無視されます。信頼できるプロキシに対してのみ有効にしてください。
ログ内の最初の POST /mcp 401 は、クライアントが認証前に保護リソースをプローブしているものです。複数の /.well-known/... アドレスへの 404 も ChatGPT の互換性プローブです。/.well-known/oauth-authorization-server が 200 を返していれば、これらは失敗の原因ではありません。
ログに Unregistered client_id=app_... や他の非 URL client ID が表示される場合、ChatGPT がサーバー側ストレージから失われた古い DCR 登録をキャッシュしていることを意味します。JWT_SIGNING_KEY を固定し、サービスを再起動してから、ChatGPT でそのカスタム MCP を削除して再作成し、/register を再呼び出しさせてください。ログインを再試行するだけでは、サーバー側で不明な古い client ID は復元されません。
テスト
uv run pytestThis server cannot be deployed
Maintenance
Related MCP Connectors
- mcp-serverOAuthio.klokin
MCP server exposing klokin time-tracking operations (employees, time entries, stores) to AI clients.
MCP server for AI access to Swagger by SmartBear.
MCP server for Product Management
Read-only MCP server for ClassQuill, a tutoring-business-management platform.