Files
bf-infra/mcp/INVENTORY.md
Christoph Emsenhuber fd05286e4b TP28 wieder geoeffnet: ap3 (cAP ax) vorbereitet, core ether21 Trunk, MikroMCP-Registry auf bf-infra
Dritter Access-Point ap3 (MikroTik cAP ax, cAPGi-5HaxD2HaxD) kommt dazu und loest
mittelfristig ap1 in Technik UG ab. Statt eines neuen TP wandert TP28 aus dem Archiv
zurueck -- neue Regel: ein archiviertes TP ist ein geschlossenes, kein versiegeltes
Ticket (Christoph-Direktive 2026-08-30).

Live am Core:
- ether21 ist AP-Trunk (10/20/30/40/50/90/99 tagged, Muster ether15). ⚠️ Erratum: erst
  war ether22 angenommen und getaggt; der Port hat keinen Link. Gegenprobe ueber die
  Bridge-Host-Tabelle: auf ether21 sitzt D0:EA:11:FF:16:9D = E01 vom ap3-Label.
  ether22 wieder leer.
- Backups vorher: pre-ap3-20260830.backup/.rsc auf core und ap1.
- Compliance vor und nach jeder Aenderung 104/104, 0 Drifts.

Golden Config (2 Pushes: e25d654b, 20472cdb):
- Core-L2-Block traegt ether21.
- AP-Zweig rendert die Bridge-Ports jetzt aus ap.extra_ports statt hartkodiert
  ether3/4/5. Das war die stille Annahme "AP == hAP ax2 mit 5 Ports"; der cAP ax hat
  zwei. Default in ap-common = hAP-ax2-Bestand, ap3 ueberschreibt mit [].
  Dass ap1/ap2 danach zeichengleich rendern, beweist die 0-Drift-Messung.

Kanalplan NICHT neu erfunden: TP25 hat ihn am 2026-08-24 fuer genau dieses Geraet
gerechnet (DFS vom User genehmigt). ap3 = 5180/Ce + 2437 (ch6, nicht ch1 -- ch1 bleibt
fuer ap1, damit 1/6/11 erstmals lueckenlos aufgeht). ap1/ap2 gehen beim Umzug auf
5260/Ce bzw. 5300/Ce, 5220/Ce bleibt Ausweichspur.

MikroMCP-Registry (MCP-Lifecycle, User-Freigabe 2026-08-30) -- zwei Drifts:
- MIKROMCP_CONFIG_PATH zeigte auf ~/dev/bf-network-r6 (Archiv-Repo); die identische
  Datei in bf-infra war wirkungslos. Jetzt bf-infra = SSoT.
- In opencode.jsonc fehlte MIKROMCP_CONFIG_PATH ganz, hinterlegt waren nur ap1/ap2 --
  opencode kannte core/branch gar nicht. Beide Clients zeigen jetzt auf dieselbe
  Registry; ap3 aufgenommen, rosVersion von stale 7.23/7.19.5 auf 7.24 korrigiert.
  Neustart des MCP noetig, Registry wird nur beim Start gelesen.

Noch offen: physischer Bring-up (Datei liegt bereit), ap1-Radios aus, CAPsMAN-Objekte
fuer ap3, Nautobot-Adoption, Messrunde -- und die Passwort-Rotation: das gemeinsame
MikroTik-Admin-PW ist in dieser Session durch eine ungefilterte Ausgabe des
mikromcp-env-Blocks ins Transkript geraten und gilt als verbrannt (Posten fuer TP30).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 12:14:21 +02:00

73 lines
10 KiB
Markdown

# MCP-Inventar — BF (Single Source of Truth gegen "1000 MCP-Leichen")
> **Regel:** Jeder MCP-Server, der für BF läuft, steht **hier** — sonst existiert er nicht.
> Kein lokaler Ad-hoc-`npx`-Wildwuchs auf Laptops. Zentral = Docker auf einem Host, FQDN-adressiert.
> Wer einen MCP abschaltet, **streicht die Zeile** (oder setzt Status `retired` mit Datum).
>
> **Richtungsentscheid (User, 2026-07-11):** MCP-Dienste gehören grundsätzlich auf **zentrale
> Serverdienste, nicht auf den Client**. Die aktuell **Client-lokal** laufenden (MikroMCP stdio)
> sind bewusste **pragmatische Interims** ("Hauptsache es funktioniert") und werden **zu einem
> späteren Zeitpunkt zentral zusammengezogen** (ein Host, Container, FQDN) — Teil
> der Control-Plane-Konsolidierung (vgl. TP11 / Komodo-Migration).
>
> **Bestand-Aufnahme 2026-08-28 (Portainer-API, alle 4 Endpoints live):**
> Mac mini (`10.40.20.167`, Portainer-Endpoint 20) hat **5 Container**: gitea, gitea-mcp,
> n8n, n8n-redis, n8n-mcp. **Mac mini ist der n8n-Host, NICHT der zentrale MCP-Host**
> (User-Direktive 2026-08-28, Performance-Restriktion: User-Workstation soll nicht zusätzlich
> durch MCP-Clients belastet werden). Der zentrale MCP-Host ist die **DS923** (`nas-bf`,
> Portainer-Endpoint 14) — dort liegen pve-mcp + nautobot-Stack. gitea-mcp + n8n-mcp laufen
> aktuell **noch** auf dem macmini (historisch gewachsen, Container-Definition dort) und
> gehören **bei Gelegenheit** auf die DS923 umgezogen (separater Punkt, **nicht** Teil dieser Session).
> DS923 (Endpoint 14) hat pve-mcp + nautobot-Stack. pve (Endpoint 2) und NAS-FM (Endpoint 21)
> ohne MCPs. Verifikation **alle 4 Endpoints** abgefragt, nicht nur Stichproben.
>
> **Portier-Regel (ab 2026-08-28):** bei jeder MCP-Eintragung/-Stilllegung Container-Existenz
> in **allen 4 Endpoints** verifizieren (`/api/endpoints/<id>/docker/containers/json?all=1`),
> nicht in einer Config glauben. Drift-Doku ist wiederholter Befund — siehe Handoff 2026-08-27 D3/D4.
>
> **MCP-Hosts künftig nur WARP/lokal (User-Direktive 2026-08-28):** kein neuer öffentlicher
> FQDN, kein neuer CF-Tunnel für MCPs. Referenzierung über lokale IP (10.40.20.x). Folge
> für bereits öffentlich exponierte MCPs (gitea-mcp, n8n-mcp): laufen lassen bis Migration,
> FQDNs werden beim Bump **nicht** erneuert. Neue MCPs entstehen entweder als
> projektspezifische `.mcp.json` mit uvx-stdio (Beispiel: portainer-mcp) oder als
> Container im BF-LAN ohne öffentliches Fronting.
## Aktive / geplante MCPs
> **Netzwerk-Schema ab 2026-08-27:** `10.40.<vlan>.<oktet>` — altes `10.40.41.x` ist tot.
> **Caddyfile (`caddy/Caddyfile`)** ist SSoT für FQDN→Backend-Port (z.B. Z. 75: `n8n-mcp.emsenhuber.net` → `10.40.20.167:3001`).
| MCP | Zweck / Geräte | Host | Transport / Endpoint | Image | Config | Status |
|---|---|---|---|---|---|---|
| **MikroMCP** (AliKarami) | MikroTik-Flotte: `crs326-core` `.99.1` · `crs326-branch` `.99.2` · ap1 `.99.11` · ap2 `.99.12` · **🆕 ap3 `.99.13` (cAP ax, 2026-08-30, Bring-up offen)** — alle RouterOS **7.24** | **jetzt: lokal (dieser Mac)** stdio / Ziel: HTTP-Container auf Mac mini `10.40.20.167` | jetzt **stdio** (`npx mikromcp serve`) / Ziel HTTP `:3000` | `ghcr.io/alikarami/mikromcp:latest` (HTTP) bzw. npm `mikromcp` (stdio) | **Registry = `bf-infra/mcp/mikromcp/config/routers.yaml`** (seit 2026-08-30 SSoT) + opencode/Claude-Code user-config | 🟢 **live (stdio), doctor 12/12, in opencode ✓Connected.** 🔴 **Zwei Drifts am 2026-08-30 gefunden und behoben:** (a) `MIKROMCP_CONFIG_PATH` in `~/.claude.json` zeigte auf **`~/dev/bf-network-r6`** (Archiv-Repo) — die identische Datei in `bf-infra` war **wirkungslos**; (b) in `opencode.jsonc` fehlte `MIKROMCP_CONFIG_PATH` **ganz** und es waren nur `ROUTER_AP1/AP2`-Creds hinterlegt → opencode kannte core/branch gar nicht. Beide Clients zeigen jetzt auf dieselbe Registry, `rosVersion` von stale 7.23/7.19.5 auf 7.24 korrigiert. ⚠️ **Neustart des MCP nötig** (Registry wird nur beim Start gelesen). ⚠️ opencode nutzt Env-Indirektion `{env:MCP_MIKROMCP_*}`, `~/.claude.json` **Klartext** — für ap3/core/branch fehlen noch `MCP_MIKROMCP_ROUTER_AP3_PASS`, `MCP_MIKROMCP_CRS326_CORE_PASS`, `MCP_MIKROMCP_CRS326_BRANCH_PASS` in `~/.secrets/exports.zsh` (TP30)** |
| **gitea-mcp** (eigenbau) | Gitea REST API (Repo-Verwaltung, Issues, Wiki, …) | **Mac mini** `10.40.20.167` (Portainer-Endpoint 20) — Docker-Bridge-IP `172.17.0.3:3000` — ⚠️ **sollte auf DS923 umziehen** (Performance-Restriktion: macmini ist User-Workstation, kein zentraler MCP-Host) | **StreamableHTTP** `https://gitea-mcp.emsenhuber.net/mcp` (Caddy + CF) bzw. `http://10.40.20.167:3000/mcp` (LAN-direkt) | `docker.io/node:22-alpine` (eigener Build) | Repo `mcp/` hatte **kein** Config-Verzeichnis — Container-Definition lebt auf macmini | 🟢 **live (seit unknown, gefunden 2026-08-28), war aus dem Inventar verschwunden. serverInfo: gitea-mcp 0.0.10. Umzug auf DS923 ausstehend (Performance-Restriktion)** |
| **n8n-mcp** (czlonkowski) | n8n-public-API (Workflows, Credentials, Executions) | **Mac mini** `10.40.20.167` (Portainer-Endpoint 20, **n8n-Host** — n8n `:5678`, n8n-redis `:6379`, n8n-mcp `:3001`) — Docker-Bridge-IP `172.19.0.4` → PublicPort `3001:3000` | **StreamableHTTP** `https://n8n-mcp.emsenhuber.net/mcp` (Caddy + CF) bzw. `http://10.40.20.167:3001/mcp` (LAN-direkt) | `ghcr.io/czlonkowski/n8n-mcp:latest` | keine im Repo (`mcp.json.example` in `blaueblueten-n8n/` ist alt, stdio-Modus) | 🟢 **live (gefunden 2026-08-28, war **nicht** im Inventar). FQDN → 401 ohne Bearer (Auth-Sanierung TP16.3). LAN-direkt :3001 antwortet korrekt mit 401 = Bearer fehlt, Server lebt. Bleibt auf macmini (zusammen mit n8n — n8n-Workflows lösen Tool-Calls aus, lokale Performance-Kopplung gewollt)** |
| **shelly-mcp** (eigenbau, FastMCP) | ~26 Shellys Gen3/4 — VLAN1→VLAN30-Migration (TP17) + Verwaltung | **geplant:** DS923 (`10.40.20.10`), macvlan-IP **`10.40.20.180`** | **StreamableHTTP** `http://10.40.20.180:3030/mcp` (geplant) | eigenbau `bf/shelly-mcp:0.1` (DS923-lokal gebaut aus `mcp/shelly/Dockerfile`) | `mcp/shelly/` ✓ (`Dockerfile` + `BUILD.md` + `requirements.txt`) · Stack gitignored in `docs/nas-vlan20/stacks/shelly-mcp.yml` | 🟡 **staged — Image-Build + Stack-Deploy auf DS923 ausstehend. Vorher-Stand war localhost `127.0.0.1:3030` mit `enabled=false` (Handoff 2026-08-28). Live-Verifikation 23 Shellys auf `10.40.30.180-250` (VLAN30) bestätigt 2026-08-28** |
| **pve-mcp** (samik081) | Proxmox VE API (Host `.100`) | DS923 (`10.40.20.10`), macvlan-IP **`10.40.20.173`** | **StreamableHTTP** `http://10.40.20.173:3000/mcp` (+ Health `/health` → `mcp-pve 0.6.1`) | `ghcr.io/samik081/mcp-pve:latest` | — (Stack via Portainer) | 🟢 **live, in opencode + claude.json eingetragen. Drift-Korrektur 2026-08-28: war im Inventar als „SSE `/sse" gelistet, Realität ist StreamableHTTP** |
| **komodo-mcp** (samik081) | Docker-Management via Komodo Core (ersetzt Portainer) | DS923 (`10.40.20.10`), macvlan-IP **`10.40.20.176`** | SSE `http://10.40.20.176:3000/sse` (geplant) | `ghcr.io/samik081/mcp-komodo:latest` | `mcp/komodo/` ✓ (`.env.example` → `.env` nach Phase 1) | 🟡 **geplant — Migration: `mcp/komodo/MIGRATION.md`** |
| **portainer-mcp** (offiziell, PyPI `mcp-portainer`) | Portainer CE 2.42.0 — Endpoints, Stacks, Container, Docker-Proxy; volle Berechtigung, replaces Direkt-API-Calls. **Vorbedingung erfüllt 2026-08-28:** Portainer-Server Bump 2.40.0 → 2.42.0 (Latest-Tag in `portainer/portainer-ce`, **nicht 2.42.6 wie README — Docker-Hub hat nur 2.42.0 als letzten 2.42.x-Tag**), Rollback-Image-Tag `portainer/portainer-ce:2.40.0-preupgrade-20260828` + Settings-JSON-Dump in `docs/portainer-upgrade-20260828/preupgrade-state.json`. | **lokal auf Mac, uvx stdio** (User-Direktive 2026-08-28: MCP-Hosts künftig nur WARP/lokal, kein neuer öffentlicher FQDN, Performance-Grund). **NUR projektebene:** `bf-infra/.mcp.json` (gitignored via `.mcp.json`-Pattern). Andere Projekte unberührt. | **stdio** via `uvx --from "mcp-portainer~=2.42.0" mcp-portainer` | `portainer_mcp` Python-Wheel | `bf-infra/.mcp.json` (gitignored) mit `PORTAINER_URL=https://10.40.20.126:9443`, `PORTAINER_API_KEY=${env:PORTAINER_API_KEY}`, `PORTAINER_TLS_VERIFY=0`. `mcp/portainer/.env` weiter SSoT für Token. | 🟢 **live seit 2026-08-28 — 193 Tools, Abnahme: `EndpointList` 4/4 Endpoints, `StackList` 31 Stacks (4/20/4/3), `StackInspect(202)` pve-mcp auf Endpoint 14 bestätigt. Tool-Gate: `get_guidance()` pro Session zwingend vor erstem Read.** |
| ~~omada-mcp~~ (jmtvms v0.15) | TP-Link Omada Controller | — | — | `jmtvms/tplink-omada-mcp:latest` | `mcp/omada/` ✓ | ⛔ **RETIRED 2026-08-27** — Omada-Stack raus, wir fahren auf MikroTik. Container stoppen, Image optional behalten. |
| ~~omada-controller~~ | Omada Software Controller | `10.40.20.175:8043` | — | `mbentley/omada-controller:6.2` | `omada/docker-compose.yml` | ⛔ **RETIRED 2026-08-27** |
| ~~ALLNET-MCP~~ | ALLNET ALL-SG8316M Core-Switch | — | — | — | — | ⛔ **bewusst NICHT** (Telnet/1-VTY/15-min-Lock auf Core = zu fragil). User-Entscheid: erst beschriebener Weg, sonst MikroTik-Core-Tausch. |
Legende: 🟢 live · 🟡 staged (Config da, nicht deployed) · 🔴 blockiert · ⛔ bewusst nicht gemacht
## Anti-Sprawl-Regeln
1. **Zentral statt lokal:** MCPs laufen als Container auf einem festen Host, nicht als `npx` pro Laptop.
2. **Eine Zeile pro MCP** in dieser Tabelle. Kein Eintrag → abschalten.
3. **Config im Git** (`mcp/<name>/`), Secrets nur in `.env` (gitignored).
4. **FQDN statt IP**, sobald eingerichtet (DNS-Rewrite) → Endpoint-Spalte updaten.
5. **Review-Datum:** mind. halbjährlich diese Tabelle gegen tatsächlich laufende Container prüfen
(`docker ps` auf den Hosts).
6. **Pflicht-Verifikation (seit 2026-08-28):** bei jeder Eintragung/-Stilllegung Container-Existenz
in **allen 4 Portainer-Endpoints** prüfen (`pve` Id 2, `nas-bf` Id 14, `macmini` Id 20, `nas-fm` Id 21).
Nicht "im Handoff gelesen" — **live abgefragt**.
## ALLNET — warum kein MCP
ALL-SG8316M (Core) nach FW-2.2.1-Flash: **Web-UI tot, nur Telnet-CLI, kein SSH/REST/SNMP-Write,
nur 1 VTY-Line, ~15 min Busy-Lock bei Stale-Sessions.** Ein MCP darüber wäre auf dem **Core-Switch**
(an dem alles hängt) fragil und lockout-gefährdet. → Management bleibt bei der bestehenden
Telnet-CLI-Toolchain (`switch/cli/`). **Strategische Option:** Core-Switch (Methusalem, Bj. 2015)
gegen einen **Omada-Switch** tauschen → fällt unter denselben Omada-Controller/omada-mcp.
Das ist Hardware-Ausgabe + Core-Cutover → **User-Entscheidung** (offen).