Scripting and CI
The CLI's automation contract in bash and PowerShell — exit codes, JSON and TSV output, discovery — plus a complete CI smoke test.
The CLI is built to live inside scripts: results go to stdout, errors go to stderr as the JSON-RPC code and message, and exit codes follow one contract — 0 success, 1 command or connection error, 2 usage error. Everything on this page is composition on top of that.
Single commands are identical in every shell — godot-mcp project info pastes into bash, PowerShell, or cmd unchanged. The tabs below appear where pipelines genuinely diverge; PowerShell examples use its native object pipeline (ConvertFrom-Json) rather than transliterated bash.
Machine output
Default output is pretty-printed JSON. --format tsv (global flags precede the group) re-renders a result for text tools: an object becomes key<TAB>value rows, an array of objects becomes a header row plus one row per element, and nested values stay as compact JSON.
godot-mcp engine commands --group node | jq -r '.methods[]'
godot-mcp --format tsv project info | awk -F'\t' '$1 == "main_scene" { print $2 }'(godot-mcp engine commands --group node | ConvertFrom-Json).methods
# PowerShell parses JSON natively, so TSV is rarely needed:(godot-mcp project info | ConvertFrom-Json).main_sceneDrive every node of a type
Queries compose with actions — batch find-nodes-by-type returns paths that feed straight back into node set:
godot-mcp batch find-nodes-by-type --type Label \ | jq -r '.matches[].path' \ | while read -r p; do godot-mcp node set --node-path "$p" --property visible --value false done(godot-mcp batch find-nodes-by-type --type Label | ConvertFrom-Json).matches.path | ForEach-Object { godot-mcp node set --node-path $_ --property visible --value false }Preflight, then launch
godot-mcp doctor checks the environment (godot binary, project, addon install state, port config, dotnet) and exits 1 only on a real failure — “no editor running yet” is a warning, so it is safe to run before you have launched anything. godot-mcp status gives the machine-readable liveness verdict (running / starting / crashed / closed); the launch policy follows from it — never start a second editor when one is running.
A complete CI smoke test
#!/usr/bin/env bashset -euo pipefail
godot-mcp doctor --project . --json > /dev/null # environment sanity: exit 1 on real problems
godot --path . --editor --headless &> editor.log & # one editor, headlessEDITOR_PID=$!for _ in $(seq 60); do # the addon writes the discovery file on bind [ -f .godot/godot-mcp.json ] && break; sleep 0.5done
godot-mcp project info > /dev/null # the editor answersgodot-mcp scene play --mode maingodot-mcp runtime eval --code 'emit(get_tree().current_scene.name)' \ | jq -e '.output[0] == "Main"' # assert against the running gamegodot-mcp scene stop
kill $EDITOR_PID$ErrorActionPreference = "Stop"
godot-mcp doctor --project . --json | Out-Null # environment sanity: exit 1 on real problemsif ($LASTEXITCODE) { exit 1 }
$editor = Start-Process godot -ArgumentList "--path", ".", "--editor", "--headless" ` -RedirectStandardOutput editor.log -RedirectStandardError editor.err.log -PassThruforeach ($i in 1..60) { # the addon writes the discovery file on bind if (Test-Path .godot/godot-mcp.json) { break }; Start-Sleep -Milliseconds 500}
godot-mcp project info | Out-Null # the editor answersif ($LASTEXITCODE) { exit 1 }godot-mcp scene play --mode main | Out-Null$name = (godot-mcp runtime eval --code "emit(get_tree().current_scene.name)" | ConvertFrom-Json).output[0]if ($name -ne "Main") { exit 1 } # assert against the running gamegodot-mcp scene stop | Out-Null
Stop-Process $editor.IdEvery step exits non-zero on failure, so set -e (bash) or the explicit $LASTEXITCODE checks (PowerShell) turn any broken link into a red build.
The catalog is data
engine commands returns the whole tool surface as JSON — the method list, a group map, and per-command param docs (attached for --group, or --docs for the full catalog). Generators become trivial: bindings, wrappers, forms, docs that cannot drift.
# every node command with its required flagsgodot-mcp engine commands --group node \ | jq -r '.docs | to_entries[] | .key + " " + ([.value.params[]? | select(.required) | "--" + .name] | join(" "))'# every node command with its required flags$cat = godot-mcp engine commands --group node | ConvertFrom-Json$cat.docs.PSObject.Properties | ForEach-Object { $_.Name + " " + ((@($_.Value.params) | Where-Object required | ForEach-Object { "--" + $_.name }) -join " ")}Standalone game rigs
With the direct-to-player channel enabled, a QA rig needs no editor at all: run a debug build, then godot-mcp --game runtime tree, --game runtime eval …, and --game input … drive it directly. See Playtest loop.