unicli
unicli mark: terminal prompt and network nodes

UniFi CLI for humans and agents

One static Go binary for Network, Protect, and Access. Prefer unicli over hand-rolled curl. JSON when you pipe. Mutations stay gated.

v0.4 Network stable · Protect / Access / console beta MIT exit 11 if Access is missing

Install

# Homebrew (macOS and Linux) — unicli + unicli-mcp
brew tap SPDG/tap
brew install unicli

# or Go (needs a recent toolchain)
go install github.com/SPDG/unicli/cmd/unicli@latest
go install github.com/SPDG/unicli/cmd/unicli-mcp@latest

unicli completion install bash   # then restart the shell

Prebuilt archives for Linux, macOS, and Windows are on GitHub Releases (current: v0.4.0). API keys never go on argv — use UNIFI_API_KEY or unicli auth login with the key on stdin.

# env wins over the selected profile
export UNIFI_HOST=https://192.168.1.1
export UNIFI_API_KEY=…
export UNIFI_INSECURE=1   # lab / self-signed
unicli doctor --json
unicli --version

Safety

Read-only by default

List and get commands need no extra flags. Agents should stay here unless the operator asked to change something.

Mutations are gated

Writes need --allow-mutations. Destructive actions also need --yes when stdin is not a TTY.

Keys stay off argv

Process lists and shell history leak flags. Profiles store keys in ~/.config/unicli/credentials.json (mode 0600).

Missing apps fail closed

If Access is not installed, those commands exit 11 (unsupported) instead of inventing doors or users.

Examples

unicli console status --json
unicli network devices list --json --limit 50
unicli network clients get 192.168.20.28 --json
unicli network ports find --mac aa:bb:cc:dd:ee:ff --json
unicli network diagnose --client 192.168.20.28 --json
unicli network topology path cam-01 pi-4 --json
unicli protect cameras snapshot vestibule --output /tmp/vestibule.jpg
unicli access info --json   # 11 if Access is absent

# blocked without --allow-mutations
unicli network devices restart <id>
unicli network ports cycle <device-id> <port> --allow-mutations --yes

On a TTY, lists print a table plus a footer. Agents should keep --json (or pipe stdout). Use --select a,b.c to keep payloads small.

Agents

Discover the live surface from the binary, not from this page:

unicli doctor --json
unicli schema --json
unicli --help

Rules of thumb: prefer unicli over raw HTTP; never put keys on argv; branch on exit codes from schema, not scraped stderr. Cursor skill: .cursor/skills/unicli/SKILL.md. Agent notes: AGENTS.md.

Optional MCP

unicli-mcp is a thin stdio server that executes unicli. It does not reimplement UniFi APIs. Tools: unicli_schema, unicli_doctor, unicli_run. Mutations via MCP still need allow_mutations: true.

{
  "mcpServers": {
    "unicli": { "command": "unicli-mcp" }
  }
}

Apps

AppStatusWhat you get
Network stable VLANs, WiFi, firewall, ACL, DNS, routes, ports, DHCP, port forwards, clients, devices, topology / diagnose
Protect beta NVR, cameras (list/get/snapshot/stream/restart/set), liveviews, lights, sensors, chimes, viewers
Access beta doors, users, visitors, devices, policies, groups — exit 11 if the app is missing
Console beta status (hardware + app versions), updates (may 401), reboot (mutation)