Checked against the official documentation available on September 1, 2026. Unity CLI and
com.unity.pipelineare experimental, so the installed version'sunity --helpis the authoritative reference.
Why writing C# is not enough
AI agents can edit Unity C#, but an edit is not a verified result. Unity may need to recompile and reimport assets; tests, Console errors, Scene state, Play Mode, or a built Player may also need inspection.
A useful agent must close this loop without asking a human to copy every result from the Editor:
Observe -> Plan -> Act -> Wait -> Verify -> Recover
Unity's standalone CLI and com.unity.pipeline provide an official execution layer for that loop. The focus here is a restricted workflow for inspection, mutation, and verification—not a complete command reference or vendor-specific CI file.
Separate the three command-line surfaces
Unity developers often call three different systems “the CLI.”
Traditional Editor arguments
The Editor executable still accepts -batchmode, -projectPath, -executeMethod, -runTests, and related flags:
Unity.exe -batchmode -quit `
-projectPath "C:\Projects\MyGame" `
-executeMethod BuildCommand.BuildWindows `
-logFile "C:\Logs\unity-build.log"
This remains useful for headless jobs, but it launches an Editor process and locks the project; it does not control an already-open Editor.
The standalone Unity CLI
The newer unity executable manages Editors, modules, authentication, projects, builds, tests, and connected instances without opening the Hub UI.
unity editors --installed --format json
unity install 6000.3.7f1 -m android
unity open ./MyGame
It supports human, TSV, JSON, NDJSON, and GitHub-oriented output, with structured stdout, diagnostic stderr, and exit codes for automation.
Unity Pipeline
After adding com.unity.pipeline, the CLI can discover commands registered by a running Editor or configured Development Player:
unity status --json
unity command
unity command get_console_logs --json
| Surface | Best fit |
|---|---|
| Editor arguments | Existing headless automation |
| Standalone CLI | Editor/module management, projects, builds, tests, CI |
| Pipeline | Fast inspection and controlled operations in a running Editor or Player |
Design a small capability surface
The agent reaches Unity through shell commands or the CLI's MCP server:
AI agent -> unity command / unity mcp -> Unity CLI
-> com.unity.pipeline -> Editor / Development Player
Do not expose unlimited Unity API access as the default. Expose named commands with declared arguments and structured results. Your team can review that surface, restrict paths, require previews, and decide which operations need human approval.
Start with these three commands:
unity --version
unity status --json
unity list --json
They identify the CLI version, connected instance, and registered schemas. Next, add a read-only project_health command. After each C# edit, require proof of final compilation, passing targeted tests, zero new Console errors, and no forbidden asset changes.
Record versions and install deliberately
As of September 1, 2026, the current documented releases are Unity CLI 1.0.0-beta.6 and com.unity.pipeline 0.5.0-exp.1. Store a compatibility record:
Unity Editor: 6000.x.yf1
Unity CLI: 1.0.0-beta.6
com.unity.pipeline: 0.5.0-exp.1
Verified: 2026-09-01
A beta channel is not a version pin. Make CI fail when unity --version differs, and avoid unconditional upgrades inside jobs.
Install the CLI through an official route, then inspect it:
# macOS/Linux
curl -fsSL https://public-cdn.cloud.unity3d.com/hub/prod/cli/install.sh \
| UNITY_CLI_CHANNEL=beta bash
# macOS/Linux alternative
brew install --cask unity-cli
unity --version
unity doctor
# Windows
winget install Unity.CLI
Installing modules with a new Editor and adding them later are separate operations:
unity install 6000.3.7f1 -m android webgl
unity install-modules -e 6000.3.7f1 -m android webgl
Open the project, install Pipeline, wait for compilation, and inspect the connection:
cd /path/to/MyGame
unity auth login
unity pipeline list-versions
unity pipeline install --package-version 0.5.0-exp.1
unity status --json
unity list --json
Confirm the exact Pipeline flags with local help. Pipeline-driven Editor control requires Unity 6.0 LTS or later. With several Editors open, run from the intended project or specify it explicitly:
unity command --project-path /path/to/MyGame editor_status --json
Old examples using --instance <host:port> are stale.
Direct commands or MCP?
Use unity command and unity eval directly when the agent can compose shell commands reliably. Unity's current guidance notes that this path is faster and consumes fewer model tokens than MCP.
Use the built-in MCP server when the client cannot run arbitrary commands or has a stronger tool-calling workflow:
unity mcp configure --list
unity mcp configure <client>
unity skill install <agent-name>
Client configuration, approval UI, working directory, and inherited permissions vary. MCP is transport and discovery, not authorization; keep policy in the repository and CI.
Unity has deprecated the MCP server bundled with the in-Editor AI assistant package in favor of unity mcp; third-party MCP packages are a separate choice.
Turn every task into a closed loop
Observe and Plan
Capture the initial Editor state, open Scenes, dirty state, and existing errors. Define success mechanically: a named test passes, new-error count is zero, only approved files changed, and Scene or Prefab edits are forbidden unless requested.
unity status --json
unity command editor_status --json
unity command list_open_scenes --json
unity command get_console_logs --json
Act and Wait
Use normal file editing for persistent C#, typed [CliCommand] methods for repeatable Unity operations, and eval only for narrow investigation. Start and completion can be different states:
recompile -> recompile_status
run_tests -> test_status
build -> build_status
Domain reloads, imports, and target switches can briefly interrupt the connection. Retry only within a bounded policy and poll a final status rather than treating request acceptance as success.
Pipeline 0.5.0-exp.1 also supports detached jobs and live progress:
unity command <long_command> --detach --json
unity job status <job-id> --json
unity job wait <job-id> --json
Detached jobs survive a client timeout, but remain serialized and do not survive domain reload.
Verify and Recover
Match evidence to the artifact:
| Change | Required evidence |
|---|---|
| C# | final compile state, targeted tests, new Console errors |
| Scene/Prefab | serialized values, dirty/save state, Git diff |
| UI | Play Mode state, Game View capture, logs |
| Runtime | Player state, Player log, exceptions, capture |
| Build | final result, output path, artifact checks |
Report commands, exit codes, test counts, new errors, changed paths, and outputs. “It looks fixed” is not evidence.
Add a typed read-only command
A custom command is a static method marked with [CliCommand]; arguments use [CliArg]. The example below depends on UnityEditor, so place it in an Editor folder or Editor-only Assembly Definition.
#if UNITY_EDITOR
using System.Linq;
using Unity.Pipeline.Commands;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
public static class ProjectHealthCommands
{
[CliCommand("project_health", "Return editor and scene state.")]
public static object GetProjectHealth()
{
var scenes = Enumerable.Range(0, SceneManager.sceneCount)
.Select(SceneManager.GetSceneAt)
.Select(s => new
{
s.name,
s.path,
s.isLoaded,
s.isDirty
})
.ToArray();
return new
{
unityVersion = Application.unityVersion,
isPlaying = EditorApplication.isPlaying,
isCompiling = EditorApplication.isCompiling,
buildTarget = EditorUserBuildSettings.activeBuildTarget.ToString(),
scenes
};
}
}
#endif
unity command project_health --json
MainThreadRequired defaults to true; keep it unless the implementation is independent of main-thread-only Unity APIs. Return fields, not prose, so an agent can assert them. At the Pipeline layer, a response conceptually resembles:
{
"success": true,
"command": "project_health",
"result": {
"isCompiling": false,
"scenes": [{ "name": "Main", "isDirty": false }]
},
"executionTimeMs": 3,
"error": null
}
For failures, add stable codes such as INVALID_ARGUMENT, NOT_FOUND, or PRECONDITION_FAILED to your own result contract. Runtime commands belong in a Player-included assembly with no UnityEditor dependency.
Keep eval for investigation
eval is useful for a one-off read:
unity eval \
"return UnityEngine.Object.FindObjectsByType<UnityEngine.Light>(UnityEngine.FindObjectsSortMode.None).Length;" \
--json
It is close to arbitrary C# execution. Never send model-generated or prompt-derived code to it without review. Limit it to short, human-inspected, read-only expressions and do not concatenate untrusted external strings.
One-off inspection -> eval
Repeated read -> read-only CliCommand
Scene/Prefab authoring -> typed CliCommand + Undo
Destructive asset operation -> dry_run + confirm + Git/backup
Stable CI task -> unity run --command / unity test / unity build
Preview mutations and separate approval
dry_run and confirm are per-command conventions; Pipeline does not provide a central approval service.
using System.Linq;
using Unity.Pipeline.Commands;
[CliCommand("normalize_enemy_layers", "Preview before applying.")]
public static object NormalizeEnemyLayers(
[CliArg("confirm", "Apply changes.")] bool confirm = false,
[CliArg("dry_run", "Preview only.")] bool dryRun = false)
{
var targets = FindTargets();
if (dryRun)
return new
{
status = "dry_run",
count = targets.Length,
samplePaths = targets.Take(10).Select(x => x.AssetPath),
warnings = targets.Length > 50
? new[] { "Target count exceeds 50." }
: System.Array.Empty<string>(),
requiresApproval = targets.Length > 20 ||
targets.Any(x => x.IsSceneOrPrefab)
};
if (!confirm)
throw new System.ArgumentException(
"Pass confirm=true or dry_run=true.");
ApplyWithUndo(targets);
return new { status = "applied", changed = targets.Length };
}
FindTargets and ApplyWithUndo are project-specific placeholders.
unity command normalize_enemy_layers --dry_run true --json
unity command normalize_enemy_layers --confirm true --json
Return a count, representative paths, warnings, and approval requirement instead of every target. This limits token usage and accidental disclosure of unpublished asset paths.
confirm=true is only an intent flag. It does not record who approved what, so it cannot replace a human approval log or pull-request diff. Automatic application should be limited to approved generated paths, no deletion, strict count limits, a clean dedicated worktree, and deterministic verification.
Require human approval for Scenes, Prefabs, ProjectSettings, Packages, deletion, bulk overwrites, external I/O, signing, or publishing. AuthoringUndoScope can group registered Scene/Object Undo operations, but AssetDatabase, Package Manager, and some settings changes need Git or backup recovery. Restrict file I/O to approved roots and reject absolute paths and .. traversal.
Parse JSON and exit codes at every layer
Use JSON for a buffered result and NDJSON for machine-readable progress:
unity editors --installed --format json
unity install 6000.3.7f1 --format ndjson
unity command project_health --json
There are two result layers:
| Layer | Typical fields |
|---|---|
| Standalone CLI |
success, command, data, errors, warnings
|
| Pipeline response |
success, command, result, executionTimeMs, error
|
Conceptually, the Pipeline response can be nested under CLI data. That is a parsing model, not a promise that every experimental build has an identical shape. Capture your installed version's actual unity command ... --json output before freezing a parser.
Unity CLI 1.0.0-beta.6 documents these process exit codes:
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Invalid usage or arguments |
| 3 | Authentication or authorization failure |
| 4 | Required configuration or context missing |
| 6 | Primary operation failed; unity test produced no verdict |
| 7 | Unity service unreachable after retries; safe to retry |
| 8 |
unity test ran and one or more tests failed; do not retry as infrastructure |
| 130 | Ctrl+C / SIGINT |
| 143 | SIGTERM or runner timeout |
unity command project_health --json \
1> result.json \
2> error.log
Evaluate success in order: process exit code, outer CLI success, inner Pipeline success, then domain results such as failed tests or build output. Exit code 0 only proves success at the process layer.
Separate the running Editor from clean CI
A running Editor is ideal for current Scene state, Console inspection, targeted tests, small authoring operations, Play Mode, and exploratory reads. Use a fresh process and workspace for pull requests, full suites, deterministic generation, and release builds.
The same registered command can run headlessly:
unity run \
--project-path ./MyGame \
--command validate_release_assets \
--json
Connect to a Development Player
Runtime connectivity targets Windows, macOS, or Linux standalone Development Builds, not release builds. Mobile, console, and WebGL are outside this article's scope.
- Add
Pipeline > Runtime Pipeline Managerto a startup Scene GameObject. - Enable
enableInBuilds; normally keepautoStartenabled and port0. - Make and launch a standalone Development Build.
- Wait for its runtime descriptor.
- Put
--runtimeor--runtime-pathimmediately aftercommand.
unity command --runtime MyGame.exe runtime_status --json
unity command --runtime-path "C:\Builds\MyGame" runtime_status --json
Runtime server code is compiled only into Development Players. enableInBuilds=true does not create a release-build backdoor. Keep custom runtime commands in a Player assembly and return structured state—Scene, position, gameplay state, exception count—alongside logs or captures.
Local-only still requires security controls
Pipeline binds to local loopback and authenticates with a bearer token from a descriptor file. Let the CLI handle discovery. A custom HTTP client should use 127.0.0.1 explicitly because localhost can resolve to IPv6 ::1, which is unreliable on the relevant Mono HttpListener path.
The agent still has repository and shell access. Use a dedicated branch or worktree, inspect git status, and expand permissions from read-only inspection to narrowly scoped mutations.
Treat logs, captures, descriptor files, credentials, signing material, IDs, and unreleased art as sensitive; define what may reach a cloud model.
Put the operational rules in AGENTS.md:
## Unity workflow rules
- Use ProjectSettings/ProjectVersion.txt as the Editor version source.
- Run unity status and project_health before changes.
- Check git status before touching Scenes, Prefabs, or settings.
- Run dry_run first; dry_run is not approval.
- Require human approval or PR review for Scenes, Prefabs,
ProjectSettings, Packages, deletion, and bulk updates.
- Use eval only for reviewed, read-only investigation.
- After C# edits, wait for compilation, run targeted tests,
and prove that new Console error count is zero.
- Never sign or upload a release.
Common failure modes
-
No Editor found: check
unity status --json,unity editors running --json,unity pipeline list --json, compilation state, and working directory. - Command missing: the method must be static, compile successfully, and live in the correct Editor or Player assembly.
-
Stale flags: read
unity --help, command-specific help, andunity list --jsonafter upgrades. -
Temporary disconnect: bound retries and poll final status after domain reload, import, target switch, or the Pipeline
0.5startup settling state. -
False test success: request acceptance is not a passing suite; poll
test_statusor inspect the NUnit report. - Unsaved Scene: report dirty state and make saving a separate explicit operation.
- Undo gap: use previews, Git, and backups for AssetDatabase, packages, and settings.
A staged adoption plan
-
Read: status, hierarchy, Console, test list, and
project_health. - Verify: bounded compile waits, targeted tests, Play Mode, and captures.
- Author narrowly: typed commands with preview, limits, approval, Undo, and Git diffs.
- Inspect runtime: combine Development Player state, logs, exceptions, and captures.
The goal is a small command set with explicit preconditions, side effects, outputs, and recovery paths.
Conclusion
Unity CLI integration matters when it turns an AI edit into a verified engineering operation. Separate the standalone CLI, traditional Editor arguments, and Pipeline. Use eval only for narrow investigation, promote repeated work into typed commands, and require every task to observe, act, wait, and verify.
Combine dry_run, confirm, limits, Undo, Git, and human approval instead of trusting one safety mechanism. Keep the fast running-Editor loop separate from clean CI, and treat local help plus captured JSON as the source of truth for the experimental versions you run.
Begin with read-only project_health; expand only after the agent can prove the before-and-after state.
Top comments (0)