3.2.5pypi · godot-ai · current release
Observed 2026-09-04T03:29:24.069Z using mcpSecurity-inventory. Status: succeeded. Negotiated protocol: 2025-06-18.
{
"experimental": {},
"logging": {},
"prompts": {
"listChanged": false
},
"resources": {
"subscribe": false,
"listChanged": false
},
"tools": {
"listChanged": true
},
"extensions": {
"io.modelcontextprotocol/ui": {}
}
}| Tool | Category | Annotations | Risk |
|---|---|---|---|
animation_createCreate a new Animation clip inside an AnimationPlayer's default library.
After creating the clip, add tracks via ``animation_manage`` ops
``add_property_track`` / ``add_method_track`` / ``create_simple``.
Track node paths are stored relative to the AnimationPlayer's
``root_node`` (default: its parent), not to the scene root — see
``animation_manage`` preset ops for a forgiving target_path that
accepts either form.
If ``player_path`` doesn't resolve, an AnimationPlayer is auto-created
at that path (parent must exist).Input schema{
"additionalProperties": false,
"properties": {
"player_path": {
"type": "string",
"description": "Scene path to the AnimationPlayer node."
},
"name": {
"type": "string",
"description": "Animation clip name (e.g. \"idle\", \"pulse\")."
},
"length": {
"type": "number",
"description": "Duration in seconds."
},
"loop_mode": {
"default": "none",
"type": "string",
"description": "\"none\" (default) | \"linear\" | \"pingpong\"."
},
"overwrite": {
"default": false,
"type": "boolean",
"description": "Replace an existing animation with the same name."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"required": [
"player_path",
"name",
"length"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
animation_manageAnimationPlayer authoring (player, tracks, autoplay, presets, playback).
Ops:
• player_create(parent_path, name="AnimationPlayer")
Create an AnimationPlayer with empty default library.
• delete(player_path, animation_name)
Delete an animation clip from the default library. Undoable.
• validate(player_path, animation_name)
Check all track paths resolve. Returns broken_count + per-track issues.
• add_property_track(player_path, animation_name, track_path, keyframes,
interpolation="linear")
Add a property track. track_path: "NodeName:property". keyframes:
[{time, value, transition?}, ...]. interpolation: linear|nearest|cubic.
• add_method_track(player_path, animation_name, target_node_path, keyframes)
Add a method track. keyframes: [{time, method, args?}, ...].
• set_autoplay(player_path, animation_name="")
Set autoplay. Empty animation_name clears.
• play(player_path, animation_name="")
Editor preview. Not saved with scene.
• stop(player_path)
Stop editor preview. Not saved with scene.
• list(player_path)
List animations with length, loop_mode, track_count.
• get(player_path, animation_name)
Inspect a clip's tracks and keyframes in detail.
• create_simple(player_path, name, tweens, length=None, loop_mode="none",
overwrite=False)
High-level: build a multi-track clip from tween specs in one call.
tweens: [{target, property, from, to, duration, delay?, transition?}].
• preset_fade(player_path, target_path, mode="in", duration=0.5,
animation_name="", overwrite=False)
One-call fade-in/out (modulate.a).
• preset_slide(player_path, target_path, direction="left", mode="in",
distance=None, duration=0.4, animation_name="", overwrite=False)
One-call slide-in/out (position).
• preset_shake(player_path, target_path, intensity=None, duration=0.3,
frequency=30.0, seed=0, animation_name="", overwrite=False)
One-call shake (jittered position).
• preset_pulse(player_path, target_path, from_scale=1.0, to_scale=1.1,
duration=0.4, animation_name="", overwrite=False)
One-call pulse / hover-bounce (3-keyframe scale ping-pong).
Preset target_path: accepts either a scene-absolute path (e.g. "/Main/World/Cube",
matching every other scene tool) or a path relative to the AnimationPlayer's
root_node (e.g. "World/Cube", matching how Animation tracks store node paths).
Scene-absolute targets outside the player's root_node subtree are converted to
a `..`-prefixed track path via root_node.get_path_to(target), the same shape
the relative form already accepts.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"add_method_track",
"add_property_track",
"create_simple",
"delete",
"get",
"list",
"play",
"player_create",
"preset_fade",
"preset_pulse",
"preset_shake",
"preset_slide",
"set_autoplay",
"stop",
"validate"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
api_manageInspect Godot API documentation-shaped metadata from the connected editor's
ClassDB: "what properties does X have", method signatures, signals, enums,
constants, defaults, and property hint strings.
Resource form (prefer for active-session reads):
godot://class/{class_name}
Ops:
- get_class(class_name, sections=None, include_inherited=False,
include_inheritors=False, offset=0, limit=100)
Return selected class-reference sections without creating a scene
instance. sections may be a comma-separated string or list containing
properties, methods, signals, enums, constants, inheritors.
Defaults to ["properties"] only — a bare get_class answers "what
properties does X have" without the multi-thousand-token full dump.
Pass the sections you want by name, or "all" for the full set
(properties, methods, signals, enums, constants). "all" does NOT
include the heavier "inheritors" section — request that by name.
For pagination, request one section at a time so offset/limit apply
only to the list you are paging.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"const": "get_class",
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
audio_manageSound effects, music, ambience (AudioStreamPlayer / 2D / 3D).
Ops:
• player_create(parent_path, name="AudioStreamPlayer", type="1d")
Create an AudioStreamPlayer / 2D / 3D node. type: "1d" | "2d" | "3d".
• player_set_stream(player_path, stream_path)
Assign an AudioStream resource (.ogg/.wav/.mp3 or .tres). Returns
duration_seconds.
• player_set_playback(player_path, volume_db?, pitch_scale?, autoplay?, bus?)
Update common playback properties atomically. Pass only fields to
change; at least one of volume_db/pitch_scale/autoplay/bus required.
• play(player_path, from_position=0.0)
Start real editor preview playback. Not undoable.
• stop(player_path)
Stop editor preview playback. Not undoable.
• list(root="res://", include_duration=True)
Scan project for AudioStream resources (every subclass + .tres/.res).
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"list",
"play",
"player_create",
"player_set_playback",
"player_set_stream",
"stop"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
autoload_manageAutoload (global singleton) management. Autoloads are scripts or scenes
loaded automatically at project start, accessible globally by name when
``singleton=True``. Persisted to ``project.godot``.
Ops:
• list()
List autoloads with name, path, and singleton flag.
• add(name, path, singleton=True)
Register an autoload (script or PackedScene) by ``res://`` path.
• remove(name)
Unregister an autoload by name. The underlying file is not deleted.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"add",
"list",
"remove"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
batch_executeExecute a list of editor sub-commands in order, stopping on first error.
Each item must be `{"command": "<plugin_command>", "params": {...}}`.
Use the underlying plugin command names (e.g. `create_node`, `set_property`,
`delete_node`, `attach_script`), not the MCP tool names. Commands run
sequentially; execution stops at the first error. When `undo` is True
(default), any successful sub-commands are rolled back via the scene's
undo history if a later sub-command fails, producing atomic-on-failure
semantics.
Use this to compose multi-step edits (create node + set property +
attach script) into a single tool call. Rollback works for sub-commands
that modify the currently edited scene. `batch_execute` itself is not
allowed as a sub-command.
Scene paths are relative to the edited scene root (e.g. "/Main/Enemy"),
NOT runtime "/root/..." paths. The example below assumes the scene
root is named "Main" — substitute the actual root name.Input schema{
"additionalProperties": false,
"properties": {
"commands": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array",
"description": "List of `{\"command\": str, \"params\": dict}` items."
},
"undo": {
"default": true,
"type": "boolean",
"description": "Roll back succeeded sub-commands on failure. Default True."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"required": [
"commands"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
camera_manageCamera2D / Camera3D authoring (zoom, FOV, projection, smoothing, follow).
Ops:
• create(parent_path, name="Camera", type="2d", make_current=False)
Create a Camera2D ("2d") or Camera3D ("3d"). When make_current=True,
unmarks previously current cameras of the same class in one undo.
• configure(camera_path, properties)
Batch-set camera-specific properties (zoom, fov, projection, smoothing,
drag, limits …). Class-aware. Enum-by-name (projection, keep_aspect,
anchor_mode, doppler_tracking, process_callback). Vector2 dict
coercion for zoom/offset. Transforms (position, rotation, scale,
transform, global_*) live on the Node — set those via
node_set_property, not here.
• set_limits_2d(camera_path, left?, right?, top?, bottom?, smoothed?)
Set Camera2D bounds. Pass only the edges to change.
• set_damping_2d(camera_path, position_speed?, rotation_speed?,
drag_margins?, drag_horizontal_enabled?,
drag_vertical_enabled?)
Smooth Camera2D motion (position/rotation smoothing speeds + drag
deadzone). drag_margins: {left,top,right,bottom} fractions [0,1].
• follow_2d(camera_path, target_path, smoothing_speed=5.0, zero_transform=True)
Reparent camera under target with smoothing — Godot-native follow.
• get(camera_path="")
Inspect a camera (class, current flag, all properties). Empty path
resolves to the currently-active camera, falling back to the first.
• list()
List every Camera2D/Camera3D in the scene.
• apply_preset(parent_path, name, preset, type=None, make_current=True,
overrides=None)
Spawn with opinionated defaults. Presets: topdown_2d, platformer_2d,
cinematic_3d, action_3d. overrides merge over preset values.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"apply_preset",
"configure",
"create",
"follow_2d",
"get",
"list",
"set_damping_2d",
"set_limits_2d"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
client_manageConfigure AI clients to use this Godot AI MCP server. Writes / removes
client config files (Claude Code, Codex, Antigravity, Cursor, Devin Desktop (Windsurf),
Zed, etc.).
Ops:
• status()
List every supported client with id, display_name, status
(configured | not_configured | configured_mismatch | error),
and installed flag.
• configure(client)
Write the MCP server entry into the named client's config file.
``client`` is one of the ids returned by status().
• remove(client)
Remove this server's entry from the named client's config.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"configure",
"remove",
"status"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
csg_manageCSG authoring (create boolean shapes, set their operation).
Create CSG shapes (box, sphere, cylinder, torus, polygon) under a Node3D
parent in the currently edited scene and set their boolean operation
(union / intersection / subtraction) so geometry like holes, caves and
tunnels can be carved directly in the editor. All write ops are undoable
via EditorUndoRedoManager. Sibling CSG shapes under the same parent combine
automatically; use a CSGCombiner3D parent for explicit grouping. Size,
position and material live on the created node — set them with
node_set_property / material_manage after creation.
Ops:
• csg_create(parent_path, name="", shape="box", operation="union")
Create a CSG shape under a Node3D parent (empty parent_path = scene
root). shape: box | sphere | cylinder | torus | polygon.
operation: union | intersection | subtraction.
Returns: {path, name, shape, operation}
• csg_set_operation(path, operation)
Set the boolean operation of a CSG shape.
operation: union | intersection | subtraction.
Returns: {operation}
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"csg_create",
"csg_set_operation"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
custom_manageList or invoke custom tools registered by third-party addons.
Active session only. Use op="list" to discover registered tools.
op="invoke" requires params: tool_name (string); optional: params (dict,
forwarded to the addon handler unvalidated — shape per the tool's
params_schema from op="list"). Inside batch_execute, address a custom tool
as "custom_tool:<name>" (deferred tools cannot run in batches).
Some custom tools are also registered first-class as "custom_<name>" with
their own schema — prefer those when present.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"invoke",
"list"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
editor_manageEditor selection, performance monitors, quit, log clearing, game eval.
Resource forms (prefer for active-session reads):
godot://editor/state, godot://selection/current, godot://performance
Ops:
• state()
Editor version, project name, current scene, readiness, play state.
• selection_get()
Currently selected node paths in the editor.
• selection_set(paths)
Replace the selection with the given list of scene paths.
• monitors_get(monitors=None)
Performance singleton values (FPS, memory, draw calls, etc.). Pass
a list of monitor names to filter; None returns everything.
• quit()
Gracefully quit the Godot editor on next frame.
• logs_clear(clear_debugger_errors=False)
Clear the MCP log buffer. Returns cleared_count. Pass
clear_debugger_errors=True to also clear the Debugger dock's
visible Errors-tab rows (user-facing UI, so opt-in only); the
response then includes debugger_errors_cleared.
• game_eval(code)
Execute GDScript in the running game with return values. Uses
'await' so user code can await internally. Errors return fast and
actionable: EVAL_COMPILE_ERROR for a syntax/parse error,
EVAL_RUNTIME_ERROR (with the real message + line) for a runtime
error; EVAL_GAME_NOT_READY if the game can't service evals — still
launching (retry once it's up), the _mcp_game_helper autoload is
missing/disabled, its main loop is not advancing (focus the game),
or its debugger session closed; EVAL_HUNG for a live game's genuine
infinite loop / never-firing await; EVAL_RESULT_TOO_LARGE if the
returned value serializes past the debugger channel's capacity
(return a smaller slice).
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"game_eval",
"logs_clear",
"monitors_get",
"quit",
"selection_get",
"selection_set",
"state"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
editor_reload_pluginReload the Godot editor plugin.
Disables and re-enables the plugin on the next frame. The response
shape depends on whether this MCP server was spawned by the plugin
or launched externally:
- **Plugin-managed (default install)**: returns a pre-flight ack
``{status: "reload_initiated", transport_will_drop: true,
old_session_id, guidance}`` immediately. The reload kills this
server, so the WebSocket transport drops; reconnect and call
``session_manage(op="list")`` to find the new session_id.
- **Externally launched** (e.g. ``python -m godot_ai --transport
streamable-http --port 8000 --reload``): waits for the new
session to register and returns
``{status: "reloaded", old_session_id, new_session_id}``.
If the old bridge disappears and no replacement registers
within 15 seconds, raises ``PLUGIN_DISCONNECTED`` with
``data.reason == "reload_timeout"`` and recovery diagnostics.Input schema{
"additionalProperties": false,
"properties": {
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
editor_screenshotCapture a screenshot of the Godot editor viewport or running game.
Picking a source: the default ``"viewport"`` captures the editor's 3D
viewport, which is empty if the edited scene has no Node3D anywhere in
the tree (or no scene is open). Those cases return ``EDITOR_NOT_READY``
with ``error.data = {editor_state: "viewport_not_3d", scene_root_type}``
and an actionable ``error.message`` — switch to ``"cinematic"`` if the
scene has a Camera3D, or open a scene with 3D content.
Sources:
- "viewport" (default): editor 3D viewport. Requires Node3D content in
the edited scene (root or any descendant); see above for the
no-3D-content / no-scene error shape.
- "viewport_2d": editor 2D viewport. Use for 2D scenes.
Not compatible with view_target/coverage/elevation/azimuth/fov.
- "cinematic": render edited scene through its active Camera3D (no
editor gizmos). Prefers a Camera3D marked ``current``; falls back to
the first Camera3D found in a depth-first walk. NODE_NOT_FOUND only
when the scene contains no Camera3D at all.
- "game": running game's framebuffer (only when project is running).
A backgrounded/minimized game window freezes its main loop; the
capture then returns the last rendered frame with
``stale_frame: true`` and a ``note`` in the metadata — focus the
game window and retry for a current frame. ``GAME_HELPER_TIMEOUT``
means the game process never replied at all (nothing rendered yet,
main thread blocked, or helper dead) — focus the window and retry,
or use game_command to confirm liveness.
``include_image=True`` (default) returns an MCP ImageContent block.
``view_target`` (comma-separated Node3D paths) reframes editor camera;
AABB metadata always returned. ``coverage=True`` with view_target
captures perspective + orthographic top-down references.Input schema{
"additionalProperties": false,
"properties": {
"source": {
"default": "viewport",
"type": "string",
"description": "\"viewport\" | \"viewport_2d\" | \"cinematic\" | \"game\". Default \"viewport\"."
},
"max_resolution": {
"default": 640,
"type": "integer",
"description": "Longest-edge resolution. Default 640. 0 = full res."
},
"include_image": {
"default": true,
"type": "boolean",
"description": "Return image data. Default True."
},
"view_target": {
"default": "",
"type": "string",
"description": "Node3D scene path(s) to frame, comma-separated."
},
"coverage": {
"default": false,
"type": "boolean",
"description": "With view_target, capture two reference shots + AABB."
},
"elevation": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Camera elevation in degrees (0=level, 90=overhead)."
},
"azimuth": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Camera azimuth in degrees (0=front, 90=right)."
},
"fov": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"description": "Camera FOV in degrees. Tight 20-30 = zoom; 60-75 = context."
},
"user_prompt": {
"default": "",
"type": "string",
"description": "Optional context from the agent that requested the\ncapture. With Vision Routing enabled it is sent alongside the\nimage so the vision model can describe what the agent is\nlooking for."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"type": "object"
} | — | — · — | — |
editor_stateGet current Godot editor state: version, readiness, open scene, play state.
Resource form: ``godot://editor/state`` — prefer for active-session reads.
Also reachable as ``editor_manage(op="state")`` (same handler) for clients
that prefer a single rolled-up tool.
Code-mode MCP adapters keep the server and tool names separate:
``call('godot-ai', 'editor_state', {})``. Never pass a server-prefixed
tool name such as ``godot-ai/get_editor_state``; that is neither the
adapter's call signature nor a registered tool. For dedicated current-
scene data, use ``readResource('godot-ai', 'godot://scene/current')``.
Side effect: refreshes the server's session readiness cache from the
live editor reply. Useful as a recovery step after a write call is
rejected as ``EDITOR_NOT_READY (state=playing)`` when you already know
the game has stopped — calling ``editor_state`` once syncs the cache
and the next write proceeds. Issue #262.
Response includes ``game_status`` for authoritative game liveness,
plus ``helper_live`` (status == "live") and ``session_active``
(status not in {"not_live", "stopped"}) mirrored from the same fields
inside ``game_status``. ``is_playing`` remains raw editor play-state;
use ``game_status.status`` for liveness decisions.
``game_status.status="break"`` means the game process is parked in a
remote-debugger break (boot-time parse errors do this before the game
helper registers); it will not resume on its own — call
``project_manage(op="stop")``.Input schema{
"additionalProperties": false,
"properties": {
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
filesystem_manageProject filesystem access via the Godot editor's EditorFileSystem.
Ops:
• read_text(path)
Read a text file at a ``res://`` path. Returns content, size,
line_count.
• write_text(path, content="")
Create or overwrite a text file. Updates the editor filesystem
entry for that one file (single-file update, not a full scan).
Newly-created files include ``data.cleanup.rm`` for transient
smoke tests; overwrite omits the field.
• reimport(paths)
Force-reimport the listed files via ``EditorFileSystem.update_file``.
``paths`` is a list of res:// paths.
Intended for imported assets such as textures, models, and audio.
Paths that are not imported resources (``.gd`` scripts, ``.tscn``,
hand-written ``.tres``, or an asset the editor has not imported yet)
report under ``skipped_non_imported`` rather than ``reimported``: their
filesystem entry is refreshed, but no import runs, so a success there is
not evidence that a script parsed or that diagnostics were produced. Use
``script_patch``/``script_create`` to save a script and receive fresh
diagnostics, or ``scan`` for an asset awaiting its first import.
Returns ``reimported``, ``skipped_non_imported``, ``not_found`` and their
counts.
• scan()
Force a full ``EditorFileSystem.scan()`` and wait for it to settle.
This is the headless equivalent of the editor regaining window focus:
``write_text``/``script_create`` register single files but do NOT
rebuild the global ``class_name`` table, so a freshly-created
``class_name MyThing extends Resource`` is invisible to
``resource_manage``/type references until a scan runs. Call this once
after adding ``class_name`` scripts when the editor isn't focused.
Single-flight (awaits any in-progress scan rather than stacking another).
Returns ``scan_completed`` and ``global_classes_registered_delta``.
• search(name="", type="", path="", offset=0, limit=100)
Find files by name, resource type, or path substring. At least one
filter must be set. Paginated.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"read_text",
"reimport",
"scan",
"search",
"write_text"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
game_manageRuntime game inspection and input simulation.
These ops target the running game process through Godot's EngineDebugger
bridge. Start the project first with project_run and poll editor_state until
game_capture_ready=true.
Ops:
- get_scene_tree(depth=10, root_path="")
Inspect the running scene tree. root_path accepts an absolute runtime
path or a scene-relative path rooted at the current scene.
- get_node_info(path, include_properties=True)
Inspect one running node's metadata and optional property snapshot.
- get_ui_elements(root_path="", include_hidden=False,
include_disabled=True, max_depth=10)
Inspect visible runtime Control nodes for UI testing. Includes path,
type, text where present, disabled state, and rect metadata.
- input_key(key, pressed=True, echo=False)
Send a key press/release to the running game.
- input_mouse(event, position=None, button="left", pressed=True)
Send a mouse motion or button event. event: "motion" | "button".
position is a {x, y} object or [x, y] array; omit it to use the
game's current cursor position. A present but malformed position is
rejected rather than silently falling back to the cursor.
- input_gamepad(device=0, control="button", index=0, pressed=True, value=0.0)
Send a joypad button or axis event. control: "button" | "axis".
- input_action(action, pressed=True, strength=1.0)
Set a project action's pressed state directly in the running game.
- input_sequence(steps, settle_frames=0)
Apply a frame-timed action timeline in one call — the frame-accurate,
multi-step form of input_action. Each step is
{at_frame, action, pressed=True, strength=1.0}; the game applies each
step's action on its scheduled frame, awaits settle_frames more, then
replies once. Use this instead of separate input_action calls whenever
timing matters (jump arcs, combos, walk-into-trigger): per-call network
latency makes hitting a target frame impossible otherwise. Steps must
be ordered by non-decreasing at_frame; frames (not ms) are the timing
basis. Action-based input is focus-independent, so it works on a
backgrounded game window. Cannot run inside batch_execute.
- input_state(actions=None)
Read current action pressed states. Empty actions = all project actions.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"get_node_info",
"get_scene_tree",
"get_ui_elements",
"input_action",
"input_gamepad",
"input_key",
"input_mouse",
"input_sequence",
"input_state"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
gridmap_manageGridMap authoring (set items, fill 3D regions, clear, read cells + library items).
All operations target GridMap nodes in the currently edited scene by
scene-relative path (e.g. "/Main/Terrain"). All write ops are undoable via
EditorUndoRedoManager.
item is the item id from the GridMap's MeshLibrary. Use
gridmap_list_library_items to discover valid ids and names before placing
cells (the 3D analogue of tileset atlas inspection). orientation is the
GridMap baked rotation index (0..24).
Ops:
• gridmap_set_item(path, item, map_x, map_y, map_z, orientation=0)
Set a single cell item at (map_x, map_y, map_z). item=-1 erases.
Returns: {map_x, map_y, map_z, item, orientation}
• gridmap_fill(path, item, rect_x, rect_y, rect_z, rect_w, rect_h, rect_d,
orientation=0)
Fill a rect_w × rect_h × rect_d region starting at (rect_x, rect_y,
rect_z) with one item in a single undo action.
Returns: {cells_filled, rect: {x, y, z, w, h, d}}
• gridmap_clear(path)
Remove all cells from the GridMap.
Returns: {cleared: true}
• gridmap_get_used_cells(path)
Return all used cell coordinates.
Returns: {cells: [{x, y, z}, ...], count: int}
• gridmap_list_library_items(path)
List the MeshLibrary items available to the GridMap.
Returns: {library, items: [{item, name, mesh}...], count: int}
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"gridmap_clear",
"gridmap_fill",
"gridmap_get_used_cells",
"gridmap_list_library_items",
"gridmap_set_item"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
input_map_manageInputMap actions and bindings (keyboard, mouse, gamepad). Persisted to
``project.godot``.
Resource form: ``godot://input_map`` — prefer for active-session reads.
Ops:
• list(include_builtin=False)
List input actions and their bound events. By default only
user-authored actions (those persisted in ``project.godot`` under
``input/<name>``) are returned; pass ``include_builtin=True`` to
also surface Godot's ``ui_*`` and editor-runtime actions
(``spatial_editor/*``, etc.). The ``is_builtin`` field on each
entry is true for any action not authored by the user.
• add_action(action, deadzone=0.5)
Create a new empty input action. ``deadzone`` must be in
``[0.0, 1.0]`` — Godot uses it as the analog-stick dead-zone
threshold; values outside this range are rejected with
``VALUE_OUT_OF_RANGE``. Typical values are 0.2-0.5; leave the
default 0.5 unless you have a reason. Not a key-repeat delay.
• ensure_action(action, deadzone=0.5)
Idempotently create or persist an input action. If the action exists
in live InputMap or in project.godot, the existing state is preserved.
• remove_action(action)
Remove an action and all its event bindings. Also removes actions
persisted in project.godot but not loaded in the live InputMap
(``loaded_in_input_map: false`` in ``list``), e.g. actions created
by a previous editor session.
• bind_event(action, event_type, keycode="", ctrl=False, alt=False,
shift=False, meta=False, button=None, axis=None,
axis_value=1.0)
Bind a key/mouse/gamepad event to an action. The action must
already exist (call ``add_action`` first). ``event_type`` is
``"key"`` | ``"mouse_button"`` | ``"joy_button"`` |
``"joy_axis"``.
- ``key``: ``keycode`` is a Godot keycode *name string* like
``"A"``, ``"Space"``, ``"Enter"``, ``"Escape"``, ``"F1"``,
``"Left"`` — not an integer and not ``KEY_*``. Modifier
booleans ``ctrl`` / ``alt`` / ``shift`` / ``meta`` optional.
- ``mouse_button``: ``button`` is an int — 1=left, 2=right,
3=middle, 4=wheel up, 5=wheel down.
- ``joy_button``: ``button`` is the ``JoyButton`` index
(e.g. 0=A/Cross, 1=B/Circle).
- ``joy_axis``: ``axis`` is the ``JoyAxis`` index and
``axis_value`` is the direction/value, usually -1.0 or 1.0.
• ensure_binding(action, event_type, ...)
Idempotently ensure the action exists and has the requested binding.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"add_action",
"bind_event",
"ensure_action",
"ensure_binding",
"list",
"remove_action"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
logs_readRead recent log lines from the Godot editor, plugin, or running game.
Resource form: ``godot://logs/recent`` — prefer for active-session reads.
Sources:
- "plugin" (default): MCP plugin recv/send/event traffic. Buffer 500.
- "game": stdout/stderr/push_error/push_warning from playing game
via ``_mcp_game_helper`` autoload (Godot 4.5+). Buffer 2000, with
lines retained across runs and tagged by run_id. Default reads return
current-run lines only; pass ``since_run_id`` from an earlier response
to read that prior run. Entries: {source, level, text, run_id};
response carries run_id, current_run_id, game_status, helper_live,
session_active, dropped_count, stale_run_id. helper_live and
session_active mirror the same fields inside game_status; is_running
is retained as a compatibility alias of session_active.
Boot-time parse/load errors fire before the game helper's logger
attaches, so they are NEVER in this buffer; when editor-side errors
were recorded during the current run the response adds
``editor_errors_count`` and ``editor_errors_hint`` pointing at
source="editor" — treat a clean game log carrying that hint as a
run that lost scripts, not a clean launch.
- "editor": editor-process script errors and the Debugger dock's
visible Errors-tab rows — parse errors, GDScript reload warnings,
@tool/EditorPlugin runtime errors, push_error/push_warning.
Logger-backed entries require Godot 4.5+; Errors-tab rows are read
from the editor UI when available. Use when the editor Output or
Debugger Errors panel shows red/yellow rows but other sources turned
up nothing. Buffer 500 for logger-backed entries; Debugger rows are
live UI state. Entries: {source, level, text, path, line, function}.
Filtered to .gd/.cs in the user project for Logger-backed entries;
addons/godot_ai/ dropped. Logger entries fired before plugin enable
are not captured.
- "all": plugin → editor → game lines (with source per entry).
Tail pattern: for game logs, poll the current run with offset=N and
keep the returned run_id. ``current_run_id`` identifies the active run;
``run_id`` identifies the run being read. Passing
``since_run_id=old_run_id`` reads retained lines for that prior run, and
``stale_run_id: true`` means the requested run is not the current run.
For editor logs, read once to capture
``next_cursor`` and pass it back as ``since_cursor`` on later calls.
``since_cursor`` reads Logger-backed editor entries only; live Debugger
Errors-tab rows are included in regular source="editor" reads but do
not have stable cursors. When ``since_cursor`` is set, it supersedes
``offset``. ``truncated: true`` means older entries fell out of the
ring before the poll; continue from the returned ``next_cursor`` and
treat ``oldest_cursor`` as the earliest retained sequence.
Set ``include_details=True`` for Errors-tab style metadata on game/editor
entries: original code/rationale, error type, resolved source, and
stack frames. Default false preserves compact responses.Input schema{
"additionalProperties": false,
"properties": {
"count": {
"default": 50,
"type": "integer",
"description": "Max lines to return. Default 50."
},
"offset": {
"default": 0,
"type": "integer",
"description": "Lines to skip. Default 0."
},
"source": {
"default": "plugin",
"type": "string",
"description": "\"plugin\" | \"game\" | \"editor\" | \"all\". Default \"plugin\"."
},
"since_run_id": {
"default": "",
"type": "string",
"description": "Game-log run id from a previous response; reads that\nretained run instead of the current run."
},
"since_cursor": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"default": null,
"description": "Editor-log cursor from a previous source=\"editor\" response."
},
"include_details": {
"default": false,
"type": "boolean",
"description": "Include rich error metadata for game/editor entries."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
material_manageMaterial authoring (StandardMaterial3D, ORMMaterial3D, ShaderMaterial,
CanvasItemMaterial). Albedo, metallic/roughness, emission, transparency,
shader uniforms.
Resource form: ``godot://materials`` — prefer for active-session reads.
Ops:
• create(path, type="standard", shader_path="", overwrite=False)
Create + save a material .tres at a res:// path. type:
"standard" | "orm" | "canvas_item" | "shader". For "shader",
shader_path points to the .gdshader.
• set_param(path, param, value)
Set a built-in property on a .tres material. Enum-valued params
accept names ("alpha" -> TRANSPARENCY_ALPHA). Color/Vector dicts.
Texture properties accept res:// paths.
• set_shader_param(path, param, value)
Set a shader uniform on a ShaderMaterial.
• get(path)
Inspect a material (type, params, uniforms, current values).
• list(root="res://", type="")
List materials under root, optional type filter.
• assign(node_path, resource_path="", slot="override", create_if_missing=False,
type="standard")
Assign a material to a node slot. Slots: "override" |
"surface_<N>" | "canvas" | "process". When create_if_missing=True
and no resource_path, makes an inline material of `type`.
• apply_to_node(node_path, type="standard", params=None, slot="override",
save_to="", overwrite=False)
High-level: build + set params + assign in one undo.
save_to optionally persists to disk; errors if the file already
exists unless overwrite=True.
• apply_preset(preset, path="", node_path="", overrides=None)
Curated looks: metal, glass, emissive, unlit, matte, ceramic.
path saves to disk; node_path assigns to a node; overrides merge.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"apply_preset",
"apply_to_node",
"assign",
"create",
"get",
"list",
"set_param",
"set_shader_param"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
node_createCreate (spawn) a new node in the scene tree.
Creates a node of the given type and adds it to the parent, or
instantiates a PackedScene from ``scene_path``. type and scene_path
are mutually exclusive — when scene_path is given, type is ignored.Input schema{
"additionalProperties": false,
"properties": {
"type": {
"default": "",
"type": "string",
"description": "Godot node class (e.g. \"Node3D\", \"MeshInstance3D\")."
},
"name": {
"default": "",
"type": "string",
"description": "Optional name; Godot auto-names if empty."
},
"parent_path": {
"default": "",
"type": "string",
"description": "Parent path relative to the edited scene root (e.g.\n\"/Main\"), NOT runtime \"/root/...\". Empty = scene root."
},
"scene_path": {
"default": "",
"type": "string",
"description": "Optional res:// path of a PackedScene to instantiate."
},
"scene_file": {
"default": "",
"type": "string",
"description": "Optional editor-scene guard (EDITED_SCENE_MISMATCH)."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
node_findFind nodes in the scene tree by name, type, or group.
At least one filter must be provided. Filters AND together. Paginated.Input schema{
"additionalProperties": false,
"properties": {
"name": {
"default": "",
"type": "string",
"description": "Substring match on node name (case-insensitive)."
},
"type": {
"default": "",
"type": "string",
"description": "Exact Godot class name (e.g. \"MeshInstance3D\")."
},
"group": {
"default": "",
"type": "string",
"description": "Group name the node must belong to."
},
"offset": {
"default": 0,
"type": "integer",
"description": "Number of results to skip. Default 0."
},
"limit": {
"default": 100,
"type": "integer",
"description": "Max number of results. Default 100."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
node_get_propertiesGet properties of a node.
Resource form: ``godot://node/{path}/properties`` — prefer for
active-session reads (returns the full property set).
The default returns every editor-visible property, which can be
50-150 entries. Pass ``fields`` to return only the properties you
need — a large response-size cut on this hot read. The response
always carries ``total_count`` (all editor-visible properties)
alongside ``count`` (returned): an unfiltered call returns the full
set, so ``count == total_count``; only the ``fields`` filter can
make ``count`` smaller. Requested names that match no
editor-visible property are listed in ``unknown_fields``, so a
nonexistent name is distinguishable from a property that exists
with a null value.
Null-valued properties are included: an unset object/resource slot
(``script`` on an unscripted node, an empty ``mesh`` or
``material``, …) returns ``"value": null`` with its declared type.
An attached script serializes to its ``res://`` path; built-in
scripts (no resource path) fall back to their string
representation.Input schema{
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"description": "Scene path relative to the edited scene root (e.g.\n\"/Main/Camera3D\"), NOT runtime \"/root/...\" paths. Derive\nfrom prior tool responses or scene_get_hierarchy."
},
"fields": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "When non-empty, return only these property names."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"required": [
"path"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
node_manageNode tree manipulation (delete, duplicate, rename, reorder, reparent,
groups, hierarchy reads).
Resource forms (prefer for active-session reads):
godot://node/{path}/properties, godot://node/{path}/children,
godot://node/{path}/groups
Ops:
• get_children(path)
Direct children of a node (name, type, path each).
• get_groups(path)
Group names the node belongs to.
• delete(path, scene_file="")
Remove the node. Cannot delete scene root. Undoable.
• duplicate(path, name="", scene_file="")
Deep-copy a node + children as a sibling. Cannot duplicate scene root.
• rename(path, new_name, scene_file="")
Rename a node. Sibling-name collision and "/" / ":" / "@" rules apply.
• move(path, index, scene_file="")
Reorder among siblings. Index 0 = first.
• reparent(path, new_parent, scene_file="")
Move under a new parent. Children preserved. Cannot move into descendants.
• add_to_group(path, group, scene_file="")
Add the node to a group.
• remove_from_group(path, group, scene_file="")
Remove the node from a group.
All write ops accept the optional ``scene_file`` guard — if non-empty, the
mutation fails with EDITED_SCENE_MISMATCH when the editor's current scene
doesn't match.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"add_to_group",
"delete",
"duplicate",
"get_children",
"get_groups",
"move",
"remove_from_group",
"rename",
"reparent"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
node_set_propertySet a property on a node.
Verify the property name first — call ``node_get_properties`` (or read
``godot://node/{path}/properties``) to confirm the exact name and type
before writing. Guessing common Godot names often fails with
PROPERTY_NOT_ON_CLASS because Godot's actual properties differ from
intuition (e.g. ``Camera3D`` uses ``fov``/``current``, not ``field_of_view``;
``Sprite2D`` uses ``texture``, not ``image``; ``Node3D`` uses
``position``/``rotation``/``scale``, not ``transform.origin``).
Coerces ``value`` to the property's type:
- Vector2/Vector3: dict with x/y/z keys.
- Color: dict {r,g,b,a} or hex string ("#ff0000").
- NodePath: string ("../Other/Node").
- Resource: res:// path string (loads + assigns); null/"" clears.
``{"__class__": "BoxMesh", ...}`` creates a built-in resource owned
by this property. After scene_save it is serialized in-place as a
``[sub_resource]`` inside the .tscn; it is not a reusable .tres.
For sharing, first call ``resource_manage(op="create",
params={"type": "BoxMesh", "properties": {...},
"resource_path": "res://meshes/box.tres"})``, then pass that res://
path here (or use resource_manage(op="assign")).
- StringName: plain string. Array/Dictionary: JSON list/object.Input schema{
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"description": "Scene path relative to the edited scene root (e.g.\n\"/Main/Camera3D\"), NOT runtime \"/root/...\" paths."
},
"property": {
"type": "string",
"description": "Property name (e.g. \"fov\", \"position\", \"mesh\"). Must match\nGodot's exact identifier — introspect with ``node_get_properties``\nif unsure rather than guessing."
},
"value": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
},
{
"type": "number"
},
{
"type": "boolean"
},
{
"additionalProperties": true,
"type": "object"
},
{
"items": {},
"type": "array"
},
{
"type": "null"
}
],
"description": "New value. Pass null (or \"\" for resources) to clear."
},
"scene_file": {
"default": "",
"type": "string",
"description": "Optional editor-scene guard."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"required": [
"path",
"property",
"value"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
particle_manageParticle systems (GPUParticles2D/3D, CPUParticles2D/3D). All write ops
create the node + sub-resources (ProcessMaterial, default QuadMesh draw
pass) in a single undo action.
Ops:
• create(parent_path, name="Particles", type="gpu_3d")
Create an emitter. type: "gpu_3d" | "gpu_2d" | "cpu_3d" | "cpu_2d".
For GPU emitters, auto-creates ProcessMaterial; for gpu_3d, also
a default QuadMesh draw pass.
• set_main(node_path, properties)
Node-level props: amount, lifetime, one_shot, explosiveness,
preprocess, speed_scale, randomness, fixed_fps, emitting,
local_coords, interp_to_end.
• set_process(node_path, properties)
Behavior props (auto-creates ProcessMaterial for GPU). Emission shape,
velocity, gravity, color_ramp, scale_curve, turbulence. See full
property list in the Godot reference. GPU gravity is a Vector3 —
pass {x, y, z} or [x, y, z], including for gpu_2d (the shared
ProcessMaterial is 3D; z is ignored in 2D).
• set_draw_pass(node_path, pass_=1, mesh="", texture="", material="")
What gets drawn per particle. GPU 3D: mesh in draw_pass_N + optional
material override. GPU 2D / CPU 2D: texture. CPU 3D: mesh.
• restart(node_path)
Restart emission. Runtime-only, not undoable.
• get(node_path)
Inspect main props, process material, draw passes.
• apply_preset(parent_path, name, preset, type="gpu_3d", overrides=None)
Curated effects: fire, smoke, spark_burst, magic_swirl, rain,
explosion, lightning. One-shot presets re-trigger via restart.
overrides = {"main": {...}, "process": {...}, "draw": {...}}; bare
keys are auto-routed to main (amount, lifetime, one_shot, ...) or
process — draw keys must be nested under "draw". draw configures
the gpu_3d draw-pass StandardMaterial3D (blend_mode, albedo_color,
emission, ...); on gpu_2d only draw.texture (res:// path) applies;
cpu_* types reject draw overrides. Unknown or malformed override
keys return INVALID_PARAMS (never silently dropped); response
reports applied_main / applied_process / applied_draw. GPU gravity
requires {x, y, z} (or [x, y, z]) even for gpu_2d.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"apply_preset",
"create",
"get",
"restart",
"set_draw_pass",
"set_main",
"set_process"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
project_manageProject run/stop and project.godot settings.
Resource form: ``godot://project/info`` and ``godot://project/settings``
— prefer for active-session reads.
Ops:
• stop()
Stop the running project (game). Takes no params — call as
``project_manage(op="stop")`` or with ``params={}``. Idempotent:
succeeds with ``was_running=false`` if the project isn't running.
Do NOT pass extra fields like ``force`` or ``reason`` inside
``params`` — only the registered keys are accepted (here, none).
For multi-editor setups, pass ``session_id`` as a sibling of
``op``/``params``, not inside ``params``.
• settings_get(key)
Read a ProjectSettings key (e.g. "application/config/name").
• settings_set(key, value)
Write a ProjectSettings key and persist to project.godot.
Refuses the startup-execution keys (``autoload/*``,
``editor_plugins/*``, ``application/run/main_scene``,
``editor/run/main_run_args``, ``editor/script/templates_search_path``);
use ``set_main_scene`` / ``autoload_manage(op="add")`` for the two
that have a validated route.
• set_main_scene(path)
Set the project's main scene — the scene ``project_run(mode="main")``
boots and the engine loads at startup. Writes
``application/run/main_scene`` and persists to project.godot. ``path``
must be a ``res://`` scene inside the project that already exists and
loads as a PackedScene, so a scaffolded project can be made runnable
without opening the generic startup-execution surface.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"set_main_scene",
"settings_get",
"settings_set",
"stop"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
project_runRun (play) the Godot project from the editor.
Modes:
- "main": Run the project's main scene (default).
- "current": Run the currently open scene.
- "custom": Run a specific scene (requires ``scene``).
Idempotent: if the project is already running, returns success with
``data.was_already_running=true`` (no scene switch). To switch scenes,
call ``project_manage(op="stop")`` first, then ``project_run`` again.
After starting playback, waits briefly for the Godot AI game helper to
check in. The response includes ``game_status``, ``helper_live``
(status == "live"), ``session_active`` (status not in {"not_live",
"stopped"}), and any ``recent_errors`` observed during the run window.
The top-level booleans mirror the same fields inside ``game_status``.
``game_status.status="not_live"`` means playback launched but the game
did not become live before the helper-ready window elapsed;
``"no_helper"`` means the project has no _mcp_game_helper autoload, as
with some headless/custom-main-loop setups (helper_live=false,
session_active=true); ``"stopped"`` means playback stopped or never
became active before liveness could be confirmed (helper_live=false,
session_active=false); ``"break"`` means the game process is parked in
a remote-debugger break — during boot this is a GDScript parse/load
error that froze the game before the helper could register, and the
response names the failing script when captured
(``game_status.break`` = ``{reason, can_debug, pre_live}``). A game at
a break cannot continue on its own: call ``project_manage(op="stop")``,
fix the error, and relaunch. Poll ``editor_state`` to see late
transitions.Input schema{
"additionalProperties": false,
"properties": {
"mode": {
"default": "main",
"type": "string",
"description": "\"main\" | \"current\" | \"custom\". Default \"main\"."
},
"scene": {
"default": "",
"type": "string",
"description": "Scene path (e.g. \"res://levels/level1.tscn\"). Required for \"custom\"."
},
"autosave": {
"default": true,
"type": "boolean",
"description": "When True (default), Godot persists in-memory MCP scene\nmutations to disk before running. Pass False for smoke tests\nwhere MCP edits should stay in memory."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
resource_manageResource (asset) search, inspection, assignment, and creation. Covers
generic Resource subclasses plus specialized authoring (Curve, Environment,
physics shapes, gradient/noise textures).
Ops:
• search(type="", path="", offset=0, limit=100)
Search for resources by type or path. Type matching includes
subclasses. At least one filter required. Paginated.
• load(path)
Inspect a .tres / .res — returns type and editor-visible properties.
• assign(path, property, resource_path)
Load and assign a resource to a node property. Undoable.
• get_info(type)
Introspect a Resource class — properties, parent, abstract flag,
concrete_subclasses (for abstract bases). Read-only.
• create(type, properties=None, path="", property="", resource_path="",
overwrite=False)
Instantiate a Resource subclass. Either path+property (assign to a
node, undoable) or resource_path (save to .tres). For specific
families (Curve, Environment, etc.) prefer the dedicated ops.
• curve_set_points(points, path="", property="", resource_path="")
Replace all points on a Curve / Curve2D / Curve3D. Auto-creates
the curve resource if the slot is empty (curve_created flag).
• environment_create(path="", preset="default", properties=None,
sky=None, resource_path="", overwrite=False)
Build Environment + Sky chain. Presets: default | clear | sunset
| night | fog. sky may be bool or a procedural sky dict such as
{"sky_material": "procedural", "sky_top_color": "#0f172a"}.
Either assign to a WorldEnvironment node or save .tres.
• physics_shape_autofit(path, source_path="", shape_type="")
Size a CollisionShape2D/3D to a nearby visual's bounds. Searches
direct siblings then parent-siblings (handles nested
Body→Collision layouts). Ambiguous matches return candidate paths
in error.data.candidates. Auto-creates the concrete Shape subclass
if needed. shape_type accepts either the short form ("box",
"sphere", "capsule", "cylinder" for 3D; "rectangle", "circle",
"capsule" for 2D) or the matching Godot class name ("BoxShape3D",
"RectangleShape2D", etc.).
• gradient_texture_create(stops, width=256, height=1, fill="linear",
path="", property="", resource_path="",
overwrite=False)
Build GradientTexture2D from color stops. fill: linear | radial | square.
• noise_texture_create(noise_type="simplex_smooth", width=512, height=512,
frequency=0.01, seed=0, fractal_octaves=0,
path="", property="", resource_path="",
overwrite=False)
Build NoiseTexture2D wrapping FastNoiseLite. Noise types: simplex |
simplex_smooth | perlin | cellular | value | value_cubic.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"assign",
"create",
"curve_set_points",
"environment_create",
"get_info",
"gradient_texture_create",
"load",
"noise_texture_create",
"physics_shape_autofit",
"search"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
scene_get_hierarchyGet the scene tree hierarchy from the open scene.
Returns a paginated flat list of nodes with name, type, path, and
child count. Walks up to the specified depth.
Resource form: ``godot://scene/hierarchy`` — prefer for active-session
reads.Input schema{
"additionalProperties": false,
"properties": {
"depth": {
"default": 10,
"type": "integer",
"description": "Maximum walk depth. Default 10."
},
"offset": {
"default": 0,
"type": "integer",
"description": "Number of nodes to skip. Default 0."
},
"limit": {
"default": 100,
"type": "integer",
"description": "Max number of nodes to return. Default 100."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
scene_manageScene authoring (create, save_as, list open roots).
Resource form: ``godot://scene/current`` and ``godot://scene/hierarchy``
— prefer for active-session reads.
Ops:
• create(path, root_type="Node3D", root_name="")
Create the initial .tscn with the given root and open it. root_name
defaults to filename basename when empty. This initial root is written
immediately, but later node_create/node_set_property mutations remain
in editor memory until scene_save or save_as is called.
• save_as(path)
Save the currently edited scene to a new file path.
• get_roots()
List scenes currently open in the editor; flag the edited one.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"create",
"get_roots",
"save_as"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
scene_openOpen an existing scene file (.tscn) in the editor.
If ``path`` is already the currently edited scene this is a no-op
— the in-memory state (including any unsaved MCP mutations) is
preserved. Pass ``force_reload=True`` when the file on disk is the
authority and the editor should discard the open in-memory copy and
re-read the scene from disk.
The reply is sent only after the editor has actually switched to the
requested scene (``switched: true``), so follow-up writes are safe
immediately. ``switched: false`` with ``settle: "timeout"`` means the
switch had not landed within the wait window. In synchronous contexts
(e.g. inside ``batch_execute``) the reply returns immediately with
``switched: false`` and ``settle: "not_waited"``. In both of those
cases, re-check ``editor_state`` before issuing follow-up writes.Input schema{
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"description": "File path of the scene to open (e.g. \"res://main.tscn\")."
},
"force_reload": {
"default": false,
"type": "boolean",
"description": "Re-read the scene from disk even when it is already\nopen. This discards unsaved in-memory edits to that scene."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"required": [
"path"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
scene_saveSave the currently edited scene to disk.
Node and property mutation tools change the editor's in-memory scene;
call this explicitly to persist those mutations to the existing path.Input schema{
"additionalProperties": false,
"properties": {
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
script_attachAttach a script to a node in the scene tree.
Replaces any existing script on the node. Undoable.Input schema{
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"description": "Scene path of the node (e.g. \"/Main/Player\")."
},
"script_path": {
"type": "string",
"description": "res:// path of the .gd (e.g. \"res://scripts/player.gd\")."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"required": [
"path",
"script_path"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
script_createCreate a new GDScript source file (.gd) on disk.
Writes content to a .gd file in the project. Overwrites if it exists.
Triggers a filesystem scan. New files include ``data.cleanup.rm``
listing the .gd + .gd.uid sidecar; overwrite omits it.Input schema{
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"description": "res:// path (e.g. \"res://scripts/player.gd\")."
},
"content": {
"default": "",
"type": "string",
"description": "GDScript source. Empty creates a blank file."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"required": [
"path"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
script_manageScript (.gd) reading, detachment, and outline.
Resource form: ``godot://script/{path}`` — prefer for active-session reads.
Ops:
• read(path)
Read full source, line count, file size.
• detach(path)
Remove the currently attached script from a node. Undoable.
• find_symbols(path)
Outline a .gd — class_name, extends, functions, signals, @export vars.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"detach",
"find_symbols",
"read"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
script_patchAnchor-based string-replace edit on a .gd file.
Finds an exact ``old_text`` and replaces with ``new_text``. Fails
on multiple matches unless ``replace_all=True``; fails on zero matches.
Exact byte match (whitespace significant). Triggers filesystem scan and
refreshes an already-loaded GDScript in place so the next call runs the
new code (response reloaded=true; otherwise reload_reason says why).
Not undoable via Ctrl+Z.Input schema{
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"description": "res:// path ending in .gd."
},
"old_text": {
"type": "string",
"description": "Exact substring to find. Must be unique unless replace_all."
},
"new_text": {
"type": "string",
"description": "Replacement (empty deletes)."
},
"replace_all": {
"default": false,
"type": "boolean",
"description": "Replace every occurrence. Default False."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"required": [
"path",
"old_text",
"new_text"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
session_activateSet the active Godot editor session for subsequent tool calls.
Accepts either an exact session_id or a substring hint matched
against the session's short name (project folder basename),
project_path, or session_id. An exact id match always wins; a
substring must resolve to exactly one session or the tool returns
an error listing the candidates.Input schema{
"additionalProperties": false,
"properties": {
"session_id": {
"type": "string",
"description": "An exact session id (``<project-slug>@<4hex>``, e.g.\n``my_game@a3f2``, from ``session_manage`` with op=\"list\")\nOR a substring hint like a project folder name\n(\"test_project\", \"my_game\")."
}
},
"required": [
"session_id"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
session_manageSession listing.
Resource form: ``godot://sessions`` — prefer for resource-aware clients.
Ops:
• list()
List every connected Godot editor with metadata: session_id, short
name, godot_version, project_path, plugin_version, server_version,
editor_pid, server_launch_mode, current_scene, play_state, readiness,
connected_at, last_seen, is_active. The response also carries the
server-global ``exclude_domains`` (tool domains not registered on
this server via --exclude-domains).
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"const": "list",
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
signal_manageSignals (Godot's event/observer mechanism) — list, connect, disconnect.
Ops:
• list(path, include_editor=False)
List all signals on the node and their current connections (built-in
and custom). By default editor-internal connections (the
SceneTreeEditor dock and friends) are filtered out — pass
``include_editor=True`` to surface them. The response carries
``editor_connection_count`` so an agent can tell how many were hidden.
• connect(path, signal, target, method)
Connect a signal from ``path`` to a method on the target node.
Undoable.
• disconnect(path, signal, target, method)
Remove an existing connection. Undoable.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"connect",
"disconnect",
"list"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
test_manageTest result inspection (re-fetches the most recent ``test_run`` payload).
Resource form: ``godot://test/results`` — prefer for active-session reads.
Ops:
• results_get(verbose=False)
Same shape as test_run — full results from the last run, no
re-execution. verbose=True includes every individual test result.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"const": "results_get",
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
test_runRun GDScript test suites inside the connected Godot editor.
Discovers test_*.gd in res://tests/, instantiates them, and runs
all test_* methods. Returns a compact summary by default (counts,
suite names, duration) plus failures only. verbose=True includes
every individual test result (each with per-test ``duration_ms``).
The whole run has a 300s budget; the plugin aborts between tests
shortly before it expires and returns TEST_RUN_TIMEOUT with the
partial summary (full partials via test_manage(op="results_get")).
Long suites are safe — the editor services the MCP transport
between tests — but one single test blocking the main thread for
20s+ can still drop the session. Not allowed inside batch_execute.
The response includes ``edited_scene`` (the scene currently open in
the editor). Many suites assume the project's main scene is open; if
it is not and there are failures, the response also carries a
``scene_warning`` — open the main scene (``scene_open``) and re-run
before treating those failures as real.Input schema{
"additionalProperties": false,
"properties": {
"suite": {
"default": "",
"type": "string",
"description": "Run only the named suite (e.g. \"scene\", \"node\", \"editor\").\nEmpty runs all suites."
},
"test_name": {
"default": "",
"type": "string",
"description": "Run only tests whose name contains this substring."
},
"exclude_test_name": {
"default": "",
"type": "string",
"description": "Skip tests whose name contains this substring."
},
"verbose": {
"default": false,
"type": "boolean",
"description": "Include every individual test result. Default False."
},
"session_id": {
"default": "",
"type": "string",
"description": "Optional Godot session to target. Empty = active session."
}
},
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
theme_manageTheme authoring (Godot's stylesheet-like resource for Controls). Cascades
down a Control subtree when assigned via theme_apply.
Ops (pass via op="..." plus a params dict):
• create(path, overwrite=False)
Create a new empty Theme .tres at a res:// path.
• set_color(theme_path, class_name, name, value)
Set a color slot. value: "#rrggbb"/"#rrggbbaa", named, or
{"r","g","b","a"}.
• set_constant(theme_path, class_name, name, value)
Set an integer constant (separation, margin, padding).
• set_font_size(theme_path, class_name, name, value)
Set a font_size slot in pixels.
• set_stylebox_flat(theme_path, class_name, name, bg_color?, border_color?,
border?, corners?, margins?, shadow?, anti_aliasing?)
Compose a StyleBoxFlat (panels, button states, line edits).
border/corners/margins/shadow each accept "all" + per-side keys.
• apply(node_path, theme_path="")
Assign the theme to a Control (cascades to descendants). Empty
theme_path clears.
All ops accept `session_id` on the wrapper to target a specific editor.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"apply",
"create",
"set_color",
"set_constant",
"set_font_size",
"set_stylebox_flat"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
tilemap_manageTileMap / TileMapLayer authoring (set tiles, fill rects, clear, read cells).
All operations target TileMapLayer nodes in the currently edited scene by
scene-relative path (e.g. "/LavaLake20x20/Ground"). All write ops are
undoable via EditorUndoRedoManager.
source_id is the TileSet source index. atlas_col/atlas_row are the
atlas coordinates of the tile within that source. For full-tile animated
sources (lava, water, sewage) use atlas_col=0, atlas_row=0.
IMPORTANT — Source-ID remapping in specialized .tres files:
When a layer uses a specialized .tres (e.g. volcano_animated.tres),
Source-IDs are re-numbered from 0. Example: volcano lava is Source 8 in
the main volcano.tres but Source 0 in volcano_animated.tres.
Always use the remapped ID when the TileMapLayer references a specialized
.tres, not the original ID from the main .tres.
Ops:
• tilemap_set_cell(path, source_id, atlas_col, atlas_row, map_x, map_y)
Set a single tile at (map_x, map_y).
Returns: {map_x, map_y, source_id, atlas_col, atlas_row}
• tilemap_set_cells_rect(path, source_id, atlas_col, atlas_row,
rect_x, rect_y, rect_w, rect_h)
Fill a rect_w × rect_h region starting at (rect_x, rect_y) with
one tile type in a single undo action.
Returns: {cells_filled, rect: {x, y, w, h}}
• tilemap_clear(path)
Remove all tiles from the layer.
Returns: {cleared: true}
• tilemap_get_cells(path)
Return all used cell coordinates.
Returns: {cells: [{x, y}, ...], count: int}
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"tilemap_clear",
"tilemap_get_cells",
"tilemap_set_cell",
"tilemap_set_cells_rect"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
tileset_manageTileSet management — atlas inspection tools.
Ops:
• tileset_get_atlas_tiles(tileset_path, source_id)
Return all occupied atlas tile positions for one source in a TileSet.
Read-only — does not modify any resource or project file.
tileset_path: res:// path to the .tres TileSet resource (required)
source_id: raw TileSet source id of the TileSetAtlasSource to query (required, ≥ 0)
Returns:
{"tiles": [{"col": int, "row": int}, ...], "count": int}
Error codes (passed through from GDScript handler):
MISSING_REQUIRED_PARAM — tileset_path empty or source_id absent
RESOURCE_NOT_FOUND — tileset_path does not exist on disk
WRONG_TYPE — not a TileSet, or source is not a TileSetAtlasSource
VALUE_OUT_OF_RANGE — source_id does not exist in this TileSet
• tileset_get_atlas_image(tileset_path, source_id, max_size=0)
Return the atlas sprite-sheet texture of a TileSetAtlasSource as a
Base64-encoded PNG image. Read-only — reads the texture directly
from the resource without any UI interaction.
tileset_path: res:// path to the .tres TileSet resource (required)
source_id: raw TileSet source id of the TileSetAtlasSource to query (required, ≥ 0)
max_size: optional int; if > 0, scale the image so its longest
edge is at most max_size pixels (default 0 = full res)
Returns:
{"image_base64": str, "width": int, "height": int,
"original_width": int, "original_height": int, "format": "png"}
Error codes (passed through from GDScript handler):
MISSING_REQUIRED_PARAM — tileset_path empty or source_id absent
RESOURCE_NOT_FOUND — tileset_path does not exist on disk
WRONG_TYPE — not a TileSet, source not a TileSetAtlasSource,
or source has no texture assigned
VALUE_OUT_OF_RANGE — source_id does not exist in this TileSet
• Atlas image workflow:
To visually inspect what tiles look like, use tileset_get_atlas_image
instead of editor screenshots. It reads the texture directly from the
resource — no UI interaction or editor state required.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"tileset_get_atlas_image",
"tileset_get_atlas_tiles"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
ui_manageUI / Control authoring (HUD, menus, layouts, vector decoration).
Ops:
• set_anchor_preset(path, preset, resize_mode="minsize", margin=0)
Apply a Control layout preset. preset: top_left | top_right |
bottom_left | bottom_right | center_left | center_top | center_right |
center_bottom | center | left_wide | top_wide | right_wide |
bottom_wide | vcenter_wide | hcenter_wide | full_rect.
resize_mode: minsize | keep_width | keep_height | keep_size.
Target must be a Control. CanvasLayer is the canonical HUD parent
but is not a Control — put a Control child under the CanvasLayer and
apply the preset to that overlay.
• set_text(path, text)
Set text on a Label/Button/LineEdit/TextEdit/RichTextLabel.
• build_layout(tree, parent_path="")
Atomically build a UI subtree from a nested spec
({type, name?, properties?, anchor_preset?, anchor_margin?, theme?,
children?}). Validates everything before mutating.
`properties` is direct node properties only. Theme constants like
container spacing live under `theme_override_constants/<name>` —
e.g. `{"theme_override_constants/separation": 8}` on a
VBoxContainer, not `{"separation": 8}` (which errors).
`theme` and `anchor_preset` require a Control / Window — for a HUD,
nest a Control under a CanvasLayer and apply them to the Control
child, not the layer itself.
• draw_recipe(path, ops, clear_existing=True)
Attach a declarative list of vector _draw() ops to a Control —
radar sweeps, gauges, corner brackets, crosshairs, waveforms.
Op kinds: line | rect | arc | circle | polyline | polygon | string.
Canonical call shape: ``{"op": "<verb>", "params": {...}}``. Flat op parameters are accepted as a compatibility alias when the client transmits them; ``op`` and ``session_id`` remain top-level.Input schema{
"additionalProperties": false,
"properties": {
"op": {
"enum": [
"build_layout",
"draw_recipe",
"set_anchor_preset",
"set_text"
],
"type": "string"
},
"params": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"session_id": {
"default": "",
"type": "string"
}
},
"required": [
"op"
],
"type": "object"
}Output schema{
"additionalProperties": true,
"type": "object"
} | — | — · — | — |
Current scene path and root node info from the active Godot editor.
{
"resource_key": "godot://scene/current",
"uri": "godot://scene/current",
"name": "get_current_scene",
"description": "Current scene path and root node info from the active Godot editor.",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "3dc92ae052be3951f371b825a3bc1673e2b9f6407a275507a97b4a1145006d23"
}Currently selected nodes in the Godot editor.
{
"resource_key": "godot://selection/current",
"uri": "godot://selection/current",
"name": "get_current_selection",
"description": "Currently selected nodes in the Godot editor.",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "fa8347178cc9f8467b430b5046ddd0b45561c2c9ee5467933ec3496577f5bced"
}{
"resource_key": "godot://custom-tools",
"uri": "godot://custom-tools",
"name": "get_custom_tools",
"description": null,
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "fd3e15ff1c989105fc8c6483ded9310f754255a9732789d771fdae45514aa273"
}Editor version, project name, current scene, readiness, play state.
{
"resource_key": "godot://editor/state",
"uri": "godot://editor/state",
"name": "get_editor_state",
"description": "Editor version, project name, current scene, readiness, play state.",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "fd28b8a4aab96db7e1ee44c64e95c2254f4659d5cd22d2429b9bf1dd70bb39c0"
}All input map actions and their bound events. Excludes built-in ui_*.
{
"resource_key": "godot://input_map",
"uri": "godot://input_map",
"name": "get_input_map",
"description": "All input map actions and their bound events. Excludes built-in ui_*.",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "788b2c899d8d020eb1bd542e2922f962bb7e53764c17f52b5fa6329af2b990b5"
}All Material resources under res:// (every Material subclass + .tres).
{
"resource_key": "godot://materials",
"uri": "godot://materials",
"name": "get_materials",
"description": "All Material resources under res:// (every Material subclass + .tres).",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "1862bfe33e5fcd5eece162d34353b642b818ad24bdf4f7d5c133891ead660fe8"
}Performance singleton snapshot (FPS, memory, draw calls, frame time).
{
"resource_key": "godot://performance",
"uri": "godot://performance",
"name": "get_performance",
"description": "Performance singleton snapshot (FPS, memory, draw calls, frame time).",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "edb8bc1a34225d03dd3c427487aa2265aed8fa26b854e14847e85a642c0d99a6"
}Project name, Godot version, paths, and play state.
{
"resource_key": "godot://project/info",
"uri": "godot://project/info",
"name": "get_project_info",
"description": "Project name, Godot version, paths, and play state.",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "dfcea65a094db402c4ebda11eabfd165b92ceab303d8b0cea158ca4f06b6e57c"
}Common project settings subset (display, physics, rendering).
{
"resource_key": "godot://project/settings",
"uri": "godot://project/settings",
"name": "get_project_settings",
"description": "Common project settings subset (display, physics, rendering).",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "a4088aee342fca97d2b3b2d3076c8d86d2c21e275d5d9c136be82485ae4a31f6"
}Last 100 log lines from the Godot editor console.
{
"resource_key": "godot://logs/recent",
"uri": "godot://logs/recent",
"name": "get_recent_logs",
"description": "Last 100 log lines from the Godot editor console.",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "d466b7ee2d0dcf165e222a14d08ff01a5979d7e90a26458e9ffc6100d79d0dcf"
}Scene tree hierarchy from the active Godot editor (first 100 nodes). A resource URI takes no arguments, so this read is capped; a truncated result sets `resource_truncated` with a hint. Use the `scene_get_hierarchy` tool for offset/limit pagination or a scoped depth.
{
"resource_key": "godot://scene/hierarchy",
"uri": "godot://scene/hierarchy",
"name": "get_scene_hierarchy",
"description": "Scene tree hierarchy from the active Godot editor (first 100 nodes).\n\nA resource URI takes no arguments, so this read is capped; a truncated\nresult sets `resource_truncated` with a hint. Use the\n`scene_get_hierarchy` tool for offset/limit pagination or a scoped depth.",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "410072917e618f7239ed1ca61231bc7d234923b964c2cdea33c8fd6189e1809b"
}All connected Godot editor sessions and their metadata.
{
"resource_key": "godot://sessions",
"uri": "godot://sessions",
"name": "get_sessions",
"description": "All connected Godot editor sessions and their metadata.",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "2f8d1f677efa1d970eab2d8646cc3a581e14f2d99ca65ac273de7b47e0d4a224"
}Most recent ``test_run`` results without re-executing tests.
{
"resource_key": "godot://test/results",
"uri": "godot://test/results",
"name": "get_test_results",
"description": "Most recent ``test_run`` results without re-executing tests.",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "9ef8ed95c48f26f0ab7c75cb216625c231d0f76fa3ac22d3ef0b30d0453026cf"
}ClassDB metadata for a class in the active Godot editor. Returns the full documentation set (properties, methods, signals, enums, constants). The `get_class` tool defaults to properties-only, but a resource URI cannot carry a `sections` argument, so the resource pins `sections="all"` to preserve its advertised full-reference contract.
{
"template_key": "godot://class/{class_name}",
"uri_template": "godot://class/{class_name}",
"name": "get_class_info",
"description": "ClassDB metadata for a class in the active Godot editor.\n\nReturns the full documentation set (properties, methods, signals,\nenums, constants). The `get_class` tool defaults to properties-only,\nbut a resource URI cannot carry a `sections` argument, so the resource\npins `sections=\"all\"` to preserve its advertised full-reference\ncontract.",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "23a23fe24e6726ccf36bb07044984c9e34d076aa859e8dcaa240e4801cf747bd"
}Direct children of the node at scene path ``path`` (name, type, path each).
{
"template_key": "godot://node/{path*}/children",
"uri_template": "godot://node/{path*}/children",
"name": "get_node_children",
"description": "Direct children of the node at scene path ``path`` (name, type, path each).",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "98fd2b686a0ac9583aba6ef3d510584b3d69160a825be64459777cb573932e19"
}Group names the node at scene path ``path`` belongs to.
{
"template_key": "godot://node/{path*}/groups",
"uri_template": "godot://node/{path*}/groups",
"name": "get_node_groups",
"description": "Group names the node at scene path ``path`` belongs to.",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "cd87b9f47f6db6b8da756ff4cdf12865d4102abd882d7cb15096f9d059262bc7"
}All properties of the node at scene path ``path`` (e.g. Main/Camera3D).
{
"template_key": "godot://node/{path*}/properties",
"uri_template": "godot://node/{path*}/properties",
"name": "get_node_properties",
"description": "All properties of the node at scene path ``path`` (e.g. Main/Camera3D).",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "389e84ab529e30748ad116d512b41304cee6c097e6d22613b739be214185405d"
}Read a GDScript file at the given res:// path. ``path`` is the res:// path with the ``res://`` prefix dropped — e.g. ``godot://script/scripts/player.gd`` reads ``res://scripts/player.gd``.
{
"template_key": "godot://script/{path*}",
"uri_template": "godot://script/{path*}",
"name": "get_script",
"description": "Read a GDScript file at the given res:// path.\n\n``path`` is the res:// path with the ``res://`` prefix dropped — e.g.\n``godot://script/scripts/player.gd`` reads ``res://scripts/player.gd``.",
"mime_type": "application/json",
"annotations": null,
"metadata_hash": "296526ceb1b72d2e3c50e087d31a4d682da667e4d050dee68dbfd3867b9ea1fa"
}