godot-mcp-rts logo

godot-mcp-rts

mikeumus/godot-mcp-rts
0 starsMITUpdated 2026-04-08Community

Is this your server?

Add your score badge to your README and get your server in front of 45k+ builders a month.

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

Extended MCP server for Godot engine with RTS agentic testing, scene/script introspection and mutation, and live game screenshot capture.

README.md

Godot MCP RTS

Extended MCP (Model Context Protocol) server for the Godot game engine, with RTS agentic testing, scene/script introspection & mutation, and live game screenshot capture.

Forked from Coding-Solo/godot-mcp.

![](https://modelcontextprotocol.io/introduction) ![Made with Godot](https://godotengine.org) ![](https://www.typescriptlang.org/) ![MCP SDK](https://www.npmjs.com/package/@modelcontextprotocol/sdk)

What this fork adds

On top of the original 14 godot-mcp tools, this fork ships 15 additional tools in three groups:

  • Test harness — agentic game testing (test_get_info,

test_get_game_state, test_validate_scenario, test_check_entity, test_validate_paths, test_run_scenario, test_check_mlx)

  • Scene & script introspection / mutationget_scene_tree,

remove_node, set_node_property, create_script, attach_script, list_scripts

  • Visual capturetake_screenshot (script-mode, standalone scenes)

and test_take_screenshot (live game via TestController IPC, real scenes with autoloads)

Plus infrastructure improvements:

  • Upgraded to MCP SDK 1.x (from 0.6.0)
  • preflightProject() helper retrofit on the scene-op handlers (−150 LoC of

validation boilerplate)

  • Dropped the unused axios dependency (npm audit clean)
  • End-to-end test suite (npm test) covering protocol handshake, all

mutation tools, and live screenshot capture

Tool reference

All 29 tools at a glance:

Original Godot MCP tools (14)

| Tool | Purpose | |---|---| | launch_editor | Open the Godot editor for a project | | run_project | Run a project in debug mode and capture output | | get_debug_output | Read stdout/stderr from the running project | | stop_project | Stop the running project | | get_godot_version | Print the installed Godot version | | list_projects | Find Godot projects in a directory | | get_project_info | Project metadata + counts of scenes/scripts/assets | | create_scene | Create a new .tscn with a chosen root node type | | add_node | Add a node to a scene | | load_sprite | Load a texture into a Sprite2D/Sprite3D/TextureRect | | export_mesh_library | Export a scene as a .res MeshLibrary | | save_scene | Save a scene (optionally to a new path) | | get_uid | Get the UID of a file (Godot 4.4+) | | update_project_uids | Resave resources to refresh UID references |

Test harness tools (7)

| Tool | Purpose | |---|---| | test_get_info | Test harness capabilities + project info | | test_get_game_state | Snapshot of autoloads, constants, config | | test_validate_scenario | Validate a scenario config before running it | | test_check_entity | Verify a unit/building/resource scene exists | | test_validate_paths | Validate all expected paths for a race | | test_run_scenario | Launch the game with --test-harness | | test_check_mlx | MLX local LLM health + Apple Silicon platform info |

Scene & script tools (6, new in v0.3.0)

| Tool | Purpose | |---|---| | get_scene_tree | Hierarchical JSON dump of a scene's nodes | | remove_node | Delete a node from a scene and save | | set_node_property | Bulk-set properties on an existing node | | create_script | Create a .gd file (custom content or extends template) | | attach_script | Attach an existing script to a node in a scene | | list_scripts | Recursively list .gd files in a project or subdir |

Visual capture tools (2, new in v0.3.0)

| Tool | Purpose | |---|---| | take_screenshot | Render a scene via --script and save PNG. Standalone scenes only — does not load autoloads. | | test_take_screenshot | Capture the currently running game via file-based IPC with TestController. Real game scenes with autoloads loaded. |

Installation

git clone https://github.com/mikeumus/godot-mcp-rts.git
cd godot-mcp-rts
npm install      # also runs npm run build via the prepare hook

Configuration

Claude Code

Add to your MCP settings (.claude/settings.json or global settings):

{
  "mcpServers": {
    "godot": {
      "command": "node",
      "args": ["/absolute/path/to/godot-mcp-rts/build/index.js"],
      "env": {
        "GODOT_PATH": "/Applications/Godot.app/Contents/MacOS/Godot"
      }
    }
  }
}

Cline / Cursor / other MCP clients

Same configuration format. The server speaks MCP over stdio.

Environment variables

  • GODOT_PATH — Path to the Godot executable. If unset, the server

auto-detects common install locations on macOS / Windows / Linux.

  • DEBUG — Set to true for verbose stderr logging.

Usage examples

Inspect a scene

get_scene_tree(
  projectPath: "/path/to/game",
  scenePath: "maps/test_map.tscn",
  includeProperties: true
)

Returns nested JSON with name, type, path, script, children, and optionally properties.position / properties.visible for each node.

Create a script and attach it

create_script(
  projectPath: "/path/to/game",
  scriptPath: "scripts/my_unit.gd",
  extendsClass: "CharacterBody3D"
)

attach_script(
  projectPath: "/path/to/game",
  scenePath: "units/my_unit.tscn",
  nodePath: "MyUnit",
  scriptPath: "scripts/my_unit.gd"
)

Set node properties

set_node_property(
  projectPath: "/path/to/game",
  scenePath: "units/my_unit.tscn",
  nodePath: "MyUnit",
  properties: { visible: false, modulate.r: 0.5 }
)

Note: Property names are converted to snake_case before reaching Godot. Built-in Godot properties (position, rotation_degrees, etc.) are already snake_case so this is a no-op for them. Vector/Color values can't currently round-trip through JSON; pass scalar properties only.

Run a test scenario

test_run_scenario(
  projectPath: "/path/to/game",
  timeout: 30000
)

Launches the game with the --test-harness flag, capturing stdout for later inspection via get_debug_output.

Capture a live game screenshot

# 1. Start the game (must be running for IPC to work)
run_project(projectPath: "/path/to/game")

# 2. Wait a few seconds for it to render the first frame, then
test_take_screenshot(projectPath: "/path/to/game")
# → Screenshot saved to: /path/to/game/.mcp_screenshots/capture_<id>.png

# 3. Stop when done
stop_project()

TestController integration

For the test harness tools and test_take_screenshot to work, your Godot project needs to include the TestController autoload from tests/harness/test_controller.gd (or its parent-repo equivalent).

Setup

  1. Copy tests/harness/test_controller.gd into your project
  2. Register it as an autoload (Project Settings → AutoLoad)
  3. The controller activates when the game runs with --test-harness,

--test-mode, or when the GODOT_MCP_TEST env var is set

  1. The screenshot polling code is independent of activation — it runs in

any debug build so test_take_screenshot works even from a plain run_project invocation

Screenshot IPC architecture

test_take_screenshot uses a file-based IPC handshake instead of trying to capture from a headless --script subprocess (which can't load autoloads or the main scene):

MCP server                                       Running game
─────────────                                    ────────────
1. Write request.json     ──→   .mcp_screenshots/    ─→  TestController._process()
   { request_id, output_path? }                            polls every 6 frames

                                                        2. Detect request
                                                        3. get_viewport()
                                                            .get_texture()
                                                            .get_image()
                                                            .save_png(...)

4. Poll for response.json ←──   .mcp_screenshots/    ←─  Write response.json
   { request_id, status, absolute_path }                    Print TestController log

The polling is gated on OS.is_debug_build() so exported builds are unaffected. The polling interval is 6 frames (~10 Hz at 60 fps), which is fast enough to feel synchronous from the MCP side and slow enough to be free.

The IPC workspace lives at <projectPath>/.mcp_screenshots/. Add it to your .gitignore:

.mcp_screenshots/

Testing

This project has an end-to-end test suite that exercises a real Godot binary. There are no unit tests — the value of testing this server lives almost entirely in verifying that real godot --headless --script invocations round-trip correctly, so e2e is the right shape.

npm run build         # always build first

npm test              # smoke + mutations (~35s, no game window)
npm run test:smoke    # ~3s   protocol handshake + tool registration
npm run test:mutations # ~30s every scene/script tool against a sandbox project
npm run test:screenshot # ~15s INTRUSIVE: opens a game window, opt-in

The screenshot test is opt-in and gated behind the MCP_TEST_PROJECT_PATH env var:

MCP_TEST_PROJECT_PATH=/path/to/your/game npm run test:screenshot

It validates the full test_take_screenshot pipeline against a live game, including the TestController IPC handshake. See tests/e2e/README.md for the full breakdown.

Architecture

Claude Code / Cursor / etc.
       │
       │ MCP over stdio (SDK 1.x)
       ▼
godot-mcp-rts (Node/TypeScript)
       │
       ├──→ child_process → godot --headless --script godot_operations.gd <op> <json>
       │                    (most tools: scene mutation, script create, etc.)
       │
       ├──→ child_process → godot --headless --script test_operations.gd <op> <json>
       │                    (test harness tools: state snapshots, validation)
       │
       ├──→ child_process → godot <project> [--debug | --test-harness]
       │                    (run_project, test_run_scenario; long-running)
       │
       └──→ file-based IPC at <project>/.mcp_screenshots/request.json
                            (test_take_screenshot, polled by TestController)

Development

npm run build        # compile TypeScript, copy .gd scripts to build/
npm run watch        # tsc --watch
npm run inspector    # launch the MCP inspector UI against the built server
npm test             # run the e2e suite (see Testing above)

When adding a new tool, see CONTRIBUTING.md for the full checklist.

Project layout

godot-mcp-rts/
├── src/
│   ├── index.ts                      # MCP server, tool definitions, handlers
│   └── scripts/
│       ├── godot_operations.gd       # Headless GDScript dispatcher (file ops)
│       └── test_operations.gd        # Headless GDScript dispatcher (test harness)
├── tests/
│   └── e2e/
│       ├── _client.mjs               # JSON-RPC stdio client + tiny test runner
│       ├── smoke.mjs                 # Protocol + tool registration check
│       ├── mutations.mjs             # All scene/script tools, 20 assertions
│       ├── screenshot.mjs            # Live game capture via TestController IPC
│       └── README.md                 # How to run / extend the suite
├── scripts/
│   └── build.js                      # Post-tsc copy of .gd files into build/
├── build/                            # Compiled JS + copied scripts (gitignored)
├── README.md
├── CONTRIBUTING.md
├── LICENSE                           # MIT
├── package.json
└── tsconfig.json

License

MIT — see LICENSE.

Credits

  • Original godot-mcp by Coding-Solo
  • RTS testing extension and v0.3.0 tool additions by the As Above, So Below team

See related servers & alternatives →

Related MCP servers

Browse all →

Related guides

Hand-picked reading to help you choose and use Other servers.