# Godot MCP (npm · @satelliteoflove/godot-mcp)

Agent-driven Godot playtesting: editor control, input injection, game-time stepping, live state.

- Trust score: 76/100 (medium)
- Change this week: +35
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-04

## Components

- npm · `@satelliteoflove/godot-mcp`: 76/100 (this document), [markdown](https://verifymcp.io/servers/satelliteoflove-godot-mcp/satelliteoflove-godot-mcp.md), [page](https://verifymcp.io/servers/satelliteoflove-godot-mcp/satelliteoflove-godot-mcp)

## Channel facts

- Registry: `npm`
- Package: `@satelliteoflove/godot-mcp`
- Version: `4.1.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-04.

- **Supply Chain Security**: 87/100
  - No malware found by supply-chain analysis.
  - Only part of the dependency tree could be resolved (95 of 99), so this covers what we could see, not the whole tree.
  - No install/post-install scripts declared.
  - Only part of the dependency tree could be resolved (95 of 99), so this covers what we could see, not the whole tree.
- **Provenance & Transparency**: 97/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to satelliteoflove/godot-mcp).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 45 days ago).
  - Security-disclosure policy not yet verified: we couldn't inspect the source repository.
- **Schema Quality & AI Usability**: 59/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 10062 tokens (~479/item across 21 items; 21 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add satelliteoflove-godot-mcp -- npx -y @satelliteoflove/godot-mcp
```

### Codex

```bash
codex mcp add satelliteoflove-godot-mcp -- npx -y @satelliteoflove/godot-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "satelliteoflove-godot-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@satelliteoflove/godot-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add satelliteoflove-godot-mcp --command npx --arg -y --arg @satelliteoflove/godot-mcp
```

### Hermes

```yaml
mcp_servers:
  satelliteoflove-godot-mcp:
    command: "npx"
    args: ["-y", "@satelliteoflove/godot-mcp"]
```

### Other

```json
{
  "mcpServers": {
    "satelliteoflove-godot-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@satelliteoflove/godot-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-04 (score 76, +4)

- [functional regression] Security disclosure: fail → unverified
- [functional improvement] Stability: unverified → 0.27

### 2026-08-02 (score 72, +56)

- [security improvement] Install scripts: unverified → pass
- [security improvement] Provenance: unverified → pass
- [security improvement] Known CVEs: unverified → partial
- [security improvement] Malware scan: unverified → pass
- [security] Stability: Stability not yet verified: not enough scan history yet (needs a 30-day window).
- [security] The attested source repository moved: satelliteoflove/godot-mcp
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Security disclosure: fail → unverified
- [functional improvement] Schema quality: unverified → excellent
- [functional improvement] License: unverified → pass
- [functional improvement] Dependency health: unverified → partial
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] MCP protocol: unverified → pass
- [functional] First check of Schema quality: unverified
- [functional] Licence: MIT

### 2026-07-31 (score 16, −25)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-27 (score 41)

First indexed and scored.

## MCP tools (21)

### `godot_scene` (~240 tokens)

Manage scenes in the editor: open a scene, save the open scene, or reload an open scene from disk after you edit its .tscn directly (so the editor picks up the change without a full restart). To create a new scene, write the .tscn file directly — header [gd_scene format=3] without a uid (the editor assigns one when it imports the file), then one [node name="X" type="Node2D"] block per node — and open it with this tool.

Input parameters:

- `action` (string, required): open: Open a scene file save: Save the current scene reload: Reload an open scene from disk, discarding the editor's unsaved in-memory copy. Use after editing a .tscn file directly to refresh the edi…
- `scene_path` (string): for open: Path to scene file to open; for save: Path to save to (defaults to the current scene path); for reload: Path of the open scene to reload (defaults to the current scene) (required for: open;…

### `godot_node_read` (~398 tokens)

Inspect scene nodes in the editor: read a node's effective properties (including class defaults a .tscn read cannot show), view the full scene tree as the editor sees it (including children inside instanced sub-scenes), and find nodes by name or type. Use it to discover node paths and verify the live state of the open scene before or after making changes. It cannot modify anything; to update properties or reparent a node, use godot_node_edit.

Input parameters:

- `action` (string, required): get_properties: Get a node's properties get_scene_tree: Full hierarchy of the open scene as the editor sees it, including children inside instanced sub-scenes (a .tscn file read cannot show those). D…
- `max_children` (integer): Cap how many children are listed per node. Omit to list every child. (for: get_scene_tree)
- `max_depth` (integer): Cap recursion depth (root = depth 1). Omit for the full tree. (for: get_scene_tree)
- `name_pattern` (string): Glob pattern to match node names, e.g. "*Spawner*", "Turret?" (for: find)
- `node_path` (string): Path to the node (required for: get_properties)
- `root_path` (string): Path to start search from (defaults to scene root) (for: find)
- `type` (string): Filter by node type, e.g. "CharacterBody2D", "Area2D" (for: find)

### `godot_node_edit` (~191 tokens)

Modify scene nodes in the editor: update a node's properties, or reparent it (the editor rewrites child paths and signal connections correctly; hand-editing .tscn for a reparent does not). Use it to change existing nodes in the open scene. To inspect properties, the scene tree, or search for nodes, use godot_node_read; to add or remove nodes, or attach scripts and connect signals, edit the .tscn file directly, then verify with godot_node_read's get_scene_tree.

Input parameters:

- `action` (string, required): update: Update a node's properties reparent: Move a node to a new parent
- `new_parent_path` (string): Path to the new parent node (required for: reparent)
- `node_path` (string, required): Path to the node
- `properties` (object): Properties to set on the node (required for: update)

### `godot_editor_read` (~939 tokens)

Observe the editor and running game: get editor state (open scene, play state, camera, viewport), read the current node selection, pull editor log messages (with an incremental cursor) and stack traces, and capture lossless PNG screenshots of the running game or an editor viewport. Reach for it to check what the editor sees before and after a change; screenshot_game needs a running game, while every other action works in the bare editor. It changes nothing - to select nodes, run/stop/restart, or move the 2D viewport use godot_editor_edit; errors from the running game (not the editor process) come via minimal-godot-mcp's get_console_output when that companion server is installed.

Input parameters:

- `action` (string, required): get_state: Get editor state: current scene, play state, version, camera, viewport get_selection: Get the currently selected nodes get_log_messages: Get errors and warnings from the EDITOR process - @…
- `clear` (boolean): Clear the editor error buffer after reading (for: get_log_messages)
- `limit` (integer): Maximum number of messages to return (default: 50) (for: get_log_messages)
- `max_width` (integer): for screenshot_game: Maximum width in pixels (default: 900). Cost scales with resolution (~1 visual token per 28x28px patch; a 900px 16:9 frame ≈ 600 tokens, a native 1080p frame ≈ 2700 on Opus). 640…
- `severity` (string): Filter by severity: "error" drops warnings (the "did anything actually break?" check), "warning" returns only warnings, "all" (default) returns both. (for: get_log_messages)
- `since` (integer): Return only messages newer than this cursor. Pass back the `cursor` from a prior response to see just what is new since then - the incremental check that avoids re-reading the whole buffer (0/omitted…
- `viewport` (string): Which editor viewport to capture (for: screenshot_editor)

### `godot_editor_edit` (~608 tokens)

Drive the editor: select a node, run or stop the project, restart the editor, and center/zoom the 2D viewport. Use run with frozen=true as the deterministic-playtest entry point (game time holds at frame 0 until godot_game_time steps or thaws it). To test edited gameplay scripts just stop then run — the launched game loads .gd/.tscn fresh from disk; reserve restart for EDITOR-side staleness (edited @tool/addon code, a stale project.godot, or a cached .gdshader). For observation only (state, selection, logs, screenshots) use godot_editor_read instead; restart does not start a cold editor, so one must already be running.

Input parameters:

- `action` (string, required): select: Select a node in the editor run: Run the project stop: Stop the running project restart: Restart the editor, reloading project.godot (autoloads, input map), addon code, and plugins from disk.…
- `center_x` (number): X coordinate to center the 2D viewport on (omitted = keep current X) (for: set_viewport_2d)
- `center_y` (number): Y coordinate to center the 2D viewport on (omitted = keep current Y) (for: set_viewport_2d)
- `frozen` (boolean): Launch with game time frozen from frame 0 (gameplay never starts racing your latency). Use godot_game_time step/thaw to advance. (for: run)
- `node_path` (string): Path to node to select (required for: select)
- `save` (boolean): Save the project before restarting (default: true). Set false to discard unsaved editor changes. (for: restart)
- `scene_path` (string): Scene to run (optional, defaults to main scene) (for: run)
- `zoom` (number): Zoom level, e.g. 1.0 = 100%, 2.0 = 200% (omitted = keep current zoom) (for: set_viewport_2d)

### `godot_project` (~285 tokens)

Read project-level data from the editor: name, path, Godot version, and main scene (get_info), plus project settings including input mappings (get_settings). After editing project.godot as a file, use check_stale to detect whether the editor is still running stale autoloads or input map from before the edit; restart via godot_editor_edit to reload. Use addon_status to diagnose addon/server version skew when commands misbehave or the connection drops. For scene contents or node properties, use godot_node_read instead.

Input parameters:

- `action` (string, required): get_info: Get project name, path, version, and main scene get_settings: Get project settings addon_status: Check addon/server version compatibility check_stale: Check whether project.godot was edited…
- `category` (string): Settings category to filter by (use "input" for input mappings) (for: get_settings)
- `include_builtin` (boolean): Include built-in ui_* actions (with category="input") (for: get_settings)

### `godot_animation_read` (~224 tokens)

Inspect animation data on AnimationPlayer nodes in the editor: list players in the scene, read a player's state and libraries, get an animation's tracks and properties, and read a track's keyframes. Reach for it to verify what the editor actually loaded, including after editing animation resources by hand. It changes and previews nothing; use godot_animation_edit to create, modify, or play animations.

Input parameters:

- `action` (string, required): list_players: List AnimationPlayer nodes in the scene get_info: Get AnimationPlayer state and library list get_details: Get an animation's tracks and properties get_keyframes: Get keyframes for a tra…
- `animation_name` (string): Animation name (required for: get_details, get_keyframes)
- `node_path` (string): Path to the AnimationPlayer (required for: get_info, get_details, get_keyframes)
- `root_path` (string): Starting node path (defaults to scene root) (for: list_players)
- `track_index` (number): Track index (required for: get_keyframes)

### `godot_animation_edit` (~663 tokens)

Create and modify animations on an AnimationPlayer and preview them in the editor: create, delete, or update animations, add and remove tracks and keyframes, and play, stop, or seek the editor's preview (playback controls the editor, not the running game). Pair each change with an immediate play or seek to check the result; this is the only way to verify animation feel without running the whole game. To inspect animation data without changing it, use godot_animation_read.

Input parameters:

- `action` (string, required): play: Play an animation stop: Stop playback seek: Seek to a position in the current animation create: Create an animation delete: Delete an animation update_props: Update animation properties add_tra…
- `animation_name` (string): Animation name (required for: play, create, delete, update_props, add_track, remove_track, add_keyframe, remove_keyframe, update_keyframe)
- `args` (array): Method arguments (for: add_keyframe)
- `custom_blend` (number): Custom blend time, -1 for default (for: play)
- `custom_speed` (number): Playback speed, 1.0 default (for: play)
- `from_end` (boolean): Play from end for reverse (for: play)
- `insert_at` (number): Track index to insert at, -1 for end (for: add_track)
- `keep_state` (boolean): Keep current animation state (for: stop)
- `keyframe_index` (number): Keyframe index (required for: remove_keyframe, update_keyframe)
- `length` (number): Animation length in seconds (for: create, update_props)
- `library_name` (string): Library name (for: create, delete)
- `loop_mode` (string): Loop mode: none, linear, pingpong (for: create, update_props)
- `method_name` (string): Method name for method tracks (for: add_keyframe)
- `node_path` (string, required): Path to the AnimationPlayer
- `seconds` (number): Position to seek to (required for: seek)
- `step` (number): Step value for keyframe snapping (for: create, update_props)
- `time` (number): Keyframe time in seconds (required for: add_keyframe; optional for: update_keyframe)
- `track_index` (number): Track index (required for: remove_track, add_keyframe, remove_keyframe, update_keyframe)
- `track_path` (string): Node path and property, e.g. "Sprite2D:frame" (required for: add_track)
- `track_type` (string): Type of track (required for: add_track)
- `transition` (number): Transition curve, 1.0 = linear (for: add_keyframe, update_keyframe)
- `update` (boolean): Update node immediately, default true (for: seek)
- `value`: Keyframe value (for: add_keyframe, update_keyframe)

### `godot_tilemap_read` (~343 tokens)

Inspect TileMapLayer data in the open scene: list layers, get layer and TileSet info, read used cells, a single cell, or a rectangular region, and convert between local positions and map coordinates. Use it whenever you need to know what tiles are placed where; cell data is stored base64-encoded in the .tscn, so reading the file is not an alternative. To place, erase, or clear tiles, use godot_tilemap_edit instead.

Input parameters:

- `action` (string, required): list_layers: List TileMapLayer nodes in the scene get_info: Get TileMapLayer info get_tileset_info: Get the layer's TileSet info get_used_cells: Get all used cells get_cell: Get a single cell get_cel…
- `coords` (object): Cell coordinates (required for: get_cell)
- `local_position` (object): Local position to convert to map coords (for: convert_coords)
- `map_coords` (object): Map coordinates to convert to local position (for: convert_coords)
- `max_coords` (object): Maximum corner of region (required for: get_cells_in_region)
- `min_coords` (object): Minimum corner of region (required for: get_cells_in_region)
- `node_path` (string): Path to the TileMapLayer (required for: get_info, get_tileset_info, get_used_cells, get_cell, get_cells_in_region, convert_coords)
- `root_path` (string): Starting node path (defaults to scene root) (for: list_layers)

### `godot_tilemap_edit` (~267 tokens)

Modify TileMapLayer cells in the open scene: set a single cell, erase a cell, clear a whole layer, or set many cells in one batch. Use it to paint or remove tiles; cell data is stored base64-encoded in the .tscn, so editing the file is not an alternative, and set_cells_batch beats repeated set_cell calls for anything beyond a few tiles. To inspect layers, TileSets, or existing cells without changing anything, use godot_tilemap_read.

Input parameters:

- `action` (string, required): set_cell: Set a single cell erase_cell: Erase a single cell clear_layer: Clear all cells in the layer set_cells_batch: Set many cells at once
- `alternative_tile` (integer): Alternative tile ID, default 0 (for: set_cell)
- `atlas_coords` (object): Atlas coordinates, default 0,0 (for: set_cell)
- `cells` (array): Array of cells to set (required for: set_cells_batch)
- `coords` (object): Cell coordinates (required for: set_cell, erase_cell)
- `node_path` (string, required): Path to the TileMapLayer
- `source_id` (integer): TileSet source ID, default 0 (for: set_cell)

### `godot_gridmap_read` (~265 tokens)

Inspect GridMap data in the open scene: list GridMap nodes, get map and MeshLibrary info, and read used cells, a single cell, or every cell using a given item. Use it whenever you need to know which mesh items occupy which 3D grid cells; cell data is stored base64-encoded in the .tscn, so reading the file is not an alternative. To place or clear cells, use godot_gridmap_edit instead.

Input parameters:

- `action` (string, required): list: List GridMap nodes in the scene get_info: Get GridMap info get_meshlib_info: Get the GridMap's MeshLibrary info get_used_cells: Get all used cells get_cell: Get a single cell get_cells_by_item:…
- `coords` (object): Cell coordinates (required for: get_cell)
- `item` (integer): MeshLibrary item index (required for: get_cells_by_item)
- `node_path` (string): Path to the GridMap (required for: get_info, get_meshlib_info, get_used_cells, get_cell, get_cells_by_item)
- `root_path` (string): Starting node path (defaults to scene root) (for: list)

### `godot_gridmap_edit` (~250 tokens)

Modify GridMap cells in the open scene: set a single cell to a MeshLibrary item with an orientation, clear a cell, clear the whole map, or set many cells in one batch. Use it to build or remove 3D grid content; cell data is stored base64-encoded in the .tscn, so editing the file is not an alternative, and set_cells_batch beats repeated set_cell calls for anything beyond a few cells. To inspect the map, its MeshLibrary, or existing cells without changing anything, use godot_gridmap_read.

Input parameters:

- `action` (string, required): set_cell: Set a single cell clear_cell: Clear a single cell clear: Clear all cells set_cells_batch: Set many cells at once
- `cells` (array): Array of cells to set (required for: set_cells_batch)
- `coords` (object): Cell coordinates (required for: set_cell, clear_cell)
- `item` (integer): MeshLibrary item index (required for: set_cell)
- `node_path` (string, required): Path to the GridMap
- `orientation` (integer): Orientation 0-23, default 0 (for: set_cell)

### `godot_resource` (~184 tokens)

Inspect a Resource file by path with type-aware structured output (SpriteFrames animations, TileSet, Material, Texture2D, etc.). Use it for imported or binary resources (.res, .scn, compressed textures) that a plain file read cannot parse, or when you want sub-resources resolved into the engine's view rather than raw .tres text. For nodes inside a scene, use godot_node_read instead.

Input parameters:

- `action` (string, required): get_info: Inspect a Resource file by path
- `include_internal` (boolean): Include internal properties starting with underscore (default: false)
- `max_depth` (number): Detail level: 0 = summary only, 1 = full detail (default), 2+ = expand sub-resources
- `resource_path` (string, required): Resource path (e.g., "res://player/sprites.tres")

### `godot_scene3d` (~299 tokens)

Read engine-computed 3D spatial data that cannot be derived from .tscn text: global transforms resolved through the parent chain, mesh AABBs, combined subtree bounds, and visibility. Use get_spatial_info for one Node3D or a filtered set of its children (by type or world-space region); use get_bounds for the combined AABB of a subtree. Read-only: to change transforms or other properties, use godot_node_edit.

Input parameters:

- `action` (string, required): get_spatial_info: Get spatial data for a Node3D and optionally its children get_bounds: Get the combined AABB of a subtree
- `include_children` (boolean): Include child nodes (for: get_spatial_info)
- `max_results` (integer): Limit number of results. Defaults to 50 when include_children=true. Set higher (e.g., 500) if needed. (for: get_spatial_info)
- `node_path` (string): Path to the Node3D (required for: get_spatial_info)
- `root_path` (string): Path to search root (defaults to scene root) (for: get_bounds)
- `type_filter` (string): Filter by node type, e.g. "MeshInstance3D" (for: get_spatial_info)
- `within_aabb` (object): Only include nodes whose global position is within this AABB (for: get_spatial_info)

### `godot_docs` (~199 tokens)

Fetch Godot Engine documentation. Use fetch_class for class references (e.g. CharacterBody2D), fetch_page for tutorials/guides. Auto-detects Godot version from editor connection. Returns clean markdown.

Input parameters:

- `action` (string, required): fetch_class: Get a class reference by name fetch_page: Get any docs page by path
- `class_name` (string): Class name to fetch, e.g. "CharacterBody2D" (required for: fetch_class)
- `path` (string): Documentation path, e.g. "/tutorials/2d/2d_movement.html" (required for: fetch_page)
- `section` (string): Which class-reference section to return (default: full). Use specific sections to reduce token usage. (for: fetch_class)
- `version` (string): Godot docs version. If omitted, auto-detects from connected Godot editor or defaults to "stable"

### `godot_input` (~1010 tokens)

Inject input into a running Godot game for testing: named actions (with analog strength), joypad buttons, analog axes, stick vectors, raw keyboard keys (with modifier combos), and relative mouse-look. Use get_map to discover available input actions and their bindings, sequence to execute inputs with precise timing (optionally with an effect probe that proves the inputs changed game state), or type_text to type into UI elements. Note: relative mouse-look is supported (look: [dx, dy], for FPS-camera _input handlers); absolute cursor positioning is not (see docs/design/mouse-input-spike.md).

Input parameters:

- `action` (string, required): get_map: List available input actions from the project Input Map sequence: Execute an input timeline. While the game runs at real speed, keep tightly-timed inputs in ONE call — e.g. the run-starting…
- `delay_ms` (integer): Delay between keystrokes in milliseconds (default 50) (for: type_text)
- `inputs` (array): Array of inputs to execute. Each entry is one of: a named ACTION (action_name, optional analog strength), a joypad BUTTON (joy_button), an analog AXIS hold (axis + value), a STICK vector (stick + x/y…
- `report` (array): Optional effect probe: GDScript expressions evaluated once before the first input and again after the last, to prove the inputs actually changed something (vs. falling into the void — player dead, UI…
- `screenshot_at_ms` (array): Optional: millisecond offsets (from sequence start) at which to capture a lossless PNG frame DURING the real-time run. The bridge owns the sequence clock, so it grabs each frame at the right moment a…
- `screenshot_max_width` (integer): Max width in px for captured frames (default 640). Resolution is the real cost lever (~1 visual token per 28x28px patch; a 640px frame ≈ 300 tokens). 640 catches transient visuals cheaply; raise it w…
- `submit` (boolean): Press Enter after typing to submit (for LineEdit text_submitted) (for: type_text)
- `text` (string): Text to type (required for: type_text)

### `godot_profiler` (~191 tokens)

Profile a running game; every action errors if no game is playing. Use snapshot for one-shot engine metrics, or start → get_data for a per-frame time series with percentile stats, frame-budget usage, spike detection, and monitor trends. get_active_processes lists scripts with live _process/_physics_process callbacks (useful for finding per-frame cost sources); get_signal_connections maps signal wiring. For observing game state rather than performance, use godot_runtime_state.

Input parameters:

- `action` (string, required): snapshot: Full performance snapshot (all engine metrics) start: Start per-frame time-series profiling stop: Stop time-series profiling get_data: Get collected time-series data with spike detection ge…
- `node_path` (string): Node path (defaults to scene root) (for: get_signal_connections)

### `godot_runtime_state` (~1168 tokens)

Observe live game state as structured data. Use digest for a one-shot entity snapshot (replaces most godot_editor_read screenshot_game calls). Use watch_start → watch_collect for state-over-time without context blowup.

Input parameters:

- `action` (string, required): digest: Snapshot current game entity state as structured JSON — exact positions, velocities, animation state, and custom game data. Much cheaper than screenshot_game (no vision tokens). Works on any…
- `duration_ms` (integer): Auto-stop after this many milliseconds (default: 1000) (for: watch_start)
- `group` (string): Group name to use when select="group" or "auto" (default: "mcp_watch") (for: digest)
- `hz` (integer): Sample rate in Hz (default: 20) (for: watch_start)
- `include` (array): Subset of fields to include (default: all available) (for: digest)
- `max_nodes` (integer): Maximum nodes in result (default: 40) (for: digest)
- `name` (string): Glob filter on node name (e.g. "Player*") (for: digest)
- `paths` (array): Explicit absolute node paths to include in addition to tier selection, e.g. ["/root/GameState"]. The digest walks the current scene only, so autoload singletons — where global game state often lives…
- `select` (string): Selection tier: "group" = nodes in mcp_watch group, "method" = nodes with _mcp_state(), "auto" = best available (default: auto picks group → method → a visibility fallback that surfaces visible 2D no…
- `signals` (array): Signals to record as discrete timeline events during the window. Each emission is buffered as {t_ms, source, signal, args} (200 events/window shared FAIRLY — each signal gets an equal sub-budget so a…
- `specs` (array): Which nodes and fields to watch. Optional when signals is provided. (for: watch_start)
- `type` (string): Class filter (e.g. "CharacterBody2D") (for: digest)

### `godot_game_time` (~1009 tokens)

Make game time answer to your clock instead of racing ahead between tool calls: freeze the running game, observe it at leisure (screenshots and state digests work while frozen), then step forward a bounded slice of game time (step) — or until a condition you specify holds (step_until) — with inputs riding inside the window. The game's own pause menu is layered correctly: freezing over it, stepping under it, and thawing back to it all preserve the game's pause intent.

Input parameters:

- `action` (string, required): freeze: Pause the game under agent control. All observation tools (screenshots, runtime state, godot_node_read find) keep working while frozen — take as long as you need. step: Advance a bounded slic…
- `duration_ms` (integer): Game time to advance in milliseconds (max 50000; loop steps for longer). Scaled by Engine.time_scale like normal play. Mutually exclusive with frames. (for: step)
- `frames` (integer): Frames to advance instead of a duration (max 1200). frames: 1 is a single-frame advance. Mutually exclusive with duration_ms. (for: step)
- `inputs` (array): for step: Input timeline executed inside the window; start_ms is game time from window start. Entries share the godot_input sequence vocabulary: named actions (with analog strength), joypad buttons,…
- `max_ms` (integer): Safety cap on game time to advance while waiting (max 50000, default 20000). If the predicate never holds within this budget (or the wall-clock budget), the call returns with predicate_met: false ins…
- `report` (array): Optional GDScript expressions (same scope as `until`) evaluated when stepping stops and returned as a { expression: value } map — e.g. ["G.wave", "tree.get_nodes_in_group(\"enemies\").size()"]. Use t…
- `until` (string): A GDScript boolean expression, re-evaluated against the running game every frame; stepping stops the frame it is truthy. Autoloads are in scope by name (e.g. `G.wave > 1`, `GameState.tick_count % 12…

### `godot_exec` (~654 tokens)

Execute GDScript inside the RUNNING game process — the scenario-setup primitive: grant weapons, skip waves, spawn entities, arm persistent test bots, without baking debug hooks into game code. Errors when no game is running. For launch-time setup, compose: godot_editor_edit run frozen=true -> godot_exec run (mutate state, attach bots under `holder`) -> godot_game_time thaw. A static denylist rejects accidental process/file-write escape (OS.execute, DirAccess, write-mode FileAccess, ResourceSaver, ProjectSettings.save, ...) and names the offending token — an accident guard, NOT a security boundary. Compile errors reject the call with the parser message; runtime errors come back in runtime_errors with the call still completing.

Input parameters:

- `action` (string, required): run: Run one-shot GDScript inside the running game and return its value list: List the nodes currently attached under the exec holder (name, class, age, processing state) remove: Remove one exec hold…
- `budget_ms` (integer): Wall-clock patience for the call, used to size the timeout cascade (default 10000, max 30000). NOT enforcement: a synchronous script cannot be preempted, so an infinite loop hangs the game past any b…
- `name` (string): Node name as reported by list (required for: remove)
- `source` (string): GDScript statements, compiled as a function body. In scope: every autoload by its own name (e.g. `G.wave = 5`), `tree` (SceneTree), `root` (root Window) — the same context as step_until predicates —…

### `godot_validate_meshes` (~255 tokens)

Check every code-built (ArrayMesh) surface in the RUNNING game for silent data corruption that renders WITHOUT any error. Run this FIRST when rendering looks wrong and no error is reported anywhere: surfaces pure black or far too dark, floors/walls invisible or see-through, geometry visible from only one side, lighting that ignores light-energy changes, scenes that "tuning" cannot fix. Detects: inside-out or mixed triangle winding (Godot front faces wind clockwise — wrong winding = culled faces or inverted lighting normals), dropped triangles / orphaned vertices (e.g. SurfaceTool.append_from of an indexed mesh mixed with raw add_vertex silently discards most of the batch), degenerate UVs that make generate_tangents() emit garbage, and NaN/zero normals or tangents. Every finding includes its likely cause and the fix. Read-only and cheap. Walks the current scene only (meshes parented elsewhere under root are not seen). Also run it after writing or changing mesh-generation code — BEFORE spending time tuning lights or materials to rescue a "too dark" scene.

Input parameters:

- `max_findings` (integer): Cap on findings returned (default 25). The total count is always reported.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/satelliteoflove-godot-mcp/satelliteoflove-godot-mcp#diagnostics

## Score history

- 2026-08-04: 76
- 2026-08-03: 72
- 2026-08-02: 72
- 2026-08-01: 16
- 2026-07-31: 16
- 2026-07-30: 41
- 2026-07-28: 41
- 2026-07-27: 41

## Links

- npm package: https://www.npmjs.com/package/@satelliteoflove/godot-mcp
- Socket report: https://socket.dev/npm/package/@satelliteoflove/godot-mcp
- Repository: https://github.com/satelliteoflove/godot-mcp
- Changelog RSS feed: https://verifymcp.io/servers/satelliteoflove-godot-mcp/satelliteoflove-godot-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/satelliteoflove-godot-mcp/satelliteoflove-godot-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/satelliteoflove-godot-mcp/satelliteoflove-godot-mcp
