OAuth 2.1 für ChatGPT, Claude & Custom Connectors
Onboard implementiert den Standard-Flow, den ChatGPTs Custom Connectors und Claude.ais Custom Connectors automatisch ausführen — Discovery, Dynamic Client Registration, PKCE-S256.
Konsumenten-Apps wie ChatGPT und Claude.ai erlauben Nutzern, eigene MCP-Server als Custom Connector hinzuzufügen. Damit der Verbindungsdialog ohne manuelles Konfigurieren funktioniert, muss der Server eine kleine Folge von Standards erfüllen — RFC 8414, RFC 9728, RFC 7591, PKCE-S256. Onboard liefert genau diese Folge.
RFC 7591 — der Relying-Party-Client registriert sich selbst beim Authorization Server, ohne dass jemand vorab manuell einen Client anlegt. Voraussetzung dafür, dass ChatGPT/Claude on-the-fly verbinden können.
Endpunkte im Überblick
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| /.well-known/oauth-authorization-server | GET | — | — | Authorization-Server-Metadaten (RFC 8414). Verweist auf Registration-, Authorization- und Token-Endpoint und gibt PKCE-S256 als einzige Code-Challenge-Methode an. |
| /.well-known/oauth-protected-resource | GET | — | — | Resource-Metadaten (RFC 9728). Wird vom MCP-Server in |
| /api/oauth/register | POST | — | — | Dynamic Client Registration. Öffentlicher Endpoint, vergibt eine client_id pro Relying Party — kein client_secret (öffentliche Clients). |
| /oauth/authorize | GET | — | — | Nutzer-sichtbare Consent-Seite. Approve/Deny. Liegt NICHT unter /api/, weil es UI ist. |
| /oauth/authorize/grant | POST | — | — | Approve-Submit. Erzeugt einen Authorization Code (10 min TTL, PKCE-S256) und redirected per 303 zurück an die redirect_uri. |
| /api/oauth/token | POST | — | — | Token-Tausch (RFC 6749 §4.1.3). Validiert PKCE, verbrennt den Code (single-use) und legt das Bearer-Token in ai_api_keys ab. |
Der vollständige Flow
- 1
Connector-Discovery (kein Code nötig)
Der Nutzer fügt in ChatGPT oder Claude.ai eine Connector-URL hinzu (typischerweisehttps://app.onboardos.org/api/mcp). Der Client ruft den ersten Endpoint auf und bekommt ein 401 mitWWW-Authenticate: Bearer resource_metadata=…-Header, folgt der Resource-Metadata und findet darüber den Authorization-Server. - 2
Dynamic Client Registration
Der Client schickt einen POST an/api/oauth/registermit redirect_uri, client_name und (optional) Logo. Antwort: eineclient_id, persistiert in oauth_clients mitregistered_via='dcr'. - 3
Consent durch den Nutzer
Der Client öffnet/oauth/authorizeim Browser des Nutzers (mit PKCE-Challenge + state). Die Consent-Seite zeigt: Connector-Name, gewünschte Berechtigungen, optional ein Eingabefeld für eine Kontakt-Email (die der Nutzer freiwillig angibt, falls er ohne Account bucht). Nach „Genehmigen" redirected Onboard mit code+state zur redirect_uri. - 4
Token-Tausch mit PKCE
Der Client schickt code + code_verifier + redirect_uri an/api/oauth/token. Onboard rechnet den S256-Hash vom Verifier nach, verbrennt den Code in einem konditionalen UPDATE (Race-safe) und antwortet mit einemaccess_token(Bearer). Das Token landet als API-Key in ai_api_keys mit oauth_client_id-Verknüpfung —verifyAiApiKey()validiert es transparent, kein Sondercode im MCP-Pfad. - 5
Tools aufrufen
Der Connector hängt nunAuthorization: Bearer <token>an jeden MCP-Aufruf. Rate-Limiting, Audit-Log und Quellenattribution greifen identisch zu Direkt-vergebenen Keys.
ai_api_keys-Tabelle, mit demselben Rate-Limit-Fenster, derselben Widerrufslogik und demselben CEO-Dashboard. Das Widerrufen einer oauth_clients-Zeile widerruft die ausgegebenen Tokens.Keine Refresh-Tokens
Onboard gibt keine Refresh-Tokens aus — das Discovery-Dokument enthält sie auch nicht. Bearer-Tokens sind langlebig bis zum Widerruf. Bei Widerruf müssen Clients den Flow neu durchlaufen — was ChatGPT und Claude automatisch tun.
Nur PKCE-S256, keine Plain-Codes
Der Authorization Server akzeptiert ausschließlich code_challenge_method=S256. Plain-PKCE und nicht-PKCE-Flows werden mit 400 abgelehnt — auch öffentliche Clients ohne Secret kommen so nicht in eine Code-Interception-Lücke.
Consent-Seiten-Verhalten
Die Consent-Seite zeigt nur Approve/Deny und — wahlweise — ein Kontakt-Email-Feld für anonyme Buchungen. Es gibt absichtlich kein Login-Formular. Die meisten Connector-Flows kommen über ChatGPT/Claude und identifizieren den Gast pro Buchung über die create_reservation-Argumente.
/.well-known/-Antworten aggressiv. Wenn sich Endpoints verschieben, brauchen bestehende Connectors einen kompletten Neu-Connect — also nur in einem Major-Release ändern.