Die volle REST-API von Xen Orchestra 6.5 — 245 Tools aus einer DADL
Xen Orchestra hat die letzten beiden Releases darauf verwendet, seine REST-API zu etwas zu machen, auf dem man aufbauen kann. XO 6.4 (April 2026) hat /rest/v0/ als stabil markiert und fein granulares RBAC v2 ergänzt; 6.5 hat PATCH /vms/{id} für partielle VM-Updates und eine eigene /vm-controllers-Collection hinzugefügt. Im Februar hat Vates außerdem einen eigenen MCP-Server mit XO 6.2 ausgeliefert — sieben Tools, bewusst read-only, damit Teams ihn vom ersten Tag an in der Produktion aktivieren können.
Wir haben einen anderen Schnitt derselben API gewählt. Die DADL für Xen Orchestra deckt die gesamte 245-Endpoint-REST-Oberfläche ab — lesend und schreibend — als eine YAML-Datei. Dieser Post ist das Build-Log und eine ehrliche Antwort auf die naheliegende Frage: Warum zwei MCP-Oberflächen für dasselbe Produkt?
Was die REST-API jetzt abdeckt
Abschnitt betitelt „Was die REST-API jetzt abdeckt“Die XO REST-API ist längst keine dünne Leseschicht mehr. Ab 6.5 exponiert sie den vollständigen Objektgraphen — VMs (inklusive PATCH-Teilupdates und Snapshot-Revert), VM-Controller, VM-Templates, VM-/VDI-Snapshots, Hosts, Pools, Storage (SR/VDI/VBD), Netzwerk (VIF/PIF/PBD), Hardware-Passthrough (PCI/PGPU/SM) — dazu jede Lifecycle-Aktion: Power, Snapshot, Clone, Migration, Export/Import, Hotplug. Über den Objekten liegen die operativen Oberflächen: Tasks, Backups (Jobs, Logs, Repositories, Restore, Schedules), Echtzeit-Änderungsevents über Server-Sent Events, RBAC v2 (Users, Groups, ACL-Roles, ACL-Privileges) und Host-/Pool-Wartung (Rolling Reboot, Rolling Update, Emergency Shutdown).
Das ist eine große API, und fast alles davon verändert Infrastruktur. Nichts von der Schreibseite ist über den eigenen MCP-Server erreichbar — by design, nicht aus Versehen.
Die Zahlen
Abschnitt betitelt „Die Zahlen“DADL (xen-orchestra.dadl) | @xen-orchestra/mcp (Vates, eigen) | |
|---|---|---|
| Tools | 245 | 7 |
| Umfang | lesend und schreibend | read-only by design |
| Coverage | jedes REST-Objekt + Lifecycle-Aktion, Backups, RBAC v2, SSE-Events, SDN-Traffic-Rules, Dashboards, Auth-Tokens | Infrastruktur-Summary, Pools / Hosts / VMs auflisten und inspizieren, Pool-Dashboard, Dokumentationssuche |
| Create / Start / Migration / Delete? | ja | nein — bewusst |
| Verteilung | eine 245-Tool-YAML-Datei | Node-Server, mitgeliefert ab XO 6.2 |
| Einem neuen API-Release folgen | ~30 Zeilen YAML pro Endpoint | kommt mit dem XO-Release |
| Governance-Schicht | Credentials, Autorisierung, Audit (über ToolMesh) | keine — lokal, in-process |
Die lokale Validierung, ausgeführt aus dem Registry-Checkout:
> cd dadl-registry && npm run validate✅ xen-orchestra.dadl — 245 toolsQuelle auf GitHub: dadl-registry/xen-orchestra.dadl. Live in der Registry unter dadl.ai/d/xen-orchestra. Die DADL-Spezifikation selbst: dadl.ai/spec.
Ein durchgespieltes Beispiel: eine VM-Änderung, rückgängig machbar
Abschnitt betitelt „Ein durchgespieltes Beispiel: eine VM-Änderung, rückgängig machbar“Der Sinn der Schreibseite ist, dass sie Infrastruktur tatsächlich verändert — sicher, mit Spur. Hier ist ein Round-Trip aus drei Calls: eine laufende VM finden, sie snapshotten, damit die Änderung umkehrbar ist, und sie dann patchen.
// 1. Find the VM by name (XO filter syntax, compact fields)const [vm] = await toolmesh.xen_orchestra_list_vms({ filter: "name_label:web-fra-01", fields: "uuid,name_label,tags"});
// 2. Snapshot first, so the change is undoableawait toolmesh.xen_orchestra_snapshot_vm({ id: vm.uuid, name_label: `pre-change ${new Date().toISOString().slice(0, 10)}`});
// 3. PATCH the live VM — tags is a hot field, applied while running (XO 6.5)await toolmesh.xen_orchestra_update_vm({ id: vm.uuid, tags: [...vm.tags, "managed:toolmesh"]});Drei Calls. Kein Glue-Code. Schritt 2 und 3 sind genau das, was ein read-only MCP-Server nicht kann — und die DADL übernimmt transparent:
- die ungewöhnliche cookie-basierte Authentifizierung (der Token wird serverseitig als
Cookie: authenticationToken=…injiziert — das Modell sieht ihn nie); - das async-by-default-Aktionsmodell — die meisten Writes geben eine Task-Referenz zurück;
syncsetzt man nur für kurze Operationen, und für lange (Migration, Export) pollt manget_task, um HTTP-Client-Timeouts zu vermeiden; - die Cold-vs-Hot-Field-Unterscheidung bei
update_vm—memoryStaticMax,cpusStaticMax,secureBootbrauchen eine heruntergefahrene VM, währendtags,nameLabelundcpuslive greifen (das Beispiel nutzttags, läuft also ohne Downtime); - Retries bei transienten Fehlern und terminale Klassifizierung für
404(“no such VM”) und RBAC-403.
Dieselben Calls aus Claude oder jedem anderen Agenten. Kein Xen-Orchestra-spezifischer Code auf der Client-Seite.
Read-only ist ein Feature, keine Lücke
Abschnitt betitelt „Read-only ist ein Feature, keine Lücke“Das naheliegende Framing — “245 schlägt 7” — ist das falsche. Die beiden Oberflächen beantworten verschiedene Fragen.
Der eigene MCP-Server von Vates ist absichtlich read-only. Er läuft in-process, kommt mit XO mit, braucht keine externe Infrastruktur und kann nichts kaputt machen. Wenn die Frage lautet “lass einen Assistenten meine Infrastruktur ansehen und Fragen dazu beantworten”, ist das die richtige Form, und man sollte ihn nutzen. Wir versuchen nicht, ihn zu ersetzen — die DADL enthält sogar ein get_mcp_status-Tool, das meldet, ob XOs eigener eingebauter MCP-Server aktiviert ist.
Die DADL beantwortet eine andere Frage: “lass einen Agenten meine Infrastruktur betreiben — erstellen, patchen, snapshotten, migrieren, sichern, RBAC provisionieren — ohne ihm rohe Admin-Credentials zu geben.” Das ergibt nur mit einer Kontrollschicht darunter Sinn. Über ToolMesh läuft jedes der 245 Tools hinter zentralisierten Credentials (der XO-Token erreicht das Modell nie), Autorisierung (ein Agent kann list_vms und snapshot_vm erhalten, aber nicht delete_sr) und einem Audit-Log (jeder Call protokolliert mit Was, Wann und Warum). Die Schreibseite ist der ganze Punkt, und die Governance-Schicht ist das, was die Schreibseite sicher exponierbar macht.
Beide Definitionen liegen in derselben Registry. Sie sind Ergänzungen: read-only-Discovery in-process, vollständiges Lifecycle-Management über ein governtes Gateway.
Der API hinterherzukommen ist ein YAML-Diff
Abschnitt betitelt „Der API hinterherzukommen ist ein YAML-Diff“XO 6.4 hat RBAC v2 ergänzt; 6.5 hat PATCH /vms/{id}, /vm-controllers und einen REST-Snapshot-Revert-Endpoint hinzugefügt. Jedes davon in der DADL nachzuziehen ist dieselbe kleine Arbeitseinheit: xen-orchestra.dadl öffnen, den Tool-Block ergänzen (~30 Zeilen YAML pro Endpoint), npm run validate laufen lassen, einen PR aufmachen, das Diff reviewen, mergen. ToolMesh nimmt die neuen Tools beim nächsten Reload auf. Keine SDK-Änderungen, kein Release zum Schnüren, kein npm-Publish, kein “bitte upgraden” an die Nutzer.
Zwei konkrete Beispiele aus dem aktuellen Release:
- 6.5 hat
POST /vms/{id}/actions/revert_snapshotfür automatisierbaren Snapshot-Revert ausgeliefert. Die DADL führt ihn bereits alsrevert_vm_to_snapshot, annotiert mit “requires XO 6.5+ (route returns 404 on older builds)” — gegen einen älteren Host bekommt der Agent also einen sauberen terminalen Fehler statt eines stillen Fehlschlags. - 6.5 legt außerdem die Grundlage für eine eigene VM-Administrator-Rolle. Darauf muss man nicht warten: Die DADL exponiert die volle RBAC-v2-Oberfläche (
create_acl_role,create_acl_privilege,attach_acl_role_to_user), sodass man heute schon eine least-privilege Operator-Rolle zusammenstellen und einem Agenten genau die Privilegien geben kann, die er haben soll — read aufvm,host,pool, mehr nicht.
Das allgemeine Argument haben wir in einem früheren Post gemacht; XO ist die konkrete Fallstudie für eine schreiblastige API.
Das Context-Window-Argument
Abschnitt betitelt „Das Context-Window-Argument“Es gibt einen zweiten Grund, warum die Tool-Zahl weniger zählt, als sie aussieht: Code Mode. Statt alle 245 XO-Tool-Beschreibungen in das Context-Window des Modells zu injizieren, exponiert ToolMesh zwei Meta-Tools (list_tools und execute_code). Das Modell entdeckt bei Bedarf, was verfügbar ist, und ruft flache Tool-Namen aus einer gesandboxten JavaScript-Runtime auf — toolmesh.xen_orchestra_list_vms, toolmesh.xen_orchestra_snapshot_vm, keinen verschachtelten Namespace.
Die Token-Kosten sind ungefähr konstant: ~1 k Tokens Meta-Tool-Beschreibung, egal ob die Registry ein Backend mit 7 Tools hält oder 24 Backends mit 3.115. Ein 245-Tool-Backend fügt jeder Claude-Konversation, die Xen Orchestra nicht aktiv anfasst, null Tokens hinzu. Das ist auch der Grund, warum das JavaScript im Beispiel oben keine Illustration ist — es ist buchstäblich das, was das Modell schreibt, um die Tools aufzurufen.
Ehrliche Einschränkungen
Abschnitt betitelt „Ehrliche Einschränkungen“Die DADL ist kein universeller Gewinn. Echte Grenzen:
- Der SSE-Event-Stream ist halb deklarativ.
open_events_streamgibt eine Subscription-ID zurück, und die DADL beschreibt den Subscribe-Handshake, aber der Server-Sent-Events-Stream selbst ist ein Streaming-Protokoll — DADL beschreibt REST, keine langlebigen Streams. Für das Pollen von Task-Status polltget_task?wait=truesauber; für einen echten Echtzeit-Feed ist man am Rand dessen, was eine deklarative REST-Definition modelliert. - VDIs lassen sich nicht über REST umbenennen. Es gibt kein
PATCH /vdis/{id}in der API — also auch keinupdate_vdi-Tool. Umbenennen geht über Tags oder den Abstieg zur JSON-RPC-API. Wir exponieren, was existiert; wir können nicht exponieren, was es nicht gibt. - SDN-Traffic-Rules brauchen ein Premium-Plugin. Die vier Traffic-Rule-Tools (
add/delete_network_traffic_rule,add/delete_vif_traffic_rule) steuern den SDN-Controller von XO — ein Plugin, das XOA Premium beiliegt und nicht Teil der dokumentierten Kern-REST-API ist. Ohne geladenes Plugin liefern die Routen404, der Agent bekommt also einen sauberen terminalen Fehler statt eines stillen No-ops. Die übrigen 241 Tools laufen gegen eine Standard-REST-API. - Die Schreibseite braucht Privilegien. Vollständige Coverage setzt einen Admin-User oder einen RBAC-v2-User mit den richtigen
acl-privilegesvoraus. Wenn man nur schauen will, ist der read-only-Server von Vates weniger Setup und ein kleinerer Blast-Radius — nimm ihn. - Jeder Call hüpft durch ToolMesh. Für interaktiven Betrieb ist das unsichtbar; für High-Throughput-Batch-Jobs gegen XO ist der direkte REST-Aufruf schneller.
DADL ist gut in einer bestimmten Sache — eine REST-API-Oberfläche schnell für Agenten verfügbar zu machen, mit einer echten Kontrollschicht darunter. Bei Xen Orchestra ist diese Oberfläche zufällig 245 Endpoints überwiegend verändernder Operationen — genau der Fall, in dem sich eine Governance-Schicht auszahlt.
Was tatsächlich anders ist
Abschnitt betitelt „Was tatsächlich anders ist“Die substanzielle Frage ist nicht “DADL vs. der eigene MCP-Server” — ToolMesh betreibt beide, und sie koexistieren in derselben Registry. Die Frage ist: Was kostet es, einem Agenten die Schreib-Seite einer API zu geben, sicher?
Bei einem read-only-Server lautet die Antwort “gar nicht” — das ist der bewusste Trade. Bei einem handgeschriebenen Read-Write-Server kostet es einen Engineering-Zyklus pro Endpoint: SDK-Shapes, Handler, Tests, ein Release, ein npm-Publish, Nutzer-Upgrades, plus die Autorisierung und das Audit, die man selbst bauen muss. Bei einer DADL hinter ToolMesh kostet es einen PR mit einem YAML-Diff, und Credentials, Autorisierung und Audit kommen aus der Runtime.
Das ist die Asymmetrie. Nicht “alle sollten den eigenen Server wegwerfen” — behalte ihn für read-only-Discovery. Nur: wenn ein Agent Xen Orchestra tatsächlich betreiben soll, ist die Arbeitseinheit ein YAML-Diff, und die Sicherheit liegt in der Schicht darunter statt im Weglassen der Schreib-Tools.