diff --git a/docs/teilprojekte.md b/docs/teilprojekte.md index 03c31f5..d40c665 100644 --- a/docs/teilprojekte.md +++ b/docs/teilprojekte.md @@ -593,6 +593,36 @@ und Letzteres verlangt die **physische Bestätigung am Gerät** — ap1 Technik `~/.secrets/credentials.env` wurden beide gegen die n8n-API getestet (**HTTP 200**), der `.env`-Wert ist ungetestet. Der Bearer dagegen ist überall identisch. Volume `n8n-mcp-deploy_n8n-mcp-data` überlebt einen Recreate, `gitea-mcp` hat gar kein Compose (reiner `docker run`). +- ✅ **F7 — `pve-mcp`-URL korrigiert (2026-08-30).** Beide globalen Configs zeigten auf + `http://10.40.20.173:3000/**mcp**`, der Server antwortet aber **nur auf dem Root-Pfad** + (live: `/` → **200**, `/mcp` → **404**) — die Session meldete entsprechend `ENDPOINT_NOT_FOUND`. + Damit widersprachen `~/.claude.json` und `~/.config/opencode/opencode.jsonc` der **eigenen + CLAUDE.md**, die den Root-Pfad seit jeher korrekt nennt („Root-Pfad, NICHT /sse"). Beide auf + `http://10.40.20.173:3000/` gezogen; `bf-infra/opencode.jsonc` war bereits richtig. + Merkregel: **wenn ein MCP „endpoint not found" meldet, zuerst die Doku gegen die Config lesen** — + hier stand die Antwort seit Monaten im Repo. +- ✅ **F6 — GUI-Apps sehen `exports.zsh` nicht: gelöst 2026-08-30 per LaunchAgent.** Aufgefallen, weil + `n8n-mcp` beim Session-Start mit **401** abgewiesen wurde, obwohl URL und Bearer stimmten. + 🔑 **Ursache — und sie reicht weit über n8n-mcp hinaus:** `~/.zprofile` sourct `exports.zsh` korrekt, + aber **`.zprofile` liest nur eine Login-Shell**. Claude Desktop und opencode starten **gar keine + Shell**, sie erben die launchd-Umgebung. Damit lösen **alle `{env:VAR}`-Referenzen zu LEER auf** — + live nachgewiesen: in **keinem** der `Claude Helper`-, `claude`- und opencode-MCP-Prozesse war + `N8N_MCP_BEARER` gesetzt, während dieselbe Variable in einer Login-Shell mit `len=64` vorhanden ist. + 🔴 **Das erklärt rückwirkend die Klartext-Secrets in `~/.claude.json`** (4 Router-PW + Hostinger-Token): + dort steht Klartext, *weil* `{env:}` in einer GUI-App nicht funktioniert — vermutlich kein + Schlamperei-, sondern ein Notbehelf. **Die naheliegende „Hygiene"-Umstellung auf `{env:}` hätte + `mikromcp` und `hostinger` stillgelegt.** Erst jetzt ist sie gefahrlos → Voraussetzung für **TP30**. + - **Lösung:** `~/Library/LaunchAgents/net.emsenhuber.gui-env.plist` (RunAtLoad) ruft + `~/dev/.bin/gui-env-sync.sh`; das Skript liest `exports.zsh` **zur Laufzeit** und setzt die + Variablen per `launchctl setenv`. **Kein Secret-Duplikat** — die plist enthält keine Werte, die + SSoT bleibt `exports.zsh`, neue Variablen dort werden beim nächsten Login automatisch mitgenommen. + Abnahme: **22 von 22** gesetzt, `N8N_MCP_BEARER` mit dem Hash des Store-Werts. + - ⚠️ **Damit ist die Konvention „niemals `launchctl setenv`" zu präzisieren, nicht zu brechen:** + verboten war der *Handaufruf*, weil er in keiner Datei steht und keinen Reboot überlebt. plist + + Skript sind genau die Datei-Form davon. In Kauf genommen: `launchctl setenv` übergibt den Wert + als Argument (kurz in `ps` sichtbar) — es gibt keine stdin-Variante. + - 📌 **Nach jeder Änderung an `exports.zsh` gilt:** Skript erneut laufen lassen **und die App neu + starten** — ein laufender Prozess erbt die Umgebung nicht nachträglich. - 🔜 **F5 — Secret-Verteilung auf Container-Hosts klären** (offen aus F1). `~/.secrets/credentials.env` ist SSoT, liegt aber **nur auf dem MacBook**; auf dem macmini existiert **kein `~/.secrets`**, und dort laufen die Container. Ein Symlink ist deshalb physisch unmöglich. Zu entscheiden: schlanke