使用说明
Godot MCP
MCP (Model Context Protocol) server and Godot 4.x editor plugin that gives AI assistants full access to the Godot editor. Build, inspect, and debug Godot games through natural language.
Works with any MCP-compatible AI client: Claude Code, Claude Desktop, Cursor, Windsurf, and others.
How It Works
graph LR
A1["AI Client (stdio)"] --> Server["In-Process MCP Server"]
A2["AI Client (HTTP)"] -->|HTTP| Daemon["HTTP Daemon"]
Server -->|WebSocket| Plugin["Godot Plugin"]
Daemon -->|WebSocket| Plugin
Plugin --> Exec["Command execution\nScene manipulation\nRuntime debugging"]
The system has two layers:
- Node.js MCP server — speaks the MCP protocol to AI clients and translates tool calls into WebSocket messages
- GDScript editor plugin — runs inside Godot, receives commands via WebSocket, executes them using the editor and engine APIs
Two transport modes:
- Stdio (default) — when spawned by an MCP client (Claude Code, Claude Desktop, Cursor), the server runs in-process and auto-starts a headless Godot in the background. No daemon, no proxy — the process IS the server. Tools are available immediately; Godot connects asynchronously.
- HTTP daemon (
--daemon) — persistent HTTP server for multi-client setups where multiple AI clients share one Godot connection.
Each Godot project gets a unique port pair (derived from the project path via FNV-1a hash), so multiple projects can run in parallel without conflicts.
Features
61 Tools Across 11 Categories
File Tools (4) — Browse and search the project filesystem
list_dirread_filesearch_projectcreate_script
Scene Tools (11) — Create and modify .tscn scene files
create_sceneread_sceneadd_noderemove_nodemodify_node_propertyrename_nodemove_nodeattach_scriptdetach_scriptset_collision_shapeset_sprite_texture
Script Tools (8) — Edit GDScript, evaluate expressions
edit_scriptvalidate_scriptlist_scriptscreate_folderdelete_filerename_fileeval_expressioneval_editor_expression
Project Tools (20) — Query and configure project settings, run scenes
get_project_settingsget_input_mapget_collision_layersget_node_propertiesget_console_logget_errorsget_debugger_errorsclear_console_logopen_in_godotscene_tree_dumplist_settingsupdate_project_settingsconfigure_input_maprescan_filesystemrun_scenestop_sceneis_playingclassdb_querysetup_autoloadeval_editor_expression
Asset Tools (1) — Generate 2D sprites from SVG
generate_2d_asset
Runtime Tools (6) — Inspect and interact with the running game
game_screenshotgame_scene_treegame_get_propertiesgame_get_propertysend_input_actionsend_key_event
Visualizer Tools (5) — Debug overlays and performance monitoring
debug_draw_overlayclear_debug_overlayhighlight_nodewatch_propertyperformance_stats
Lifecycle Tools (3) — Manage the Godot process
start_godotstop_godotgodot_process_status
Assert Tools (3) — Automated testing meta-tools
assert_propertyassert_node_existswait_for_condition
Status (1) — Built-in connection check
get_godot_status
9 Read-Only Resources
Resources let AI clients pull project context without side effects:
| URI | What it returns |
|---|---|
godot://project/settings |
Main scene, window size, physics, rendering config |
godot://project/input-map |
All input actions and their bindings |
godot://scenes |
Every .tscn file in the project |
godot://scripts |
Every .gd file with metadata |
godot://editor/scene-tree |
Node hierarchy of the currently edited scene |
godot://editor/errors |
Latest errors and warnings |
godot://editor/console |
Latest console output |
godot://scene/{path} |
Parsed structure of a specific scene file |
godot://file/{path} |
Contents of any project file |
Runtime Debugging
When the AI calls runtime tools (game_*, visualizer tools), the plugin automatically:
- Injects a
__MCPRuntimeBridge__autoload into the project - Launches the scene with the debugger bridge active
- Routes commands through Godot's
EditorDebuggerPluginmessage channel - Cleans up the autoload when the scene stops
This means the AI can screenshot the running game, inspect live node properties, draw debug overlays, watch property changes over time, and read performance metrics — all without modifying your game code.
Visualizer System
The visualizer draws on a CanvasLayer at z-index 100, above all game content:
- Shapes: rectangles, circles, lines, arrows, labels with configurable color and thickness
- Node highlighting: automatically adapts to Control (rect), Node2D (circle), or generic nodes (label)
- Auto-screenshot:
debug_draw_overlayandhighlight_nodecapture a screenshot after drawing so the AI sees the result - Auto-expire: overlays clear after a configurable duration
Setup
Prerequisites
- Godot 4.2+ (tested on 4.6)
- Node.js 20+
Installation
Option A: Symlink (for development)
# Clone the repo
git clone https://github.com/elfensky/godot-mcp.git
cd godot-mcp/server && npm install && npm run build
# Symlink the addon into your Godot project
ln -s /path/to/godot-mcp/addons/godot_mcp /path/to/your-project/addons/godot_mcp
Option B: npx (coming soon)
npx @elfensky/godot-mcp --daemon
Enable the Plugin
- Open your Godot project
- Go to Project > Project Settings > Plugins
- Enable Godot MCP
- The plugin auto-starts the daemon if it detects the server in the symlinked repo
Configure Your AI Client
Add a .mcp.json to your Godot project root (next to project.godot):
{
"mcpServers": {
"godot-mcp": {
"command": "npx",
"args": ["@elfensky/godot-mcp"]
}
}
}
This works with Claude Code, Claude Desktop, Cursor, Windsurf, and any MCP client that supports stdio. The server runs in-process, auto-discovers the Godot project from the working directory, and auto-starts a headless Godot in the background.
Alternative: streamable-http (for multi-client setups)
If you need multiple AI clients sharing one Godot session, use the HTTP daemon mode:
{
"mcpServers": {
"godot-mcp": {
"type": "streamable-http",
"url": "http://127.0.0.1:6506/mcp"
}
}
}
Note: The port (6506) is the default. With
--project, each project gets a unique port via hash. In daemon mode, check.godot/mcp-daemon.jsonfor the actual port.
Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
GODOT_MCP_PORT |
auto | WebSocket port for Godot (overrides hash-based assignment) |
GODOT_MCP_HTTP_PORT |
auto | HTTP port for MCP clients (overrides hash-based assignment) |
GODOT_MCP_TIMEOUT_MS |
30000 | Tool call timeout in ms |
GODOT_MCP_IDLE_TIMEOUT_MS |
30000 | Daemon auto-shutdown when idle (no Godot + no sessions) |
GODOT_MCP_PROJECT |
— | Godot project path (alternative to --project flag) |
GODOT_PATH |
godot |
Path to Godot binary (for start_godot tool) |
CLI Flags
node dist/index.js [flags]
--project <path> Godot project path (enables dynamic ports + process management)
--port <n> Override the HTTP port
--daemon Force HTTP daemon mode (stdio is the default when stdin is piped)
--no-force Don't kill existing processes on startup
--http Accepted for backwards compat (no-op, HTTP is always on)
Port Assignment
Without --project, the server uses default ports 6505/6506. With --project, each project gets a unique port pair derived from its absolute path via FNV-1a hash (range 6505–8504). This means multiple Godot projects can run simultaneously without port conflicts.
In HTTP daemon mode, the daemon writes .godot/mcp-daemon.json with its actual ports so that plugins can discover it. In stdio mode, ports are used only for the internal WebSocket connection to Godot.
Architecture
Data Flow
graph TD
subgraph Clients
S["AI Client (stdio)"]
H["AI Client (HTTP)"]
end
subgraph StdioServer["Stdio Mode (in-process)"]
MCP1["MCP Server<br/>(server.ts)"]
Bridge1["GodotBridge<br/>(WebSocket)"]
MCP1 -->|"Tool validation<br/>Resource serving<br/>Screenshot encoding"| Bridge1
end
S -->|stdio| MCP1
subgraph Daemon["HTTP Daemon Mode"]
MCP2["MCP Server<br/>(server.ts)"]
Bridge2["GodotBridge<br/>(WebSocket)"]
MCP2 -->|"Tool validation<br/>Resource serving<br/>Screenshot encoding"| Bridge2
end
H -->|HTTP :auto| MCP2
subgraph Godot["Godot Editor Process"]
Client["MCPClient<br/>(WebSocket)"]
Handler["CommandHandler<br/>(router)"]
Procs["FileCommands<br/>SceneCommands<br/>ScriptCommands<br/>ProjectCommands<br/>AssetCommands<br/>RuntimeCommands<br/>VisualizerCmds"]
Debugger["DebuggerPlugin"]
Game["Running Game<br/>(__MCPRuntimeBridge__)<br/>screenshots · overlays · props"]
Client --> Handler --> Procs
Client --> Debugger --> Game
end
Bridge1 -->|"WebSocket :auto"| Client
Bridge2 -->|"WebSocket :auto"| Client
Command Processing Pattern
The plugin uses Chain of Responsibility: the CommandHandler iterates registered processors until one handles the tool name. Each processor:
- Declares its tools via
get_supported_tools() -> PackedStringArray - Routes via
handles_tool(name) -> bool - Executes via
process_command(name, args) -> Dictionary - Returns
{&"ok": true, ...data}or{&"ok": false, &"error": "message"}
WebSocket Protocol
Messages between server and plugin are JSON over WebSocket:
| Direction | Type | Purpose |
|---|---|---|
| Server -> Plugin | tool_invoke |
Execute a tool with {id, tool, args} |
| Plugin -> Server | tool_result |
Return result with {id, success, result/error} |
| Server -> Plugin | ping |
Keepalive (every 10s) |
| Plugin -> Server | pong |
Keepalive response |
| Plugin -> Server | godot_ready |
Connection established with {project_path, protocol_version} |
Screenshot Pipeline
For tools that produce images (game_screenshot, debug_draw_overlay, highlight_node):
- GDScript captures the viewport to a PNG file on disk
- Returns the absolute file path in the tool result
- Server reads the PNG, encodes as base64
- Returns as MCP
ImageContentalongside text metadata - AI client renders the image inline
Testing
Server Tests (Node.js)
cd server
npm run build
npm test
194 tests covering initialization, tool listing, resource listing, WebSocket round-trip, session management, assert tools, lifecycle tools, offline handlers, port assignment, daemon discovery, protocol version negotiation, and tool manifest validation.
Plugin Tests (GDScript)
Run from any Godot project with the addon:
godot --headless --script res://tests/test_plugin.gd
44 tests validating class loading, processor instantiation, tool declarations, command routing, WebSocket client contracts, and protocol version presence.
Adding New Tools
- Define the tool schema in
server/src/tools/<domain>-tools.ts - Register in
server/src/tools/index.ts - Implement the handler in
addons/godot_mcp/commands/<domain>_commands.gdextendingMCPBaseCommandProcessor - Register the processor in
commands/command_handler.gd - Update the expected tool list in
server/tests/tool-manifest.test.mjs - Rebuild:
cd server && npm run build
Tool Conventions
- Descriptions: 1-2 sentences, action-oriented. Use CAPS for constraints (e.g., "RUNNING game" vs editor).
- Validation: Always validate inputs before executing. Return
{&"ok": false, &"error": "..."}. - Results: All handlers return Dictionary with
&"ok": bool. - Naming: snake_case, prefixed by domain (
game_,debug_).
Contributing
This project uses GitHub Flow:
- Create a feature branch from
main:git checkout -b feature/my-change - Make changes, commit with clear messages
- Open a pull request against
main - After review and CI pass, merge to
main - Tag releases with semantic versions:
git tag v0.2.0
Versioning follows Semantic Versioning. The version lives in three places — keep them in sync:
server/package.json(source of truth, read at runtime)addons/godot_mcp/plugin.cfgCHANGELOG.md
Compatibility
- Godot: 4.2+ (runtime debugging requires 4.2+, tested on 4.6)
- Node.js: 20+
- MCP Protocol: 2025-03-26
- Platforms: macOS, Linux, Windows
License
MIT
