# CorMind MCP — Client-Setup

Anleitung, um einen MCP-Client (Perplexity, Claude, ChatGPT, Cursor, Gemini CLI, ...)
mit dem self-hosted CorMind-Memory-Server zu verbinden.

> Diese Datei ist die kanonische Quelle (SSOT). Sie wird live unter
> https://cormind.hcai42.com/setup ausgeliefert und als Lesekopie im Obsidian-Vault
> (`3cors/Reference/cormind-mcp-setup.md`, der Wiki-Baum) gespiegelt, damit CorMind sie selbst findet.

> Secrets stehen **nicht** in diesem Dokument. Client-Secrets liegen gitignored in
> `content-engine/.claude/scripts/.env`; den passenden Wert gibt der Operator (oder
> der Agent via `cormind-automation`) auf Anfrage heraus.

## Was CorMind ist

Self-hosted MCP-Server, der das zentrale File-Memory (und read-only den Obsidian-Vault)
tool-agnostisch exponiert. Jeder MCP-fähige Client spricht denselben Speicher an.

- **MCP-Endpoint:** `https://cormind.hcai42.com/mcp`
- **Transport:** Streamable HTTP
- **Auth:** OAuth 2.1 (Authorization Code + PKCE S256) gegen Keycloak, Realm `3cors`
- **Authorization Server (Discovery):** `https://cormind.hcai42.com`
  (Protected-Resource-Metadata unter `/.well-known/oauth-protected-resource`;
  `/authorize` und `/token` werden an Keycloak weitergereicht)

## Tools

| Tool | Zweck | benötigte Rolle |
|------|-------|-----------------|
| `memory_search` | Hybrid/Keyword/Semantic-Suche im Memory | `cormind` / `admin` |
| `memory_list` | MEMORY.md-Index | `cormind` / `admin` |
| `memory_get` | einzelne Memory-Datei lesen | `cormind` / `admin` |
| `memory_remember` | neue Memory schreiben | `cormind` / `admin` |
| `vault_search` | Keyword-Suche im Obsidian-Vault (inkl. Wiki) | `cormind-vault` / `admin` |
| `vault_read` | Vault-Notiz lesen | `cormind-vault` / `admin` |
| `vault_list` | Vault-Notizen auflisten | `cormind-vault` / `admin` |
| `diary_search` | Keyword-Suche im persönlichen Tagebuch (`OBSIDIAN-DEV/Tagebuch`) | `cormind-diary` / `cormind-vault` / `admin` |
| `diary_get` | Tagebuch-Tag lesen (`YYYY-MM-DD`, `today`, `yesterday`) | `cormind-diary` / `cormind-vault` / `admin` |
| `diary_list` | Jüngste Tagebuch-Tage auflisten | `cormind-diary` / `cormind-vault` / `admin` |

Rollen werden dem Login-User in Keycloak (Realm `3cors`) zugewiesen. `admin` schließt alles ein.
Hinweis: CorMind listet aktuell immer alle Tools; die Rolle gated die **Ausführung**, nicht die Sichtbarkeit.

## Voraussetzung: ein OAuth-Client in Keycloak

Es gibt drei Wege, in absteigender Bequemlichkeit:

1. **Shared-Client `cormind-connectors` (empfohlen).** Ein Client für alle OAuth-Connectoren.
   Pro neuem Dienst wird nur dessen Redirect-URI ergänzt; Client-ID und Secret bleiben gleich.
2. **Dynamic Client Registration (DCR).** Clients, die MCP-OAuth-Discovery können (z.B. Claude),
   registrieren sich selbst. In Keycloak per Trusted-Hosts-Policy freigeschaltet (aktuell `claude.ai`).
3. **Eigener Client pro Dienst.** Z.B. `cormind-perplexity`. Nur nötig, wenn Isolation gewünscht ist.

Clients werden vom Agenten über den Service-Account `cormind-automation` verwaltet
(siehe Operator-Abschnitt), ohne Keycloak-Master-Passwort.

## Einen Client verbinden (generisch)

Im MCP-Client einen „custom connector" anlegen und eintragen:

- **MCP-Server-URL:** `https://cormind.hcai42.com/mcp`
- **Authentifizierung:** OAuth
- **Client-ID:** der Keycloak-Client (z.B. `cormind-connectors`) — **nicht** die eigene E-Mail
- **Client Secret:** der zugehörige Wert aus `.env` (Operator/Agent gibt ihn heraus)
- **Transport:** Streamable HTTP

Nach „Hinzufügen" leitet der Client zu Keycloak; nach Login mit dem `3cors`-Account
ist die Verbindung aktiv und das Token trägt `aud=cormind` + Rollen.

### Perplexity
„Benutzerdefinierten Konnektor hinzufügen" → Felder wie oben. Perplexity macht **kein** DCR,
daher Client-ID + Secret manuell. Perplexity bietet für Custom-Connectoren **keine**
Pro-Tool-Schalter; alle Tools stehen dem Modell zur Verfügung und werden im Chat genutzt.

### Claude (Web/Desktop)
Nutzt DCR: nur die MCP-Server-URL eintragen, der Rest läuft automatisch (Trusted-Host `claude.ai`).
Claude zeigt Pro-Tool-Toggles für Custom-MCP-Server.

### Andere (ChatGPT, Cursor, Gemini CLI, Codex)
Wie „generisch". Falls der Client DCR kann und sein Redirect-Host freigeschaltet ist,
genügt die URL; sonst Shared-Client-Credentials eintragen.

## Einen neuen Dienst freischalten (Operator/Agent)

Für einen weiteren Dienst muss nur dessen OAuth-Redirect-URI am Shared-Client ergänzt werden.
Schnellster Weg ist der Helper (ohne Keycloak-Master-Passwort):

```
cd content-engine/.claude/scripts
uv run python cormind_connector.py list
uv run python cormind_connector.py add-redirect "<redirect-uri-des-dienstes>"
```

Manuell:

1. Redirect-URI des Dienstes ermitteln (steht in dessen Connector-Doku oder im
   `GET /authorize?...&redirect_uri=...`-Aufruf im CorMind-Log).
2. Per `cormind-automation` (Rolle `manage-clients`) die URI zu `cormind-connectors`
   `redirectUris` hinzufügen — ein Admin-REST-Call, kein Master-Passwort nötig.
3. Im Dienst Client-ID `cormind-connectors` + Secret + MCP-URL eintragen.

Details zum Keycloak-Zugang: siehe Operator-Runbook (Auto-Memory `reference_keycloak_admin_access`).

## Troubleshooting

- **„Client not found" auf der Keycloak-Login-Seite:** In „Client-ID" wurde etwas Falsches
  eingetragen (häufig die eigene E-Mail). Es muss der **Keycloak-Client-Name** sein.
- **Status „verbunden", aber Login/Token schlägt fehl / `invalid_client_credentials`:**
  Das eingetragene Client-Secret ist falsch oder ein gecachter Altwert. Connector **entfernen
  und neu hinzufügen**, Secret sauber einfügen (keine Leerzeichen). Im Zweifel Secret rotieren.
- **Verbunden, aber im Chat passiert nichts:** Connector im jeweiligen Chat/Space aktivieren;
  oft ist ein Reasoning-/Pro-Modus nötig. Custom-MCP-Tools erscheinen nicht im reinen Such-Modus.
- **Keine Pro-Tool-Schalter (Perplexity):** Client-UI-Grenze für Custom-Connectoren, kein
  Server-Defekt. Claude.ai bietet die Schalter.
- **Tools werden nicht erneut geladen:** Clients cachen die Tool-Liste nach dem Handshake.
  Connector neu verbinden, um eine frische `tools/list` zu erzwingen.

## Diagnose-Logs

- CorMind-HTTP/MCP: `journalctl --user -u cormind -f`
- Keycloak-Token-Fehler: `docker logs --since 5m 3cors-keycloak | grep CODE_TO_TOKEN`
- Discovery prüfen: `curl https://cormind.hcai42.com/.well-known/oauth-protected-resource`