netbox-cli is an API-first NetBox client that supports both:
- direct command execution (
nbx dcim devices get --id 1) - interactive Textual TUI (
nbx tui)
The project is bootstrapped from CLAUDE.md requirements:
- API-only integration with NetBox (no model access)
- async HTTP via
aiohttp - shared backend logic for CLI and TUI
- OpenAPI-driven command/resource discovery
- automatic TUI discovery for plugin REST resources under
/api/plugins/
The fastest way to try netbox-cli — one command installs everything and connects to the public demo.netbox.dev instance.
Install:
# Debian/Ubuntu — install curl if not present
sudo apt-get update && sudo apt-get install -y curl
curl -fsSL https://raw.githubusercontent.com/emersonfelipesp/netbox-cli/main/install.sh | bashThe script installs uv if not present, fetches netbox-cli directly from this GitHub repository, and sets up Playwright Chromium for the demo login flow.
Reload your shell after install (the installer runs in a subshell, so PATH changes need to be applied):
source ~/.bashrc # bash
source ~/.zshrc # zshIf nbx is still not found, run it directly by full path as a fallback:
~/.local/bin/nbx --helpAuthenticate with the demo instance:
nbx demo init
# enter your demo.netbox.dev username and password when promptedOr non-interactively (CI / scripted):
nbx demo init --username <your-demo-user> --password <your-demo-password>Run CLI commands against demo.netbox.dev:
nbx demo dcim devices list
nbx demo dcim sites list
nbx demo ipam prefixes list
nbx demo circuits circuit-terminations get --id 15 --trace-onlyLaunch the interactive TUI:
nbx demo tuiUse / to search, g to focus the nav tree, q to quit. All commands that work under nbx demo … are available inside the TUI with the same demo profile.
If your NetBox instance has plugins with a full REST API implementation, the TUI can discover their /api/plugins/... resources automatically and render them in navigation without extra configuration.
cd <path-to-netbox-cli>
uv tool install --force .Preferred (uv tool):
uv tool install --force <path-to-netbox-cli>
nbx --helpIf nbx is not found, ensure your shell PATH includes ~/.local/bin.
For bash:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
nbx --helpFor zsh:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
nbx --helpAlternative (repo-local maintenance environment):
cd <path-to-netbox-cli>
uv sync --dev
uv run nbx --helpThis keeps a project-managed environment for development tasks. The main end-user install path remains uv tool install.
Contributor standard:
cd <path-to-netbox-cli>
uv sync --dev
uv run pre-commit install --hook-type pre-commit --hook-type pre-push
uv run pre-commit run --all-filesCommits and pushes should go through pre-commit, which runs Ruff linting and formatting locally and in GitHub Actions.
nbx init
# prompts for base URL, token key, token secret, timeoutIf configuration is missing, nbx will prompt for host/token credentials automatically before executing commands (including nbx tui).
Demo profile bootstrap:
nbx demo initThis always targets https://demo.netbox.dev/, opens the NetBox login flow in Playwright, prompts for demo username/password in the terminal, creates a fresh API token, and stores that token in the separate demo profile.
Install the Playwright browser first if you want browser-based demo bootstrap:
uv tool run --from playwright playwright install chromium --with-depsIf you already have a demo API token, you can skip Playwright entirely:
nbx demo --token-key <key> --token-secret <secret>The normal nbx profile and the nbx demo profile are stored separately in the same config file.
Stored config path:
$XDG_CONFIG_HOME/netbox-cli/config.json- or
~/.config/netbox-cli/config.json
Environment overrides:
NETBOX_URLNETBOX_TOKEN_KEYNETBOX_TOKEN_SECRET
Authentication is v2-token only and sent as:
Authorization: Bearer nbt_<KEY>.<TOKEN>
nbx dcim devices list
nbx dcim devices get --id 1
nbx ipam ip-addresses create --body-json '{"address":"192.0.2.10/24","status":"active"}'
nbx dcim devices list -q name=switch01This path is now fully registered as real Typer subcommands generated from OpenAPI, so --help works at each level:
nbx dcim --help
nbx dcim devices --help
nbx dcim devices get --helpDemo mode uses the same command tree against https://demo.netbox.dev/:
nbx demo dcim devices list
nbx demo ipam prefixes list
nbx demo tuiSupported action aliases:
list -> GETget -> GET(requires--id)create -> POSTupdate -> PUT(requires--id)patch -> PATCH(requires--id)delete -> DELETE(requires--id)
nbx call GET /api/status/
nbx call POST /api/ipam/ip-addresses/ --body-file ./payload.jsonnbx groups
nbx resources dcim
nbx ops dcim devicesnbx tuiTheme options:
nbx tui --theme # list available themes
nbx tui --theme dracula # start with Dracula
nbx tui --theme netbox-lightYou can also switch theme live from the top-left Theme dropdown in the TUI.
Theme contract:
- every Textual widget and subcomponent must inherit its visual styling from the active theme
- never hardcode runtime colors in Python or TCSS outside
netbox_cli/themes/*.json - do not opt into builtin Textual widget palettes when they override the repo theme tokens
- if a widget needs a custom state, express it with semantic variables and theme-backed component classes
Textual composition contract:
- use React-style composition for Textual UI work: small reusable widgets, explicit constructor props, nested
compose()trees - prefer composition over inheritance for layout reuse
- extract shared primitives into
netbox_cli/ui/widgets.py - standard reusable controls should expose semantic arguments instead of ad-hoc class combinations
- pass theme-aware styling intent through semantic props such as
tone,surface, andsize
Themes are loaded dynamically from:
netbox_cli/themes/
Built-ins:
netbox_cli/themes/netbox-dark.jsonnetbox_cli/themes/dracula.jsonnetbox_cli/themes/netbox-light.json
To add a custom theme, place <theme>.json in that folder. It will be auto-discovered.
Strict validation rules:
- required top-level keys:
name,label,dark,colors - optional keys:
variables,aliases colorsmust define:primary,secondary,warning,error,success,accent,background,surface,panel,boost- all color values must be
#RRGGBB - unknown keys, malformed colors, duplicate names, and alias conflicts fail fast with clear errors
TUI behavior (initial bootstrap):
- shell layout inspired by NetBox web UI:
- top quick-search bar
- left navigation tree (group -> resource)
- main tabbed workspace (
Results,Details) plus filter dialogs - footer status/help
- results view with incremental async refresh and row selection tracking
- details view rendered as panelized object attributes
- filters view with field picker + filter modal
- persisted last context/filter in local TUI state
Useful TUI keys:
/: focus searchg: focus navigations: focus results tabler: refresh current resourcef: open filter modalspace: toggle row selectiona: toggle select all visible rowsd: jump to details tabq: quit
netbox_cli/config.py: config storage + env overridesnetbox_cli/schema.py: OpenAPI loading and indexingnetbox_cli/api.py: asyncaiohttpclientnetbox_cli/services.py: shared request resolution and action mappingnetbox_cli/cli.py: Typer entrypoint (CLI + dynamic parser)netbox_cli/ui_common.tcss: shared visual design layer for both Textual appsnetbox_cli/ui/dev_app.py: request-workbench Textual appnetbox_cli/ui/app.py: shell-style Textual appnetbox_cli/ui/panels.py: panel widgets for detail renderingnetbox_cli/ui/widgets.py: shared composition primitives for Textual widgetsnetbox_cli/ui/state.py: persisted TUI view statenetbox_cli/tui.py: compatibility wrappernetbox_cli/dev_tui.py: compatibility wrapper for the dev TUI
This is the initial bootstrap version. It establishes the architecture needed to mirror NetBox UI workflows over time while keeping CLI and TUI parity on top of the same API execution layer.