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: 33 (Docker, Community Applications, Netzwerk und Unraid-System)
Architektur
┌─────────────────────────────────────────────────────────┐
│ Unraid (192.168.1.2) │
│ │
│ /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_readonlybereit. 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. nonebedeutet tatsächlich keine Tools aktiv;allist 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.logprotokolliert. - 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 http://192.168.1.2:4000/michael/MUA-Mikes-Unraid-Agent/raw/branch/main/dist/mua-2026.08.24.r020-x86_64-1.txz
# Installieren
upgradepkg --install-new mua-2026.08.24.r020-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://192.168.1.2:3002/health
# → {"status":"ok","version":"2026.08.24.r020","auth":"required"}
API-Key generieren (WebGUI)
- Settings → User Utilities → MUA in der Unraid-WebGUI öffnen
- Unter „API-Key (Authentifizierung)" auf „Neuen API-Key generieren" klicken
- 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://192.168.1.2:3002/mcp
Auth: Authorization: Bearer <dein-api-key>
Unterschied zu den anderen MCP-Servern: Die übrigen Tools (Web-Suche, Home Assistant, Unraid, Sonarr/Radarr) laufen auf 192.168.1.196 und werden per SSH-stdio angebunden. MUA läuft direkt auf Unraid und spricht HTTP — kein SSH-Wrapper nötig.
Beispiel: Hermes Agent
Hermes kann MCP-Server per stdio (Wrapper) oder direkt per HTTP anbinden.
Da MUA HTTP spricht, reicht ein HTTP-Client-Wrapper, der die stdio-Requests
an http://192.168.1.2:3002/mcp mit dem Bearer-Token weiterleitet:
# ~/.hermes/config.yaml
mcp_servers:
mua:
command: /usr/bin/ssh
args:
- -T
- -o
- BatchMode=yes
- -o
- IdentitiesOnly=yes
- -i
- /Users/mike_i386/.ssh/lmstudio_unraid
- root@192.168.1.196
- /usr/bin/python3
- /opt/mike-ai/mua/mua_mcp_http.py
env:
MUA_URL: http://192.168.1.2:3002/mcp
MUA_API_KEY: <dein-api-key>
connect_timeout: 30.0
enabled: true
Hinweis: Der Wrapper
mua_mcp_http.py(auf 196) übersetzt stdio → HTTP mit Bearer-Token. Alternativ: jeder MCP-Client, der Streamable HTTP nativ unterstützt, kann MUA direkt anbinden.
Beispiel: Direkter HTTP-Test (curl)
# Health-Check (ohne Auth)
curl http://192.168.1.2:3002/health
# MCP-Initialisierung (mit Auth)
curl -X POST http://192.168.1.2: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://192.168.1.2: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://192.168.1.2: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://192.168.1.2: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 (10) | 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 |
Deaktivierte Tools werden vom MCP-Server gefiltert — sie erscheinen nicht in
tools/list und können nicht aufgerufen werden (→ ERROR: Tool disabled).
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
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
# 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.jsonsrc/helpers.ts(MUA_VERSION)plugin/plugin.jsonplugin/mua.plg(Version + txzURL + CHANGES)mcp/server.phpmcp/helpers.php
Nach Build: SHA256 im .plg aktualisieren:
shasum -a 256 dist/mua-*.txz
Release-Prozess
- Version erhöhen (alle Dateien)
bunx tsc --noEmitbun build src/index.ts --compile --target=bun-linux-x64 --outfile dist/muabash scripts/package.sh- SHA256 im
.plgaktualisieren xmllint --noout plugin/mua.plggit add -A && git commit -m "rNNN: ..." && git push- Auf Unraid: Plugins → MUA → Update