CLI reference
Every hostssh command the agent binary dispatches — purpose, key flags, exit codes, and what each does — grounded in agent/internal/cli/cli.go.
CLI reference
The hostssh agent is the CLI: one static Go binary whose first argument
selects a command. This page enumerates every command the dispatcher actually
implements, grouped by area, with the flags each parses. It is a code-grounded
reference — the source of truth is
agent/internal/cli/cli.go, where Run()
switches on args[0] and each cmd* function declares its own flag.FlagSet.
For the four-surface philosophy (CLI ⇄ REST ⇄ MCP ⇄ dashboard parity) see API & CLI; for the wire the agent daemon speaks see Agent protocol.
How dispatch works
Run(args) (cli.go) is the entry point:
- With no args it prints usage and exits
0. - It calls
enforceLicense(args[0])— see Licensing. - It switches on
args[0]to the matchingcmd*handler. - Unknown commands print usage to stderr and exit
2.
Add --json to the read commands (status, doctor, fleet, audit, drill,
and transfer --new-key) for machine-readable output. Not every command takes
--json — only the ones noted below.
Honesty note.
clone,migrate, andprovisionare advertised in the binary's own usage text but are not implemented in this build. Invoking any of them prints`hostssh <cmd>` is on the roadmap and not in this build yet.and exits3(see thecase "clone", "migrate", "provision"arm inRun()). They are documented here as roadmap so the usage text and this page agree.
Licensing & exit codes
enforceLicense (cli.go) gates a fixed set of licensed features —
gatedCommands in the source: deploy, db, mcp, clone, migrate,
transfer, provision, ssh. Recovery (capture, restore) and all
read/admin commands are deliberately not gated — your data is never held
hostage.
| Status | Behavior |
|---|---|
| Active | command runs |
| Grace (offline) | command runs; prints ⚠ HostSSH offline grace: ~N day(s) left |
| Blocked | prints how to recover + activate, exits 12 |
Other exit codes seen across handlers: 0 success · 1 command failed ·
2 usage/flag error · 3 advertised-but-unimplemented (clone/migrate/provision) ·
12 license-denied. doctor exits 1 if any check is fail, else 0.
Lifecycle — agent, status, doctor, version, help, license
| Command | Purpose | Key flags |
|---|---|---|
hostssh agent | Run the long-lived daemon (the systemd service). Starts the heartbeat, job-drain, Web-SSH poll, and daily reaper goroutines and serves /healthz, /events, /logs on cfg.Listen. | --config PATH |
hostssh status | Health + identity: version, host, state, control plane, listen, channel. | --json, --config PATH |
hostssh doctor | Check local prerequisites and env wiring — config readable, control-plane HTTPS, license token, mTLS cert/key, docker, hostpack, BuildKit (BUILDKIT_HOST), reachability (public vs private/CGNAT), cloudflared (named tunnel + systemd), engine scripts, cleanup policy. | --json, --config PATH |
hostssh version (-v, --version) | Print hostssh <Version>. | — |
hostssh help (-h, --help) | Print the usage block. | — |
hostssh license activate | Activate a key against the control plane; writes the client cert/key + config and starts the offline-grace clock. Only activate is implemented (no status/transfer subcommand in this build). | --key KEY (required), --api URL (default https://api.hostssh.com), --config PATH |
doctor is the fastest triage: it never mutates anything, and a fail row
(e.g. missing engine scripts or an unreachable BUILDKIT_HOST) is what exits 1.
Warnings (e.g. cloudflared absent, private/CGNAT-only addresses) are non-fatal — a Node that
never exposes a port doesn't need a tunnel. The agent is pull-only. See
tunnel-first join.
Deploy — deploy, db, proxy, logs
| Command | Purpose | Key flags |
|---|---|---|
hostssh deploy | Build → run → route an app through the agent's own pipeline (HostPack/Dockerfile build, Docker run, Traefik route). | --name (required), --source (default .), --ref, --domain, --port (default 3000), --readiness-path, --network (default hostssh), --builder (hostpack|dockerfile|image, default hostpack), --image (alias for --source when builder=image), --image-limit-mb, --gpu (all|<count>|<ids e.g. 0,1> — reserve GPUs, needs a GPU node; see GPU support), --migrate, --verify, --command, --slot, --slot-size (s|m|l|xl), --env-file, --env K=V (repeatable), --volume name:/path, plus a trailing -- CMD ARGS argv run verbatim after the image entrypoint |
hostssh db create | Provision a managed database container on this Node. Postgres provisions pgvector by default; the DATABASE_URL is stored in the on-host secret store. | --engine (default postgres; valid set from database.Engines()), --name (required), --network (default hostssh), --version, --force (destroy + recreate — data loss) |
hostssh proxy up|down|status | Manage the Node's edge proxy (Traefik + automatic Let's Encrypt). up is idempotent. | --network (default hostssh), --acme-email (or HOSTSSH_ACME_EMAIL; enables TLS), --staging (LE staging CA), --force (recreate to apply changed config) |
hostssh logs <app> | Stream a container's logs via the Docker runtime. | --follow, --tail N (default 200, 0 = all) |
Notes grounded in cli.go:
--builderresolves indeploy.go:imageruns a prebuilt image from--source;dockerfilebuilds from a Dockerfile in the source (also auto-detected when a Dockerfile is present); otherwise HostPack builds from source.--slot-sizeresolves CPU/memory/pids caps viaslotCaps(), which mirrors the control-planeslotCapsresolver (base 0.5 vCPU / 512 MB / 256 pids per unit;s=1,m=2,l=4,xl=8).--slotalone only sets thehostssh.slotlabel; caps stay unbounded without--slot-size.--env-fileloadsKEY=VALUElines (blank/#lines skipped,export+ quotes stripped, only the first=separates) as the base env;--envflags override it. Parsing is strict — a line that isn't a validKEY=VALUEfails the deploy with the file and line number rather than being skipped, and the deploy prints how many vars it loaded so a partial env is visible. It works with or without a trailing newline; note that appending to a file that lacks one glues your new var onto the previous value (LAST=valNEW_VAR=x) — check the printed count against what you expect.--readiness-pathis probed from the host before the deploy is accepted, and becomes the Traefik active healthcheck path for the route (G24). Give it a cheap endpoint (/api/version), not the SSR homepage. Without it the healthcheck stays/.proxyparses its subcommand before the flags —proxy up --acme-email Xworks because the handler pullsupoff first (a Goflagquirk noted in the source).
For how env and secrets actually reach the container, see Environment variables & secrets.
Backup — capture, restore, drill, retention, prune, audit
| Command | Purpose | Key flags |
|---|---|---|
hostssh capture | Capture this server to an encrypted .hsi image via the capture engine, then (best-effort) register the snapshot in the control-plane ledger. Never license-gated. | --tag clone-<name> (normalized), --note NOTE, plus positional [box-name [note]] |
hostssh restore | Restore this server from an image via the restore engine. Never license-gated. | (passed through to engine.Restore) |
hostssh drill | Run a real restore into an isolated scratch directory, verify that files materialized, clean the scratch data, and persist the evidence for telemetry. Use --mode check only for a repository-integrity diagnostic; it does not prove restore. | --mode restore|check (default restore), --tag, --include, --scratch, --restic BIN, --sample PCT (check only), --json |
hostssh retention get|set|preview|apply | Show / configure / preview / enforce the image-retention policy. Defaults to keep-all; set with no keep flags stays keep-all (never silently configures unbounded deletion). | --tag, --keep-all, --keep-last N, --keep-daily N, --keep-weekly N, --keep-monthly N, --restic BIN |
hostssh prune | Reclaim Docker disk: keep last-N images per app, drop dangling images, bound the build cache. Volumes are never pruned. | --keep-last, --builder-gb, --builder-until-hours, --dry-run (preview only) |
hostssh audit (audit verify) | Show or verify the tamper-evident action log. verify checks internal chain consistency (local check only). | --json |
Notes:
capturebuilds an engine arg plan (capturePlan) from the tag/box/note, runsengine.Capture, thenregisterCapturedImagePOSTs the snapshot to the ledger. Registration failure is non-fatal — the capture already succeeded.prunedefaults come from env (HOSTSSH_KEEP_LAST,HOSTSSH_BUILDER_KEEP_GB,HOSTSSH_BUILDER_UNTIL_HOURS) viareaper.PolicyFromEnv(); the flags override per run. The same reaper runs daily insidehostssh agentand is available as theprunejob kind.auditis powered byaudit.Verify(); most write commands callauditLogto append a best-effort entry (a write failure warns but never aborts the action).
Access — access, ssh, transfer
| Command | Purpose | Key flags |
|---|---|---|
hostssh ssh <node-fingerprint> | Open an interactive shell on a fleet Node through the control plane's Web-SSH relay — no inbound port. Mints a session, dials the relay, raw-mode bridges the local terminal ⇄ the node's PTY. License-gated. | --config PATH, --relay wss://… (override) |
hostssh access connect | Run one outbound Web-SSH session directly (dial relay, open host PTY, bridge). The daemon normally drives this from its poll; the CLI form is for testing/manual use. | --relay, --sid, --token, --shell |
hostssh transfer --new-key | Mint a one-time, scope-locked peer transfer key (Mode 2 source side); persists its hash to the keyring for exactly-once redemption. License-gated. | --scope (server|<account>), --endpoint host:port (repeatable), --ttl (default 15m), --relay, --json, --config PATH |
hostssh transfer --serve | Run the source peer endpoint (HTTPS) that redeems presented keys once and streams the scoped image from --capture-cmd. Prints its SPKI pin for the target to pin. | --tls-cert, --tls-key (required), --capture-cmd (required), --listen (default :8443), --capture-timeout (default 2h), --resumable, --stage-dir |
hostssh transfer --pull <key> | Redeem a key on the target: dial the source (pinned via --source-pin/$HOSTSSH_TRANSFER_PINS), stream the scoped image into --restore-cmd. | --from host:port, --restore-cmd (required), --source-pin, --resume, --attempts (default 5) |
transfer enforces exactly one mode (--new-key, --serve, or --pull); passing
more than one exits 2. The three modes together are the peer-to-peer wedge — see
Agent protocol §Control RPCs.
Fleet — fleet, firewall, and roadmap verbs
| Command | Purpose | Key flags |
|---|---|---|
hostssh fleet servers|backups | List the license's fleet — reporting servers (state, version, last seen) or backup health (last capture, drill pass) — from the control plane. | --server (filter backups to one host), --json, --config PATH |
hostssh firewall up|status | One-click host hardening (deny-in, allow-out, SSH always open) or show status. | --ssh-port (default 22), --tcp (default 80,443), --udp (e.g. 51820), --reset |
hostssh clone | Roadmap — not in this build. Advertised in usage; exits 3. | — |
hostssh migrate --new-ip | Roadmap — not in this build. Advertised in usage; exits 3. | — |
hostssh provision | Roadmap — not in this build. Advertised in usage; exits 3. | — |
clone/migrate/provision are the managed-relocation verbs described in
API & CLI and Agent protocol; they are
license-gated in gatedCommands and reserved in the dispatcher, but the
concrete implementation is not present in this build (the case prints the roadmap
message and returns 3).
MCP — mcp
| Command | Purpose | Key flags |
|---|---|---|
hostssh mcp | Run the MCP server over stdio so an AI agent drives the platform. Keeps its serverInfo version in lockstep with the binary. License-gated. | — (reads stdin, writes stdout) |
See API & CLI §The MCP server for the tool catalog and guardrails.
Relationship to the deploy queue
hostssh deploy, db create, prune, firewall, and restore also run as
deploy-queue jobs the control plane enqueues and the daemon claims — the same
engine, different trigger. hostssh agent is the loop that claims and executes
them. For the enqueued-side contract — kinds, JobSpec fields, secret delivery, and
the executeJob switch — see Job kinds.
See also: API & CLI · Agent protocol · Job kinds · Environment variables & secrets