Skip to main content
Glama
LJH-snow

Godot Safe Change MCP

by LJH-snow

Godot Safe Change MCP is an MCP server for AI-assisted Godot development. TypeScript owns contracts, preview plans, confirmation, task orchestration, and audit evidence; the Godot EditorPlugin owns live editor context, UndoRedo, run control, and diagnostics.

The server does not expose arbitrary Godot RPC. Every write follows a bounded lifecycle:

Inspect context → preview a diff → confirm → acquire a project lease → apply through Godot UndoRedo → verify → rollback safely when needed

Why this project

  • Intent-level tools, not arbitrary RPC: create, move, instantiate, edit, run, and verify bounded Godot operations.

  • Evidence for every write: preview diff, expected revision, explicit confirmation, operation ID, UndoRedo report, and rollback evidence.

  • Safe multi-window work: project leases, heartbeat renewal, TTL takeover, and stable PROJECT_BUSY responses.

  • Real Godot verification: GitHub Actions runs the same EditorPlugin fixture against Godot 4.5.1 and 4.7.2.

Related MCP server: godot-mcp-server

Quick Start

Requirements

  • Node.js 22.22.2 or newer

  • A Godot 4.x editor; CI currently verifies 4.5.1 and 4.7.2

  • An MCP-capable agent client

1. Install and start the MCP server

git clone https://github.com/LJH-snow/godot-safe-change-mcp.git
cd godot-safe-change-mcp
npm ci
npm run build
npm run dev

The development server exposes:

Override the bridge with GODOT_BRIDGE_URL when needed.

2. Install the Godot plugin

Copy godot-plugin into the target project:

your-godot-project/addons/godot-safe-change-bridge/

Enable Godot Safe Change Bridge in Project → Project Settings → Plugins. The plugin listens only on loopback at 127.0.0.1:8765.

3. Connect an MCP client

Add this Streamable HTTP server to the client:

http://127.0.0.1:3000/mcp

Or run the built entry point directly:

npm run build
node bin/mcp-server.mjs

Using the Inspector

The Inspector is the local MCP debugging UI provided by mcp-use. Running npm ci or npm install installs the locked @mcp-use/inspector package into node_modules; starting the server does not download it again on every run.

Use it as follows:

  1. Start Godot and enable Godot Safe Change Bridge.

  2. Run npm run dev from the project root; this starts the development server and loads the Inspector.

  3. Open http://127.0.0.1:3000/mcp/inspector if the browser does not open automatically.

  4. In Tools, call editor_context first and check the current scene, full node tree, and connection state.

  5. Use search_project or find_references to verify read-only project intelligence.

  6. For writes, keep the lifecycle explicit: preview_scene_change → confirm_scene_change → apply_scene_change → rollback_scene_change.

  7. Use operation_history, task_status, and task_timeline to inspect audit, lease, and recovery evidence.

To debug without opening a browser, or to disable the UI entirely:

npm run dev -- --no-open
npm run dev -- --no-inspector

The Inspector is for local development, manual acceptance, and demos; CI and the production entry point do not depend on it. The development server binds to 127.0.0.1 by default. Do not expose the development Inspector publicly or enter sensitive credentials into tool forms.

First workflow

Start with read-only requests:

Read the current Godot editor context and complete scene tree.
Search the project for Player or PackedScene nodes, scripts, and resources.
Find which scenes or scripts reference res://scripts/player.gd.

For a write, keep the states separate:

  1. Call preview_scene_change and inspect the diff.

  2. Check the target, NodePath, property changes, and expected revision.

  3. Call confirm_scene_change explicitly.

  4. Call apply_scene_change; the plugin performs the real UndoRedo action.

  5. Run the scene or verify scene state and diagnostics.

  6. Call rollback_scene_change only while the revision and history guards remain valid.

Workflow

flowchart LR
    A[Agent / MCP Client] --> B[Godot Safe Change MCP]
    B --> C[Read context and search]
    C --> D[Preview + Diff]
    D --> E[User confirmation]
    E --> F[Task lease + revision guard]
    F --> G[Loopback EditorPlugin]
    G --> H[Godot UndoRedo / bounded file change]
    H --> I[Run scene and collect diagnostics]
    I --> J[Verify state or diagnostics]
    J --> K[Rollback or continue]
    K --> F

Capability map

Area

Tools and operations

What it covers

Project intelligence

project_overview, search_project, find_references

Scenes, nodes, scripts, resources, signals, input actions, and reverse references.

Editor context

editor_context

Full current scene tree with node groups, selected-node properties, open resources, run state, and diagnostics.

Scene structure

create, delete, reparent, rename, duplicate, reorder, instantiate, connect/disconnect signal, add/remove group

Safe NodePaths, ownership, names, parent relationships, instance source paths, sibling indices, signal/method validation, and group membership checks; connections, disconnections, and group changes use Godot UndoRedo apply/rollback.

Scene content

scene.set_property, scene.attach_script, scene.detach_script, scene.set_unique_name

Allowlisted visible, position, rotation_degrees, scale, size, text, and color properties, project-local GDScript attachment/detachment, and scene-unique %Name exposure.

Files and settings

resource references, input actions, script creation and ranges, autoload registration, project.setting.set

File or project-settings revision guards, full-byte revisions, independent disk readback, atomic writes, byte-preserving recovery, and guarded rollback.

Runtime evidence

run_current_scene, run_scene

Run IDs, terminal state, output, warnings, errors, source, line, and NodePath evidence.

Multi-step work

create/get/advance/pause/resume/cancel

Scene/resource/script verification steps, diagnostics repair preview, and step-level operation IDs.

Recovery

task leases, task_status, task_timeline

Heartbeats, TTL takeover, owner visibility, and auditable recovery events.

Safety model

preview → confirm → lease/revision check → apply → verify → rollback (when needed)

The server never executes agent-generated GDScript, shell commands, Python workers, arbitrary Godot RPC, or unrestricted filesystem writes. The plugin independently validates the project root, safe paths, operation allowlists, active-plan identity, and UndoRedo history. The documented checks are a bounded implementation/evidence description, not a claim of a complete security audit.

project.setting.set is deliberately narrower than a general ProjectSettings setter. It accepts exactly three keys: application/run/main_scene (an existing project-local res:// .tscn, or a uid:// reference that Godot's ResourceUID registry resolves to one), display/window/size/viewport_width, and display/window/size/viewport_height (the viewport values must be integers from 1 through 16384). A supplied main-scene path or uid is persisted in the same form and snapshots report that form verbatim. The strict settingKey/value payload rejects unknown keys, extra fields, traversal, non-integers, non-finite values, and missing scenes. This is a project-level lifecycle: preview, confirmation, apply, and rollback can run without a current scene. The /v1/project-settings/read snapshot reports an unconfigured main scene as exists: false and value: null.

The revision is derived from the complete project.godot bytes and is checked at preview, confirmation, apply, and rollback. Godot persists the setting with ProjectSettings.save(), while the bridge independently reads project.godot from disk with ConfigFile and verifies the typed persisted value before reporting success. Recovery captures both original and attempted bytes; if save or readback fails, it uses a temporary file plus atomic rename to restore the original bytes and verifies the bytes and revision. Structured failures expose recoveryRequired: true with a phase such as save, verify, rollback, or rollback-verify; pending recovery blocks a new project-setting apply until it is resolved. Rollback refuses to overwrite an external edit and returns REVISION_CONFLICT, preserving the edited file.

Short apply/rollback leases and long-lived task leases live in the user state directory, not inside the Godot project. A live lease held by another MCP process returns PROJECT_BUSY; a crashed owner can be replaced only after TTL expiry.

Tests and CI

Run local quality gates:

npm test
npm run typecheck
npm run build
npm run package:check
npm run release:check
git diff --check

Run the real bridge smoke when a local Godot editor is available:

GODOT_BIN=/path/to/Godot node tests/godot-runtime-smoke.mjs

Every push runs four GitHub Actions jobs:

  • check: Node.js typecheck, regression tests, and build

  • npm package boundary: verifies the actual release tarball

  • Godot 4.5.1 runtime: real EditorPlugin fixture smoke

  • Godot 4.7.2 runtime: the same fixture on the second supported version

The smoke covers search, context, scene/property/structure/instance/script apply-rollback, resources, input settings, bounded project.setting.set persistence/readback/rollback and external-edit conflict protection, diagnostics, task leases, two-process contention, and TTL takeover. The project-setting evidence covers the three-key allowlist, project-level operation without a current scene, unconfigured main-scene snapshots, full-file revisions, and recovery behavior; it is not a complete security audit.

Developer commands

npm ci
npm run dev
npm run typecheck
npm test
npm run build
npm run package:check
npm run release:check

More detail:

License

MIT

Related MCP Connectors

Related MCP Servers