Skip to content

MCP server

The editor has an MCP server built in. An agent like Claude Code, or a plain Python script, can use it to inspect and edit maps, take screenshots and play input into the UI.

Use it to let an AI assistant build or review a level, to script repetitive edits, or to test the editor automatically. The server is off until you start it, and it only listens on your own machine.

Starting it

Transport How to start it
HTTP Launch the editor with --mcp-http for port 7841, or --mcp-http=PORT for another port. To have it start every time, go to File > Preferences, open Advanced, tick enable on startup next to MCP server (HTTP, localhost), set the port beside it and restart
stdio Launch with --mcp. The client starts the editor itself for each session and talks to it over standard input and output

Pick HTTP when you keep the editor open and work in it yourself while an agent helps. Pick stdio when the client should own its editor, or when other people use the same computer. To connect Claude Code to either:

claude mcp add --transport http trenchdot http://127.0.0.1:7841/mcp   # HTTP
claude mcp add trenchdot -- /path/to/trenchdot --mcp                 # stdio

The repository's .mcp.json already points Claude Code at the HTTP server. File > Preferences shows the command for the server that runs, and Copy command puts it on the clipboard.

Started the editor on another port? Set TRENCHDOT_MCP_URL and tools/mcp_client.py and tools/mcp_script.py connect there instead.

The HTTP token

Any program on your computer can reach the HTTP server, and so can other people signed in to it. To keep them out, tick Require a token under Advanced in File > Preferences. From the next request on, the server only answers requests that send its token as Authorization: Bearer <token>. The command in Preferences then includes the token, use it instead of .mcp.json. stdio needs no token, only the client that started the editor can talk to it.

The editor makes a random token the first time you ask for one and keeps it in mcp-token, a file only you can read, next to its settings: %APPDATA%\TrenchDot\data on Windows, ~/.local/share/trenchdot on Linux and ~/Library/Application Support/TrenchDot on macOS. A --default-prefs run keeps its own in trenchdot-default-prefs.mcp-token in the temp folder.

To pick the token yourself for one run, set TRENCHDOT_MCP_TOKEN or launch with --mcp-token=<token>, which wins over the variable. Either one turns the token on whatever Preferences says, and Require a token shows it ticked and greyed out. tools/mcp_client.py and tools/mcp_script.py send a token only when you give them one, with --token or TRENCHDOT_MCP_TOKEN.

Turning MCP off

To keep agents and scripts out of the editor altogether, untick MCP at the top of the MCP part of File > Preferences. The HTTP server closes at once and drops its open connections, a client on stdio gets an error for every request, and the other MCP settings grey out. The setting is saved at once, so every editor you start without --default-prefs keeps MCP off until you tick it again, which brings the HTTP server back on its port.

The MCP part of Preferences: MCP ticked, the HTTP server row with its port, and Require a token

To turn MCP off for one run whatever Preferences says, set TRENCHDOT_DISABLE_MCP to anything but empty or 0. MCP then shows unticked and greyed out. While MCP is off, --mcp and --mcp-http start no server. The editor still opens and its status line says MCP is off, and a client on stdio gets an error saying so instead of waiting.

An agent can turn MCP off as well, with set_editor and "mcp": false. Only you can turn it back on.

Tools

Area What it is for Tools
Inspect Read the map, the editor state, the entity definitions and how to use an entity from game code, without changing anything get_state, summarize_map, list_nodes, get_node, changes_since, validate_map, get_game_config, code_reference
Create Add brushes, meshes, terrains, entities and imported models, and trim along face edges create_brush, create_mesh, create_terrain, create_entity, import_model, trim
Edit Change what exists: entity keys, selection, placement, faces, textures, terrain, layers and groups, and worldspawn update_entity, select, transform, duplicate, set_face, mesh_edit, texture, terrain_edit, hierarchy, set_map_properties, bake_lighting
Paint and gameplay Scatter models, blend materials, paste pieces from the prefab library, and turn brushes into doors, platforms and buttons scatter, blend, prefab_library, random_fill, gameplay
Editor Run menu actions, open and save files, change editor settings, move the camera, take screenshots, send input and check where a player can walk run_action, map_file, open_project, set_editor, set_camera, screenshot, simulate_input, walkability
Project Add the Gameplay entities pack, the nature models or the demo to the open Godot project project_content
Scripts Replay a saved list of tool calls, see MCP scripts run_script

Each tool's description lists its operations and arguments, so an agent learns them straight from the server. tools/mcp_client.py prints them with list and calls a tool from the shell:

python tools/mcp_client.py call screenshot '{"target":"3d","width":1280,"height":720}' --out shot.png

Screenshots

screenshot returns a PNG of the whole editor window, or of one view when target is 3d, top, front or side. For a view, the other arguments decide what you get:

Arguments Result
None The whole editor window
target only That docked view as it is, overlays included
width and height Rendered offscreen up to 4096 pixels, without grid, entity boxes, gizmos or selection
width, height and "overlays": true Offscreen, with the editor overlays
"overlays": false A clean shot at the docked size

What Godot renders

"source": "godot" asks the Godot editor to render the map with its real lights, environment, fog and post processing. You get that PNG back, plus any errors or warnings Godot logged while building it. Handy for judging lighting and materials without launching the game.

python tools/mcp_client.py call screenshot '{"source":"godot","position":[0,256,512],"look_at":[0,64,0]}' --out godot.png
  1. Save the map inside the project that is open in TrenchDot.
  2. Open that project in the Godot editor, with a scene whose FuncGodotMap builds the map.
  3. Call screenshot with "source": "godot". Without position and look_at it uses the 3D view's camera.

Without live mode Godot first builds the map as shown in TrenchDot, like Build in Godot. "build": false captures the scene as Godot has it. width and height default to 1280 by 720, and fov to the 3D view's.

Note

Godot needs a window to render, a headless Godot returns an error instead of an image. The window can be in the background or minimized.

Reading and reviewing a map

Step Tool
Get an overview summarize_map lists the layers, entity classes, I/O links and materials, and any missing assets
Find nodes list_nodes filters by layer, material, property ({"model": "*crate*"}) or a box in the map
Look at one get_node returns one node. compact: true leaves out vertices and faces
Show what you changed changes_since compares against the last save, a number of undo_steps back, or a map file
Take it back Each call and each run_script is one undo step named MCP: .... run_action undo with steps undoes several

See Reviewing changes for keeping maps in git.

Behavior worth knowing

Topic Behavior
Browsers The HTTP server refuses any request with an Origin header and any POST that is not application/json, so web pages cannot reach it, not even ones served from localhost
Errors A tool that could not do its job returns isError, including a failed run_action
File dialogs Actions that open one are refused, use map_file with a path. run_action save needs a map that already has a file
Unsaved tabs run_action close_tab refuses unsaved changes unless args.discard is true. args.close_others closes every tab but the active one instead
File paths res:// and relative paths in map_file, run_script, import_model, changes_since and validate_map start at the open project, or at the editor's working directory without one. map_file open and open_tab resolve the path to an absolute one before opening, so a later save cannot land somewhere else
Editor settings transform and run_action rotate and flip pivot on the selection center, snapped to the grid only while snapping is on, and keep textures locked while UV lock is on. transform takes snap and uv_lock to override that for one call, duplicate takes uv_lock. run_action sculpt and blend use the tool settings a person can change, terrain_edit uses fixed defaults
Selection select refuses unknown ids and skips hidden or locked nodes, listing them in skipped
CSG csg_subtract, csg_merge, csg_intersect, csg_hollow and clip_apply return replaced, old ids mapped to new ones
Timeouts Calls time out after 120 s, except run_script, project_content and bake_lighting
Content question The question a new project gets about ready made content closes on the first call other than get_state, screenshot and simulate_input, and does not open again in that session
Script variables $name/rest (unbraced) is an error when name is a known variable, since only $name alone or ${name}/rest expand it. Write ${project}/maps

Tool notes

Tool Note
run_action copy, cut, paste Copy and cut return the clipboard text, paste takes it as args.text with an optional offset or origin
run_action clip_apply Takes a plane (point and normal, or three points) and keep: front, back or both
run_action create_decal Places a decal, use it instead of thin brushes
create_brush openings carves doors and windows, {min, max, count, step, rows, row_step} repeats one as a grid
create_mesh rotate [x, y, z] degrees in Godot's YXZ order, so [0, 0, 90] lays a cylinder along X
transform Applies translate, rotate, flip and scale_to in that order, as one undo step. rotate turns 90 degrees about Y unless told otherwise
create_terrain origin is the terrain's minimum corner, unlike other tools. center places it around a point instead
create_brush, create_mesh A gable ridge runs along Z for brushes and along X for meshes. Both tools take ridge_x and ridge_z
map_file exports path is the written file, kept for older callers, exported names it too and map_path is the open map
terrain_edit probe [x, z] without op only reads the height. clear_layer needs layer
validate_map Accepts any method or property of the target's Godot class or script as an input. coplanar_faces flags faces that will flicker. Every issue has bounds. path checks a saved map without opening it, project: true checks every map in the project
run_action reload_materials Rescans the texture folder now, though new files are found on their own anyway
set_editor live_link_port Talks to a Godot editor whose project sets another trenchdot/live_link_port
scatter preset Adds the embedded Blockbench models a preset needs. A glTF preset in a project without the nature pack is an error that names project_content
bake_lighting Bakes like Bake Lighting and waits for it. Options left out keep what the map was last baked with. bake: false only switches the view, remove: true drops the bake. out_of_date says whether the map changed since
project_content install: "nature" or "demo" downloads from the release and answers once the files are in. install: "gameplay" copies the Gameplay entities pack from the project's addon, also inside scripts. Without arguments it says what the project has