CLI reference
Every hubzoid command and subcommand in Hubzoid 1.0.1, with usage lines, arguments, options, defaults and exit codes for each one.
The hubzoid command is installed with the package. python -m hubzoid runs the same CLI, which is useful from a source checkout. Every command accepts --help.
Conventions
- A Hub path argument defaults to
.(the current directory) unless the usage line shows it as required. Paths resolve against the directory you run the command from. - The Hub's
.envis loaded by the commands that build or serve the Hub, and it wins over variables already set in your shell. See configuration. - Commands that change access or runs (
grant,revoke,schedule pause,schedule resume,schedule cancel,backup) record the operator as the actor, for examplecli:aliceorcli:alice@build-host. - Exit code
0means success. Where a command defines other codes, they are listed with the command.
Command index
| Command | Purpose |
|---|---|
hubzoid init | Create a new Hub from a bundled template. |
hubzoid new workflow | Scaffold a code workflow in an existing Hub. |
hubzoid run | Serve one Hub: bridge, web chat, edge and optional surfaces. |
hubzoid gateway | Serve several Hubs behind one shared web chat. |
hubzoid slack | Run the Slack adapter or print its manifest and service unit. |
hubzoid inbound | Run the WhatsApp, Telegram and webhook receiver or print its service unit. |
hubzoid test | Send one prompt to the Hub's agent and print the reply. |
hubzoid doctor | Check a Hub and its deployment. |
hubzoid eval | Run and inspect the Hub's eval cases. |
hubzoid schedule | Inspect, fire, pause, resume and cancel scheduled work. |
hubzoid grant | Grant a permission to a person. |
hubzoid revoke | Revoke a permission. |
hubzoid access | Check, list, bootstrap, migrate and sync access. |
hubzoid audit | Show restricted tool decisions. |
hubzoid backup | Save a deployment's state to one archive. |
hubzoid restore | Put a backup back. |
hubzoid version | Print the installed version. |
Create a Hub
hubzoid init
Scaffold a new Hub folder from a bundled template.
hubzoid init [NAME] [--template minimal|demo|watchtower] [--model MODEL] [--force]Prop
Type
What it writes:
- Every file of the template into the Hub folder. Existing files are skipped unless you pass
--force. Runtime state (.hubzoid/,.openwebui-data/) is never copied. - A
.envwith a randomBRIDGE_API_KEYSvalue, created with mode0600.MODELis--modelwhen given. Otherwise, in an interactive terminal on a new Hub, Hubzoid detects authenticated localclaudeandcodexlogins, uses the only one it finds, or asks once when both are usable. Without either,MODEL=claude-local. - When the parent folder looks new (empty, or holding only dotfiles,
README.md,requirements.txt,LICENSE,LICENSE.mdor.env), a repository wrapper in the parent:requirements.txtpinned to the installed Hubzoid version,.gitignoreandREADME.md. Existing parent files are never overwritten, even with--force.
Run hubzoid init again in the same parent to add another Hub beside the first. An unknown template name exits with code 2 and lists the templates that exist. See templates.
hubzoid new workflow
Scaffold workflows/<name>/main.py with a runnable example workflow.
hubzoid new workflow NAME [HUB_DIR]Prop
Type
The generated file declares a manual workflow with @workflow(), reads and writes hub.state, and performs a side effect in a @step. It needs no model or outside service. The command prints the hubzoid schedule run line that runs it once. Add a schedule and timezone after you have tested its effects. The command exits with code 1 if the folder already exists. See code workflows.
Serve
hubzoid run
Start one Hub: the bridge, the web chat (Open WebUI), the public edge and any surfaces you ask for.
hubzoid run [HUB] [--port N] [--bridge-port N] [--host ADDR] [--no-ui] [--slack] [--whatsapp] [--telegram] [--webhook]Prop
Type
What starts, in order:
- The bridge on
127.0.0.1:<bridge-port>. The command waits up to 60 seconds for/healthzand exits with code1if the bridge does not come up. - The web chat on a loopback port. By default this is the public port plus 40000 (or plus 1 when that would pass 65000).
HUBZOID_OWUI_PORToverrides it. - The edge on
<host>:<port>. It forwards/artifactsand/portalto the bridge,/mcpwhenMCP_SERVER=true,/webhooks/<hub>when an inbound surface is enabled, and everything else to the web chat. - The Slack adapter and the inbound receiver as child processes, when requested and configured.
With HUBZOID_DISABLE_EDGE=1, no edge runs and the web chat binds the public port itself. Ctrl+C stops every child process. The command exits with code 2 when the Hub folder or its AGENTS.md is missing. See architecture and single server.
hubzoid gateway
Run one shared web chat over several Hubs, with one headless bridge per Hub.
hubzoid gateway HUB [HUB ...] [--port N] [--host ADDR] [--public-url URL] [--name NAME] [--data-dir DIR] [--launch-bridges | --no-bridges]Prop
Type
Behavior worth knowing:
- The gateway writes
<data-dir>/deployment.json. Bridges and operator commands discover it, so ahubzoid grantrun in any Hub folder lands in the store the gateway reads. - All bridges share one operational database,
sqlite:///<data-dir>/hubzoid-operational.db, unlessHUBZOID_OPERATIONAL_DBorDATABASE_URLis set. Workflow engine databases stay per Hub. A multi-Hub gateway refuses a SQLiteHUBZOID_DBOS_DB. - Each bridge runs as
hubzoid run <hub> --no-uiwith scheduled code workflows enabled. - Downloads route through
/b/<hub>/artifacts, MCP through/b/<hub>/mcpfor Hubs withMCP_SERVER=true, and the Console through/portal. - With
HUBZOID_GATEWAY_ADMIN_EMAIL,HUBZOID_GATEWAY_ADMIN_PASSWORDandWEBUI_AUTH=true, each Hub's model entry and team group are provisioned in the web chat at boot.
See gateway deployment.
hubzoid slack
Slack chat surface. The adapter uses Socket Mode, so it needs no public URL.
hubzoid slack run [HUB]
hubzoid slack manifest [HUB] [--format json|yaml]
hubzoid slack systemd [HUB] [--user USER] [--python PATH]| Subcommand | What it does |
|---|---|
run | Starts the adapter in the foreground. The Hub's bridge must already be running (hubzoid run). Reads SLACK_BOT_TOKEN and SLACK_APP_TOKEN from the Hub's .env and exits with code 2 when either is missing. |
manifest | Prints a Slack app manifest filled in from AGENTS.md to stdout. Paste it into Slack's app creation page. |
systemd | Prints a systemd unit for hubzoid-slack@<hub>.service to stdout. |
Prop
Type
See Slack.
hubzoid inbound
The receiver for WhatsApp, Telegram and the generic webhook.
hubzoid inbound run [HUB]
hubzoid inbound systemd [HUB] [--user USER] [--python PATH]| Subcommand | What it does |
|---|---|
run | Serves every configured surface on 127.0.0.1:HUBZOID_INBOUND_PORT (default 8100) under /webhooks/<hub>/. The bridge must already be running. Exits with code 1 when no surface is configured and 2 when the Hub has no AGENTS.md. |
systemd | Prints a systemd unit for hubzoid-inbound@<hub>.service to stdout. Takes the same --user and --python options as hubzoid slack systemd. |
hubzoid run --whatsapp, --telegram or --webhook starts the same receiver for you. See WhatsApp and Telegram and webhooks.
Test and check
hubzoid test
Send one prompt to the Hub's agent and print the reply. Runs in process, with no bridge or web chat.
hubzoid test [HUB] [--prompt TEXT] [--file PATH ...]Prop
Type
The backend follows the Hub's model: claude-local runs on the Claude Agent SDK, codex-local on local Codex, and anything else on the OpenAI Agents SDK. With --file, uploads and artifacts live in <hub>/.hubzoid/chats/cli-test/. A file larger than HUBZOID_MAX_UPLOAD_BYTES exits with code 2 before the model is called.
hubzoid doctor
Check a Hub and its deployment. Read only.
hubzoid doctor [HUB] [--json] [--skip-secret-fetch]Prop
Type
Exit codes: 0 when no check fails, 1 when any check fails, 2 when the Hub folder does not exist. Every check id is described in the doctor reference.
hubzoid eval
Run the Hub's eval cases from evals/*.md and inspect results.
hubzoid eval run [HUB] [--tag TAG] [--case GLOB] [--no-judge] [--judge-model MODEL] [--model MODEL] [--compare] [--quiet]
hubzoid eval list [HUB]
hubzoid eval status [HUB]
hubzoid eval explain HUB CASEProp
Type
| Subcommand | What it does |
|---|---|
run | Runs the selected cases through the Hub's own runtime and writes .hubzoid/evals/<timestamp>.json. Exits with code 1 when any case fails, 2 when a case file cannot be parsed, and 0 when there are no cases. |
list | Lists each case with its checks, tags and schedule. |
status | Shows the last run, its pass rate and the cases failing now. |
explain | Prints the prompt, full response, tool calls, each check's verdict and the judge's reasoning for one case from the last run. |
See evals.
Schedules and runs
hubzoid schedule
Inspect and control markdown tasks (schedule/*.md) and code workflows (workflows/<name>/*.py). Scheduled work fires inside the running bridge. These commands inspect it and act on it.
hubzoid schedule list [HUB]
hubzoid schedule status [HUB]
hubzoid schedule run HUB TASK [--timeout SECONDS] [--max-rounds N] [--model MODEL] [--dry-run]
hubzoid schedule pause HUB NAME
hubzoid schedule resume HUB NAME
hubzoid schedule cancel HUB RUN_ID| Subcommand | What it does |
|---|---|
list | One line per code workflow and markdown task (as md:<task>) with state, timezone, next run and the account it runs as, or cannot run: with the fix. Then markdown tasks with their cron in words, next fire time, last result and flags (script, model, commit, push). Webhook tasks show their trigger. Exits with code 1 when any task file is invalid. |
status | Code workflow state, next run and missed slots, the 20 most recent runs with status and duration, and each markdown task's first seen, last fired, last result and last run log. |
run | Fires one task or workflow now. See below. |
pause | Stops scheduled runs of one markdown task or code workflow until resumed. Runs already queued or running continue (use cancel). Manual runs still work. Recorded in the access audit. |
resume | Resumes scheduled runs. A markdown task that became due while paused runs once. Code workflows do not back-fill missed slots. |
cancel | Cancels a queued or running run by id. The run stops at its next step boundary. Work already done, such as a sent message or a pushed commit, is not undone. Recorded in the access audit. |
schedule run looks for a markdown task named TASK first. It runs on the Hub's workflow engine on the same one-at-a-time markdown queue as scheduled fires, so it never overlaps a scheduled run, and it ignores the cron and the idle gate. When no markdown task matches, it looks for a code workflow by folder or function name (hyphens and underscores are interchangeable) and runs it.
Prop
Type
Exit codes for schedule run: 0 when the task reported done or the workflow returned, 1 when the run failed or ended without finishing, 2 when no task or workflow matched or a workflow was given --timeout, --max-rounds or --model. See operating runs and markdown tasks.
Access
These commands act on the access store for the Hub, or on the shared store of a gateway when the Hub belongs to one. grant and revoke print the store they write to, with any password hidden. See access administration.
hubzoid grant
hubzoid grant SUBJECT PERMISSION [HUB_DIR] [--hub NAME] [--org]Prop
Type
Granting any tool permission also grants use_hub in the same Hub. The wildcard permission * is never grantable. New access for everyone signed in (the subject *) is refused and exits with code 1. An existing one can still be removed with hubzoid revoke '*' use_hub --hub <hub>. Scheduled work runs as an account, so grant the permissions a workflow needs to the account it runs as.
hubzoid revoke
hubzoid revoke SUBJECT PERMISSION [HUB_DIR] [--hub NAME] [--org]Takes the same arguments as grant. Revoking use_hub removes every permission the subject holds in that Hub. The command refuses to remove the last organization admin and exits with code 1.
hubzoid access
hubzoid access check SUBJECT [HUB_DIR] [--hub NAME]
hubzoid access list [HUB_DIR] [--hub NAME]
hubzoid access bootstrap [HUB_DIR] [--admin SUBJECT ...] [--authoritative]
hubzoid access migrate [HUB_DIR] [--from-owui URL] [--model-id ID] [--standalone-public] [--apply] [--remigrate]
hubzoid access diff [HUB_DIR] [--from-owui URL] [--model-id ID] [--standalone-public]
hubzoid access rollback BACKUP [HUB_DIR]
hubzoid access sync [HUB_DIR]| Subcommand | What it does |
|---|---|
check | Prints every permission a subject effectively holds in a Hub, including organization and public grants. |
list | Lists all grants as subject, permission and Hub. --hub limits the list to one Hub. |
bootstrap | First boot. Grants organization manage_access to each --admin once (idempotent). --authoritative makes the access store the authority for this Hub on a fresh install with nothing to migrate. |
migrate | Turns legacy access (identity/access.csv, plus Open WebUI groups and model access with --from-owui) into direct grants. A dry run by default. --apply performs the cutover. |
diff | Shows grants the migration plan would add (+) and stale grants in the store (-). A zero diff is the cutover gate. |
rollback | Restores an access snapshot written by migrate --apply. The snapshot must belong to the selected Hub. |
sync | Recomputes which Hubs each person can see and mirrors that into the web chat. The recovery path when a projection was missed. Exits with code 1 on error. |
Prop
Type
migrate --apply refuses to run without model evidence (--from-owui or --standalone-public), refuses an empty plan, writes a snapshot to .hubzoid/backups/access-<id>.json before it changes anything, and exits with code 1 unless the store matches the plan exactly afterwards. It exits with code 2 when the migration is blocked, when effective access would change, or when the Hub is already migrated and --remigrate is absent.
hubzoid audit
Show restricted tool decisions: who called which restricted tool, on which surface, and whether it was allowed.
hubzoid audit [HUB] [--limit N] [--user EMAIL] [--denied]Prop
Type
Each line shows the time, user, ALLOW or DENY, the tool, and the surface with the reason. The Console's Activity page shows the same decisions. See people and activity.
Operations
hubzoid backup
Save a deployment's databases, chat data and Hub state to one archive while chat keeps working.
hubzoid backup [HUB] [--out PATH] [--include-secrets] [--wait SECONDS]Prop
Type
New scheduled runs are held while the backup runs, and running ones finish first. Hub content (AGENTS.md, skills, knowledge) belongs in Git and is not included. PostgreSQL databases are not included either. The command names each one so you can back it up with pg_dump. The archive holds user accounts and chats, so store it like a secret. Exits with code 1 on error. See backup and restore.
hubzoid restore
Put a backup back. Stop the Hub or gateway first.
hubzoid restore ARCHIVE [--move OLD=NEW ...] [--dry-run]Prop
Type
Everything returns to its original path unless moved. Whatever is at a target now is kept beside it as <name>.pre-restore-<time>. When database passwords were left out of the saved deployment manifest, the command says so. Start the gateway before any bridge, because hubzoid gateway rewrites that manifest from its environment. Run hubzoid doctor after starting.
hubzoid version
hubzoid versionPrints the installed Hubzoid version.
Next steps
Observability
Watch a Hubzoid deployment through usage and cost in the Console, tool decisions with hubzoid audit, OpenTelemetry traces, logs and health checks.
Configuration reference
Every environment variable Hubzoid 1.0.1 reads, grouped by area, with its type, default and effect, and how the .env files are loaded.
