> ## Documentation Index
> Fetch the complete documentation index at: https://docs.b3iq.org/llms.txt
> Use this file to discover all available pages before exploring further.

# 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.

**Not the host-agent CLI**

`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](/operations/cli-commands) for that one.

## Install

```bash
pnpm add --global @b3dotfun/b3iq-cli
```

Requires Node 22.23.4 or newer on 22.x, or 24.22.1 or newer on 24.x. The package ships a compiled executable; no B3IQ source
checkout or build toolchain is required.

**Published command support**

npm's current release is **0.1.1**, checked on October 12, 2026.
  Check your installation with `b3iq --version`. The [published package](https://www.npmjs.com/package/@b3dotfun/b3iq-cli)
  is separate from the repository's development version. Plugin management,
  command history, and hardware qualification commands described below are
  development additions, unavailable in 0.1.1. Native coding-client and media MCP
  commands are also unavailable in that release; they target 0.2.0 after
  qualification and publication. Installing the current package does not enable
  those commands.

## Get an evaluation package

There is no public preview download yet. To request a compiled evaluation package,
email [hello@b3iq.org](mailto:hello@b3iq.org?subject=B3IQ%20CLI%200.2.0%20evaluation%20package)
with the subject **B3IQ CLI 0.2.0 evaluation package**, your operating system and
intended coding client. Do not send an API key. Wait for an approved `.tgz` file,
its version/source revision and `SHA256SUMS`; no private repository access is needed.
Verify the tarball with `shasum -a 256 <file.tgz>` on macOS, comparing it with
`SHA256SUMS`, or `sha256sum --check SHA256SUMS` on Linux from the download directory.
Only after the checksum matches, run from the extracted tarball's directory:

```bash
pnpm add --global "@b3dotfun/b3iq-cli@file:$PWD/b3iq-cli-0.2.0.tgz"
b3iq --version
b3iq inference --help
b3iq mcp media --help
```

Use an absolute tarball path for this global install. `$PWD` supplies the current
directory; do not use `./b3iq-cli-0.2.0.tgz`. The explicit package name replaces
a prior preview entry even when its tarball was deleted. Keep the current tarball
in place until you replace it. An upgrade refused because the old tarball is
missing leaves the old CLI installed. Relaunch after a successful upgrade.

The package includes `NATIVE_AGENTS.md` with setup, client compatibility limits,
skills, media and rollback instructions. Preview tests do not establish complete
live coding, context, memory or media support. Anthropic does not officially support
non-Claude gateway models.

## Owned models in coding clients

### Prepare the serving context

The development `models context` command needs a qualified CLI build and a
host/inference release supporting `model.context.configure`; it is unavailable
in the published 0.1.1 package. It uses your machine-management personal access
token (`B3IQ_TOKEN`). Dashboard gateway keys remain inference-only.

```bash
b3iq models context 'YOUR_INSTALLED_MODEL' --machine 'YOUR_MACHINE' --json
```

For installed Ollama text models, this preserves an explicit operator window or
selects up to 131,072 tokens within the model maximum. It requires known hardware
capacity and tool support, checks runtime safety limits, allocates the window,
verifies it through [Ollama /api/ps](https://docs.ollama.com/api/ps), then saves it.
Automatic setup needs at least 32,768 tokens; Claude Code needs 100,000. Other
backends are refused until their allocation can be verified.

Use `--tokens <count>` to change an existing choice. The result includes
`previous_override_tokens`: restore a nonzero value with `--tokens`, or use
`--reset` for zero. Reset clears context while retaining other override metadata.
`--no-wait` returns a command ID for `commands get <id> --machine <id> --json`.
Allocation changes the model's RAM/VRAM budget and can evict idle Ollama models.
Run it when B3IQ chat traffic is idle. A failed verification or save leaves the
prior configuration effective; the attempted allocation can remain in memory.
Wait for `inference models --machine <id>` to report the verified window before
launching the client. Setup does not run `models context` for you. If the
personal machine list does not include the machine, the CLI says so and does not
offer `models context` as the next command. `B3IQ_ORG_ID` does not widen a
personal token to organization machines. An administrator who already manages
the machine can grant personal owner access on the staff Owners tab. A missing
match is not proof that grant is what you need, and it is not proof the id
does not exist.

On October 16, 2026, Codex Desktop setup for `qwen3.8:27b-bf16` on
`b3iq_a81534a5128404d7` stopped at a generic 32K refusal. Discovery had reported
a 4096-token window, image input, and tool calling. `models context` then said
`No machine matches` that id. The machine was organization-owned and absent from
the personal list. After a personal owner grant, the same context command
completed with `verified: true` and `context_window_tokens: 131072`. The current
text for those two failures is in the CLI's `NATIVE_AGENTS.md`.

### Launch the client

Customers use a distributed CLI package and a dashboard gateway key. They do not
need the private B3IQ repository or a source build. Once the approved 0.2.0 release
is available, install that version:

```bash
pnpm add --global @b3dotfun/b3iq-cli@0.2.0
b3iq --version
b3iq --help
```

Create an owned-machine gateway key at [Dashboard → API keys](https://b3iq.org/dashboard/keys)
and supply it as `B3IQ_GATEWAY_API_KEY` through your secret manager. This key is
separate from the personal access token used by machine-management commands.
Do not put it in command arguments or committed settings.

```bash
b3iq inference models
cd '/path/to/your/project'
b3iq inference codex --model 'YOUR_SERVED_MODEL_ID'
b3iq inference claude --model 'YOUR_SERVED_MODEL_ID'
b3iq inference opencode --model 'YOUR_SERVED_MODEL_ID'
```

Use the exact text-model ID returned by discovery. The gateway and serving host
must support the native-client endpoints and verified context/tool metadata; CLI
installation does not update them. These launchers configure terminal sessions.
Plain `codex` or `claude` continues using existing settings.
For one-time native activation, `b3iq inference setup codex --model ...` registers
an opt-in CLI profile and reports `codex --profile b3iq-...`. Claude setup reports
a native command with session-only settings, MCP and skill flags. Neither changes
normal user settings. These terminal setups do not add optional B3IQ entries to
the Codex or Claude desktop model menus. Do not merge the generated model/provider
settings into global configuration; that would change normal defaults.


The saved file `~/.b3iq/gateway-key` contains the same key created at
[Dashboard → API keys](https://b3iq.org/dashboard/keys); it is not a separate key.
If the key is not already in your environment, run this block in your own macOS
zsh terminal, then paste the key at the hidden prompt and press Return:

```zsh
{
  read -rs 'b3iq_gateway_key?Paste your B3IQ gateway key: '
  printf '\n'
  printf '%s' "$b3iq_gateway_key" | b3iq inference key-save
  unset b3iq_gateway_key
}
```

The CLI creates the directory and saves the key with mode `0600`; it does not
change client defaults. `B3IQ_GATEWAY_API_KEY` takes precedence over the saved file
when set. Verify discovery with `b3iq inference models`, adding
`--machine YOUR_PERMITTED_NODE_ID` to pin that request.

### Desktop deployment prerequisites

Wait for the updated control-plane and public gateway deployments before setup.
The Codex approval fix also requires the matching host and inference plugin
release on the serving machine. Merging source does not publish those binaries
or the npm package. Install a compiled CLI build containing the desktop commands
below and save the dashboard gateway key with `b3iq inference key-save`.
Desktop setup does not update the serving machine.

Codex's `--activate` opens a separate B3IQ instance. Claude's `--activate` saves
its provider choice and asks you to reopen Claude; `open -a Claude` does that on
macOS. Omitting `--activate` saves the setup without switching either app.

### Codex desktop: preserve normal defaults while B3IQ runs

On macOS, save a separate B3IQ desktop launcher after saving the gateway key:

```bash
b3iq inference setup codex --desktop --install \
  --model 'YOUR_SERVED_MODEL_ID' \
  --machine YOUR_PERMITTED_NODE_ID
```

The receipt's `activation_command` opens the separate instance. On later starts,
double-click `desktop_setup.installed_launcher` in Finder; it is saved under
`~/Applications`. Add `--activate` to the setup command to open it immediately.
Your normal desktop and plain `codex` keep their defaults while B3IQ is active.
The separate instance has its own settings and history. Select your local project
and the **B3IQ · model ID** entry there. Filesystem tools run on your computer.

Without `--install`, the shortcut stays in the private generated directory.
The instance uses workspace-write sandboxing and on-request approvals. It does
not copy normal account tokens, trusted projects, MCP settings, plugins or
approval rules. Keep its config and state separate from your normal Codex home.
The saved gateway key supplies inference and media credentials.

This integration is experimental. It uses separate engine and desktop data
paths exposed by the installed macOS app; the launcher checks for those settings
before opening it. Engine discovery and file-tool checks passed on desktop
26.1002.52244 / engine 0.162.0-alpha.2. One user-operated GUI mock test completed
onboarding, model selection and an exact-content local file write. Live Qwen,
real-key GUI inference and repeated GUI cold starts remain unqualified.
The normal desktop picker does not gain a B3IQ entry. For an app installed outside
`/Applications/ChatGPT.app` or `/Applications/Codex.app`, add
`--desktop-app '/absolute/path/to/Codex.app'`.

Keep the installed CLI and generated directories in place. Setup refuses to
replace user-edited files. To remove it, close the B3IQ instance and remove only
its reported shortcut and generated directory after saving needed conversations.
There is no normal-default restoration step and no local proxy to run.

### Claude desktop: save, activate and restore

The experimental desktop integration requires the updated control-plane and
frontend gateway deployments plus the compiled CLI containing these commands.
In our Desktop 2.37337.1 test, discovery rejected the real Qwen ID and accepted
an opaque routing alias. The dedicated endpoint uses that alias with an explicit
**B3IQ · real model ID** label; normal API clients keep the real served model ID.
Requests handled by this endpoint route to the selected owned model, with no
Anthropic inference fallback. This does not describe all background app traffic
or guarantee compatibility with other Desktop versions. Anthropic does not
support non-Claude gateway models. The tested desktop surface is Code with local
tools; Cowork and automatic large-context compaction are not qualified.

Save the gateway key using the stdin recipe above. On macOS, open **Help →
Troubleshooting → Enable Developer Mode**, then **Developer → Configure
Third-Party Inference** once to initialize the library. Quit Claude, then run:

```bash
b3iq inference setup claude --desktop --install \
  --model 'qwen3-coder-next:q8_0' --machine YOUR_PERMITTED_NODE_ID
```

Replace the placeholder with your full permitted machine ID. Setup fills the
model-specific endpoint, helper executable/arguments, machine header and model
entry. It saves a separate inactive configuration and preserves normal defaults.
Omit `--install` to export JSON only. The receipt's `desktop_setup.ui_fields`
contains exact values, including helper arguments as a copyable JSON array.
No API key is printed or embedded. Desktop setup and its `--saved` credential helper both use the saved key file, so a different terminal environment key cannot qualify the connection. Managed preferences can override local
configuration; automatic activation refuses managed devices.

Reopen the configuration window and select the reported name in the **top-right
saved-configuration dropdown beside Export**, initially labelled Default. Keep
Provider set to Gateway. Test script, model discovery and inference before use.
Do not click Apply Changes when only inspecting the inactive entry.

To activate explicitly, quit Claude and run:

```bash
b3iq inference setup claude --desktop --install --activate \
  --model 'qwen3-coder-next:q8_0' --machine YOUR_PERMITTED_NODE_ID
```

Reopen Claude normally, select your local project in Code, and confirm the
B3IQ-labelled model. The provider selection persists; no launch command is needed
on subsequent starts. This switches the desktop provider rather than adding Qwen
beside subscription models. Local files remain local; the GPU host serves inference.
To restore the provider recorded before activation, quit Claude and run:

```bash
b3iq inference restore claude --desktop
```

Restoration works offline, preserves new saved entries and unrelated preferences,
and handles an empty original Default configuration. It refuses to overwrite a
later user-selected configuration or a changed original entry. Manual Apply
Changes does not create the CLI's recovery journal. Use explicit CLI activation
when you want CLI-managed restoration.

| Connection field | Generated value |
| --- | --- |
| Provider / credential kind / auth scheme | Gateway / Helper script / Bearer |
| Gateway base URL | Model-specific URL, `https://b3iq.org/v1/claude-desktop/<encoded-model>`; copy the exact generated value |
| Helper script | Absolute Node executable from the installed CLI's receipt |
| Helper script arguments | Absolute installed CLI entrypoint, `inference`, `credential`, `--saved`, as separate entries |
| Custom inference headers | `x-b3iq-node-id` → your full permitted machine ID |
| Models | Generated alias and B3IQ/real-model label; 1M disabled, effort capped to low |
| Gateway API key / artifact preview iframe origin | Leave blank |
| Stream idle timeout | Default 300 seconds |

Claude appends `/v1/models`, `/v1/messages` and `/v1/messages/count_tokens` to the
base URL. The helper supplies the saved key through a private pipe; never run
`b3iq inference credential` in a captured terminal. Exports contain helper paths
and the machine routing ID. Claude's sensitive-values warning includes that
header; a manually entered static key would also appear in an export.

The model must be serving text/tool calling with at least 100K configured context;
the tested Qwen profile uses 131,072. Output is capped at 8,192. The catalog reports
the served window, but Code may still display 200K. Token counting returns a
conservative byte-based estimate including tools, not exact tokenizer usage.
Actual response usage is unchanged. Compact early on long conversations;
automatic compaction at the served boundary needs desktop acceptance.

Setup refuses an incompatible gateway before saving. For a 404, verify the exact
machine ID, key node scope and serving metadata; a typo can fail with a valid key.
[Anthropic's configuration reference](https://claude.com/docs/third-party/claude-desktop/configuration)
and [model guide](https://claude.com/docs/third-party/claude-desktop/models) explain
provider settings and labels. The packaged `NATIVE_AGENTS.md` includes the full
installation and rollback instructions without requiring a source checkout.

OpenCode setup defaults to major version 2; use `--client-version 1` for a version
1 client. For OpenCode desktop, save the gateway key privately and explicitly
install persistent settings:

```bash
printf '%s' "$B3IQ_GATEWAY_API_KEY" | b3iq inference key-save
b3iq inference setup opencode --desktop --install --model 'YOUR_SERVED_MODEL_ID'
```

This merges B3IQ provider/media MCP settings into OpenCode's global JSON/JSONC
configuration and reports a private backup when a config already exists. It
preserves default models, built-in agent settings, other providers and permissions. Restart the app and its background
server if necessary, open your own project, and choose B3IQ's exact model ID.
The saved key works without a terminal environment. OpenCode's native instruction
and skill discovery remains available, including `~/.agents/skills` and project
skills. The packaged guide covers versions, overrides and rollback. GUI selection
and real-model behavior require separate live verification.


## 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, whether 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 from a terminal; print the ssh invocation when piped |
| ` 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 |

**Long-running installs and restarts**

`models install`, `models remove`, and `runtimes restart` wait for the change
  to finish by default. Model installs get up to 45 minutes since a download
  can run to many GB. Pass `--no-wait` to get the command ID back immediately.
  In 0.1.1, inspect its state on the machine's dashboard page; `commands get`
  is not available. A timed-out wait does not cancel the queued operation, so
  check its state before retrying.

A machine boots with monitoring only. Models and runtimes belong to the
`inference` plugin, so `models list --machine` and `runtimes list` are empty
until it is installed.

## Development additions

The repository's 0.2.0 source adds the commands below. They are not in the
published 0.1.1 package. Do not use them in automation against that release.
For provisioning or command progress, use the [machine dashboard](https://b3iq.org/dashboard/nodes)
or ask the B3IQ team.

| Development command | Purpose |
| --- | --- |
| ` b3iq machines qualify <machine> [--no-wait] ` | Re-run hardware qualification |
| ` b3iq machines guests <machine> [--quiet] ` | A KVM host's guests and cards: every guest for its owner, your own guest on one you rent |
| ` b3iq plugins list [--machine <m>] ` | List available or installed plugins |
| ` b3iq plugins install <plugin> --machine <m> [--no-wait] ` | Install a plugin |
| ` b3iq plugins remove <plugin> --machine <m> [--no-wait] ` | Remove a plugin and what it installed |
| ` b3iq commands list --machine <m> [--limit N] ` | List recent commands |
| ` b3iq commands get <command-id> --machine <m> ` | Read command status, progress, and result |

## 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. `--json` forces it anywhere; `--pretty` forces 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 for
  `for 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:

```bash
b3iq 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

```bash
b3iq 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`). A machine in
a B3IQ facility is reached through a jump host instead, which needs no
`cloudflared`.

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 `--` forward straight to `ssh`. From a terminal, a trailing
command runs on the machine and returns:

```bash
b3iq ssh my-box -- nvidia-smi
```

In `--json` mode or when stdout isn't a TTY, `b3iq ssh` prints the resolved
`ssh` invocation and runs nothing, the trailing command included. A script or
an agent runs the printed invocation itself:

```bash
b3iq ssh my-box --json -- nvidia-smi > ssh.json
eval "ssh -o BatchMode=yes $(jq -r '.ssh_args | @sh' ssh.json)"
```

The JSON carries `transport`, `hostname`, `user` and `ssh_args`.
`BatchMode=yes` makes `ssh` fail instead of asking for a password.

On a KVM host you rent, each rental runs in its own virtual machine with every
GPU, and `b3iq ssh` opens yours: it logs in as the user your virtual machine
was created with (`renter`), and the JSON adds `guest_id`. The host is not in
`b3iq machines list`, because it stays its owner's; `b3iq ssh` and
`b3iq machines guests` find it among your rentals.

## 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:

```bash
export B3IQ_TOKEN=...                     # a personal access token; no login step needed

b3iq status --json | jq .machines_online
b3iq machines list --quiet                # node ids, one per line
for id in $(b3iq machines list --quiet); do
  b3iq machines get "$id" --json | jq '{id:.node.node_id, up:.liveness, state, serving}'
done

b3iq models list --machine <id> --json    # what a machine can serve
b3iq runtimes list --machine <id> --json  # its serving runtimes
b3iq doctor --json                        # preflight: auth, API, cloudflared
```

`machines get --json` nests the node record, so the id is `.node.node_id`.
The rows of `machines list --json` carry `node_id` at the top level.

No command changes state as a side effect of reading. These change a machine:
`models install`, `models remove`, and `runtimes restart`. The development-only
plugin and qualification commands also change machine state. `login`, `logout`
and `config` manage local credentials/configuration; `logout --revoke` also
revokes the token server-side.

The CLI package ships an `AGENTS.md` with the full agent guide: setup, the
fields to read before trusting a machine, and the commands that block.

## 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. A personal access token is personal-scope, so it is refused with one (exit 3) |

Env vars always win over the saved config file (`~/.b3iq/config.json`, mode
`0600`), which in turn wins over the built-in defaults.

## Related

**[Hosted Gateway](/developers/hosted-gateway)**

The same account and machines, reachable over HTTP for application code.
  **[Organizations](/developers/organizations)**

Roles and capabilities that govern what a member can do with org machines.