CLI reference
The cihub CLI manages your Companion Hub stack, apps, models, and CI Account registration from the terminal. It is bundled with the desktop app and Linux packages — there is no separate npm package.
Install
Install Companion Hub from ci.computer/download — see Installation. The cihub CLI comes with the desktop app and the Linux packages.
On first launch of the desktop app, cihub is copied to:
| Platform | Location |
|---|---|
| macOS / Linux | ~/.local/bin (or ~/bin) |
| Windows | %LOCALAPPDATA%\Companion Hub\bin |
Open a new terminal after first launch, then verify:
cihub --helpThe .deb package also links cihub to /usr/bin/cihub when you install it, so on a Linux headless server where you never opened the GUI it already works. If cihub isn’t found, use the bundled path directly:
/usr/lib/companion-hub/resources/cihub --helpnpm install -g ci-hub is not supported — the CLI is not published to the npm
registry. Install the desktop app or Linux package instead.
Quick reference
Every command group on this page, in one table. Details and flags follow in the sections below.
| Command | What it does | Section |
|---|---|---|
cihub wizard [env] | Guided setup: Docker check, registration, start | Setup & registration |
cihub setup [env] | Initialize Traefik and Docker auth; on a packaged install, seed the data folder | Setup & registration |
cihub register [env] [--code <code>] [--fresh] [--move] | Pair this Hub with your CI Account | Setup & registration |
cihub claim [env] [--email <addr>] | Create the first admin without a browser | Setup & registration |
cihub device-id [--from-hub] | Print this machine’s device ID | Setup & registration |
cihub up [env] [--detached|--attached], cihub down [env] | Start or stop the Hub stack | Hub lifecycle |
cihub restart [env], cihub recreate [env] [--yes] | Restart, or reset runtime state and start again | Hub lifecycle |
cihub status [env] | Containers and ports, Cloudflare tunnel state, Tailscale IP | Hub lifecycle |
cihub logs [env] [service], cihub config [env] | Stream compose logs; print resolved config values | Hub lifecycle |
cihub update [--check], cihub self-update [--to <version>] [--check] | Update the desktop app and stack; replace a standalone CLI binary | Updates |
cihub models list, install <model>, rm <model> | Manage models in an Ollama container (standard installs run Ollama on the host) | Models |
cihub app <list|status|logs|inspect|add|edit|start|stop|restart|delete|stop-managed|remove-managed> | Manage Docker containers on the host | App lifecycle |
cihub app start-all, stop-all, restart-all, update-all [env] | Run one action over every app, through the running Hub | App lifecycle |
cihub public-web status, repair | Diagnose and repair Public Web routing (source checkout only) | Public Web |
cihub mcp setup, shutdown, config | Turn the MCP setting on or off, or print it, in the current folder’s env file | MCP |
cihub connect openclaw, hermes | Wire a host-installed agent to Companion Memory | Connect an agent |
cihub api-key create, list | Mint and list the keys MCP clients use | API keys |
cihub login, logout, submit <dir> | Sign in to Portal and submit an app to the marketplace | Other command groups |
cihub pool ..., cihub fleet ... | Hub Pool inference pooling, and multi-machine installs over SSH | Other command groups |
cihub doctor [env] [--repair-networks] | Validate Docker, env files, bind mounts, registration, and compose inputs | Maintenance |
cihub clean, reset [--dry-run], uninstall | Remove generated files or runtime state; uninstall needs a source checkout | Maintenance |
cihub --help, cihub man, cihub version [--short] | Help and version | Help |
Environments
Most commands accept an optional environment argument. On a packaged install (desktop app or Linux package), up, down, reset, and clean always target your prod data directory regardless of the env name you pass, and cihub up runs detached unless you add --attached.
| Value | Env file | Compose files | When to use |
|---|---|---|---|
local (default in checkout) | .env.local | docker-compose.local.yml | Source-based development from a git clone |
dev | .env.dev | docker-compose.prod.yml | Dev appliance |
staging | .env.staging | docker-compose.prod.yml + staging overlay | Staging appliance |
prod | .env.prod | docker-compose.prod.yml | Explicit prod appliance from checkout |
# From a git clone (contributors):
cihub up local
cihub up dev --detached
cihub status prod
# From a packaged install (any directory):
cihub up --detached
cihub statusSetup & registration
cihub wizard [env]
Guided setup wizard. It needs an interactive terminal. On first run (no env file found), it enters FTUE mode: it asks for an environment, checks Docker, runs setup, starts the Hub, and asks for a pairing code, then offers to install a first model.
cihub wizardOn a packaged install the environment prompt has no effect — Hub always targets the prod install — so press Enter at it. Returning users get an action menu: setup, up, register, config, MCP, down, app-list, reset, restart.
cihub setup [env]
Initializes Traefik and Docker auth config for the target environment. On a packaged install with no data folder yet, it creates one, and asks you to choose a database password unless POSTGRES_PASSWORD is set.
cihub register [env]
Pairs this Hub with your CI Account. The Hub must be running. It prints your device ID and the hub.ci.computer registration URL, then asks for the six-character pairing code you generate in your CI Account.
cihub register --code ABC123| Flag | Effect |
|---|---|
--code <code> | Give the pairing code up front. Required when there is no terminal, such as over ssh -n; the command exits with code 2 instead of waiting |
--fresh | Clear leftover local registration data first, so the Hub registers as a new device |
--move | Confirm moving a Hub that belongs to another organization |
cihub claim [env] [--email <addr>]
Creates the Hub’s first admin without a browser. Run it on the Hub, after cihub register. It’s safe to re-run: a Hub that already has an admin is reported and the command exits 0. Then sign in through your CI Account with the same email address.
cihub claim --email you@example.comcihub device-id [--from-hub]
Prints this machine’s stable device ID. --from-hub asks the running Hub instead of resolving it locally.
Hub lifecycle
cihub up [env] [--detached] # start the hub stack
cihub down [env] # stop the hub stack
cihub restart [env] # restart the target environment
cihub recreate [env] [--yes] # reset runtime state, then start again (destructive)
cihub status [env] # containers and ports, tunnel state, Tailscale IP
cihub logs [env] [service] # stream compose logs
cihub config [env] # resolved config values (env file in the current folder)--detachedruns the stack in the background (equivalent todocker compose up -d). On a packaged installcihub upis already detached by default; add--attachedto stay in the foreground.cihub restartandcihub recreaterun in the foreground until you add--detached.- Before it starts the stack,
cihub upprints the Docker Compose and Docker Engine versions it found. Docker Compose older than 2.33 stops the start with a red Docker update needed box and exit code1. Docker Engine older than 28 prints a yellow Docker Engine update recommended box, and the start continues.restartandrecreaterun the same check;cihub up localdoesn’t. cihub upon a machine that has never run Hub asks you to choose a database password and creates the data folder. SetPOSTGRES_PASSWORD(orCIHUB_POSTGRES_PASSWORD) to skip the prompt.statusshows Containers (color-coded, with their published ports), Network (a dashboard line, the Cloudflare tunnel state, and the Tailscale VPN IP), and, only when Ollama runs as a container in the Hub’s Compose project, Models (installed Ollama models). Read the dashboard port from theci-hubcontainer row, which shows<host port>->5002/tcp: the Dashboard line prints5002unless your env file setsFRONTEND_PORTorBACKEND_PORT, and the Cloudflare line readsactiveornot configured.
Updates
cihub update [--check] # report CLI and stack versions, then update
cihub self-update [--to <version>] [--check] # replace a standalone cihub binary
cihub version [--short] # this CLI's version, then the running Hub's buildcihub update prints the CLI version next to the running stack’s version first, then hands the update to companion-hub update. That works when companion-hub is on your PATH, which a Linux package install does. On macOS and Windows only cihub is on your PATH, so cihub update reports that there is no desktop app here: update the app from Settings → System instead. cihub self-update only applies to a standalone cihub binary; it refuses when cihub came inside the desktop package or from a source checkout. See Updating Companion Hub.
Packaged / headless startup
companion-hub --detached # Linux headless, no GUI
cihub up --detached # same prod install, from any shellFor source-based local development:
cihub up localModels
cihub models list
cihub models install llama3.2
cihub models rm llama3.2These commands run the ollama command inside an Ollama container that belongs to the Hub’s Compose project. A standard Hub install doesn’t run one, because Hub uses the Ollama on your host. On such an install every cihub models command reports Ollama container not running and exits with code 1. Manage models with ollama list, ollama pull, and ollama rm on the host instead, or pick them in Settings → AI. See AI and inference.
App lifecycle
Manage Docker containers on the host, independently of the Hub compose stack:
cihub app list
cihub app status [name]
cihub app logs <name> [--tail N]
cihub app inspect <name>
cihub app add <name> <image> [--port h:c] [--env K=V]
cihub app edit <name> <image> [--port h:c] [--env K=V]
cihub app start <name>
cihub app stop <name>
cihub app restart <name>
cihub app delete <name>
cihub app stop-managed # stop every Hub-managed app container
cihub app remove-managed # remove every Hub-managed app containerThose commands drive Docker directly. To run one action over every app through the running Hub, so each app goes through the same steps as the dashboard’s Batch actions menu, use:
cihub app start-all [env] # start every stopped app
cihub app stop-all [env] # stop every running app
cihub app restart-all [env] # restart every running app
cihub app update-all [env] # update every app with a newer version, with a backup of each firstRun these on the Hub machine: they need the Hub running and the device key that Hub keeps in state/settings.json. They report that the Hub accepted the request, not that the apps finished; run cihub app status to watch them change state.
Public Web
Diagnose and repair the routing for apps whose Exposure mode is Public Web:
cihub public-web status [env]
cihub public-web repair [env] [--app <name>]These commands run only from a CI-Hub source checkout. On an installed Hub they stop with Run from a CI-Hub checkout. On an installed Hub, check the tunnel with cihub status and the Cloudflare Tunnel card in Settings → Network, and select Repair routing in the app’s settings to fix an app’s public route.
MCP
Hub’s MCP server for agent apps is on by default: Hub loads it unless MCP_ENABLED is false. These commands set or print that variable:
cihub mcp setup [env]
cihub mcp shutdown [env]
cihub mcp config [env]They read and write the env file in the current folder (.env.local by default), so use them from a source checkout. On an installed Hub they don’t read or change the Hub’s own env file, and cihub mcp setup creates a .env.local in the folder you run it from. You don’t need cihub mcp setup before creating an API key.
Connect an agent
Wire an agent installed on this host to Companion Memory, so it gets passive capture rather than memory tools it has to call:
cihub connect openclaw --memory-url <url> --memory-key <key>
cihub connect hermes --memory-url <url> --memory-key <key>| Flag | Effect |
|---|---|
--memory-url, --memory-key | Companion Memory base URL and an API key. Prompted for on a TTY |
--hub-url, --hub-key | Also register the Hub MCP server. Give both or neither |
--force | Claim the memory slot even if another provider holds it (openclaw) |
--dry-run | Print the plan and write nothing |
It probes every server you give it before touching disk, so a failed probe leaves the machine
exactly as it was. The memory probe checks the key, not just the address — it calls an endpoint
requiring the memory scope, so a key that would fail silently at capture time is refused up front.
For openclaw it backs up the agent’s config before editing and restores it on a failed write; for
hermes it stages the plugin, writes mcp_servers.hub when you pass the Hub flags, and hands the
memory credentials to hermes memory setup, which you still run to finish. It configures the
host it runs on — for an agent on another machine, follow the per-agent instructions in
Connect an existing agent.
API keys
Mint and list the keys an MCP client uses to reach the Hub. Run these on the appliance host:
cihub api-key create --name <label> [--scope mcp|qa:read|inference] [--capability read|write|full]
cihub api-key list| Flag | Values | Default |
|---|---|---|
--name | any label | required |
--scope (or --scopes) | mcp, qa:read, inference | mcp |
--capability | read, write, full | write |
mcp opens the MCP endpoint. qa:read is a read-only key for a test harness or monitor, and inference opens the OpenAI-compatible inference routes for an editor or SDK. Each of the last two must be the only scope on its key and is stored as read, so --capability write and full are refused for them.
The key is printed once, at creation, and cannot be retrieved afterwards. api-key list shows
IDs, names, scopes, capability and a prefix — never the key itself.
Choosing a capability, and connecting a client once you have a key, are covered in Connect an existing agent.
There is no subcommand for changing an existing key — create and list are the whole CLI surface.
Change a key’s capability from Settings → Security in the Hub dashboard instead.
Other command groups
cihub login [--device] [--org <slug>],cihub logout, andcihub submit [--dry-run] <dir>sign in to Portal and submit an app folder to the marketplace. See Submit with the CLI.cihub pool ...operates Hub Pool from the terminal — status, a read-onlydoctorpreflight, pairing, and routing across several Hubs. Its subcommands are listed in the Hub Pool command reference;cihub --helphas a Hub Pool group, andcihub pool --helpis not supported.cihub fleet ...installs and updates Hubs on other machines over SSH. Runcihub --helpfor the full list.
Maintenance
cihub doctor [env] [--repair-networks] # validate Docker, env files, bind mounts, registration, and compose inputs
cihub clean [env] [--yes] # remove generated host-state files for one environment
cihub reset [env] [--yes] [--dry-run] # remove runtime state for one environment
cihub uninstall [--yes] # full cleanup of Hub state (source checkout only)doctorstarts with a box that names the Hub it checks: Targeting prod install with the data folder on an installed Hub, or Targeting checkout with the checkout path. In a checkout the box turns yellow when the running Hub was started from another folder, and says where to runcihub doctorto check that Hub. It also compares the CLI and stack versions: acihubrun from a source checkout names no release, so doctor compares commits and a difference is only a note. And it fails a registered Hub that has no admin yet (runcihub claim). It probes the Hub’s own API port, Ollama, vLLM, and Lemonade, plus an MTPLX or speculative-inference server only when its URL is in the env file, and leaves off any service that isn’t listening on the host.resetis the wipe path for an installed Hub. It removes your installed apps, the Hub containers and volumes, the data folder, and the Hub’s tunnel token and registration files.--dry-runlists what would go without deleting it, and--yesskips the confirmation prompt. On an installed Hub,cihub reset --yesis how you remove the Hub’s data from the terminal. See Uninstalling.uninstallis the machine-wide wipe path for a source checkout. It needs to run from a CI-Hub repository directory, so on an installed Hub it stops withRun from a CI-Hub checkoutand exits with code2. Useresetthere.
On a packaged install, clean and reset are not partial: outside a
source checkout they wipe the whole prod install, including its data.
recreate resets runtime state too. Back up first — see Backup and
restore — and use reset --dry-run to see
what would be removed.
Help
cihub --help
cihub man
cihub versionFor running Hub without the desktop window, see Running Companion Hub.