← Zurück zum Blog

Wie wir einen Echtzeit-MCP-Server für Godot gebaut haben

Einblicke in VberAIs Godot-MCP-Architektur: Wie ein Echtzeit-MCP-Server Godots Editor mit KI-Clients verbindet, ohne den Szenenbaum einzufrieren.

Veröffentlicht
  • vberai
  • godot
  • mcp
  • architecture
  • realtime

Warum “Echtzeit” für einen MCP-Server in Godot wichtig ist

Die meisten MCP-Demos funktionieren mit einer REST-artigen Welt: Das Modell stellt eine Frage, ein Tool gibt JSON zurück, und niemand kümmert sich darum, ob der Roundtrip zwei Sekunden gedauert hat. Godot ist anders. Der Editor besitzt einen live Szenenbaum, Ressourcenimporte und eine Play-Mode-Schleife. Wenn Ihr MCP-Server den Hauptthread blockiert – oder nur eine veraltete Momentaufnahme des Projekts sieht – fühlen sich KI-Clients nicht mehr wie Co-Piloten an, sondern wie Remote-Dateieditoren mit Extraschritten.

Als wir Godot MCP für VberAI entworfen haben, war das Briefing klar:

  • Ein KI-Assistent (Cursor, Claude, Windsurf und ähnliche MCP-Clients) muss den Editor bedienen, nicht nur .gd-Dateien von der Festplatte lesen
  • Aktionen wie Node erstellen, umbenennen, Skript anhängen und Auswahl abfragen müssen abgeschlossen sein, während der Editor reaktionsfähig bleibt
  • Play-Mode- und Edit-Mode-Kontexte müssen ehrlich bleiben – Tools sollten laut fehlschlagen, wenn eine Operation mitten im Play unsicher ist

Dieser Beitrag ist die Engineering-Story: wie wir einen Echtzeit-MCP-Server gebaut haben, der neben Godot sitzt, anstatt so zu tun, als wäre das Projekt ein statisches Repo.

Das Problem mit “nur-Datei”-MCP für Engines

Ein naiver Ansatz ist verlockend:

  1. MCP-Server auf den Projektordner zeigen lassen
  2. read_file / write_file / list_dir bereitstellen
  3. Das Modell GDScript erfinden lassen und hoffen, dass der Editor sauber neu lädt

Das funktioniert für Dokumentationsseiten. Bei Engine-Arbeit scheitert es, weil:

  • Szenenbesitz lebt im Speicher – ungespeicherte .tscn-Diffs, offene Szenen und Editor-Auswahl sind auf der Festplatte unsichtbar
  • Import-Pipelines sind zustandsbehaftet – das Schreiben einer PNG ist nicht dasselbe wie “Ressource bereit mit korrekten Importeinstellungen”
  • Signale und Node-Pfade sind Graphdaten – String-Änderungen brechen Verdrahtung stillschweigend
  • Latenz summiert sich – jede “Ist der Node erschienen?”-Bestätigung wird zu einem weiteren vollständigen Dateisystem-Scan

Wir brauchten eine MCP-Oberfläche, die widerspiegelt, was ein Mensch bereits im Godot-Dock sieht: Hierarchie, Inspektor-förmige Eigenschaften und Ressourcen-Handles – nicht nur Pfadstrings.

Architekturübersicht

Auf hoher Ebene besteht Godot MCP aus drei zusammenarbeitenden Schichten:

MCP-Client (Cursor / Claude / …)
        │  JSON-RPC über stdio oder lokalen Transport
        ▼
MCP-Server (VberAI Godot-Bridge-Prozess)
        │  Befehls-Warteschlange + Ergebnis-Envelopes
        ▼
Godot-Editor-Plugin (GDExtension / Editor-Plugin)
        │  verzögerte Aufrufe auf dem Hauptthread
        ▼
Editor-Szenenbaum / ResourceDB / Skript-Editor

Schicht 1 – MCP-Tool-Oberfläche

Tools sind bewusst klein und verb-förmig:

  • godot_get_scene_tree – Momentaufnahme der bearbeiteten Szene mit Node-Typen und -Pfaden
  • godot_create_node / godot_set_property
  • godot_attach_script / godot_run_script_snippet (geschützt)
  • godot_list_resources / godot_get_selection

Wir vermeiden ein einziges riesiges do_anything-Tool. Kleinere Tools sind einfacher zu validieren, einfacher zu protokollieren und schwerer von einem Modell zu missbrauchen, um unbegrenzte Patches zu erzeugen.

Schicht 2 – die Echtzeit-Bridge

Die Bridge ist der Ort, an dem “Echtzeit” tatsächlich lebt:

  • Ein bidirektionaler Kanal zwischen dem MCP-Prozess und dem Editor-Plugin (lokaler Socket oder Named Pipe in der Entwicklung; Produkt-Builds können dies hinter dem VberAI-Desktop-Helper verbergen)
  • Eine Befehls-Warteschlange, die Mutationen serialisiert, sodass zwei überlappende Tool-Aufrufe nicht um den Szenenbaum konkurrieren können
  • Request-IDs + Bestätigungen, sodass der MCP-Client auf “angewendet” warten kann, ohne das Dateisystem zu pollen
  • Heartbeat / Editor-Liveness, damit Clients wissen, wann Godot mitten in der Sitzung beendet wurde

Schicht 3 – Hauptthread-Sicherheit in Godot

Godots UI- und Szenen-APIs sind nicht frei-threaded. Das Plugin mutiert Nodes niemals auf dem MCP-I/O-Thread. Stattdessen:

  1. MCP-Befehl kommt auf dem Bridge-Thread an
  2. Payload wird in die Warteschlange eingereiht
  3. Editor-verzögerter Callback läuft auf dem Hauptthread (call_deferred / Idle-Frame-Hook)
  4. Ergebnis-Envelope gibt Erfolg, strukturierten Fehler oder “nach Play-Mode-Ende erneut versuchen” zurück

Dieses Muster ist bewusst langweilig. Langweilig ist, was “Echtzeit” davor bewahrt, zu “zufälligen Editor-Freezes” zu werden.

Es fühlt sich echtzeit an (ohne über Latenz zu lügen)

“Echtzeit” bedeutet hier nicht magische Null-Latenz. Es bedeutet, dass die Feedback-Schleife der Art und Weise entspricht, wie Menschen im Editor arbeiten.

Momentaufnahme vs. Stream

Frühe Prototypen gaben bei jedem Aufruf den gesamten Szenenbaum zurück. Das kollabierte bei großen Open-World-Setups. Wir wechselten zu:

  • Flachen Momentaufnahmen standardmäßig (Wurzel + eine Ebene oder auswahlfokussiert)
  • Pfadbezogenen Lesevorgängen, wenn das Modell bereits einen Teilbaum kennt
  • Optionalen Änderungs-Tokens, sodass nachfolgende Aufrufe fragen können “Was hat sich seit X geändert?”, anstatt alles neu zu serialisieren

Diff-freundliche Ergebnisse

Tool-Ergebnisse enthalten:

  • Kanonische NodePath-Strings
  • Typnamen (CharacterBody2D, Control, …)
  • Eigenschaftsschlüssel, die sauber auf Inspektor-Felder abbilden
  • Explizite Warnungen, wenn ein Schreibvorgang angewendet wurde, die Szene aber noch unsauber / ungespeichert ist

Modelle iterieren schneller, wenn Ergebnisse wie UI-Zustand aussehen, nicht wie ein Blogbeitrag mit Freitext.

Begrenztes Play-Mode-Verhalten

Der Play-Mode ist die Quelle der Hälfte der Tickets “KI hat mein Projekt kaputt gemacht”. Unsere Regeln:

ModusErlaubtBlockiert oder eingeschränkt
EditSzenen-Mutationen, Ressourcen-AbfragenDestruktive Projektlöschungen ohne Bestätigung
PlayHauptsächlich Lesen / Abfragen von Laufzeit-NodesStrukturelle Änderungen an der bearbeiteten Szene
ÜbergangWarten / Wiederholen-HinweiseStille No-Ops

Klare Fehler schlagen Cleverness. Wenn das Modell während des Plays nicht bearbeiten kann, sagt die MCP-Antwort dies in strukturierter Form – damit der Client dem Benutzer sagen kann, er soll den Play-Mode beenden und dann erneut versuchen.

Harte Probleme, auf die wir gestoßen sind (und behalten haben)

1. Der Editor ist keine Datenbank

Node-Reihenfolge, Owner-Beziehungen und gepackte Szenen interagieren auf eine Weise, die in einem GIF einfach und in einer .tscn unübersichtlich aussieht. Wir verließen uns auf Godots eigene APIs (Node, EditorInterface, Ressourcen-Loader), anstatt ein paralleles Szenenmodell zu erfinden, das abweichen würde.

2. Skripte vs. Szenen als zwei Quellen der Wahrheit

Ein Skript anzuhängen ist nicht dasselbe wie sicherzustellen, dass das Skript kompiliert und der Klassenname aufgelöst wird. Der Server meldet Kompilierungs-/Anhänge-Ergebnisse getrennt. Das stoppte eine Klasse von Fehlern wie “Tool sagte Erfolg, Inspektor zeigt nichts”.

3. Multi-Fenster / Multi-Projekt-Sitzungen

Entwickler öffnen mehr als eine Godot-Instanz. Die Bridge bindet an eine explizite Editor-Sitzungs-ID, damit Tool-Aufrufe nicht nach einem Wochenende Schlaf + erneutem Öffnen im falschen Projekt landen.

4. Sicherheitsgrenzen

Ein MCP-Server, der Szenen umschreiben kann, ist mächtig. Lokal-first-Transport, explizite Tool-Allowlists und keine stille Cloud-Exfiltration des gesamten Projektbaums sind nicht verhandelbar. “KI-Helfer” und “Remote-Shell über Ihr Spiel” müssen getrennte Produktkategorien bleiben.

Wie dies neben AI Studio und dem Rest von VberAI passt

Godot MCP ist der Engine-Operator. Ergänzende Teile:

  • VberAI Studio (AI Studio) – Design-to-Engine-Struktur für Figma/PSD → Control-Hierarchien; MCP verdrahtet dann Buttons und benennt Nodes nach dem Import um
  • Unity MCP / Cocos MCP – dieselbe MCP-Idee, andere Editor-Hosts und Sicherheitsregeln
  • AI Super Matting – bereinigt Alpha, bevor Texturen zu Engine-Ressourcen werden, die das MCP später zuweist

Die gemeinsame These: KI sollte die live Produktionsoberfläche (Editor, Assets, Szenen) berühren, nicht nur das Repo als Text.

Praktische Tipps, wenn Sie Ihre eigene Engine-MCP bauen

  1. Mutationen auf dem Engine-Hauptthread in die Warteschlange stellen – geben Sie niemals vor, Spiel-Engines seien Shared-Nothing-Server
  2. Bevorzugen Sie kleine Tools mit Schemas – Validierung schlägt Prompt-Poesie
  3. Geben Sie NodePaths und Typen zurück, keine Prosa – Modelle benötigen operable Handles
  4. Kodieren Sie Play-/Edit-Modi in jede Antwort – Mehrdeutigkeit hier zerstört Vertrauen
  5. Messen Sie den Roundtrip bis “im Dock sichtbar” – nicht nur die JSON-Encode-Zeit

Wenn Sie nur den MCP-Prozess optimieren und die Editor-Bridge ignorieren, liefern Sie eine schnelle Halluzinations-Schleife.

Fazit

Einen Echtzeit-MCP-Server für Godot zu bauen bedeutete, den Editor als live Kollaborateur zu behandeln: eine in die Warteschlange gestellte, hauptthread-sichere Bridge; Tools, die wie Editor-Aktionen geformt sind; und Ehrlichkeit über Play-Mode-Grenzen. Nur-Datei-MCP ist einfacher – und unvollständig für szenen-native Arbeit.

Sie möchten den ausgelieferten Pfad statt eines Wochenend-Prototyps? Beginnen Sie mit VberAI Godot MCP, verbinden Sie Ihren bevorzugten MCP-Client und versuchen Sie einen trivialen ersten Tool-Aufruf: Listen Sie den aktuellen Szenenbaum auf und erstellen Sie dann einen Node unter der Auswahl. Diese einzelne Schleife – Abfragen → Mutieren → im Dock sehen – ist das Produkt. Alles andere ist Zuverlässigkeitstechnik darum herum.

Weitere Guides, die Sie interessieren könnten