feat(mcp): OAuth so claude.ai and ChatGPT can connect as connectors
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m49s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m49s
MindSift becomes the OAuth authorization server for its own MCP endpoint: discovery (RFC 9728/8414), dynamic client registration, authorization code with PKCE (S256), rotating refresh tokens with reuse detection. The consent page lives in the app at /oauth/authorize. A grant is an api_keys entry (kind 'oauth'), so scopes, origin badges, renaming and revoking work as for keys; tokens are valid for /mcp only. Unused connections expire after OAUTH_IDLE_DAYS (default 90). Requires BASE_URL; off in demo mode. Release 0.51.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
994f6dc554
commit
75aea4a7d4
31 files changed
+1581
-49
No files matched your search
+22
-1
@@ -104,7 +104,28 @@ MindSift ist ein [MCP](https://modelcontextprotocol.io)-Server (Streamable HTTP,
|
||||
|
||||
Was ein Agent anlegt oder ändert, bekommt eine dauerhafte Herkunft (`origin`, siehe [API-Schlüssel](#api-schlüssel-rechte-und-herkunft)). `create_task` geht auch mit `webhook:task`, `add_list_item` auch mit `webhook:list`.
|
||||
|
||||
Freigaben gelten wie für die Person selbst: Leser-Listen lassen sich nicht ändern, fremde Listen sind unsichtbar. Einrichtung z. B. in Claude Code: `claude mcp add --transport http mindsift https://mindsift.example.com/api/v1/mcp --header "X-API-Key: mindsift_sec_…"`; die Einstellungen zeigen die Varianten für Codex (`config.toml`) und JSON-Konfigurationen (Claude Desktop, Cursor). claude.ai und ChatGPT im Browser verlangen OAuth und werden noch nicht unterstützt.
|
||||
Freigaben gelten wie für die Person selbst: Leser-Listen lassen sich nicht ändern, fremde Listen sind unsichtbar. Einrichtung z. B. in Claude Code: `claude mcp add --transport http mindsift https://mindsift.example.com/api/v1/mcp --header "X-API-Key: mindsift_sec_…"`; die Einstellungen zeigen die Varianten für Codex (`config.toml`) und JSON-Konfigurationen (Claude Desktop, Cursor). claude.ai und ChatGPT verbinden sich per OAuth (nächster Abschnitt).
|
||||
|
||||
### OAuth für claude.ai und ChatGPT
|
||||
|
||||
Clients, die keinen `X-API-Key` setzen können, verbinden sich per OAuth 2.1 nach der MCP-Spezifikation (Autorisierung, Stand 2025-06-18). In claude.ai wird dafür nur `<BASE_URL>/api/v1/mcp` als eigener Connector eingetragen; den Rest erledigt der Client. Voraussetzung ist `BASE_URL` (Issuer und Ressource); ohne `BASE_URL` und im Demo-Modus antworten alle Endpunkte mit `404`. `GET /auth/status` liefert die Adresse als `mcpConnectorUrl` (leer, wenn OAuth aus ist).
|
||||
|
||||
| Methode | Pfad (ohne `/api/v1`) | Zweck |
|
||||
|---|---|---|
|
||||
| GET | `/.well-known/oauth-protected-resource` (auch mit Anhang `/api/v1/mcp`) | Ressourcen-Beschreibung (RFC 9728): `resource`, `authorization_servers`, `scopes_supported` |
|
||||
| GET | `/.well-known/oauth-authorization-server` | Server-Beschreibung (RFC 8414) |
|
||||
| POST | `/oauth/register` | Dynamische Client-Registrierung (RFC 7591), JSON `client_name`, `redirect_uris` (nur `https://` oder `http://localhost`/`127.0.0.1`, höchstens 10). Alle Clients sind öffentlich (`token_endpoint_auth_method: none`); 20 Registrierungen pro Adresse und Viertelstunde |
|
||||
| GET | `/oauth/authorize` | Zustimmungsseite in der App (Anmeldung, Rechte wählen, Erlauben/Ablehnen). Pflicht: `response_type=code`, `client_id`, `redirect_uri` (exakt registriert), `code_challenge` mit `code_challenge_method=S256`; optional `state`, `scope` (Leerzeichen-getrennte Rechte), `resource`. Die Antwort an den Client trägt `code`, `state` und `iss` bzw. `error` |
|
||||
| POST | `/oauth/token` | Formular: `grant_type=authorization_code` (`code`, `client_id`, `redirect_uri`, `code_verifier`) oder `refresh_token` (`refresh_token`, `client_id`). Fehler als `{"error":"invalid_grant",…}` |
|
||||
| POST | `/oauth/revoke` | Token widerrufen (RFC 7009); ein Refresh-Token beendet alle Tokens der Verbindung |
|
||||
|
||||
Die Zustimmungsseite nutzt `GET`/`POST /api/v1/oauth/authorize` (nur mit Anmeldung, nicht mit Schlüsseln).
|
||||
|
||||
- **Rechte:** dieselben wie bei Schlüsseln, angeboten werden `tasks:read`, `tasks:write`, `lists:read`, `lists:write` und `webhook:triage`. Fragt der Client nichts Bestimmtes an, sind Lesen und Ändern für Aufgaben und Listen vorbelegt.
|
||||
- **Verbindung = Eintrag unter `/keys`** mit `kind: "oauth"` und dem Namen „<Client> (OAuth)“. Rechte ändern, umbenennen und löschen wie bei jedem Schlüssel; Herkunft (`origin`) mit diesem Namen. Erneutes Zustimmen desselben Clients verwendet den Eintrag weiter.
|
||||
- **Tokens:** Code 10 Minuten und einmal gültig, Zugangs-Token (`mindsift_oat_…`) 1 Stunde, Refresh-Token (`mindsift_ort_…`) 90 Tage und bei jeder Erneuerung neu. Wird ein bereits ersetzter Refresh-Token noch einmal benutzt, enden alle Tokens der Verbindung. Zugangs-Tokens gelten nur für `POST /mcp`, nicht für REST oder Webhooks.
|
||||
- **Verfall:** Eine Verbindung, die `OAUTH_IDLE_DAYS` (Standard 90, `0` = nie) nicht benutzt wurde, wird gelöscht.
|
||||
- Ohne gültiges Token antwortet `/mcp` mit `401` und `WWW-Authenticate: Bearer resource_metadata="…"`.
|
||||
|
||||
### API-Schlüssel: Rechte und Herkunft
|
||||
|
||||
|
||||
Reference in new issue
Block a user