KRITISCH: /token akzeptierte authorization_code OHNE client_secret
('rely on PKCE alone'-Zweig) und ueberging PKCE wenn code_challenge leer war.
Da client_id nur der Benutzername ist (z.B. 'stefan', steht in der Subdomain),
konnte jeder mit ratbarem Namen einen 30-Tage-Vollzugriffs-Token holen
(verifiziert ausnutzbar). Token galt zudem fuer alle 5 MCP-Dienste.
Fix:
- /authorize: code_challenge (PKCE) PFLICHT
- /token: client_secret PFLICHT (_resolve_client) UND PKCE-Verifikation PFLICHT,
Bypass-Zweige entfernt.
claude.ai sendet beides (client_secret_post + S256-PKCE, per Audit verifiziert)
-> kein erneutes Verbinden noetig, bestehende Tokens bleiben gueltig.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
URLs: mail.mcp.home.slohmaier.de, calendar.mcp..., etc.
No more path-prefix routing — each service has its own domain.
OAuth tokens stored in shared .active_tokens.json file so all
services can validate tokens issued by any service.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Self-hosted MCP servers with OAuth client_credentials auth.
Each server connects to a different backend:
- Mail: reads Maildir IMAP backups
- Calendar/Tasks: CalDAV against Radicale
- Contacts: CardDAV against Radicale
- Files: WebDAV against oCIS
- Notes: Joplin REST API
Credentials externalized to config.json (not in repo).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>