nxstate
Read-only Cisco Nexus (NX-OS) state, as clean JSON — for your coding agent and for you. It runs
showcommands across one switch or a whole fleet, and it physically cannot configure a device: any non-read input is refused (WRITE_REFUSED). "Noconf t" is the product boundary, not a flag.
📖 Documentation: https://rnwolfe.github.io/nxstate/
Conforms to the Agent CLI Guidelines v0.4.0 at the Full level — verify from the binary with
nxstate schema | jq .conformance.
Demo rendered from demo/nxstate.tape via vhs.
Why nxstate
- Read-only by design — no mutating commands exist; the
show/debugpassthrough refuses anything but reads. Safe to point an autonomous agent at production. - Structured output —
--format json|plain|tsv,--select,--limit; NX-OSTABLE_/ROW_noise normalized into clean arrays. - Self-describing —
nxstate schema(machine-readable command tree + exit codes + live safety state) andnxstate agent(a usage guide embedded in the binary). - Fleet-ready — inventory + concurrent multi-device fan-out with per-device error isolation.
- Prompt-injection hardened — device free-text (descriptions, neighbor names, logs) is fenced as untrusted so an agent won't execute instructions hidden in it.
- Credential-safe — passwords via stdin/env/OS-keyring, never on the command line.
Install
| Method | Command |
|---|---|
| Zero-install trial | uvx nxstate --help |
| For repeated use | uv tool install nxstate |
| pip | pip install nxstate |
| Max parser coverage | uv tool install "nxstate[genie]" (adds Genie's ~293 NX-OS parsers) |
Quickstart
# Resolution is flag → inventory → env → default, so export defaults once:
export NXSTATE_HOST=sw1 NXSTATE_USERNAME=netops NXSTATE_PASSWORD=... # never on argv
nxstate doctor # verify reachability + credentials
nxstate system version --json
nxstate interface list --format tsv
nxstate show "show ip ospf neighbors" # generic read passthrough (non-read → WRITE_REFUSED)
Authentication
nxstate needs a target (--host or an inventory --device) and a username; the password is
resolved --password-stdin → NXSTATE_PASSWORD → OS keyring → prompt — never via argv.
nxstate auth login --host sw1 -u netops # store the password in the OS keyring (user@host)
nxstate auth status --host sw1 # is a credential available? (token redacted)
Use a least-privilege network-operator (read-only) account. NX-API with a self-signed cert
needs --insecure (trusted networks only). Transport defaults to auto (probe NX-API → SSH).
Inventory & multi-device fan-out
Define hosts/groups in ~/.config/nxstate/inventory.yaml (copy docs/inventory.example.yaml) —
defaults ← groups ← host, no secrets in the file:
defaults: { username: netops, transport: auto }
groups: { datacenter: { transport: nxapi, insecure: true } }
hosts:
leaf1: { host: 10.1.1.11, groups: [datacenter] }
leaf2: { host: 10.1.1.12, groups: [datacenter] }
nxstate interface list --device leaf1 # one host → clean output
nxstate interface list --group datacenter # many → concurrent, NDJSON per device
nxstate system version --all --select nxos_ver_str
Fan-out runs concurrently (--workers N, default 10), streams one JSON object per device
({device, host, ok, data|error}), isolates per-device failures, and exits 15 if any
device failed.
Cookbook
nxstate vlan list --select vlanshowbr-vlanid,vlanshowbr-vlanname # project fields
nxstate route list --vrf default --limit 20 # bound output
nxstate neighbor list --protocol cdp --json | jq '.[].device_id' # pipe to jq
nxstate logging # raw text, fenced untrusted
nxstate debug "ip ospf" --allow-debug # gated control-plane read (warns)
nxstate tech-support --allow-tech # gated, large/slow
nxstate schema | jq '{tool, read_only, exit_codes, safety}' # self-description
Exit codes
0 ok · 2 usage / HOST_REQUIRED · 4 auth · 9 unreachable · 11 WRITE_REFUSED ·
13 input required · 14 parse unavailable · 15 partial (some devices failed). Full table:
nxstate schema.
Development
uv sync --extra dev
uv run pytest -q # offline; network stubbed, no device needed
uv run ruff check .
See CONTRIBUTING.md, SECURITY.md, and AGENTS.md.
Status
Implemented and live-verified against a Cisco DevNet Nexus 9000v sandbox (NX-OS 10.3(8)):
SSH (| json) + NX-API accelerator, structured device-error handling, fan-out with per-device
isolation, untrusted fencing, and the WRITE_REFUSED boundary all confirmed end-to-end.
License
Licensed under the MIT License.
Release files for nxstate 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nxstate-0.2.0.tar.gz | 21.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nxstate-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.2 kB
Release files / nxstate-0.2.0.tar.gz
| Download URL | nxstate-0.2.0.tar.gz |
|---|---|
| Size | 21.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6155e52816ce45b152917ba74a8718bf0bc9852690ee6066c5d6696f99cae497
|
|
BLAKE2b-256 checksum How to use checksums |
568db9bc2ab8b56f6fbab844616e931133dcedffcab65cdb8f1675631cb870bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / nxstate-0.2.0-py3-none-any.whl
| Download URL | nxstate-0.2.0-py3-none-any.whl |
|---|---|
| Size | 24.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a9e4c33f5c3c4bbdf9aba3df91775865c8785223561ca6990a9739226127bc28
|
|
BLAKE2b-256 checksum How to use checksums |
95cbf6d9f879ceea690184ae79e18af866a5f86459a07b76a9407ea91c46dd22
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|