CLI for LLM agents¶
The unifi CLI exposes every Network and Protect REST operation, generated at
runtime from the embedded OpenAPI specs. Its primary user is an LLM agent.
Install¶
go build -o bin/unifi ./cmd/unifi # or `just build-cli`
Authenticate¶
Credentials come from flags, then environment:
| Variable | Flag | Purpose |
|---|---|---|
UNIFI_API_KEY |
--api-key |
API key (required) |
UNIFI_HOST |
--host |
local console host (selects local transport) |
UNIFI_CONSOLE_ID |
--console-id |
remote console id (selects remote transport) |
UNIFI_INSECURE |
--insecure |
skip TLS verification for self-signed certs |
Set exactly one of host / console-id.
.env files¶
Credentials may also live in a .env file. The CLI auto-loads ./.env from the working directory
when it exists; pass --env-file <path> to load a specific file instead. Resolution order is
flags > environment > .env — values already set in the real environment are never overwritten,
and flags still override everything.
# .env
UNIFI_API_KEY=your-api-key
UNIFI_HOST=192.168.1.1
unifi network GetInfo # auto-loads ./.env
unifi network GetInfo --env-file ./prod.env
The grammar is deliberately small: blank lines and # comment lines are ignored, an optional leading
export is stripped, the line splits on the first =, and a value wrapped in matching single or
double quotes keeps its inner text literally (unquoted values are whitespace-trimmed). There is no
inline-comment stripping and no escape expansion. A missing ./.env is ignored; a missing file named
explicitly with --env-file is a usage error. .env is gitignored, so secrets stay out of version
control.
Discover¶
unifi protect list-operations # JSON array of operations
unifi schema --app protect # full embedded OpenAPI spec
unifi protect GetV1Cameras --help # usage for one operation
Call¶
export UNIFI_API_KEY=... UNIFI_HOST=192.168.1.1
unifi protect GetV1Cameras # JSON to stdout
unifi network getAdoptedDeviceDetails --format human # human-readable view
Output and errors¶
- stdout is JSON by default;
--format json|raw|humanselects the renderer. - Errors are a JSON envelope on stderr with stable exit codes:
0ok,1usage,2auth/config,3API non-2xx,4transport.
Safe writes¶
Mutating operations require --confirm and support --dry-run:
unifi protect PatchV1AlarmHubsId --body '{...}' --dry-run # preview only
unifi protect PatchV1AlarmHubsId --body '{...}' --confirm # execute
Operation IDs for Protect are synthesized from method and path (the upstream Protect spec omits operationIds), so they match the generated SDK method names.
Real-time WebSocket subscriptions are intentionally not in the CLI; use the Go SDK for those.
Contract notes for agents¶
- Every successful command prints JSON to stdout. The one exception is
--help/-h, which prints human-readable usage (the only non-JSON, exit-0 surface). - Running with no command, an unknown command, or an unknown operation returns
the JSON error envelope on stderr with exit code
1. - An empty
2xxresponse body renders asnullin JSON mode. - Prefer the
UNIFI_API_KEYenvironment variable over--api-keyso the key does not appear in the host's process argument list.