b3iq CLI
Install the b3iq CLI to manage your machines, models, runtimes, logs, and SSH access from the terminal or a script.
The b3iq CLI manages your machines, models, runtimes, and SSH access from a
terminal or a script — the same account and endpoints as the HTTP APIs, wrapped
in commands built for humans and agents alike.
b3iq is the account-level CLI covered on this page — it talks to the
control plane and manages your whole fleet remotely. It's a different tool
from b3iq-host, the local daemon CLI that runs on a machine itself; see
CLI Commands for that one.
Install
bashnpm i -g @b3dotfun/b3iq-cli
Requires Node ≥ 20. Ships compiled, with zero runtime dependencies.
Sign In
Run b3iq login
With no arguments, login starts a browser device flow: the terminal
prints a short code and opens your browser to approve it.
Approve the code in the dashboard
Confirm the code matches what your terminal shows, then approve. The CLI
polls in the background and saves a personal access token to
~/.b3iq/config.json (mode 0600) once you approve.
Non-interactive / CI login
Pass a token directly — b3iq login --token <token> — or set
B3IQ_TOKEN in the environment; either skips the browser flow entirely.
Mint a token without the device flow under Settings → CLI tokens in
the dashboard.
b3iq logout forgets the saved token; b3iq logout --revoke also revokes it
server-side. Every token the CLI has minted — from login or from Settings —
is listed under Settings → CLI tokens, where you can revoke any of them
individually.
Command Reference
| Command | Purpose |
|---|---|
| b3iq login [--token <t>] | Sign in via the browser device flow, or non-interactively with --token / B3IQ_TOKEN |
| b3iq logout [--revoke] | Forget the saved token; --revoke also revokes it server-side |
| b3iq whoami | Show the signed-in account |
| b3iq status | Fleet overview: machines online and servable models |
| b3iq machines list [--quiet] | List your machines (--quiet ⇒ node ids only) |
| b3iq machines get <machine> | One machine's detail |
| b3iq models list [--machine <m>] | Servable models fleet-wide, or one machine's full install catalog with --machine |
| b3iq models install <model> --machine <m> [--no-wait] | Install a model onto a machine |
| b3iq models remove <model> --machine <m> [--no-wait] | Uninstall a model from a machine (also accepts: uninstall) |
| b3iq runtimes list [--machine <m>] | Engines a machine runs, with endpoint and whether it self-heals if it crashes |
| b3iq runtimes restart <runtime> --machine <m> [--no-wait] | Restart one runtime on a machine |
| b3iq logs [--limit N] [--follow] | Recent inference requests (default 50, max 200; --follow tails new ones) |
| b3iq ssh <machine> [-- cmd] | Open an SSH session, or run one remote command non-interactively |
| b3iq config [default-machine <id>] | View config, or set the default machine used when a machine argument is omitted |
| b3iq doctor | Check auth, API reachability, and cloudflared |
models install, models remove, and runtimes restart wait for the
change to finish by default — installs get up to 45 minutes since a model
download can run to many GB. Pass --no-wait to get the command id back
immediately instead of blocking.
Output Contract
- stdout is data, stderr is logs. Parse stdout and ignore (or surface) stderr — progress lines, spinners, and hints never touch stdout.
- JSON is automatic when piped. If stdout isn't a TTY, every command emits
JSON.
--jsonforces it anywhere;--prettyforces the human-readable table even when piped (the two flags can't combine).--quiet(-q) prints only ids, one per line, regardless of JSON mode — built forfor id in $(b3iq machines list --quiet)loops. - Exit codes are stable. Branch on them, not on message text:
| Exit code | Reason |
|---|---|
| 0 | ok |
| 1 | usage — bad arguments, or an ambiguous/missing machine selector |
| 2 | api — the request reached the API and failed |
| 3 | auth — not logged in, or the token was rejected |
| 4 | rate-limited |
Machine Selectors
Any <machine> argument accepts a node id, an id prefix, or a case-insensitive
substring of the machine's name. An exact id or name match always wins, so a
full id is never ambiguous; a substring that matches more than one machine
errors (exit 1) and lists the candidates.
Set a default so you can drop the argument entirely:
bashb3iq config default-machine <id>
Every command that resolves a machine falls back to the default when the
<machine> argument (or --machine) is omitted.
SSH Access
bashb3iq ssh <machine> [-- cmd]
Opens a session without you ever writing an SSH config or a ProxyCommand.
The CLI resolves the machine's SSH-lane hostname and connects through a
cloudflared-brokered tunnel as the b3iq user — install cloudflared locally
first (brew install cloudflared, or check with b3iq doctor).
The SSH lane has to be turned on for the machine first — enable it from the
machine's page in the dashboard. If it's off, b3iq ssh fails with a message
pointing you there.
Args after -- run non-interactively and forward straight to ssh:
bashb3iq ssh my-box -- nvidia-smi
In --json mode or when stdout isn't a TTY, b3iq ssh prints the resolved
ssh invocation instead of taking over the terminal — useful for an agent
that wants to inspect or reuse the command rather than open an interactive
shell.
Headless & Agent Use
The CLI is built to be driven by a script or an agent as easily as by a human — see the output contract above. A few recipes:
bashexport B3IQ_TOKEN=... # a personal access token; no login step neededb3iq status --json | jq .machines_onlineb3iq machines list --quiet # node ids, one per linefor id in $(b3iq machines list --quiet); do b3iq machines get "$id" --json | jq '{id:.node_id, up:.liveness}'doneb3iq models list --machine <id> --json # what a machine can serveb3iq ssh <machine> -- nvidia-smi # run one remote command, capture stdoutb3iq doctor --json # preflight: auth, API, cloudflared
No command changes state as a side effect of reading — ssh, login,
logout, and config are the only verbs that mutate anything.
Config
| Env var | Purpose |
|---|---|
| B3IQ_TOKEN | Personal access token; skips the browser login flow entirely |
| B3IQ_API_URL | Overrides the control-plane base URL (defaults to https://control-plane.b3iq.org) |
| B3IQ_ORG_ID | Scopes commands to an organization instead of your personal account |
Env vars always win over the saved config file (~/.b3iq/config.json, mode
0600), which in turn wins over the built-in defaults.

