Skip to main content
Glama
beaconfire-projects

mcp-oauth-test

FastMCP OIDC Server

Dies ist ein MCP-Server, der mit FastMCP geschrieben und durch OIDC-Login geschützt ist. Er verwendet den OIDCProxy von FastMCP: Der MCP-Client authentifiziert sich über die vom Server bereitgestellten OAuth-Metadaten, während der eigentliche Login und Token-Austausch an den QA-OIDC-Provider weitergeleitet werden.

Derzeit ist die QA MGT OpenAPI angebunden, die MCP-Tools für Trainee, Bestellungen, Produkte, Kunden, Campus-Recruiting und internationale Rekrutierung generiert.

Die OIDC-Discovery-Adresse ist standardmäßig wie folgt konfiguriert:

https://auth-qa.drillinsight.com/.well-known/openid-configuration

Authentifizierungsvorbereitung

Registrieren Sie zuerst eine OAuth-Anwendung unter auth-qa.drillinsight.com und fügen Sie die folgende Callback-Adresse zur Whitelist hinzu:

http://localhost:8000/auth/callback

Wenn Sie auf einer anderen Adresse bereitstellen, ersetzen Sie http://localhost:8000 durch den Wert von BASE_URL. Die Callback-Adresse muss exakt mit dem BASE_URL von FastMCP übereinstimmen.

Lokale Ausführung

cp .env.example .env
# 编辑 .env,至少填写 OIDC_CLIENT_ID 和 OIDC_CLIENT_SECRET
uv sync
uv run mcp-oidc-server

Sie können das Modul auch direkt ausführen:

uv run python -m oidc_mcp_server.server

Der Dienst lauscht standardmäßig auf http://127.0.0.1:8000. Wenn der MCP-Client auf einer anderen Maschine oder in einem Container läuft, setzen Sie eine für den Client erreichbare BASE_URL und eine geeignete HOST-Adresse (z. B. 0.0.0.0).

Claude Code Plugin

Das Repository enthält einen privaten Claude-Code-Marketplace und ein MCP-Plugin:

.claude-plugin/marketplace.json
└── plugins/mcp-oauth-test/
    ├── .claude-plugin/plugin.json
    ├── .mcp.json
    └── README.md

Das Plugin verbindet Claude Code lediglich mit dem bereits bereitgestellten Remote-MCP-Dienst und startet keinen lokalen Python-Dienst. Für Entwicklungs- und Testzwecke kann es direkt geladen werden:

claude --plugin-dir ./plugins/mcp-oauth-test

Das Plugin ist fest mit dem MCP-Server der Entwicklungsumgebung verbunden:

https://api-mcp-oauth-dev.beaconfireinc.com/mcp

Es kann auch über den privaten Marketplace installiert werden:

/plugin marketplace add /path/to/mcp-oauth-test
/plugin install mcp-oauth-test@authsome-internal

Das aktuelle Marketplace-Root-Verzeichnis ist das Repository-Root. Bitte halten Sie diesen Marketplace in einem privaten GitHub-Repository des Unternehmens und übermitteln Sie ihn nicht an einen öffentlichen Marketplace. Für gemeinsame Umgebungen sollten Sie HTTPS-Adressen verwenden und den Zugriff auf Unternehmensbenutzer auf der Seite des IdP und des MCP-Servers beschränken.

Warum OIDCProxy

Der Upstream auth-qa.drillinsight.com muss kein DCR oder CIMD unterstützen. OIDCProxy ist genau für dieses Szenario gedacht:

ChatGPT ── MCP OAuth / CIMD ──> FastMCP OIDCProxy
                                      │
                                      └── 固定 client_id/client_secret ──> auth-qa.drillinsight.com

Im Upstream muss nur die OAuth-Anwendung FastMCP vorab registriert werden, und ${BASE_URL}/auth/callback muss konfiguriert werden. Das von ChatGPT verwendete CIMD wird von der FastMCP-Proxy-Schicht verarbeitet und nicht an den Upstream-OAuth-Server weitergeleitet.

ChatGPT CIMD-Konfiguration

Wählen Sie beim Erstellen eines benutzerdefinierten MCP in ChatGPT unter den erweiterten OAuth-Einstellungen für „Client-Registrierung“ die folgende Option:

客户端标识元数据文档(CIMD)

Die vom aktuellen ChatGPT-Connector generierten Informationen sind:

CIMD Client ID / 客户端元数据 URL:
https://chatgpt.com/oauth/0Buhw3sHVv1-/client.json

ChatGPT Callback URL:
https://chatgpt.com/connector/oauth/0Buhw3sHVv1-

Die CIMD-URL selbst ist die client_id, die ChatGPT beim Zugriff auf den FastMCP-OAuth-Proxy verwendet. Sie muss nicht und sollte nicht beim Upstream auth-qa.drillinsight.com registriert werden.

Dieses Projekt enthält zwei verschiedene Ebenen von OAuth-Client-IDs:

OAuth-Kette

client_id

Konfigurationsort

ChatGPT → FastMCP OIDCProxy

https://chatgpt.com/oauth/0Buhw3sHVv1-/client.json

Von ChatGPT automatisch bereitgestellt; nach Auswahl von CIMD keine manuelle Eingabe erforderlich

FastMCP OIDCProxy → auth-qa.drillinsight.com

app_74a4b555-5b87-4212-9dda-d584fa78caf8

OIDC_CLIENT_ID des MCP-Servers

Der entsprechende Datenfluss ist:

ChatGPT
  │ client_id=https://chatgpt.com/oauth/0Buhw3sHVv1-/client.json
  ▼
FastMCP OIDCProxy
  │ client_id=app_74a4b555-5b87-4212-9dda-d584fa78caf8
  ▼
auth-qa.drillinsight.com

Die Umgebungsvariablen des MCP-Servers:

OIDC_CLIENT_ID=app_74a4b555-5b87-4212-9dda-d584fa78caf8
OIDC_CLIENT_SECRET=<上游 OAuth Server 颁发的客户端密钥>

Der Upstream-OAuth-Server muss nur die FastMCP-Callback-Adresse für die app_...-Anwendung konfigurieren:

https://heroic-verbally-crawdad.ngrok-free.app/auth/callback

Konfigurieren Sie die ChatGPT-Callback-Adresse https://chatgpt.com/connector/oauth/... nicht am Upstream-OAuth-Server; diese Adresse wird von der FastMCP-Proxy-Schicht nach Abschluss der Authentifizierung verwendet.

Zu Beginn der Authentifizierung sollte im normalen Log zuerst die CIMD-Client-ID von ChatGPT erscheinen:

CIMD document fetched and validated
GET /authorize?client_id=https://chatgpt.com/oauth/.../client.json ... 302

Anschließend verwendet FastMCP app_74a4b555-..., um zum Upstream-OAuth-Server weiterzuleiten.

MCP-Client-Konfiguration

Konfigurieren Sie die MCP-Adresse wie folgt:

http://localhost:8000/mcp

FastMCP stellt die folgenden Authentifizierungs-Discovery-Adressen bereit:

http://localhost:8000/.well-known/oauth-authorization-server
http://localhost:8000/.well-known/oauth-protected-resource/mcp

Der Client sollte diese MCP/OAuth-Discovery-Endpunkte automatisch lesen. Nach erfolgreichem Login können zwei geschützte Tools aufgerufen werden:

  • ping: Gesundheitscheck.

  • who_am_i: Gibt die client_id, Scopes und Claims zurück, die FastMCP aus dem aktuellen Authentifizierungstoken extrahiert.

Konfigurationsoptionen

Umgebungsvariable

Erforderlich

Standardwert

Beschreibung

OIDC_CLIENT_ID

Ja

-

Upstream-OIDC-Client-ID

OIDC_CLIENT_SECRET

Eines von beiden

-

Geheimnis des vertraulichen Clients

JWT_SIGNING_KEY

Eines von beiden

-

Signaturschlüssel für öffentliche PKCE-Clients oder FastMCP-Token in der Produktion

OIDC_CONFIG_URL

Nein

QA-Discovery-URL

OIDC-Discovery-Adresse

BASE_URL

Nein

http://localhost:8000

Öffentliche Adresse des MCP-Servers

OIDC_REQUIRED_SCOPES

Nein

openid

Scope für OAuth-Autorisierungsanfragen/Standardwerbung; nicht für die Access-Token-Scope-Validierung

OIDC_TOKEN_ISSUER

Nein

OIDC-Discovery-Issuer

JWT-iss-Validierungswert; wird gesetzt, wenn die Auth-Middleware den Issuer umschreibt

OIDC_JWKS_URI

Nein

https://auth-qa.drillinsight.com/oauth/jwks

JWKS-Adresse für benutzerdefinierte Token-Issuer

OIDC_TOKEN_AUDIENCE

Nein

-

Optionaler JWT-aud-Validierungswert

HOST

Nein

127.0.0.1

Lauschadresse

PORT

Nein

8000

Lauschport

MGT_API_BASE_URL

Nein

QA-MGT-Adresse

Basis-URL für tatsächliche MGT-API-Aufrufe

MGT_OPENAPI_SPEC_PATH

Nein

specs/mgt-qa-openapi.json

Pfad zur lokalen OpenAPI-Spezifikation

Setzen Sie in der Produktion explizit einen zufälligen JWT_SIGNING_KEY und verwenden Sie eine HTTPS-BASE_URL. Committen Sie weder .env noch Client-Secrets in Git.

Benutzerdefinierter Token-Issuer

Wenn der iss des Tokens nicht der vom OIDC-Discovery zurückgegebene Issuer ist, sondern von der Auth-Middleware in eine Mandantenadresse umgeschrieben wird, z. B.:

实际 token iss:
https://api-authsome-qa.drillinsight.com/auth-middleware/t_adecdb63-afab-4346-a1aa-b50bbbae7aee/

Setzen Sie:

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/jwks

OIDC_CONFIG_URL wird weiterhin für die OAuth-Login- und Autorisierungs-Endpunkt-Discovery verwendet; OIDC_TOKEN_ISSUER dient nur zur Validierung des iss des JWT-Access-Tokens. Beide können unterschiedlich sein. OIDC_TOKEN_ISSUER muss exakt mit dem iss im Token übereinstimmen, einschließlich des abschließenden /.

Das aktuelle Projekt validiert weder den scope- noch den scp-Claim des Access-Tokens, da historische MGT-Tokens ein nicht standardkonformes Scope-Format verwenden. OIDC_REQUIRED_SCOPES wird weiterhin für OAuth-Autorisierungsanfragen verwendet, blockiert jedoch keine gültigen Tokens ohne standardkonforme Scope-Claims. Signatur-, Issuer-, Audience-, Ablaufzeit- und JWKS-Validierung bleiben erhalten.

QA MGT OpenAPI-Anbindung

Die QA-OpenAPI-Spezifikation wurde fest unter folgendem Pfad gespeichert:

specs/mgt-qa-openapi.json

MCP greift zur Laufzeit nicht auf die Online-/api-docs zu, sodass die zukünftige Produktionsumgebung ohne offene API-Dokumentation weiterhin funktioniert. Über MGT_API_BASE_URL kann die tatsächliche API-Adresse umgeschaltet werden. Das Docker-Image kopiert specs/mgt-qa-openapi.json nach /app/specs/mgt-qa-openapi.json und setzt MGT_OPENAPI_SPEC_PATH automatisch.

Der in der ersten Version freigegebene API-Umfang:

/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)

Die Schnittstelle für Bestellungs-Zahlungslink wird gemäß den aktuellen Anforderungen angebunden:

/api/v1/order/queryPayLink
/api/v1/order/reGenaratePayLink

Weiterhin ausgeschlossen sind Rückerstattungs-, Zahlungs-Callback- und Kundendatenexport-Schnittstellen:

/mall/v1/order/refund
/alipay/**
/stripe/**
/weixin/refund/**
/api/v1/customers/export
/api/v1/campus-recruitment/export
/api/v1/recruitment-info/export

Bei jedem MGT-Aufruf holt der OpenAPI-Client das Upstream-OAuth-Access-Token des Benutzers aus der aktuellen FastMCP-Anfrage und sendet:

Authorization: Bearer <user access token>
X-Application-Id: <token.app_id>

Dabei muss X-Application-Id nicht zusätzlich konfiguriert werden; es wird direkt aus dem app_id-Claim des validierten JWT gelesen. Tokens ohne app_id werden abgelehnt, um unvollständige Anfragen an MGT zu vermeiden.

Daher muss MGT den von auth-qa.drillinsight.com ausgestellten Benutzer-Tokens vertrauen und die Berechtigungssteuerung basierend auf der Benutzeridentität durchführen.

Fehlerbehebung bei ChatGPT CIMD-Timeout

Wenn das Log Folgendes enthält:

CIMD fetch failed for https://chatgpt.com/.../client.json: Timeout fetching
Unregistered client_id=https://chatgpt.com/.../client.json

bedeutet dies, dass FastMCP nicht direkt auf die von ChatGPT gehosteten Client-Metadaten zugreifen kann. Wenn die aktuelle Maschine für den Zugriff auf das Internet über einen vertrauenswürdigen ausgehenden Proxy gehen muss, konfigurieren Sie:

FASTMCP_SSRF_TRUST_PROXY=true
HTTPS_PROXY=http://127.0.0.1:7897

Stoppen und starten Sie den Dienst dann vollständig neu. Das Programm lädt automatisch die .env im Projektstamm, bevor FastMCP importiert wird; FastMCP führt standardmäßig DNS-Validierung und IP-Pinning für CIMD/JWKS-Anfragen durch und verwendet daher nicht automatisch normale Proxy-Umgebungsvariablen. Wenn diese Option aktiviert ist, wird die SSRF-Schutzverantwortung an den angegebenen Proxy übertragen und NO_PROXY ignoriert. Aktivieren Sie sie nur für vertrauenswürdige Proxys.

Das erste POST /mcp 401 im Log ist der Client, der vor der Authentifizierung geschützte Ressourcen abtastet; die 404-Antworten auf mehrere /.well-known/...-Adressen sind ebenfalls Kompatibilitätstests von ChatGPT. Solange /.well-known/oauth-authorization-server 200 zurückgibt, sind sie nicht die Ursache dieses Fehlers.

Wenn das Log Unregistered client_id=app_... oder eine andere Nicht-URL-Client-ID anzeigt, bedeutet dies, dass ChatGPT eine alte DCR-Registrierung zwischengespeichert hat, die aus dem Server-Speicher verloren gegangen ist. Fixieren Sie JWT_SIGNING_KEY, starten Sie den Dienst neu und löschen Sie dann das benutzerdefinierte MCP in ChatGPT und erstellen Sie es neu, damit es /register erneut aufruft. Ein erneuter Login-Versuch stellt die dem Server unbekannte alte Client-ID nicht wieder her.

Tests

uv run pytest
-
license - not tested
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • MCP server for AI access to Swagger by SmartBear.

  • Read-only MCP server for ClassQuill, a tutoring-business-management platform.

  • MCP Server for agents to onboard, pay, and provision services autonomously with InFlow

View all MCP Connectors

Latest Blog Posts

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/beaconfire-projects/mcp-oauth-test'

If you have feedback or need assistance with the MCP directory API, please join our Discord server