Coach-MCP — Runbook (Verbinden, Tokens, Betrieb)
Der Silverscale Coach ist ein lesender MCP-Server: in Claude-Chat eingebunden,
zieht Claude darüber die echten Daten eines Profils und coacht damit. Der Server
liefert nur Fakten (gemessen vs. geschätzt markiert) — die Intelligenz ist Claude.
v1 = read-only. Architektur/Tool-Schnitt: docs/syntheses/coach-mcp.md.
In Claude verbinden (für Dennis / Jacky)
- In der App → Einstellungen → ✨ KI-Coach.
- Falls noch kein Zugang: „Zugang erzeugen". Es erscheinen Adresse + Schlüssel.
- In Claude → Einstellungen → Connectors → eigenen Connector hinzufügen:
- Adresse:
https://mcp.silverscale.dennisfisch.de/coach- Authentifizierung: Bearer-Token = der Schlüssel aus der App. - Fertig — Claude kann jetzt z. B. „Wie war meine Woche?" beantworten.
Profil-Trennung: Jeder Schlüssel zeigt nur das Profil, zu dem er gehört (am Token festgenagelt, serverseitig hart gescoped). Jacky trägt ihren eigenen Schlüssel in ihrem eigenen Claude-Login ein — so sieht sie nur ihr Profil.
Tokens — Lebenszyklus
- Speicherort: DB-Tabelle
mcp_tokens(ein aktiver Token je Profil). Erzeugt/ rotiert über die App-Einstellungen (POST /api/coach/connection/regenerate). - Widerruf / „geleakt = verbrannt": in den Einstellungen „Neu generieren" → der alte Schlüssel wird sofort ungültig. Danach in Claude den neuen eintragen.
- Bootstrap/Test (optional): Env
MCP_TOKEN_<SLUG>(z. B.MCP_TOKEN_DENNIS) gilt als zusätzlicher Token; in Produktion ist der DB-/UI-Weg der Normalfall, die.envträgt keine Coach-Tokens. - Niemals einen Token über den Agent-Bus oder in Commits schicken (persistiert/ Backup). Übergabe nur in der App ansehen/kopieren.
Betrieb / Architektur
- Läuft im App-Prozess (FastAPI), gemountet unter
/coach; eigener ASGI-Bearer-Auth-Layer (kein Pocket-ID-Cookie, kein globalerX-Internal-Token). Liest über die bestehende Connection — kein zweiter Prozess auf die Live-SQLite. - Traefik: Router
silverscale-mcp→ Hostmcp.silverscale.dennisfisch.de→ derselbe Service. Cert via DNS-01/Cloudflare (cf). DNS deckt der Wildcard*.silverscale…ab — kein eigener DNS-Eintrag nötig. - Host-Allowlist (DNS-Rebinding-Schutz):
mcp.silverscale.dennisfisch.de+ localhost sind erlaubt; weitere via EnvMCP_ALLOWED_HOSTS(Komma-Liste). Unerlaubter Host →421. - Deploy-Gate: Contract-Tests in
app/tests/contract/test_coach_mcp.py(Auth-Gate + Handshake). Vor Backend-Deploys./app/tests/run.sh.
Schnelltest (ohne Token → 401)
curl -s -o /dev/null -w "%{http_code}\n" https://mcp.silverscale.dennisfisch.de/coach/
# erwartet: 401
Tools (Stand)
- Lesen (v1, SILV-393/394):
whoami(Profil + Ziele +schreibrecht),get_concepts,get_day,get_week_summary,get_activities,get_workout_detail,get_body_metrics,get_nutrition_analysis,get_meal_context. -
Schreiben (v2, SILV-435, nur
meal_plan, Scopecoach:write):plan_get,plan_meal_create,plan_meal_update,plan_meal_delete,plan_copy,plan_template_preview,plan_template_generate; Historieget_food_history. Details/Guardrails:docs/syntheses/coach-mcp.md§9. -
v2.1 (29.08., SILV-438/442):
plan_getliefert je Tag Summen vs Ziel, Kurven-KPIs, Einheit,session_changed_at,two_dayundoutcomeje Eintrag (liestGET /api/plan/week). Ein Coach-Update macht die Zeileorigin=coach, ein Coach-Delete hinterlässt einen Tombstone — der Intervals-Sync regeneriert nur noch Tage ohne Nutzer-/Coach-Zeilen (energie-vertrag.md§5d).
Schreibfreigabe (SILV-435)
TOK=$(grep ^INTERNAL_API_TOKEN .env | cut -d= -f2)
curl -s -X POST "http://127.0.0.1:9300/api/coach/write-grant?user_id=1¬e=Dennis" -H "X-Internal-Token: $TOK"
curl -s -X DELETE "http://127.0.0.1:9300/api/coach/write-grant?user_id=1" -H "X-Internal-Token: $TOK"
curl -s "http://127.0.0.1:9300/api/plan/audit?user_id=1&days=7" -H "X-Internal-Token: $TOK" # wer/wann/was
Wirkt sofort (Scope wird je Token-Validierung gelesen, keine Rotation). Ohne Freigabe = read-only (Jacky). Widerruf = sofortiger Schreibstopp; der Token bleibt zum Lesen gültig.