Getting started

godot-cli works on Godot 4 text scenes (.tscn), resources (.tres), and project.godot. It does not need the editor running, and it does not need a Godot install unless you want to run the game or the round-trip suite. Godot 4.6 or later: every node it writes carries the unique_id the engine added in 4.6.

Install

curl -fsSL https://raw.githubusercontent.com/unabated-games/godot-cli/main/install.sh | bash
source "$HOME/.godot-cli/env.sh"
godot-cli --version

The installer downloads the release archive for your platform, checks it against the release SHA256SUMS, and refuses to install if the two disagree. Everything lands in ~/.godot-cli:

Path Contents
bin/godot-cli The binary
templates/ Built-in scene templates for scene template copy
docs/ Agent guides, command reference, mcp_tools.json
examples/ Intent, patch, and batch JSON you can copy
share/completions/ bash, zsh, and fish completions
share/man/man1/ godot-cli(1), so man godot-cli works
env.sh Sets PATH, MANPATH, and loads completions

Add the source line to ~/.zshrc or ~/.bashrc to keep it.

To pin a version, pass --version 0.12.0. To install somewhere else, pass --prefix /opt/godot-cli. From a checkout, ./install.sh builds with Zig 0.16 instead of downloading.

Windows

The same command works in Git Bash (which comes with Git for Windows), MSYS2 or Cygwin:

curl -fsSL https://raw.githubusercontent.com/unabated-games/godot-cli/main/install.sh | bash
source "$HOME/.godot-cli/env.sh"

It fetches the .zip rather than the tarball, verifies it against the same SHA256SUMS, and installs godot-cli.exe. env.sh sets PATH for that shell; add the source line to ~/.bashrc to keep it.

Without a POSIX shell, there is a PowerShell installer:

irm https://raw.githubusercontent.com/unabated-games/godot-cli/main/install.ps1 | iex
. "$env:USERPROFILE\.godot-cli\env.ps1"

It takes -InstallSkill to copy the agent skill into the editor directories, and -AddToPath to put bin\ on your user PATH permanently.

The Git Bash path is the tested one. install.sh has been run end to end against the real Windows archive; install.ps1 has not yet been run on Windows by its author — if it fails for you, the fallback is to unpack the .zip from the releases page and add bin\ to PATH, and please open an issue with what it said.

Author a scene

Run these from a Godot project directory, the one holding project.godot. From an empty folder, project new writes that file the way the project manager would, with the name, the main scene, and the window size:

godot-cli project new --name MyGame --main-scene res://level.tscn --width 640 --height 360
godot-cli scene new --output level.tscn --root-name Level --root-type Node2D
godot-cli scene node add level.tscn --parent /root/Level --name Player --type CharacterBody2D

Nodes are addressed by viewport path (/root/Level/Player), not by line number or section index. Renaming or reparenting a node rewrites the parent attribute on every descendant, which is the part that goes wrong when a scene is edited by hand.

Sub-resources work the same way. Create one, then reference its id:

shape=$(godot-cli scene sub add level.tscn --type CapsuleShape2D --property radius --value 16.0 --json \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["data"]["id"])')

godot-cli scene node add level.tscn --parent /root/Level/Player --name Collision \
  --type CollisionShape2D --property shape --value "SubResource(\"$shape\")"

Instancing another scene writes the ext_resource entry and the instance= node together:

godot-cli scene instance add level.tscn --parent /root/Level \
  --scene res://ui/hud.tscn --name HUD --project-root .

Read it back with scene node list for the tree, scene inspect for sections and parsed property values, and scene validate to check ids, ordering, and res:// references:

godot-cli scene node list level.tscn --json
godot-cli scene validate level.tscn --project-root . --json   # exits 1 when there are errors

The file that comes out is an ordinary scene. Open the project in Godot and the tree is there, with nothing to import or convert.

When to pass --project-root

--project-root is how godot-cli resolves res:// paths, reads .godot/uid_cache.bin, looks up catalog ids, and seeds resource ids to match what Godot would write.

Commands Pass it?
Writes: scene new, node *, instance add, apply, set-property Yes
All catalog * and all project * Yes
scene validate, scene inspect, scene refs Yes, to enable res:// and UID checks
scene node list, scene node get, scene diff Optional, accepted and ignored

Every command speaks JSON

Add --json and stdout carries one document: ok, version, command, data, messages, and failure. Exit codes are 0 for success, 1 for a runtime failure, and 2 for a usage error.

The same commands can be driven as JSON instead of argv:

godot-cli --json --request '{"argv": ["scene", "node", "list", "level.tscn"]}'

Or served over MCP, one tool per command, with godot-cli mcp --project-root .. Set up an agent has the config for Claude Code, Cursor, and OpenCode.

Next

Build a scene covers the authoring commands in depth. Teach an agent your sub-scenes is the guide worth reading before pointing any coding agent at a project.