# Godot MCP Loop (npm · godot-mcp-loop)

Drive a live Godot 4 editor: edit scenes and scripts, run and test the game, record GIFs.

- Trust score: 87/100 (high trust)
- Change this week: +4
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- npm · `godot-mcp-loop`: 87/100 (this document), [markdown](https://verifymcp.io/servers/ai-osho-godot-mcp-loop/godot-mcp-loop.md), [page](https://verifymcp.io/servers/ai-osho-godot-mcp-loop/godot-mcp-loop)

## Channel facts

- Registry: `npm`
- Package: `godot-mcp-loop`
- Version: `0.9.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-11-05.

- **Supply Chain Security**: 98/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - 30 of 94 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 100/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to AI-osho/godot-mcp-loop).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 0 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 67/100
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 6232 tokens (~152/item across 41 items; 41 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 53/100
  - Stability observed for 16 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 97/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 92% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 42 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the Godot MCP Loop server?

Godot MCP Loop runs locally as an npm package, launched with npx -y godot-mcp-loop. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add ai-osho-godot-mcp-loop -- npx -y godot-mcp-loop
```

### Cursor

```json
{
  "mcpServers": {
    "ai-osho-godot-mcp-loop": {
      "command": "npx",
      "args": [
        "-y",
        "godot-mcp-loop"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "ai-osho-godot-mcp-loop": {
      "command": "npx",
      "args": [
        "-y",
        "godot-mcp-loop"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add ai-osho-godot-mcp-loop -- npx -y godot-mcp-loop
```

### opencode

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

### OpenClaw

```bash
openclaw mcp add ai-osho-godot-mcp-loop --command npx --arg -y --arg godot-mcp-loop
```

### Hermes

```yaml
mcp_servers:
  ai-osho-godot-mcp-loop:
    command: "npx"
    args: ["-y", "godot-mcp-loop"]
```

### Netclaw

```json
{
  "McpServers": {
    "ai-osho-godot-mcp-loop": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "godot-mcp-loop"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add ai-osho-godot-mcp-loop -t stdio -c npx -a -y godot-mcp-loop
```

### Other

```json
{
  "mcpServers": {
    "ai-osho-godot-mcp-loop": {
      "command": "npx",
      "args": [
        "-y",
        "godot-mcp-loop"
      ]
    }
  }
}
```

## 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-11-05 (score 87, +1)

No change was recorded against any check on this day. Stability & Change Management went from 50 to 53. That category is still filling its 30-day observation window: 15 days of observed history at the previous scan, 16 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-03 (score 86, +1)

No change was recorded against any check on this day. Stability & Change Management went from 43 to 47. That category is still filling its 30-day observation window: 13 days of observed history at the previous scan, 14 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-01 (score 85, +1)

No change was recorded against any check on this day. Stability & Change Management went from 37 to 40. That category is still filling its 30-day observation window: 11 days of observed history at the previous scan, 12 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-30 (score 84, +1)

No change was recorded against any check on this day. Stability & Change Management went from 30 to 33. That category is still filling its 30-day observation window: 9 days of observed history at the previous scan, 10 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-28 (score 83, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-25 (score 82, +1)

No change was recorded against any check on this day. Stability & Change Management went from 13 to 17. That category is still filling its 30-day observation window: 4 days of observed history at the previous scan, 5 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-23 (score 81, +1)

No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-21 (score 80, +16)

- [security improvement] Malware scan: unverified → pass
- [functional improvement] Stability: unverified → 0.03

## MCP tools (41)

### `godot_status` (~43 tokens)

Godot status

Check the connection to the Godot editor and get basic state: Godot version, project name, currently edited scene and whether the game is running. Call this first.

### `project_list` (~76 tokens)

List Godot projects

List the Godot projects this server may switch to: folders with project.godot below the --projects-root folders (up to 3 levels down, hidden folders skipped), each with its name, whether the MCP Loop addon is installed, whether an editor is running for it, and which one is current. Use project_connect to switch.

### `project_connect` (~135 tokens)

Switch project

Point this running server at another Godot project, so the following tool calls work on it — one MCP registration for many games. Only projects below the folders given with --projects-root are allowed (without it the server stays on its --project). Returns the new project's status like godot_status, or, when no editor is open for it, how to open one. The previous project's editor and game keep running. Don't switch while another tool call runs.

Input parameters:

- `path` (string, required): Project folder (the one with project.godot): absolute, ~/..., or relative to a projects root, e.g. 'games/shooter'.

### `editor_launch` (~170 tokens)

Open the Godot editor

Open the Godot editor on the current project and wait until the MCP Loop bridge answers, then return the same fields as godot_status. Does nothing when an editor already runs for the project. Godot is found from the server's --godot / GODOT_BIN, else PATH and the usual install folders (4.5+ required). The project needs the MCP Loop addon installed and enabled. headless: true opens it without a window (no screenshots; for servers and CI). The editor keeps running after the server stops; editor_quit closes editors opened here.

Input parameters:

- `headless` (boolean): Start the editor without a window (default false).
- `timeout_ms` (integer): How long to wait for the bridge (default 120000; the first open of a project imports every asset).

### `editor_quit` (~114 tokens)

Close the Godot editor

Close the Godot editor of the current project — only one this server opened with editor_launch (an editor the user opened is refused with EDITOR_NOT_LAUNCHED). Stops a running game, saves the open scenes unless save: false, quits, and waits for the process to end (stopped with SIGTERM after timeout_ms).

Input parameters:

- `save` (boolean): Save all open scenes first (default true).
- `timeout_ms` (integer): How long to wait for the editor to exit (default 20000).

### `project_export` (~209 tokens)

Export the project

Export the project with one of its export_presets.cfg presets (Godot's `--export-release`, headless, fixed argument list, no shell). The output always goes under res://build/ — pass `path` to choose the name, or omit it for res://build/<preset>/ (index.html for Web). Returns the files written with their sizes, plus the tail of Godot's log. Fails with TEMPLATES_MISSING when Godot has no export templates installed. `dry_run` shows the command and the target without exporting.

Input parameters:

- `dry_run` (boolean): Validate the preset and the path, show the command, export nothing.
- `path` (string): Output under res://build/... — a folder or .html for Web, a file for the other platforms.
- `preset` (string, required): Preset name from export_presets.cfg (project_info can list them).
- `timeout_ms` (integer): Limit for the export process (default 600000).

### `project_info` (~123 tokens)

Project info

Project overview: name, main scene, autoloads, input actions and their events (Godot's built-in ui_* actions are hidden unless include_builtin_actions), and (optionally) a file list filtered by a glob.

Input parameters:

- `glob` (string): If set, list res:// files matching this glob, e.g. '*.tscn' or 'scripts/**/*.gd'.
- `include_builtin_actions` (boolean): Also list Godot's built-in ui_* actions (about 90).
- `max_files` (integer): Cap on listed files (default 200).

### `scene_open` (~49 tokens)

Open scene

Open a scene in the editor and make it the edited scene. Subsequent node_* tools operate on it.

Input parameters:

- `path` (string, required): res:// path of a .tscn/.scn file.

### `scene_create` (~136 tokens)

Create scene

Create a new scene file with a single root node and open it. Fails if the file already exists.

Input parameters:

- `dry_run` (boolean): Preview only: validate and describe the change without applying it.
- `path` (string, required): res:// path ending in .tscn, e.g. 'res://levels/level_1.tscn'. Folders are created.
- `root_name` (string): Root node name (default: file name in PascalCase).
- `root_type` (string, required): Root node class, e.g. 'Node2D', 'Node3D', 'Control', 'CharacterBody2D'.

### `scene_save` (~16 tokens)

Save scene

Save the currently edited scene to disk.

### `scene_tree` (~88 tokens)

Scene tree

Node hierarchy of the edited scene: name, class, relative path, attached script and instanced scene for each node.

Input parameters:

- `depth` (integer): Max depth below the subtree root (default 10).
- `path` (string): Subtree root. Node path relative to the edited scene's root; '.' is the root itself (e.g. 'Player/Sprite2D'). Default '.'.

### `node_add` (~320 tokens)

Add node

Add a node to the edited scene (undoable). Provide either 'type' (a class like 'Sprite2D') or 'scene' (a res:// .tscn to instance). Initial properties are validated before anything is changed. Value formats: Vector2/3 as [x, y(, z)] or {x, y}; Color as '#rrggbb', '#rrggbbaa', a name like 'red', or [r, g, b, a] in 0..1; NodePath/StringName as strings; Rect2 as [x, y, w, h]; resources as {"res": "res://path"} for a file, or {"new": "RectangleShape2D", "properties": {"size": [32, 48]}} to create an embedded one (shapes, materials, styles; not scripts); null clears. Nested fields can be set with Godot's indexed syntax, e.g. "position:x".

Input parameters:

- `dry_run` (boolean): Preview only: validate and describe the change without applying it.
- `name` (string): Node name (made unique among siblings if taken).
- `parent` (string): Parent node. Node path relative to the edited scene's root; '.' is the root itself (e.g. 'Player/Sprite2D'). Default '.'.
- `properties` (object): Initial property values.
- `scene` (string): res:// path of a scene to instance instead of 'type'.
- `type` (string): Node class to create.

### `node_delete` (~84 tokens)

Delete node

Delete a node and its children from the edited scene (undoable with edit_undo). The scene root cannot be deleted.

Input parameters:

- `dry_run` (boolean): Preview only: validate and describe the change without applying it.
- `path` (string, required): Node path relative to the edited scene's root; '.' is the root itself (e.g. 'Player/Sprite2D').

### `node_get` (~101 tokens)

Get node properties

Read properties of a node in the edited scene. By default returns only properties that differ from the class default plus script variables.

Input parameters:

- `changed_only` (boolean): When no list is given: only non-default values (default true).
- `path` (string, required): Node path relative to the edited scene's root; '.' is the root itself (e.g. 'Player/Sprite2D').
- `properties` (array): Only these properties (supports 'position:x').

### `node_set` (~256 tokens)

Set node properties

Set one or more properties on a node as a single undoable action. All values are validated first; nothing changes if any is invalid. Returns before/after values. Value formats: Vector2/3 as [x, y(, z)] or {x, y}; Color as '#rrggbb', '#rrggbbaa', a name like 'red', or [r, g, b, a] in 0..1; NodePath/StringName as strings; Rect2 as [x, y, w, h]; resources as {"res": "res://path"} for a file, or {"new": "RectangleShape2D", "properties": {"size": [32, 48]}} to create an embedded one (shapes, materials, styles; not scripts); null clears. Nested fields can be set with Godot's indexed syntax, e.g. "position:x".

Input parameters:

- `dry_run` (boolean): Preview only: validate and describe the change without applying it.
- `path` (string, required): Node path relative to the edited scene's root; '.' is the root itself (e.g. 'Player/Sprite2D').
- `properties` (object, required): Property name -> new value.

### `script_read` (~40 tokens)

Read script

Read a text resource inside the project (GDScript, shader, .tscn, .cfg ...).

Input parameters:

- `path` (string, required): res:// path.

### `script_write` (~120 tokens)

Write script

Create or overwrite a GDScript (.gd) file. The code is compiled first; on errors nothing is written and the errors (with line numbers) are returned. Returns a unified diff for changed files and a one-line summary for new ones. Undoable with edit_undo. For small changes to an existing file prefer script_edit.

Input parameters:

- `content` (string, required): Full new file content.
- `dry_run` (boolean): Preview only: validate and describe the change without applying it.
- `path` (string, required): res:// path ending in .gd.

### `script_edit` (~132 tokens)

Edit script

Change part of an existing GDScript file by exact text replacement, without resending the whole file. Each edit's 'old' must match exactly once (including indentation; GDScript uses tabs) unless replace_all is set; edits apply in order. The result is compiled first; on errors or a non-matching edit nothing is written. Returns a unified diff. Undoable with edit_undo.

Input parameters:

- `dry_run` (boolean): Preview only: validate and describe the change without applying it.
- `edits` (array, required)
- `path` (string, required): res:// path of an existing .gd file.

### `script_attach` (~99 tokens)

Attach script

Attach an existing script to a node in the edited scene (undoable). Pass script=null to detach.

Input parameters:

- `dry_run` (boolean): Preview only: validate and describe the change without applying it.
- `node` (string, required): Node path relative to the edited scene's root; '.' is the root itself (e.g. 'Player/Sprite2D').
- `script` (string|null, required): res:// path of the script, or null to detach.

### `edit_undo` (~62 tokens)

Undo AI edits

Undo the most recent edits made through this MCP server (node, property, script changes), newest first. Stops without touching anything if a human made a later edit in the same history.

Input parameters:

- `steps` (integer): How many actions to undo (default 1).

### `file_write` (~171 tokens)

Write text file

Create, overwrite or partially edit a text file in the project: .yaml/.yml (e.g. scenarios), .json, .md, .txt, .csv. Give 'content' for the whole file or 'edits' (exact replacements, like script_edit). YAML syntax is checked before writing and scenario files are validated (warnings); JSON must parse. Undoable with edit_undo. Use script_write for .gd files.

Input parameters:

- `content` (string): Full file content (creates or overwrites).
- `dry_run` (boolean): Preview only: validate and return the diff without writing.
- `edits` (array): Exact text replacements applied in order to the existing file.
- `path` (string, required): res:// path, e.g. 'res://tests/scenarios/jump.yaml'.

### `image_write` (~349 tokens)

Write pixel-art PNG

Create a PNG sprite from text, NES-style: 'palette' maps single characters to colors and each string in 'rows' is one row of pixels ('.' and ' ' are transparent). 'frames' (a list of row lists) makes a horizontal sprite sheet for animation. Scaled with nearest neighbour, imported immediately, undoable with edit_undo. Use the result as {"res": path} for a Sprite2D texture.

Input parameters:

- `dry_run` (boolean): Validate and report the size without writing.
- `frames` (array): Several same-sized frames, laid out left to right. Each frame is a list of row strings: [["..##..", ...], ["..##..", ...]].
- `mirror` (string): Symmetric sprites: give only the left half ('x'), top half ('y') or top-left quarter ('xy'); the rest is mirrored.
- `mirror_overlap` (boolean): Share the middle column/row instead of repeating it (odd widths/heights).
- `palette` (object, required): Character -> color ('#rrggbb', '#rrggbbaa', a name, or [r, g, b, a] in 0..1), e.g. {"k": "#000000", "r": "#d82800"}. null or 'transparent' = see-through ('.' and ' ' already are).
- `path` (string, required): res:// path ending in .png.
- `rows` (array): One image: rows of palette characters, all the same length (max 256x256).
- `scale` (integer): Integer upscale factor (default 1). Prefer 1 and scale the node instead.

### `input_action_set` (~153 tokens)

Set input action

Add or replace an input action in the project's input map (project.godot), or remove it with remove: true. Keys are matched by physical position (e.g. 'A', 'Space', 'Left', 'Shift'). Undoable with edit_undo. A running game picks up changes after game_run with restart: true.

Input parameters:

- `deadzone` (number): Default 0.2.
- `dry_run` (boolean)
- `joypad_buttons` (array)
- `keys` (array)
- `mouse_buttons` (array)
- `name` (string, required): Action name, e.g. 'shoot' or 'move_up'.
- `remove` (boolean): Remove the action instead.

### `project_setting_set` (~133 tokens)

Set project setting

Change one project setting from a fixed list: the main scene, the viewport size, the window size override, the stretch mode/aspect, the project name and max_fps. Anything else (rendering, physics, autoloads, input map) is refused — use the editor. Values may be sent as strings. Undoable with edit_undo; the editor window and a running game pick most settings up when they start.

Input parameters:

- `dry_run` (boolean): Return before/after without writing.
- `key` (string, required): Setting key.
- `value` (required): New value; converted to the setting's type.

### `game_run` (~128 tokens)

Run game

Launch the game from the editor and wait until the MCP runtime inside it is connected. Script errors in the game are logged and auto-continued unless pause_on_error=true.

Input parameters:

- `pause_on_error` (boolean): Leave the game paused in the debugger on script errors (default false).
- `restart` (boolean): Stop a running game first instead of failing.
- `scene` (string): 'main' (default), 'current' (the edited scene), or a res:// scene path.
- `timeout_ms` (integer): How long to wait for the game to connect (default 20000).

### `game_stop` (~24 tokens)

Stop game

Stop the running game. Its logs stay readable with logs_read(source='game').

### `game_query` (~108 tokens)

Query running game

Read live state from the running game. With 'properties' returns those values (supports 'position:x'); without, returns the node's class, children and common properties plus script variables. It only reads properties: to call a method use game_call.

Input parameters:

- `node` (string): Node in the running game: relative to the running scene (e.g. 'Player') or absolute (e.g. '/root/Main/Player'). Default: the running scene root.
- `properties` (array)

### `game_input` (~303 tokens)

Send input to game

Play a sequence of input steps in the running game (actions, keys, mouse), in order and with real timing; hold_frames/wait_frames count physics frames for deterministic timing. Inline set/call/assert/wait_for steps run inside the game between inputs with no time passing, so one call can set up, act and check (a failing step aborts and releases held input). Returns when the whole sequence has finished. To observe something brief (e.g. the top of a jump), pass 'record': the properties are sampled every frame while the steps run, and min/max (with times) are returned. min/max are computed from every recorded frame (up to 3000 frames); only the returned sample list is thinned to 50 entries, so interval_ms is not needed for accuracy. Add a final {wait_ms} step to keep recording after the input ends. Set pause_at_end to leave the game paused when the sequence finishes, so the next call measures the state the input left behind instead of a later one.

Input parameters:

- `pause_at_end` (boolean): Pause the game when the sequence finishes (default false). The response says paused: true.
- `record` (object): Sample node properties during the sequence. Returns summary {min, max, min_at_ms, max_at_ms, first, last} over every recorded frame, samples_total, and an evenly thinned list of at most 50 samples.
- `steps` (array, required)

### `game_ui_audit` (~143 tokens)

Audit UI layout

Walk the Control nodes of the running game and report layout problems: Controls with no size, Controls outside the viewport or beyond their parent panel, text that needs more room than its rect (clipped) and overlapping labels. Returns the tree (path, class, rect, size, anchors, text) plus the issues, so a HUD can be checked without reading a screenshot.

Input parameters:

- `include_hidden` (boolean): Also list hidden Controls (default false).
- `node` (string): Node in the running game: relative to the running scene (e.g. 'Player') or absolute (e.g. '/root/Main/Player'). Default: the running scene root.

### `game_in_view` (~119 tokens)

Is a node on screen

Check whether a Node3D is inside the camera's view (not behind it, projected inside the viewport) and where it lands on screen — the 3D judgement that otherwise needs a screenshot.

Input parameters:

- `camera` (string): Camera3D to use; default the active 3D camera.
- `node` (string): Node in the running game: relative to the running scene (e.g. 'Player') or absolute (e.g. '/root/Main/Player'). Default: the running scene root (must be a Node3D).

### `game_ray` (~147 tokens)

Cast a ray in the running game

Cast a ray between two world-space points and return the hit position, normal, distance and collider (or hit: false). World axes do not follow a body's rotation, unlike a child RayCast3D.

Input parameters:

- `collide_with_areas` (boolean): Include Area3D (default false).
- `collide_with_bodies` (boolean): Include bodies (default true).
- `collision_mask` (integer): Physics layers to hit (default all).
- `exclude` (string): CollisionObject3D to ignore (e.g. the body casting the ray).
- `from` (required): World start point [x, y, z].
- `to` (required): World end point [x, y, z].

### `game_contacts` (~87 tokens)

Contact points of a rigid body

List a RigidBody3D's contact points, normals and the bodies they touch (contact_monitor must be on), so grounding can be read instead of inferred from a picture.

Input parameters:

- `node` (string, required): Node in the running game: relative to the running scene (e.g. 'Player') or absolute (e.g. '/root/Main/Player'). A RigidBody3D.

### `game_set` (~140 tokens)

Set values in running game

Change state in the running game, e.g. to set up a test: {"score": 300, "position:x": 40, "items:2": 5}. Paths may address members, array elements and dictionary keys. Values are converted to the existing type; all of them are validated first and nothing changes if one is invalid. Returns before/after per path.

Input parameters:

- `node` (string): Node in the running game: relative to the running scene (e.g. 'Player') or absolute (e.g. '/root/Main/Player'). Default: the running scene root.
- `properties` (object, required): Property path -> new value.

### `game_pause` (~80 tokens)

Pause / resume running game

Pause (paused: true) or resume the running game. While paused, game nodes don't run but game_query, game_set, game_call and game_wait_for still work — inspect and set up a situation across several calls without time passing, then advance with game_step. Input sent with press: true stays held while stepping.

Input parameters:

- `paused` (boolean, required)

### `game_step` (~169 tokens)

Advance running game by N frames

Run exactly N physics frames, then leave the game paused (pauses it first if needed). Deterministic: every pausable node gets the same N _physics_process calls, independent of call latency. press/release/tap are sent just before the first stepped frame, like real input, so the game sees them in that frame as Input.is_action_just_pressed() and as input events (tap lasts one frame) — input sent with game_input while paused can't do that.

Input parameters:

- `frames` (integer, required): Physics frames to run (60 per second by default).
- `press` (array): Actions to press before the first frame and keep held.
- `release` (array): Held actions to release before the first frame.
- `tap` (array): Actions to press for exactly the first frame.

### `game_call` (~136 tokens)

Call method in running game

Call a method on a node in the running game (e.g. a test hook such as restart() or spawn_wave(3)) and return its result. Arguments are converted to the declared parameter types; coroutines are awaited.

Input parameters:

- `args` (array): Positional arguments.
- `method` (string, required): Method name.
- `node` (string): Node in the running game: relative to the running scene (e.g. 'Player') or absolute (e.g. '/root/Main/Player'). Default: the running scene root.
- `timeout_ms` (integer): How long to wait for the result. Default 10000.

### `game_wait_for` (~326 tokens)

Wait for game condition

Wait until a property of a node in the running game (or the return value of one of its methods, e.g. {method: 'summary', property: 'state'}) satisfies a condition, checked every frame. Fails with TIMEOUT and the last observed value. timeout_ms=0 checks once (an assertion). op changed/increased/decreased waits for a change from the value seen when waiting starts.

Input parameters:

- `args` (array): Arguments for 'method'.
- `message` (string): Explains a failure in the test's words; prefixed to the error.
- `method` (string): Check this method's return value instead of a property, e.g. a summary() test hook. Called on every check, so it should only read state.
- `node` (string, required): Node in the running game, relative to the running scene (e.g. 'Player') or absolute.
- `op` (string, required): Comparison; changed/increased/decreased compare with the value when waiting starts.
- `property` (string): Property path, e.g. 'position:x', 'items:2', or a script variable. With 'method': a path inside its return value (e.g. 'message').
- `timeout_ms` (integer): Default 5000.
- `tolerance` (number): Allowed difference for numbers with ==, !=, >=, <= (default 0.0001).
- `value`: Expected value: a number, boolean, string, null or array (vectors as [x, y]). Not used by changed/increased/decreased.

### `logs_read` (~103 tokens)

Read logs

Read captured output: prints, errors and warnings (with file/line and stack when available). source='game' (default; kept after the game stops) or 'editor'. Pass the returned 'next' as 'since' to read only new entries.

Input parameters:

- `limit` (integer): Default 200.
- `min_level` (string): Default 'info'.
- `since` (integer): Cursor from a previous call's 'next'.
- `source` (string)

### `screenshot` (~149 tokens)

Screenshot

Capture an image of the running game (target='game', default) or of the editor's 2D/3D viewport (target='editor'). Game captures are scaled to the project's viewport size (normalize='viewport') so repeated screenshots compare like for like; pass normalize='none' to keep the window size. The text says the size and, when it differed, the window size. Not available when running headless.

Input parameters:

- `max_width` (integer): Downscale to at most this width (default 1280).
- `normalize` (string): Game only: scale to the project's viewport size (default) or keep the window size (editor captures are unchanged).
- `target` (string)

### `scenario_run` (~479 tokens)

Run scenario test

Run a scripted play-test: (re)start the game, then execute steps in order — wait_for, assert, input, query, screenshot, wait_ms, assert_no_errors, set, call, repeat — stopping at the first failure. Returns a summary with per-step result, what was checked and the observed value, game errors, and screenshots; report='full' adds the JSON report. Pass a YAML/JSON file in the project (path), a folder or a list of files (paths) to run several and get one summary, or an inline scenario. save_to keeps the screenshots and a report as files in the project. movie records every frame with Godot's Movie Maker (fixed frame rate, needs a game window) and saves movie.gif plus contact.png — a grid of evenly spaced frames, also returned as an image so you can see the motion.

Input parameters:

- `include_screenshots` (boolean): Attach screenshots as images (default true; for a folder or paths, default is failure screenshots only).
- `movie` (object): Record the run with Movie Maker (one scenario; needs save_to and a game window — not with --headless in Main Run Args). Waits in the scenario are game time, so prefer frame-based steps for exact timi…
- `path` (string): Scenario file, e.g. 'res://tests/scenarios/move.yaml', or a folder to run every .yaml/.yml/.json file in it (natural name order, so 2_ runs before 10_).
- `paths` (array): Several scenario files, run in the given order.
- `report` (string): 'summary' (default) or 'full' to also return the JSON report.
- `save_to` (string): Folder in the project for evidence, e.g. 'res://qa/evidence/move': every screenshot as NN-label.png, report.md and report.json (a folder run: one subfolder per scenario plus summary.md). Re-runs repl…
- `scenario`: Inline scenario as YAML text or an object: {name, scene?, steps: [...]}.
- `stop_on_failure` (boolean): With a folder or paths: stop after the first scenario that does not pass.

### `test_run` (~223 tokens)

Run unit tests

Run the project's unit tests with GUT or GdUnit4 (whichever is installed in addons/) in a separate headless Godot process started by the editor, and return pass/fail counts, every failing test with its message, and errors from the log. Use it for game logic; use scenario_run for play. Failing tests are a normal result (not a tool error).

Input parameters:

- `framework` (string): Default 'auto': the one installed.
- `path` (string): Test folder or one test script, e.g. 'res://test/unit' or 'res://test/unit/test_player.gd'. Default: res://test or res://tests (GUT: the folders in res://.gutconfig.json when it exists).
- `report` (string): 'full' adds the JSON result with every test's status.
- `test` (string): GUT only: run the tests whose name contains this, e.g. 'test_jump'.
- `timeout_ms` (integer): Stop the run after this long (default 120000).

## Diagnostics

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

## Score history

- 2026-11-05: 87
- 2026-11-04: 86
- 2026-11-03: 86
- 2026-11-02: 85
- 2026-11-01: 85
- 2026-10-31: 84
- 2026-10-30: 84
- 2026-10-29: 83
- 2026-10-28: 83
- 2026-10-27: 82
- 2026-10-26: 82
- 2026-10-25: 82
- 2026-10-24: 81
- 2026-10-23: 81
- 2026-10-22: 80
- 2026-10-21: 80
- 2026-10-20: 64

## Common questions

### What is the Godot MCP Loop server?

Godot MCP Loop is listed in the public MCP registry as io.github.AI-osho/godot-mcp-loop. Drive a live Godot 4 editor: edit scenes and scripts, run and test the game, record GIFs. This page covers its npm package (godot-mcp-loop).

### Is the Godot MCP Loop server safe to use?

Godot MCP Loop scores 87 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Godot MCP Loop server expose?

Godot MCP Loop exposes 41 tools: godot_status, project_list, project_connect, editor_launch, editor_quit, and 36 more. Their descriptions and schemas cost roughly 6,043 tokens of context every time the server is loaded.

### Is the Godot MCP Loop server still maintained?

Godot MCP Loop is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Godot MCP Loop server under?

Godot MCP Loop declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

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