MCP server intelligence profile

Godot AI MCP Server

Connects MCP clients directly to a live Godot editor, enabling AI assistants to build scenes, edit nodes, and control the editor through over 120 operations

Local Onlyhi-godot
Awaiting current scanPypi · 3.2.5

The selected current version does not yet have completed public verification. Unknown does not mean clean or vulnerable.

1Distribution channel
46Independently observed tools
0Linked remote endpoints
AvailableVersion intelligence

Detailed security scan evidence is not public for this MCP yet. Public identity, registry metadata, and independently observed protocol inventory remain available.

Install and connect

Installation and connection instructions are shown only when supported by retained package, repository, or endpoint evidence.

Install godot-ai from PyPI

Install exact version 3.2.5. The executable name has not been verified, so it is intentionally not guessed.

python -m pip install 'godot-ai==3.2.5'

Identity

Canonical sluggodot-ai-f0a2dc01DeploymentLocal Only
Canonical packagepypi:godot-aiRepositoryhi-godot/godot-ai
First publishedAug 11, 2026Latest releaseSep 3, 2026
Last security verificationClassification confidence90%
PublicationDraftOfficial distributionNot verified

Distributions

ChannelIdentifierCurrent versionVersionsSource
pypigodot-ai3.2.56Repository

Current release

PackageVersionPublished / observedInventorySecurity scan
pypigodot-ai3.2.5CurrentSep 3, 202646 toolsSucceeded · 13 resources · 0 promptsEvidence restricted
Enterprise protection

Continuously monitor this MCP for security risk

Independently scan the exact version your agents use, receive alerts when its risk changes, and investigate every finding with retained version evidence.

  • Independent exact-version security scans
  • Continuous release and vulnerability monitoring
  • Risk-change alerts with capability context
  • Historical evidence and API exports
Custom pricingContact salesTailored to your organization, integrations, data needs, and support requirements.

Current version evidence

No public current-version evidence is available yet.

Current protocol inventory

2025-06-18Negotiated protocol
Godot AIServer-reported name
6Capability groups
Sep 4, 2026Observed

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

  • get_current_scenegodot://scene/current

    Current scene path and root node info from the active Godot editor.

  • get_current_selectiongodot://selection/current

    Currently selected nodes in the Godot editor.

  • get_custom_toolsgodot://custom-tools
  • get_editor_stategodot://editor/state

    Editor version, project name, current scene, readiness, play state.

  • get_input_mapgodot://input_map

    All input map actions and their bound events. Excludes built-in ui_*.

  • get_materialsgodot://materials

    All Material resources under res:// (every Material subclass + .tres).

  • get_performancegodot://performance

    Performance singleton snapshot (FPS, memory, draw calls, frame time).

  • get_project_infogodot://project/info

    Project name, Godot version, paths, and play state.

  • get_project_settingsgodot://project/settings

    Common project settings subset (display, physics, rendering).

  • get_recent_logsgodot://logs/recent

    Last 100 log lines from the Godot editor console.

  • get_scene_hierarchygodot://scene/hierarchy

    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.

  • get_sessionsgodot://sessions

    All connected Godot editor sessions and their metadata.

  • get_test_resultsgodot://test/results

    Most recent ``test_run`` results without re-executing tests.

Resource templates 5

  • get_class_infogodot://class/{class_name}

    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.

  • get_node_childrengodot://node/{path*}/children

    Direct children of the node at scene path ``path`` (name, type, path each).

  • get_node_groupsgodot://node/{path*}/groups

    Group names the node at scene path ``path`` belongs to.

  • get_node_propertiesgodot://node/{path*}/properties

    All properties of the node at scene path ``path`` (e.g. Main/Camera3D).

  • get_scriptgodot://script/{path*}

    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``.

Prompts 0

  • None observed.

Remote endpoints

EndpointTransportAuthenticationHealthObserved
No verified remote endpoint is linked.

Godot AI MCP Server questions

How do I install Godot AI MCP Server?

Install the selected package version with: python -m pip install 'godot-ai==3.2.5'

What tools does Godot AI MCP Server provide?

Godot AI MCP Server exposed 46 tools during independent protocol observation, including animation_create, animation_manage, api_manage, audio_manage, autoload_manage, batch_execute, camera_manage, client_manage, and others.

Is Godot AI MCP Server secure?

The selected current version does not yet have completed public verification. Unknown does not mean clean or vulnerable.

Explore related MCP server guides

Curated product and capability guides containing this catalog record.

Official vs Community MCP Servers

Let’s talk about MCP security.

Share your details and our security team will contact you.