Through the Editor Bridge
The Godot Editor Bridge is a separate addon of Daelok's that opens a socket into the running editor, with a command line and an MCP server in front of it. Once it is installed in a project, DaelokBase adds its data commands to it: the bridge finds addons/daelokbase/bridge_ops.gd on its own, and the MCP server lists each command as a tool.
Installing the bridge
From the bridge's repository:
python tools/install.py C:/path/to/your/project
Then enable Editor Bridge in Project Settings, Plugins. Its dock shows the port it listens on. Take it out of the enabled plugins before you commit project.godot, unless the whole team runs it.
Calling a command
From a terminal, in the bridge's repository:
python tools/editor.py data_entries collection=Items filter="rarity = Rare" values=true
Arguments are key=value. A number, true and false are read as such; a list is [a, b]; a map is {price: 12, tags: [a, b]}; quote a value that has spaces. Through MCP the same commands appear as tools named after them, with the same arguments as fields.
Every command answers with a map, or refuses with a reason and changes nothing: a wrong value in data_set refuses the whole command and names every problem. The Data tab, when it is open, is shown what changed.
The commands
| command | arguments | what it does |
|---|---|---|
data_collections |
every collection: class, folder, base, entry count, key and label fields, the fields with their kinds and options, the preview scene | |
data_collection |
collection=Items |
one collection with its whole metadata (layout, pins, retired fields) and its script's path |
data_entries |
collection=Items filter="weight > 3" values=false |
its entries: path, key, label, and every value when values=true; the filter is the Data tab's |
data_entry |
path=res://data/items/x.tres, or collection=Items key=x |
one entry with every value: a picture as its path, a group as its rows, each a map |
data_new_entry |
collection=Items values={name: Elixir, price: 12} |
a new entry, its key by the id mode unless given, saved; the path comes back |
data_set |
path=… values={price: 12, icon: res://art/x.svg, tags: [a, b]} |
values set, each as its field's kind, and saved |
data_delete_entry |
path=… |
the file to the OS bin |
data_new_collection |
class=Relics folder=res://data/relics fields=[{name: id, type: id}, {name: power, type: number, int: true}] key_field=id label_field=name |
a class written, scanned and registered, its metadata made |
data_change_fields |
collection=Items fields=[{old_name: weight, name: mass}, {name: level, type: number, int: true}] retire=[tags] pin_defaults=true dry_run=true |
the migration plan; with dry_run=false, the change made after a snapshot |
data_purge_retired |
collection=Items |
the retired fields out of the class and the files for good, after a snapshot |
data_revert |
collection=Items |
the latest snapshot put back: the class, its metadata, its entry files; files an import made taken away |
data_validate |
every problem the validator finds, errors first, with the counts and a summary in words | |
data_write_loader |
collection=Items |
the loader script written beside the entries |
data_import |
path=res://x.dlb root=res://data dry_run=true |
a DaelokBase Classic project as classes, folders, metadata and entries; the plan's summary first |
data_backlinks |
path=…, or collection=Items key=x |
every entry of every collection that points at it, with the field |
data_export |
collection=Items format=csv path=res://items.csv |
the collection as CSV or JSON: written to the path, or the text itself when no path is given |
data_import_rows |
collection=Items path=res://items.csv dry_run=true, or rows=[{id: x, price: 3}] |
the plan in words; with dry_run=false, the rows written after a snapshot |
A field in fields= is a map of name, type (string, bbcode, number, boolean, enum, texture, audio, array, id, reference, group) and, by type, int, min, max, step, suffix, options, item_type, min_items, max_items, soft, target, id_mode, prefix, padding, slug_from, slug_separator. In data_change_fields, old_name renames, fields not spoken of stay as they are, retire= names the ones to retire, and a group's map may carry columns=[…] and retire_columns=[…].
An agent at work
An agent connected through the MCP server reads with data_collections, data_entries and data_entry, proposes with the dry runs of data_change_fields, data_import and data_import_rows, and writes with data_set, data_new_entry and the same commands with dry_run=false. Every write is saved through the editor, so files keep their UIDs, and every change of many files has a snapshot behind it that data_revert puts back.