Zum Inhalt springen

Die volle REST-API von Xen Orchestra — 252 Tools aus einer DADL

Xen Orchestra hat die letzten 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; 6.6 (Juni 2026) hat im selben Tempo weitergemacht — gescopte Storage- und Network-Administrator-Rollen, schreibbare Backup-Repositories und PATCH für VDIs und VIFs. 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 252-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?

Die XO REST-API ist längst keine dünne Leseschicht mehr. Ab 6.6 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, mit PATCH-Umbenennung und Disk-Vergrößerung bei VDIs seit 6.6), Netzwerk (VIF/PIF/PBD, mit PATCH bei VIFs seit 6.6), 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 — seit 6.6 schreibbar — 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.

DADL (xen-orchestra.dadl)@xen-orchestra/mcp (Vates, eigen)
Tools2527
Umfanglesend und schreibendread-only by design
Coveragejedes REST-Objekt + Lifecycle-Aktion (inkl. PATCH bei VMs, VDIs, VIFs), Backups mit schreibbaren Repositories, RBAC v2, SSE-Events, SDN-Traffic-Rules, Dashboards, Auth-TokensInfrastruktur-Summary, Pools / Hosts / VMs auflisten und inspizieren, Pool-Dashboard, Dokumentationssuche
Create / Start / Migration / Delete?janein — bewusst
Verteilungeine 252-Tool-YAML-DateiNode-Server, mitgeliefert ab XO 6.2
Einem neuen API-Release folgen~30 Zeilen YAML pro Endpointkommt mit dem XO-Release
Governance-SchichtCredentials, 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 — 252 tools

Die vollständige Definition ist live und durchsuchbar unter dadl.ai/d/xen-orchestra — die autoritative Quelle, stets auf dem Stand des aktuellsten XO-Releases. 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 undoable
await 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; sync setzt man nur für kurze Operationen, und für lange (Migration, Export) pollt man get_task, um HTTP-Client-Timeouts zu vermeiden;
  • die Cold-vs-Hot-Field-Unterscheidung bei update_vmmemoryStaticMax, cpusStaticMax, secureBoot brauchen eine heruntergefahrene VM, während tags, nameLabel und cpus live greifen (das Beispiel nutzt tags, 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.

Das naheliegende Framing — “252 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 252 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.

XO 6.4 hat RBAC v2 ergänzt; 6.5 hat PATCH /vms/{id}, /vm-controllers und einen REST-Snapshot-Revert-Endpoint hinzugefügt; 6.6 hat gescopte Storage- und Network-Administrator-Rollen, schreibbare Backup-Repositories und PATCH für VDIs und VIFs ergänzt. 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.

So sieht von hier an jedes XO-Release aus. 6.6 waren sieben neue Tool-Blöcke und ein Versionssprung von 245 auf 252 — ein Diff an einem Nachmittag, kein Ereignis. Einen zweiten Blick wert sind nicht die Releases, die Endpoints hinzufügen, sondern die, die eine Lücke schließen, die man als Einschränkung notiert hatte.

Zwei konkrete Beispiele aus 6.6:

  • Das Release hat PATCH /vdis/{id} ergänzt. Eine frühere Version dieses Posts führte “VDIs lassen sich nicht über REST umbenennen” unter den ehrlichen Einschränkungen — 6.6 hat diese Lücke geschlossen, und das Nachziehen war ein einziger update_vdi-Tool-Block (eine Disk umbenennen oder vergrößern), annotiert mit “added in XO 6.6 — returns 404 on older builds”, sodass ein Agent gegen einen älteren Host einen sauberen terminalen Fehler statt eines stillen Fehlschlags bekommt.
  • Backup-Repositories wurden schreibbar: POST / PATCH / DELETE /backup-repositories. Drei neue Tool-Blöcke, dieselbe Form wie jeder andere Schreib-Endpoint, hinter denselben Credentials, derselben Autorisierung und demselben Audit — am Gateway hat sich nichts geändert. Die neuen eingebauten Rollen Storage Administrator und Network Administrator brauchen gar keine neuen Tools; sie setzen sich aus der RBAC-v2-Oberfläche zusammen, die die DADL bereits exponiert hat.

Das allgemeine Argument haben wir in einem früheren Post gemacht; XO ist die konkrete Fallstudie für eine schreiblastige API.

Es gibt einen zweiten Grund, warum die Tool-Zahl weniger zählt, als sie aussieht: Code Mode. Statt alle 252 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 30 Backends mit 4.010. Ein 252-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.

Die DADL ist kein universeller Gewinn. Echte Grenzen:

  • Der SSE-Event-Stream ist halb deklarativ. open_events_stream gibt 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 pollt get_task?wait=true sauber; für einen echten Echtzeit-Feed ist man am Rand dessen, was eine deklarative REST-Definition modelliert.
  • Host-Power-Aktionen fehlen in der REST-API. Für Hosts gibt es keine REST-Route für start / shutdown / reboot / restart_toolstack — nur disable, enable und management_reconfigure sind exponiert. Für Host-Power nutzt man pool-weites rolling_reboot / rolling_update oder steigt zur JSON-RPC-API ab. Wir exponieren, was existiert; wir können nicht exponieren, was es nicht gibt. (Der Eintrag, der früher hier stand — “VDIs lassen sich nicht über REST umbenennen” — ist entfallen, als 6.6 PATCH /vdis/{id} ausgeliefert hat.)
  • SDN-Traffic-Rules brauchen ein Premium-Plugin. Die sechs Traffic-Rule-Tools (add / delete / update_network_traffic_rule, add / delete / update_vif_traffic_rule — die beiden update-Varianten neu in 6.6) 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 Routen 404, der Agent bekommt also einen sauberen terminalen Fehler statt eines stillen No-ops. Die übrigen 246 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-privileges voraus. 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 252 Endpoints überwiegend verändernder Operationen — genau der Fall, in dem sich eine Governance-Schicht auszahlt.

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.