← Godot AI

Godot AI 3.2.5

pypi · godot-ai · current release

46
Tools
13
Resources
5
Templates
0
Prompts

Observation

Observed 2026-09-04T03:29:24.069Z using mcpSecurity-inventory. Status: succeeded. Negotiated protocol: 2025-06-18.

Server capabilities
{
  "experimental": {},
  "logging": {},
  "prompts": {
    "listChanged": false
  },
  "resources": {
    "subscribe": false,
    "listChanged": false
  },
  "tools": {
    "listChanged": true
  },
  "extensions": {
    "io.modelcontextprotocol/ui": {}
  }
}

Tools 46

ToolCategoryAnnotationsRisk
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"
}
— · —

Resources 13

Resource templates 5

Prompts 0

Let’s talk about MCP security.

Share your details and our security team will contact you.