How it works
The addon-as-server architecture, the two-hop runtime IPC, and crash-aware discovery.
godot-mcp (Go CLI / client) --WebSocket (JSON-RPC 2.0) :9080--> Godot editor addon (server) | file IPC (user://) <------+--> running game (MCPGameInspector / MCPGameInput autoloads)Not Godot’s built-in CLI
Godot’s own command line (godot --headless, --export-release, --script) starts a fresh engine process each time — the right tool for CI exports and batch scripts, with no notion of a session. godot-mcp is the other half: it connects to the editor already running — the open scene, the current selection, the undo history — and to the game that editor is playing. Different jobs; use both. godot-mcp itself launches the editor through Godot’s CLI when needed.
The addon is the server
The addon runs a WebSocket server inside the editor, the long-lived process with a stable port. The CLI is a short-lived client that dials in, runs one command, and exits. The serve (MCP) mode is also just a long-lived client of the same server, so one connection model covers both.
- The server binds
127.0.0.1only. It is a local dev bridge. - The CLI resolves the port from
<project>/.godot/godot-mcp.json(written by the addon on bind), so the common case needs no flags. - The message envelope is JSON-RPC 2.0 with dotted methods (
node.add,scene.play,runtime.capture_frames).
The two-hop runtime IPC
runtime and input commands reach the running game, a separate process. The editor brokers that hop over file IPC through two game-side autoloads. The addon self-installs these autoloads on plugin-enable, so they work in any project without being pre-committed.
Crash-aware discovery
The discovery file doubles as a liveness signal. A clean shutdown deletes it; a crash leaves it stale with a now-dead pid. On any connection failure the CLI attaches a verdict:
| Verdict | Meaning |
|---|---|
running | the server answered a TCP probe |
starting | the file is present, pid alive, not bound yet |
crashed | the file is present, pid dead |
closed | no discovery file |
Safety guards
127.0.0.1-only bind, never0.0.0.0.- Audited code execution: both
editor.run_scriptandruntime.evallog the body before running;run_scriptadditionally refuses direct editor write APIs without--allow-unsafe-editor-io. - Project-path jailing on every write sink: caller-supplied paths that escape
res:///user://are rejected.