Files
MUA-Mikes-Unraid-Agent/README.md
T

14 KiB

MUA — Mikes Unraid Agent

MCP-Server für Unraid: Docker-Container, Netzwerk und System-Tools. Kompiliertes Bun-Binary (TypeScript), läuft als SysVinit-Service auf Unraid.

  • MCP-Endpunkt: http://UNRAID-IP:3002/mcp (Streamable HTTP, POST-only, JSON-RPC 2.0)
  • Health-Check: http://UNRAID-IP:3002/health (offen, ohne Auth)
  • Config-Server: http://127.0.0.1:3013/config (localhost + separater Admin-Token)
  • Auth: API-Key (Bearer-Token) für /mcp
  • Tools: 35 (Docker, Community Applications, Netzwerk, Unraid-System und optionale Toolbox)

Für Hermes und andere KI-Agenten

Dieses Repository enthält bereits den fertigen MUA-MCP. Ein Agent soll keinen zweiten Unraid-MCP entwickeln, sondern zuerst AGENTS.md und die kompakte Hermes-Anleitung lesen. Darin stehen Erkennung, direkte Registrierung, Secret-Behandlung, Tests und Rückbau vollständig.

Kurzform für Hermes:

hermes mcp add unraid \
  --url http://UNRAID-IP:3002/mcp \
  --auth header \
  --connect-timeout 30
hermes mcp test unraid

Hermes fragt den MUA-API-Key verdeckt ab und speichert ihn außerhalb des Repositories. Läuft /health bereits erfolgreich, ist kein Build und keine erneute MUA-Installation nötig.


Architektur

┌─────────────────────────────────────────────────────────┐
│  Unraid (UNRAID-IP)                                    │
│                                                        │
│  /usr/local/bin/mua  (kompiliertes Bun-Binary)         │
│  ├── MCP-Server      0.0.0.0:3002  (Bearer-Auth)       │
│  └── Config-Server   127.0.0.1:3013 (nur localhost)    │
│                                                        │
│  /etc/rc.d/rc.mua  (SysVinit-Service)                  │
│  /boot/config/plugins/mua/mua.conf  (API-Key + Tools)  │
│  /usr/local/emhttp/plugins/mua/mua.page  (WebGUI-Tab)  │
└─────────────────────────────────────────────────────────┘
         ▲                          ▲
         │ HTTP + Bearer-Token      │ HTTP (localhost)
         │                          │
┌────────┴─────────┐      ┌────────┴─────────┐
│  MCP-Client      │      │  Unraid WebGUI   │
│  (Hermes, etc.)  │      │ User Utilities → MUA │
└──────────────────┘      └──────────────────┘

Wichtig: Der MCP-Endpunkt (Port 3002) ist extern erreichbar und braucht einen Bearer-Token. Der Config-Server (Port 3013) läuft nur auf localhost und verlangt zusätzlich einen bei jedem Start neu erzeugten Admin-Token. Die WebGUI schützt schreibende Formulare außerdem mit einem CSRF-Token.

Sicherheitsmodell

  • Neuinstallationen starten im Profil Nur Lesen. Container-Steuerung, aktive Netzwerktests, Container-Umbauten und die Root-Shell sind aus.
  • Für Diagnosen steht unraid_system_shell_readonly bereit. Es startet nur fest freigegebene Leseprogramme als direkte Argumentliste, niemals über /bin/sh; Verkettungen, Pipes, Umleitungen und schreibende Optionen werden dadurch verhindert. Die freie Root-Shell bleibt separat und kritisch.
  • none bedeutet tatsächlich keine Tools aktiv; all ist ein expliziter Vollzugriff und wird in der GUI deutlich gewarnt.
  • Container-Umgebungswerte werden nie ausgegeben, nur ihre Variablennamen.
  • Häufige Secret-Formate in Logs werden zusätzlich redigiert. Logs können trotzdem Nutzdaten enthalten und sollten gezielt abgefragt werden.
  • Der API-Key erscheint nur unmittelbar nach seiner Erzeugung vollständig.
  • Tool-Aufrufe werden ohne Argumente oder Ausgaben in /var/log/plugins/mua-audit.log protokolliert.
  • Community-Applications-Installationen laufen immer über Suche, Vorschau und ein exakt an diese Änderung gebundenes, zehn Minuten gültiges Freigabeticket. Das Ergebnis bleibt über ein reguläres Unraid- Benutzertemplate vollständig in der Docker-GUI verwaltbar.
  • CORS ist standardmäßig aus. Requests sind auf 1 MiB, 120 pro Minute je Client und vier gleichzeitig laufende Werkzeuge begrenzt. Diese Grenzen lassen sich per Umgebungsvariable anpassen.

Installation

1. Plugin installieren

Über die Unraid-WebGUI: Settings → Plugins → Community Plugins → MUA (Mikes Unraid Agent) suchen und installieren.

Oder manuell:

# .txz von Gitea laden
curl -O https://git.casaderoll.de/michael/MUA-Mikes-Unraid-Agent/raw/branch/main/dist/mua-2026.08.31.r028-x86_64-1.txz

# Installieren
upgradepkg --install-new mua-2026.08.31.r028-x86_64-1.txz

2. Service starten

/etc/rc.d/rc.mua start

Der Service startet automatisch bei jedem Boot (SysVinit).

3. Health-Check

curl http://UNRAID-IP:3002/health
# → {"status":"ok","version":"2026.08.24.r022","auth":"required"}

API-Key generieren (WebGUI)

  1. Settings → User Utilities → MUA in der Unraid-WebGUI öffnen
  2. Unter „API-Key (Authentifizierung)" auf „Neuen API-Key generieren" klicken
  3. Den einmalig angezeigten Key kopieren (64-stellige Hex-Zeichenfolge)

Der Key wird in /boot/config/plugins/mua/mua.conf gespeichert (chmod 600).

Hinweis: Der Key wird nur einmal angezeigt. Wenn du ihn verlierst, generiere einen neuen — der alte funktioniert dann nicht mehr.


MCP-Client konfigurieren

MUA ist ein Standard-MCP-Server (Streamable HTTP, POST-only, JSON-RPC 2.0). Jeder MCP-Client kann es nutzen — URL + Bearer-Token reichen:

URL:  http://UNRAID-IP:3002/mcp
Auth: Authorization: Bearer <dein-api-key>

MUA läuft direkt auf Unraid und spricht Streamable HTTP. Ein SSH-Wrapper ist weder erforderlich noch empfohlen. Dadurch bleiben Verbindungen kompakt und routinemäßige Tool-Aufrufe erzeugen keine SSH-Anmeldungen im Unraid-Syslog.

Beispiel: Hermes Agent

Hermes bindet MUA direkt per HTTP an. Wenn MCPHub eingesetzt wird, zeigt Hermes stattdessen auf die vom Hub veröffentlichte Route; MCPHub verbindet sich dann direkt mit diesem MUA-Endpunkt.

# Direkte Anbindung ohne MCPHub
mcp_servers:
  unraid:
    url: http://UNRAID-IP:3002/mcp
    headers:
      Authorization: Bearer <dein-api-key>
    timeout: 1800
    connect_timeout: 30
    enabled: true

Bei einer zentralen MCPHub-Installation wird dieselbe URL einmalig im Hub registriert. Alle Clients verwenden anschließend die Hub-Route und benötigen keine eigene SSH- oder MUA-Konfiguration.

Beispiel: Direkter HTTP-Test (curl)

# Health-Check (ohne Auth)
curl http://UNRAID-IP:3002/health

# MCP-Initialisierung (mit Auth)
curl -X POST http://UNRAID-IP:3002/mcp \
  -H "Authorization: Bearer <dein-api-key>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'

# Tool-Liste
curl -X POST http://UNRAID-IP:3002/mcp \
  -H "Authorization: Bearer <dein-api-key>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'

# Tool aufrufen
curl -X POST http://UNRAID-IP:3002/mcp \
  -H "Authorization: Bearer <dein-api-key>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"unraid_docker_list","arguments":{}}}'

Ohne API-Key → 401

curl -X POST http://UNRAID-IP:3002/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'
# → 401 Unauthorized

Tools aktivieren/deaktivieren (WebGUI)

In Settings → User Utilities → MUA stehen vier Sicherheitsprofile bereit:

  • Nur Lesen (empfohlen): Status, Diagnose, Logs und Inventar
  • Betrieb + Diagnose: zusätzlich aktive Prüfungen und Start/Stop/Restart
  • Alles sperren: MCP bleibt erreichbar, bietet aber keine Werkzeuge an
  • Vollzugriff: einschließlich Container-Umbau und uneingeschränkter Root-Shell

Zusätzlich kann jedes Werkzeug einzeln nach Risikostufe freigegeben werden:

Gruppe Tools
Docker (16) unraid_docker_list, unraid_docker_inspect, unraid_docker_logs, unraid_docker_analyze_logs, unraid_docker_processes, unraid_docker_stats, unraid_docker_info, unraid_docker_update_status, unraid_docker_start, unraid_docker_stop, unraid_docker_restart, unraid_docker_create, unraid_docker_modify, unraid_docker_update, unraid_docker_update_verified_batch, unraid_docker_rebuild
Community Applications (3) unraid_ca_search, unraid_ca_install_preview, unraid_ca_install
Netzwerk (6) unraid_network_inventory, unraid_network_list, unraid_network_inspect, unraid_network_host_state, unraid_network_audit_tcp, unraid_network_lan_probe
System (13) unraid_system_health, unraid_storage_status, unraid_disk_health, unraid_notifications_list, unraid_shares_list, unraid_share_inspect, unraid_files_inventory, unraid_system_connection_test, unraid_system_shell_readonly, unraid_system_shell, unraid_system_job_start, unraid_system_job_status, unraid_system_job_cleanup

Deaktivierte Tools werden vom MCP-Server gefiltert — sie erscheinen nicht in tools/list und können nicht aufgerufen werden (→ ERROR: Tool disabled).

Optionaler Agent-Werkzeugcontainer

MUA kann einen allgemeinen Werkzeugcontainer dynamisch über das Docker-Label mike.ai.role=toolbox erkennen. Sobald mindestens ein solcher Container existiert, wird in der WebGUI der Schalter „Werkzeugcontainer für KI-Agenten bekanntgeben“ verfügbar. Fehlt das Label, bleibt er ausgegraut.

Bei aktiviertem Schalter stellt MUA zwei eigene, dynamisch sichtbare Werkzeuge bereit:

  • unraid_toolbox_status erkennt den Container und prüft angefragte Programme wie ffmpeg, ffprobe, yt-dlp oder mediainfo.
  • unraid_toolbox_exec führt Befehle direkt darin aus und kann auf ausdrücklichen Auftrag fehlende Pakete dort installieren.

Der Containername ist nicht fest in MUA eingebaut. Wird der Container ersetzt, genügt dasselbe Label am Nachfolger. Die Toolbox-Werkzeuge erscheinen in keinem MCP-Client, solange der Schalter aus ist oder kein passender Container existiert.

Beispiel für Docker beziehungsweise DockerMan ExtraParams:

--label=mike.ai.role=toolbox

Bei freigegebenem Vollzugriff ist unraid_system_shell das direkte Terminal auf dem Unraid-Host. Agenten sollen es für normale Docker-, Datei- und Administrationsaufträge unmittelbar verwenden und weder den MUA-Quellcode untersuchen noch Befehle über ein lokales Client-Terminal weiterreichen. Das Werkzeug akzeptiert mehrzeilige Skripte bis 256 KiB und Laufzeiten bis 30 Minuten. Nur noch längere Arbeiten gehören in unraid_system_job_start.


Service-Verwaltung

Aktion Befehl
Starten /etc/rc.d/rc.mua start
Stoppen /etc/rc.d/rc.mua stop
Neu starten /etc/rc.d/rc.mua restart
Status /etc/rc.d/rc.mua status
Logs tail -f /var/log/plugins/mua.log

Auto-Restart bei Update

Das Binary prüft alle 30 s, ob sich das Binary auf Platte geändert hat (mtime + size). Wenn ja → rc.mua restart + sauber beenden. Der neue Prozess startet automatisch. Zusätzlich führt der POST-INSTALL-Hook im .plg nach jedem Update rc.mua restart aus.


Konfiguration

Datei Zweck
/boot/config/plugins/mua/mua.conf API-Key + Tool-Filter (chmod 600)
/usr/local/emhttp/plugins/mua/mua.page WebGUI-Tab (PHP)
/etc/rc.d/rc.mua SysVinit-Service-Script
/usr/local/bin/mua Kompiliertes Bun-Binary

Config-Datei-Format (mua.conf)

MUA_API_KEY=a1b2c3d4...
MUA_ENABLED_TOOLS=unraid_docker_list,unraid_docker_inspect,unraid_network_list
MUA_TOOLBOX_ENABLED=false

Sonderwerte: all aktiviert ausdrücklich alles, none deaktiviert alles.


Entwicklung

Voraussetzungen

  • Bun (Runtime + Build-Tool)
  • xz (für .txz-Packing)
  • xmllint (für .plg-Validierung)

Build

# TypeScript-Check
bunx tsc --noEmit

# Linux-Binary (für Unraid)
bun build src/index.ts --compile --target=bun-linux-x64 --outfile dist/mua

# macOS-Binary (für lokalen Test)
bun build src/index.ts --compile --target=bun-darwin-arm64 --outfile dist/mua-mac

# .txz packen (Version wird aus package.json gelesen)
bash scripts/package.sh

Lokaler Test

Die PHP-Statushelper lassen sich unabhängig vom laufenden MUA-Dienst testen (PHP 8 erforderlich):

php scripts/test-notifications.php
php scripts/test-docker-update-status.php

Der Benachrichtigungsparser liest auch mehrzeilige URBM-Meldungen und erhält Text wörtlich, ohne INI-Variablen wie ${HOME} auszuwerten.

# Test-Setup (ohne Unraid)
MUA_CONFIG_DIR=/tmp/mua-test MUA_PORT=3999 MUA_CONFIG_PORT=3998 ./dist/mua-mac

# Health-Check
curl http://127.0.0.1:3999/health

# Config-Server
curl http://127.0.0.1:3998/config

Versionierung

Format: YYYY.MM.DD.rNNN (Release-Counter hinter Datum).

Version in allen Dateien aktualisieren:

  • package.json
  • src/helpers.ts (MUA_VERSION)
  • plugin/plugin.json
  • plugin/mua.plg (Version + txzURL + CHANGES)
  • mcp/server.php
  • mcp/helpers.php

Nach Build: SHA256 im .plg aktualisieren:

shasum -a 256 dist/mua-*.txz

Release-Prozess

  1. Version erhöhen (alle Dateien)
  2. bunx tsc --noEmit
  3. bun build src/index.ts --compile --target=bun-linux-x64 --outfile dist/mua
  4. bash scripts/package.sh
  5. SHA256 im .plg aktualisieren
  6. xmllint --noout plugin/mua.plg
  7. git add -A && git commit -m "rNNN: ..." && git push
  8. Auf Unraid: Plugins → MUA → Update