TP16.3 F1 DURCH: gitea-mcp/n8n-mcp geschnitten + Doku nachgezogen
Der grosse Schnitt (803a287) hatte diese zwei Namen bewusst ausgelassen, weil Werkzeug daran hing. F1 hat die Abhaengigkeit aufgeloest, danach fiel der Schnitt: Ingress bf-mm 4 -> 2 (nur noch n8n + Catch-all) DNS beide CNAMEs geloescht Gesamt 14 statt 12 Hostnames Migriert wurden 12 Client-Configs (nicht 10 wie geschaetzt) - zwei Worktree-Kopien in bf-network-r6{,.opencode} fand erst ein Sweep. Der opencode.jsonc-Teil steckt bereits infd05286: ich hatte den Main-Checkout direkt editiert, damit opencode die IP sofort hat, und die Parallelsession hat ihn mit eingesammelt. Doku an vier Stellen nachgezogen (Ist-Stand, "Naechster Schritt", Quick-Index, Follow-up F1) - die Drei-Stellen-Regel aus CLAUDE.md. Befunde, jetzt im F1-Eintrag festgehalten: - Claude Code und opencode haben VERSCHIEDENE Konfigpfade: .mcp.json ist pro Projekt (Claude Code), opencode liest EINE globale Datei. Deshalb reichte fuer opencode die eine Migration aus TP35 Schicht 1, waehrend Claude Code acht Einzeldateien brauchte. - n8n-mcp laeuft NICHT ohne Bearer (process.exit(1) ohne AUTH_TOKEN); er ist der einzige echte Zugriffs-Bearer im Setup. - gitea-mcp auf 10.40.20.167:3000 gebunden; Nutzen klein, da der macmini nur en0 hat. - Geschnittene Namen antworten NOERROR + leer, nicht NXDOMAIN - gegengeprueft an den vier Namen aus dem grossen Schnitt. Neu angelegt: F4 (n8n-mcp-Compose versoehnen - Container stimmt mit keiner seiner drei Definitionsquellen ueberein, compose up waere destruktiv) und F5 (Secret-Verteilung auf Container-Hosts; credentials.env liegt nur auf dem MacBook, macmini hat kein ~/.secrets). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -44,9 +44,10 @@ liest, liest ihn als Erstes: er wird bei jeder Änderung mitgezogen, nicht nur d
|
||||
**und** DNS entfernt — `pve`/`portainer`/`pve-mcp`/`ha-mcp`/`ds-bf`/`ccu`/`iobroker`/`z2m25`/`pbs`
|
||||
plus die drei CF-Access-SSH-Ziele. Ingress: `bf-mm` 6→4, `bf-nas` 6→3, `bf-pve` 9→2. **Öffentlich
|
||||
bleiben nur `vw`/`hass`/`n8n`/`gitea`** (weiterhin HTTP 200). Intern unverändert über AdGuard→Caddy
|
||||
(9× HTTP 200). ⚠️ **`gitea-mcp`/`n8n-mcp` bewusst stehen gelassen** — hängen noch in 10 Dateien
|
||||
(8 fremde Projekte, `bf-infra/opencode.jsonc`, `~/.claude.json`); **TP35 Schicht 1 ist nur global
|
||||
vollzogen, nicht auf Projekt-Ebene.** 🔴 **`bf-public` hat weiterhin 0 Connectoren** — er gehört
|
||||
(9× HTTP 200). ✅ **Nachtrag 2026-08-30 (F1 durch): `gitea-mcp`/`n8n-mcp` sind jetzt AUCH
|
||||
geschnitten** — damit **14 Hostnames** gesamt und `bf-mm` **4→2** (nur noch `n8n` + Catch-all).
|
||||
Möglich wurde das, weil zuvor **12 MCP-Client-Configs** auf LAN-IP migriert wurden (nicht 10 wie
|
||||
geschätzt: zwei Worktree-Kopien in `bf-network-r6{,.opencode}` kamen dazu). 🔴 **`bf-public` hat weiterhin 0 Connectoren** — er gehört
|
||||
laut Entscheid auf **ap1/ap2**, dort fehlen aber `container`-Paket **und** `device-mode container=yes`
|
||||
(physische Bestätigung nötig). Bis dahin stehen `bf-mm`/`bf-nas`/`bf-pve` mit **6 Containern**.
|
||||
Backups: `docs/cf-backup/*-20260830-vor-tp16.3-schnitt.json`.
|
||||
@@ -121,8 +122,9 @@ liest, liest ihn als Erstes: er wird bei jeder Änderung mitgezogen, nicht nur d
|
||||
|
||||
**Nächster Schritt (Stand 2026-08-30): Vor-Ort-Session ap1/ap2** — sie ist der einzige Weg, den
|
||||
Public-Strang auf `bf-public` zu heben und die drei Alt-Tunnel samt sechs Containern abzubauen
|
||||
(TP16.3 Follow-up F2). Davor unabhängig machbar: **F1** (`gitea-mcp`/`n8n-mcp` in 10 Dateien auf
|
||||
LAN-IP, vollendet TP35 Schicht 1) und die Announcement-Doku (TP35 Schicht 4).
|
||||
(TP16.3 Follow-up F2). ✅ **F1 ist am 2026-08-30 durch** (12 Client-Configs auf LAN-IP, danach
|
||||
`gitea-mcp`/`n8n-mcp` aus Ingress+DNS geschnitten) — davor unabhängig machbar bleibt nur noch die
|
||||
**Announcement-Doku (TP35 Schicht 4)**, die den anderen Projekten die neuen MCP-URLs mitteilt.
|
||||
|
||||
**Vorherige Fassung (Stand 2026-08-28): drei Folge-Sessions parallel** (siehe `docs/handoff-20260828-mcp-bestand-und-performance.md`):
|
||||
> - ✅ **Session A** — `/projektstatus`-Skill global für opencode (TP35 Schicht 6). Funktionsbeweis erbracht 2026-08-28.
|
||||
@@ -232,7 +234,7 @@ nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Na
|
||||
> | TP14.4 | 🔜 | CF-Access-Token | — |
|
||||
> | TP16 | ✅ | CF-Tunnel HA wieder voll | 2026-08-24 |
|
||||
> | TP16.2 | 🔜 | Härtung bypass-Dienste | — |
|
||||
> | TP16.3 | ⏳ | cloudflared-Reduktion (12 Hostnames geschnitten 08-30; Abbau braucht Vor-Ort-Session) | — |
|
||||
> | TP16.3 | ⏳ | cloudflared-Reduktion (14 Hostnames geschnitten 08-30, F1 durch; Abbau braucht Vor-Ort-Session) | — |
|
||||
> | TP17.1 | ❌ | Shelly Gen4 → Zigbee | 2026-08-23 |
|
||||
> | TP17.3 | ✅ | Shelly-Regression behoben | 2026-08-23 |
|
||||
> | TP18 | 🔜 | Garage-Objektspeicher | — |
|
||||
@@ -474,13 +476,15 @@ nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Na
|
||||
Ingress-Bilanz: `bf-mm` 6→4 · `bf-nas` 6→3 · `bf-pve` 9→2. Catch-all in allen dreien geprüft letzte.
|
||||
- **`pbs` und die SSH-Ziele standen nicht in der Kandidatenliste** — User-Entscheid 2026-08-30: beide
|
||||
mesh-only. PBS erreicht man über `10.40.20.135:8007`, SSH direkt per IP, jeweils mit WARP.
|
||||
- 🔴 **Zwei Namen bewusst NICHT geschnitten: `gitea-mcp` und `n8n-mcp`.** Die TP16.3-Vorprüfung
|
||||
(„hängt Werkzeug am öffentlichen Namen?") schlägt hier an: `gitea-mcp.emsenhuber.net` steht in
|
||||
**9 Dateien** — `~/dev/{bf-network-r6,bf-network-r6.opencode,blaueblueten-n8n,dachterrasse,ha,
|
||||
ha-xstate,poulios-recherche,valamar}/.mcp.json` plus `bf-infra/opencode.jsonc` — und
|
||||
`~/.claude.json` nutzt zusätzlich `n8n-mcp.emsenhuber.net`. **TP35 Schicht 1 hat nur die globale
|
||||
`~/.config/opencode/opencode.jsonc` auf LAN-IP migriert**; Projekt-Ebene und `~/.claude.json` sind
|
||||
zurückgeblieben. Erst migrieren, dann schneiden → Follow-up **F1** unten.
|
||||
- ✅ **Zwei Namen zunächst NICHT geschnitten: `gitea-mcp` und `n8n-mcp` — am selben Tag per F1 nachgeholt.**
|
||||
Die TP16.3-Vorprüfung („hängt Werkzeug am öffentlichen Namen?") schlug hier an:
|
||||
`gitea-mcp.emsenhuber.net` stand in **11 Dateien** (nicht 9 — beim Edit kamen zwei
|
||||
Worktree-Kopien dazu, s. F1) — `~/dev/{bf-network-r6,bf-network-r6.opencode,blaueblueten-n8n,
|
||||
dachterrasse,ha,ha-xstate,poulios-recherche,valamar}/.mcp.json` plus `bf-infra/opencode.jsonc` —
|
||||
und `~/.claude.json` nutzte zusätzlich `n8n-mcp.emsenhuber.net`. **TP35 Schicht 1 hatte nur die
|
||||
globale `~/.config/opencode/opencode.jsonc` auf LAN-IP migriert**; Projekt-Ebene und
|
||||
`~/.claude.json` waren zurückgeblieben. Regel „erst migrieren, dann schneiden" eingehalten:
|
||||
**F1 hat migriert, danach fiel der Schnitt** (Ingress `bf-mm` 4→2, beide DNS-CNAMEs gelöscht).
|
||||
- ✅ **Abnahme (2026-08-30), beide Richtungen gemessen:**
|
||||
- **intern trägt weiter:** AdGuard löst alle neun Namen unverändert auf `10.40.20.40` (Split-Horizon,
|
||||
TP31 Schritt 4), Caddy antwortet über HTTPS mit **HTTP 200** (`pve` 0,08 s · `portainer` 0,03 s ·
|
||||
@@ -511,9 +515,34 @@ und Letzteres verlangt die **physische Bestätigung am Gerät** — ap1 Technik
|
||||
→ Runbook-Bedarf als Follow-up **F2**; bis dahin bleiben die drei Alt-Tunnel mit je 2 Connectoren stehen.
|
||||
|
||||
#### 📌 Follow-ups aus dieser Session (2026-08-30)
|
||||
- **F1 — `gitea-mcp`/`n8n-mcp` FQDN→LAN-IP in 10 Dateien** (8 fremde Projekte + `bf-infra/opencode.jsonc`
|
||||
+ `~/.claude.json`). Vollendet **TP35 Schicht 1**, entsperrt die letzten zwei CF-Hostnames.
|
||||
⚠️ Projektübergreifend → gehört ins **Announcement** (TP35 Schicht 4), eigene Session.
|
||||
- ✅ **F1 — `gitea-mcp`/`n8n-mcp` FQDN→LAN-IP, DURCH 2026-08-30.** Statt der geschätzten 10 waren es
|
||||
**12 Dateien**: `~/.claude.json` (beide Namen), `bf-infra/opencode.jsonc`, 8× `dev/*/.mcp.json` und
|
||||
**zwei Worktree-Kopien** in `bf-network-r6{,.opencode}/.claude/worktrees/frosty-hermann-76f9cd/`,
|
||||
die erst ein Sweep fand. Danach fiel der Schnitt (s. oben). Backups je Datei.
|
||||
- 🔑 **Die zwei Clients haben verschiedene Konfigpfade — das ist die Stelle, an der man Dateien übersieht.**
|
||||
**Claude Code** liest `<projekt>/.mcp.json`, also **eine Datei pro Projekt**. **opencode** liest
|
||||
**eine globale** `~/.config/opencode/opencode.jsonc`; projekt-lokal existiert nur
|
||||
`bf-infra/opencode.jsonc`. Deshalb genügte für opencode die eine globale Migration (TP35 Schicht 1),
|
||||
während Claude Code acht Einzeldateien brauchte. `.mcp.json` ist **kein** opencode-Pfad.
|
||||
- 🔴 **`n8n-mcp` lässt sich NICHT ohne Bearer betreiben.** `dist/http-server.js` ruft
|
||||
`process.exit(1)`, wenn `AUTH_TOKEN` fehlt („required for HTTP mode"). Damit ist er der **einzige
|
||||
echte Zugriffs-Bearer** im Setup — `gitea-mcp` hat gar keine Auth, alles andere (`mikromcp`,
|
||||
`hostinger`, `portainer`, `github`) sind Arbeits-Credentials der MCPs, kein Zugriffsschutz.
|
||||
Der Wunsch „Bearer für alle weg" ist also faktisch schon erfüllt, bis auf den einen, der es nicht kann.
|
||||
- 🔧 **`gitea-mcp` auf `10.40.20.167:3000` gebunden** (war `0.0.0.0:3000`). Zustandslos, kein Volume,
|
||||
per `docker run` rekonstruiert; Token über die Prozessumgebung (`-e VAR` ohne Wert), **nicht** über
|
||||
argv — dieselbe Klasse wie die `sshpass -p`-Falle. ⚠️ Der Nutzen ist klein: der macmini hat **nur
|
||||
`en0`**, `0.0.0.0` war dort faktisch schon `.167`. `n8n-mcp` blieb deshalb auf `*:3001`.
|
||||
- ⚪ **Tote Diagnose-Permissions entfernt:** `blaueblueten-n8n/.claude/settings.local.json` hatte 3×
|
||||
`Bash(dig/host/curl … gitea-mcp.emsenhuber.net)` in der `allow`-Liste (10→7 Einträge). Das waren
|
||||
**keine** MCP-Verbindungen — `enabledMcpjsonServers: ["gitea-mcp"]` gibt per **Name** frei und
|
||||
blieb unberührt. Projektweit geprüft: nur dieses eine Projekt betroffen.
|
||||
- 📌 **Nachweis-Korrektur zur Abnahme oben:** geschnittene Namen antworten öffentlich mit
|
||||
**`NOERROR` + leerer Antwort**, nicht mit `NXDOMAIN` — gegengeprüft an `pve`/`portainer`/`ha-mcp`/`pbs`
|
||||
aus dem großen Schnitt, die sich identisch verhalten. Gültiger Nachweis bleibt der zurückgelesene
|
||||
Ingress plus die leere Antwort.
|
||||
- ⚠️ Projektübergreifend → gehört ins **Announcement** (TP35 Schicht 4), eigene Session.
|
||||
Dort mitnehmen: **„achte auf opencode"** sowie den neuen Pfad `~/dev/bf-infra` / Repo `admin/bf-infra`.
|
||||
- **F2 — Vor-Ort-Runbook ap1/ap2:** `container`-Paket + `device-mode`, cloudflared-Image als `.tar`,
|
||||
`bf-public`-Token, danach CNAME-Umhang der vier Public-Dienste und Abbau von `bf-mm`/`bf-nas`/`bf-pve`
|
||||
samt der **sechs** Container (LXC400 `.126`: `cloudflared-bfmm`+`cloudflared-bfnas` · macmini `.167`:
|
||||
@@ -522,6 +551,33 @@ und Letzteres verlangt die **physische Bestätigung am Gerät** — ap1 Technik
|
||||
Ebenso unberührt: Tunnel `fm.emsenhuber.net` (Standort FM).
|
||||
- **F3 — CF-Connectoren in Nautobot abbilden** (User-Wunsch 2026-08-30, „durchgehende Netzwerkdoku
|
||||
Stück für Stück"). Als **TP37** vorgeschlagen, noch nicht angelegt — wartet auf dein Okay.
|
||||
- 🔜 **F4 — `n8n-mcp`-Compose versöhnen** (Befund aus F1, 2026-08-30; User-Entscheid: eigener Punkt,
|
||||
nicht nebenbei). Der laufende Container stimmt mit **keiner** seiner Definitionsquellen überein —
|
||||
ein `docker compose up -d` wäre deshalb **destruktiv**, es würde die interne n8n-Anbindung umstellen:
|
||||
|
||||
| Quelle | `N8N_API_URL` | Netz | Port |
|
||||
|---|---|---|---|
|
||||
| `.env` (macmini) | `http://10.40.41.167:5678` ← **totes 41.x-Schema** | — | `3000` |
|
||||
| `docker-compose.yml` | `https://n8n.emsenhuber.net` (hartkodiert, ignoriert die `.env`) | `web` | `${HOST_PORT:-3000}` |
|
||||
| **laufender Container** | `http://n8n:5678` ← korrekt, Container-DNS | `n8n_default` | `3001` |
|
||||
|
||||
Zu tun: Netz als `external: true` auf `n8n_default`, `N8N_API_URL` aus der Env statt hartkodiert,
|
||||
Image auf den laufenden Digest pinnen (`sha256:2c8ff077…` = v2.57.1; heute `:latest` +
|
||||
`pull_policy: always`, was bei jedem Recreate unkontrolliert hochzieht), Bind auf `10.40.20.167`.
|
||||
⚠️ **`N8N_API_KEY` ist in allen drei Quellen verschieden**; der laufende und der aus
|
||||
`~/.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`).
|
||||
- 🔜 **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
|
||||
Ableitung mit nur den nötigen Keys je Host, oder Vollspiegelung. Zusammen mit **TP30** lösen — dort
|
||||
liegt der verwandte Posten: `~/.claude.json` hält **5 Secrets im Klartext** (4 Router-PW,
|
||||
Hostinger-Token), wo die opencode-Configs an denselben Stellen `{env:…}` nutzen.
|
||||
🔴 **Falle beim Auslesen des Stores:** die Zeilen tragen **Inline-Kommentare**
|
||||
(`CF_MM_TUNNEL_ID=7a32… # bf-mm …`). Naives `cut -d=` liefert einen 80-Zeichen-Wert, die CF-API
|
||||
antwortet dann `7003 Could not route`. Ein globales `set -a; source` setzt die Variablen gar nicht
|
||||
(`len=0`, Grund ungeklärt). Richtig ist gezieltes Lesen **mit** `sed -E 's/[[:space:]]+#.*$//'`.
|
||||
- 📌 **Ein Argument des TP ist entfallen:** die HA-Degradierung, die §7 als Nebeneffekt anführte, ist am
|
||||
**selben Tag repariert** (TP16 ✅). Der Fall steht damit allein auf dem eigentlichen Argument —
|
||||
**weniger bewegliche Teile für Dienste, die öffentlich nicht gebraucht werden.**
|
||||
|
||||
Reference in New Issue
Block a user