Skip to content

CLI reference

Every fleetd command, from fleetd help in the binary this site was built with.

Exit code Means
0 ok
1 failed: a check did not pass
2 usage error
3 refused
4 the hub or the node is unreachable
fleetd version

print the fleetd version and protocol

fleetd help

show this message

fleetd update [--check] [--channel <c>]

replace this fleetd with the latest release, then restart its hub and node at once: what they were running carries on by itself. The app’s Update button does this for the hub and every node; this is for a machine without the app. --channel edge (the newest build of main) or stable; default: the channel this build came from

On the hub machine.

fleetd init [--yes] [--home <dir>] [--listen <host:port>] [--url <url>]
[--git-identity "Name <email>"] [--no-service] [--unit-suffix <s>]

set up fleetd step by step in a terminal: the hub on this machine (home default ~/.fleetd/hub, kept running by a systemd or launchd user service), where it listens (your tailnet when there is one), the claude and gh logins, the machines that run agents, a first project and the desktop app, then the hub’s setup steps. Run it again to check and repair; it keeps what works. --yes takes every default. Without a terminal and without --yes it only sets up the hub. --url is how devices reach the hub (default http://<listen>); --git-identity is the commit author for every machine (the GitHub noreply address for public repos); --no-service prepares everything but leaves starting the hub to you

fleetd init --join <hub url> --code <code> [--machine-id <id>] [--git-identity "Name <email>"] [--rejoin]
[--claude-config-dir <dir>]

make this machine a worker of that hub, without SSH from the hub: the command fleetd pair --worker prints on the hub. Run again, it keeps the node’s enrolment and repairs the rest; --rejoin enrols again with a new code

fleetd init --step <address|machines|claude|github|people|google|notion> [--home <dir>]

open one of the hub’s setup steps: why, the values to paste and the pages to open, then Test it, or put it off for later. The app’s Settings › Hub › Setup has the same steps

fleetd doctor [--home <dir>]

run every setup check on the hub now: the setup steps first, then each other problem with its fix

fleetd uninstall [--home <dir>] [--purge]

stop and remove the hub’s service; its data stays unless --purge, which also removes what an older fleetd installed for T3 Code

fleetd machine add <ssh-host> | --local [--machine-id <id>] [--tags a,b] [--dry-run] [--no-service]
[--hub-url <url>] [--ssh-config <file>] [--home <hub home>] [--unit-suffix <s>]
[--claude-config-dir <dir>]

set up a machine that runs agents, over SSH (--local: this machine): copies this fleetd there (for another OS or CPU, this version’s release build for it, checked against its SHA256SUMS; there is no Linux ARM build yet), checks its claude (installed, version >=2.1.300, <2.2.0, logged in), enrolls the node and runs it as a user service, then waits until the machine is online; prints every command first, --dry-run only prints (for a fresh machine, without connecting); --no-service enrolls the node but writes no service and prints how to run it; safe to run again

fleetd machine remove <id> [--purge] [--home <hub home>]

stop and remove the node’s service on the machine and revoke its key on the hub; --purge also deletes ~/.fleetd/node and ~/.fleetd/claude.env there, and what an older fleetd installed for T3 Code

fleetd machine set <id> --max-agents <n>|auto [--home <dir>] [--hub <url>]

the most agents the machine runs at once (admin key), up to the fleet cap, in place of what it is measured to fit; auto: what it fits again. Raising starts queued agents at once; lowering stops nothing

fleetd machine set <id> --roles agents,sessions [--max-sessions <n>|auto] [--home <dir>] [--hub <url>]

what the machine is for (admin key): agents, sessions (screens: browsers and devices) or both, and the most screens it hosts at once (1 to 64; auto: what it fits). A screen an agent starts runs on its own machine when it can, else on another that can, through the hub. Without agents, running agents finish and new ones wait

fleetd pair [--name <device>] [--role <read|operate|admin>] [--no-qr] [--home <dir>]

print a one-time code (15 min) that pairs the fleetd app with this hub, and a QR of its link for the phone app to scan (--no-qr leaves it out); the desktop app on this machine pairs by itself. The device gets --role (default admin, which changes the hub’s settings) on every machine

fleetd pair --worker <machine-id> [--home <dir>]

print the one command that makes another machine a worker of this hub, with a one-time code (15 min): for a machine the hub can’t reach over SSH

fleetd invite --name <name> [--role <member|admin|owner>] [--home <dir>]
fleetd invite --person <personId> [--home <dir>]

invite someone to this hub: prints a link and a code (single use, 7 days) that pair their app as a device of a new person, a member unless --role; with --person, one more device of someone already here

fleetd invite list [--home <dir>]
fleetd invite revoke <inviteId> [--home <dir>]

takes back an open invite; someone it invited who never joined goes with it

fleetd people [--home <dir>]

the hub’s people, with their role and devices

fleetd people role <personId> <owner|admin|member> [--home <dir>]
fleetd people remove <personId> [--home <dir>]

signs out all their devices; one device: fleetd hub key revoke <keyId>. The hub always keeps an owner

fleetd github-app [--home <dir>]

the hub’s own GitHub App: where it is installed and its last test

fleetd github-app create [--org <org>] [--name <name>] [--port <port>] [--home <dir>]

make it on GitHub with nothing to paste: opens a page on this machine (127.0.0.1) that sends GitHub the App’s manifest; press Create on GitHub and the hub keeps its keys, sealed. From another computer, forward the port first: ssh -L <port>:127.0.0.1:<port> <this machine>

fleetd github-app test [--home <dir>]

mint a token for each installation and say where the App reaches

fleetd github-app remove [--home <dir>]

forget it; the hub’s gh goes back to this machine’s own login

fleetd project add [<path|github-url>] [--machine <id>] [--title <t>] [--dest <dir>]
[--use-existing] [--yes] [--home <dir>] [--hub <url>]

add a project: a checkout or a plain folder on a machine (this one by default), or a GitHub repo cloned onto one (the least busy worker by default), with progress; then its CI, merge rules and what the lead will need. No argument: pick one

fleetd project add --new <name> [--machine <id>] [--dest <dir>] [--git-init] [--home <dir>] [--hub <url>]

start a new, empty project: the machine makes its folder (~/fleetd/projects/<name> by default, or --dest; one that holds files is refused). A plain folder with no repo, unless --git-init; add a repo later with project repo add

fleetd project list [--machine <id>] [--home <dir>] [--hub <url>]
fleetd project stop <machine>/<project> --key-file <human key> [--yes] [--home <dir>] [--hub <url>]

stop its lead’s turn and its agents, as you; the lead and its chat stay, and the chat says what stopped

fleetd project remove <machine>/<project> [--yes] [--home <dir>] [--hub <url>]

stop its agents and forget it; its files, branches and worktrees stay

fleetd project repo list <machine>/<project> [--home <dir>] [--hub <url>]
fleetd project repo add <machine>/<project> <path|github-url> [--name <n>] [--dest <dir>]
[--use-existing] [--home <dir>] [--hub <url>]

add a repo to the project: a checkout on its machine, or a GitHub repo cloned there, with progress. A checkout that is a project of its own is archived: its chat stays, its lead stops running

fleetd project repo remove <machine>/<project> <name> [--yes] [--home <dir>] [--hub <url>]

take the repo out of the project and end its agents; its files stay

fleetd project set <machine>/<project> --max-agents <n>|default [--pause-extras] [--home <dir>] [--hub <url>]
fleetd project set --fleet-cap <n> [--home <dir>] [--hub <url>]

the most agents the project runs at once (its lead not counted), or the fleet’s cap on running agents (admin key); more wait queued and start as slots free. default: its machine’s cap within the fleet cap, following both. Lowering stops nothing; --pause-extras has the newest agents above the new max push their work and wait

fleetd project set <machine>/<project> --profiles <name>,...|none [--home <dir>] [--hub <url>]

the task profiles its lead may run agents on besides the hub’s default, which every project allows; none: the default alone

fleetd project profiles [<machine>/<project>] [--home <dir>] [--hub <url>]

the hub’s task profiles: model, effort, fast mode and note, and which the project allows

fleetd project profile <name> [--model <model>] [--effort low|medium|high|xhigh|max]
[--fast on|off] [--note <text>] [--rename <new>] [--default] [--delete]
[--home <dir>] [--hub <url>]

create or change a task profile (owner or admin), or delete one. A new one needs --model and --effort. --default makes it the one the lead, every review and helper calls run on

fleetd project set <machine>/<project> [--fast-check <check>]... [--after-merge <check>]...
[--home <dir>] [--hub <url>]

how the merge train treats the repo’s checks. It waits only for its fast set: the checks the base branch requires, plus each --fast-check, each until it reports. Each --after-merge never stops a merge, even once failed. A check outside the fast set that fails after the merge opens a fix order. Each option replaces its list; none empties it

fleetd navi create <name> [--machine <id>] [--home <dir>] [--hub <url>]

make a Navi: a personal assistant with its own chat, memory and folder (navi/<name> under the machine’s fleetd home; the least busy worker by default)

fleetd navi list [--archived] [--machine <id>] [--home <dir>] [--hub <url>]
fleetd navi rename <machine>/<navi> <name> [--home <dir>] [--hub <url>]
fleetd navi archive|unarchive <machine>/<navi> [--home <dir>] [--hub <url>]

archived, its lead stops and its chat, memory and folder stay; <navi> is its id or its name

fleetd hub start [--home <dir>] [--listen <host:port>] [--queue-ttl <seconds>]

run the hub (default home ~/.fleetd/hub, listen 127.0.0.1:4790, writes to an offline machine wait 24 h)

fleetd hub key create --name <name> --role <read|operate|admin> --machines <'*'|id,id> [--out <file>] [--home <dir>]

create an agent key for the MCP endpoint; prints the key once, or with --out writes it to a new file (0600) and prints the file’s path

fleetd hub key create --agent <name> [--machines <'*'|id,id>] [--out <file>] [--home <dir>]

a named agent’s key, to write in a project’s chat (fleetd chat --key-file): its messages show as that agent’s, never yours. Operate on every machine unless --machines. Written to a new file (0600), <hub home>/keys/<name>.key unless --out; prints only the file’s path

fleetd hub key create --human --name <device> [--role <role>] [--machines <'*'|id,id>] [--out <file>] [--home <dir>]

a key for a person’s device (the desktop app): what it answers is recorded as the human’s; role defaults to operate on every machine

fleetd hub key list [--home <dir>]
fleetd hub key revoke <keyId> [--home <dir>]

takes effect at once, also on a running hub

fleetd node join --hub <url> (--token <token> | --token-file <file|->) --machine <id> [--tags a,b]
[--name <name>] [--home <dir>] [--enroll-only] [--claude-config-dir <dir>]

enroll this machine with the hub, then keep its link up (node home default ~/.fleetd/node); --token-file - reads the token from stdin; --enroll-only exits once the hub has accepted this node; sessions use your own claude setup (~/.claude) unless --claude-config-dir names a dedicated one

fleetd node run [--home <dir>]

keep the link up for a machine that has joined

fleetd prompts list [--project <machine>/<project>] [--home <dir>]

every prompt fleetd sends a model, which text is in effect, and “update” where a release changed the default you edited

fleetd prompts show <id> [--project <machine>/<project>] [--default] [--home <dir>]
fleetd prompts show --session <machine>/<thread> [--home <dir>]

the text in effect (or the shipped one), or exactly what a session was told

fleetd prompts edit <id> [--project <machine>/<project>] [--home <dir>]

edit it in $VISUAL or $EDITOR; warns when a placeholder or a safety rule is gone

fleetd prompts reset <id> [--project <machine>/<project>] [--home <dir>]
fleetd prompts diff <id> [--project <machine>/<project>] [--home <dir>]

shipped vs yours; after a release changed it, what changed in each

fleetd instructions show|edit [--project <machine>/<project>] [--home <dir>]

your custom instructions, appended to every lead and task

fleetd push-relay [--listen 127.0.0.1:4795]

forward hubs’ sealed phone notifications to APNs and FCM with your own credentials: FLEETD_APNS_KEY_FILE (a .p8), FLEETD_APNS_KEY_ID, FLEETD_APNS_TEAM_ID, FLEETD_APNS_TOPIC (the app’s bundle id), FLEETD_APNS_SANDBOX=1 for development builds; FLEETD_FCM_SERVICE_ACCOUNT (a Firebase service account’s JSON key). FLEETD_PUSH_RELAY_KEY_FILE (a file holding a key): take only hubs that send it; set one when the relay is reachable beyond this machine. It never reads, keeps or logs a notification. Run your own only for an app you build yourself

fleetd push-relay set <url|off> [--relay-key-file <path>] [--hub <url> --key-file <path> | --home <dir>]

hubs send phone notifications through https://push.fleetd.sh, the relay for the published app, without a key. <url> sends them through your own relay instead, with the key in --relay-key-file when it takes one, sealed to the hub; https://push.fleetd.sh goes back to the default; off sends none (admin key on every machine)

fleetd time [<order>|<project>] [--since 7d] [--json] [--hub <url> --key-file <path> | --home <dir>]

where agents’ time went: an order’s critical path, agent time by category, the slowest commands and the findings; a project by id or title (<machine>/<project> when two machines have one), the whole fleet with neither. --since takes 1h to 400d, a date or an ISO time. On the hub machine it needs no --hub or --key-file

fleetd time --retention <days> [--hub <url> --key-file <path> | --home <dir>]

keep 1-365 days of timelines (admin key); daily totals are kept 400 days

fleetd metrics [--project <p>] [--days 30] [--json] [--hub <url> --key-file <path> | --home <dir>]

what the factory turned out: PRs merged per day by route, time from order to merged, your minutes per merged PR and the share through fleetd, over the last --days calendar days (1-400, today included) in this machine’s zone; one project by id or title (<machine>/<project> when two machines have one), the whole fleet without one. On the hub machine it needs no --hub or --key-file

fleetd metrics --retention <days> [--hub <url> --key-file <path> | --home <dir>]

keep 30-400 days of landed changes (admin key on every machine)

fleetd status [<project>] [--watch] [--json] [--hub <url> --key-file <path> | --home <dir>]

one row per project, as the app’s Status screen shows it: what it is doing (working, waiting on you, blocked and why, idle), its work in groups (waiting on you, in review, working, landing, idle, done), agents running and the last merge; one project by id or title (<machine>/<project> when two machines have one). --watch prints the rows again after each change; a stale row says so. On the hub machine it needs no --hub or --key-file

fleetd usage [<machine>] [--json] [--hub <url> --key-file <path> | --home <dir>]

each machine’s Claude usage pause: open or not, why, until when, and how much is parked

fleetd usage resume <machine> [--json] [--hub <url> --key-file <path> | --home <dir>]

lift the machine’s usage pause now and send every parked agent “continue”, like Resume in the app; one whose login is still limited parks again with the real reset. --json adds pauseLifted (null when the pause couldn’t be read first). On the hub machine neither needs --hub or --key-file

fleetd steer <W|T> "<text>" [--now] [--wait] --key-file <human key> [--hub <url> | --home <dir>]

steer an order’s lead (W41) or one agent (T88) mid-run. Plain: it lands at the agent’s next step, after the tool it is running returns. --now stops that step and delivers at once. --wait follows the receipt: exit 0 acknowledged, 1 not acknowledged, withdrawn or failed. Without --hub it uses the hub on this machine

fleetd steer withdraw S<n> --key-file <human key> [--hub <url> | --home <dir>]

take back a steer the agent has not taken in yet

fleetd steers <W|T> --key-file <human key> [--hub <url> | --home <dir>]

an order’s (or one agent’s) recent steers and their receipts

fleetd chat <machine>/<project> "<text>" [--now] [--wait | --follow] --key-file <key> [--hub <url> | --home <dir>]

write to a project’s lead, as the app does: it starts the lead’s next turn, or lands at its next step while it works; --now (a human key) stops that step and delivers at once. --wait prints the lead’s reply when its turn ends; --follow streams it as it is written. Exit 0 it replied, 1 its turn ended without a reply. A human key writes as you; an agent key as that agent, by its name

fleetd chat history <project> [--page <n>] --key-file <key> [--hub <url> | --home <dir>]

the project’s chat: who wrote each message, when, and what; the newest page, older ones with --page

fleetd work [list] --key-file <key> [--hub <url> | --home <dir>]

what is in flight on this checkout’s repo and base: fleetd’s agents, PRs on the merge train, and people’s claims

fleetd work claim "<intent>" [--issue <key>]... [--paths <a,b>] [--anyway]
[--not-duplicate-of <ids> --why "<reason>"] --key-file <key> [--hub <url> | --home <dir>]

check the intent against the work in flight and claim it, with the repo, branch, user.email and changed paths read from this checkout. Exit 0 claimed (or yours: a fleetd agent on its own task’s branch), 1 taken or a likely duplicate (it says by what). Again on the same branch: renews it. --anyway (a human key only) claims taken work regardless

fleetd work done [C<n>] [--landing <sha>] --key-file <key> [--hub <url> | --home <dir>]

end your claim as landed (by default the one on this branch); --landing: the commit on the base. --key-file defaults to $FLEETD_KEY_FILE

fleetd work drop [C<n>] --key-file <key> [--hub <url> | --home <dir>]

end your claim as dropped (by default the one on this branch): you stop, or leave it to someone else