Zum Inhalt

Homelab MCP – Home-Assistant-MCP-Anbindung

Stand 08.09.2026: CT 109 ist inzwischen über eine eigene interne MCP-Upstream-Capability direkt mit dem bestehenden Home-Assistant-MCP auf 10.10.10.20:9583 verbunden. Die Verbindung ist optional und bleibt durch die äußere Homelab-MCP-Policy getrennt in read, write und destructive.

Ziel

Der neue generische MCP soll Home Assistant nicht über freie HTTP-Aufrufe ansprechen. Stattdessen gibt es eine dedizierte interne Capability, die ausschließlich die fünf bekannten Gateway-Tools des bestehenden HA-MCP verwendet.

flowchart LR
    CLIENT["MCP-Client"] --> HMCP["homelab-mcp auf CT 109"]
    HMCP --> POLICY["Default-Deny-Policy"]
    POLICY --> HAPLUGIN["Plugin home-assistant-mcp"]
    HAPLUGIN --> UPSTREAM["interne home-assistant-mcp-upstream Capability"]
    UPSTREAM --> HAMCP["HA-MCP 10.10.10.20:9583"]
    HAMCP --> HA["Home Assistant"]

Äußere Gateway-Tools

Das Plugin spiegelt absichtlich nicht den vollständigen HA-MCP-Toolkatalog nach außen.

Stattdessen existieren nur:

Tool Risiko Stand CT 109
ha_search_tools read freigegeben
ha_call_read_tool read freigegeben
ha_get_skill_guide read freigegeben
ha_call_write_tool write gesperrt
ha_call_delete_tool destructive gesperrt

Die aktuell aktive Policy lautet:

home-assistant-mcp.read=true
home-assistant-mcp.write=false
home-assistant-mcp.destructive=false

Damit erscheinen die beiden riskanteren Gateways bereits nicht in tools/list.

Warum ein Gateway statt aller HA-Tools?

HA-MCP kann sehr viele Tools anbieten und sich unabhängig vom äußeren MCP weiterentwickeln.

Der Ablauf bleibt deshalb stabil:

  1. ha_search_tools durchsucht den aktuellen Upstream-Katalog;
  2. das gewünschte innere HA-Tool wird gefunden;
  3. je nach Risiko wird es über den passenden äußeren Gateway aufgerufen;
  4. die äußere Homelab-MCP-Policy entscheidet weiterhin, ob dieser Gateway überhaupt sichtbar ist.

Neue HA-MCP-Tools erhalten dadurch nicht automatisch neue Rechte im äußeren MCP.

Lokale Upstream-Konfiguration

Die installationsspezifische Konfiguration liegt auf CT 109 unter:

/etc/homelab-mcp/upstreams.json

Darin stehen nur nicht geheime Metadaten:

  • Target-ID home-assistant;
  • Capability home-assistant-mcp-upstream;
  • Credential-Name ha-mcp-url;
  • Plugin-Allowlist home-assistant-mcp;
  • die fünf erlaubten Gateway-Toolnamen;
  • allowInsecureHttp.

Der eigentliche Secret-Pfad der HA-MCP-URL steht nicht in dieser Datei und nicht im Wiki.

Secret / URL-Credential

Die bereits produktiv verwendete interne HA-MCP-URL wurde von CT 108 übernommen, ohne den Wert auszugeben.

Auf CT 109 liegt sie als root-geschützte Secret-Datei:

/etc/homelab-mcp/secrets/ha-mcp-url

Rechte:

root:root 0600

Der vollständige URL-Wert einschließlich Secret-Pfad wird weder im GitHub-Repository noch im Wiki dokumentiert.

systemd LoadCredential

Der unprivilegierte Benutzer homelab-mcp erhält keinen direkten Leserechtszugriff auf den gesamten Secret Store.

Stattdessen lädt systemd genau dieses eine Credential für homelab-mcp.service:

[Service]
Environment=HOMELAB_MCP_UPSTREAM_CONFIG=/etc/homelab-mcp/upstreams.json
LoadCredential=ha-mcp-url:/etc/homelab-mcp/secrets/ha-mcp-url

systemd stellt dem Dienst danach ein eigenes CREDENTIALS_DIRECTORY bereit.

Geprüfter Zustand auf CT 109:

ha-mcp-url  homelab-mcp:homelab-mcp 0400

Der normale MCP-Prozess sieht damit nur das explizit geladene Credential und nicht den kompletten root-eigenen Secret Store.

Der separate Admin-Dienst läuft ohnehin als geschützter Root-Kontrollpfad und kann für seine Plugin-Bereitschaft den lokalen Secret Store direkt prüfen.

Credential-Härtung

Der neue Credential-Reader akzeptiert nur streng validierte Namen und:

  • bleibt innerhalb des konfigurierten Credential-Verzeichnisses;
  • akzeptiert nur reguläre Dateien;
  • lehnt Symlinks ab;
  • lehnt leere oder übergroße Credential-Dateien ab;
  • gibt Secret-Werte nicht über normale Admin-Endpunkte zurück.

HTTP im internen LAN

Der vorhandene HA-MCP-Endpunkt auf Port 9583 verwendet intern HTTP.

Deshalb ist für genau diesen Target gesetzt:

"allowInsecureHttp": true

Diese Freigabe bedeutet nicht, dass beliebige HTTP-Upstreams erlaubt sind.

Der neue Transport akzeptiert unverschlüsseltes HTTP nur zu literal angegebenen privaten beziehungsweise Loopback-IP-Adressen. Öffentliche IP-Adressen über HTTP werden auch bei gesetztem Flag abgewiesen.

HTTPS bleibt der Standard für alle anderen Upstreams.

Retry-Regeln

Read-only Gateway-Aufrufe dürfen nach einem Transportfehler einmal die Verbindung neu aufbauen und wiederholt werden:

ha_search_tools
ha_call_read_tool
ha_get_skill_guide

Write-/Delete-Aufrufe werden bei einem unsicheren Transportfehler nicht automatisch wiederholt:

ha_call_write_tool
ha_call_delete_tool

Wenn nicht sicher festgestellt werden kann, ob die Aktion bereits bei HA angekommen ist, liefert der äußere MCP ausdrücklich den Hinweis, dass die Operation möglicherweise bereits ausgeführt wurde und nicht automatisch erneut gesendet werden darf.

Capability-Fassade

Beim ersten Live-Test wurde ein Architekturfehler gefunden: Die Registry hatte das komplette Capability-Objekt mit Object.freeze() eingefroren.

Das war bei zustandslosen Capabilities unauffällig, verhinderte aber beim neuen MCP-Upstream das Setzen des internen Verbindungszustands client und connecting.

Die Registry wurde deshalb geändert:

  • das echte Capability-Objekt bleibt intern und darf seinen eigenen Zustand verwalten;
  • Plugins erhalten nur eine eingefrorene Methoden-Fassade;
  • interne Felder wie Clientzustand oder Secrets werden nicht nach außen gereicht;
  • Methoden bleiben fest an die interne Implementierung gebunden.

Damit bleibt die ursprüngliche Sicherheitsgrenze erhalten, ohne zustandsbehaftete Transportschichten zu blockieren.

Erfolgreiche Live-Tests

Der aktuelle CT-109-Stand wurde Ende-zu-Ende mit dem offiziellen MCP-v2-Client geprüft.

1. Upstream direkt

Der v2-Client konnte direkt mit dem bestehenden HA-MCP kommunizieren. Damit war bestätigt, dass HA-MCP und der neue MCP-v2-Client grundsätzlich interoperabel sind.

2. Interne Capability

Die home-assistant-mcp-upstream-Capability wurde als Benutzer homelab-mcp mit dem systemd-Credential getestet.

Ergebnis: erfolgreich.

3. Äußerer MCP

Der sichtbare Toolkatalog auf CT 109 enthielt exakt die erlaubten HA-Gateways:

ha_search_tools
ha_call_read_tool
ha_get_skill_guide

Nicht sichtbar:

ha_call_write_tool
ha_call_delete_tool

4. Toolsuche

ha_search_tools mit der Suche nach system overview lief erfolgreich durch CT 109 bis HA-MCP.

Unter anderem wurde das read-only Tool gefunden:

ha_get_system_health

5. Read-Tool-Aufruf

Anschließend wurde über:

ha_call_read_tool

ha_get_system_health erfolgreich aufgerufen.

6. Skill-Guide

Auch ha_get_skill_guide wurde erfolgreich über CT 109 ausgeführt.

7. Audit

Die äußeren Aufrufe erscheinen im privileggetrennten Homelab-MCP-Audit unter anderem als:

ha_search_tools
ha_call_read_tool
ha_get_skill_guide

Die Tool-Argumente und Rückgaben werden dabei nicht in das äußere Audit kopiert.

HA-MCP besitzt zusätzlich sein eigenes inneres Audit für die tatsächlich ausgeführte Home-Assistant-Operation.

Aktueller sichtbarer MCP-Katalog auf CT 109

Mit der aktuellen read-only Policy sind über den neuen MCP insgesamt sichtbar:

system_status
proxmox_list_containers
proxmox_get_container_status
ha_search_tools
ha_call_read_tool
ha_get_skill_guide

Proxmox-Start/Stop/Restart sowie HA-Write/Delete bleiben weiterhin policybedingt unsichtbar.

Nächste Schritte

Die HA-Anbindung ist als read-only Basis abgeschlossen.

Als Nächstes können die Verwaltungsfunktionen der Admin-Oberfläche weiter ausgebaut werden, insbesondere Update/Rollback, Backup/Restore und Verbindungsverwaltung. Write-/Delete-Rechte für Home Assistant werden erst später bewusst über die Policy freigeschaltet und separat getestet.