Hubzoid
Reference

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 .env is 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 example cli:alice or cli:alice@build-host.
  • Exit code 0 means success. Where a command defines other codes, they are listed with the command.

Command index

CommandPurpose
hubzoid initCreate a new Hub from a bundled template.
hubzoid new workflowScaffold a code workflow in an existing Hub.
hubzoid runServe one Hub: bridge, web chat, edge and optional surfaces.
hubzoid gatewayServe several Hubs behind one shared web chat.
hubzoid slackRun the Slack adapter or print its manifest and service unit.
hubzoid inboundRun the WhatsApp, Telegram and webhook receiver or print its service unit.
hubzoid testSend one prompt to the Hub's agent and print the reply.
hubzoid doctorCheck a Hub and its deployment.
hubzoid evalRun and inspect the Hub's eval cases.
hubzoid scheduleInspect, fire, pause, resume and cancel scheduled work.
hubzoid grantGrant a permission to a person.
hubzoid revokeRevoke a permission.
hubzoid accessCheck, list, bootstrap, migrate and sync access.
hubzoid auditShow restricted tool decisions.
hubzoid backupSave a deployment's state to one archive.
hubzoid restorePut a backup back.
hubzoid versionPrint 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 .env with a random BRIDGE_API_KEYS value, created with mode 0600. MODEL is --model when given. Otherwise, in an interactive terminal on a new Hub, Hubzoid detects authenticated local claude and codex logins, 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.md or .env), a repository wrapper in the parent: requirements.txt pinned to the installed Hubzoid version, .gitignore and README.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:

  1. The bridge on 127.0.0.1:<bridge-port>. The command waits up to 60 seconds for /healthz and exits with code 1 if the bridge does not come up.
  2. 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_PORT overrides it.
  3. The edge on <host>:<port>. It forwards /artifacts and /portal to the bridge, /mcp when MCP_SERVER=true, /webhooks/<hub> when an inbound surface is enabled, and everything else to the web chat.
  4. 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 a hubzoid grant run in any Hub folder lands in the store the gateway reads.
  • All bridges share one operational database, sqlite:///<data-dir>/hubzoid-operational.db, unless HUBZOID_OPERATIONAL_DB or DATABASE_URL is set. Workflow engine databases stay per Hub. A multi-Hub gateway refuses a SQLite HUBZOID_DBOS_DB.
  • Each bridge runs as hubzoid run <hub> --no-ui with scheduled code workflows enabled.
  • Downloads route through /b/<hub>/artifacts, MCP through /b/<hub>/mcp for Hubs with MCP_SERVER=true, and the Console through /portal.
  • With HUBZOID_GATEWAY_ADMIN_EMAIL, HUBZOID_GATEWAY_ADMIN_PASSWORD and WEBUI_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]
SubcommandWhat it does
runStarts 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.
manifestPrints a Slack app manifest filled in from AGENTS.md to stdout. Paste it into Slack's app creation page.
systemdPrints 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]
SubcommandWhat it does
runServes 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.
systemdPrints 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 CASE

Prop

Type

SubcommandWhat it does
runRuns 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.
listLists each case with its checks, tags and schedule.
statusShows the last run, its pass rate and the cases failing now.
explainPrints 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
SubcommandWhat it does
listOne 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.
statusCode 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.
runFires one task or workflow now. See below.
pauseStops 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.
resumeResumes scheduled runs. A markdown task that became due while paused runs once. Code workflows do not back-fill missed slots.
cancelCancels 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]
SubcommandWhat it does
checkPrints every permission a subject effectively holds in a Hub, including organization and public grants.
listLists all grants as subject, permission and Hub. --hub limits the list to one Hub.
bootstrapFirst 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.
migrateTurns 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.
diffShows grants the migration plan would add (+) and stale grants in the store (-). A zero diff is the cutover gate.
rollbackRestores an access snapshot written by migrate --apply. The snapshot must belong to the selected Hub.
syncRecomputes 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 version

Prints the installed Hubzoid version.

Next steps

Read this page as Markdown

Choose which cookies Hubzoid can use. You can change this at any time from Cookie settings in the footer. Read the Cookie Policy for details.