agentop is the single binary for everything agentistics does: run the dashboard,
the terminal TUI, the OpenTelemetry daemon, host or join a Team Mode central,
and manage autostart + updates.
Get the binary from the install instructions (install.sh,
the Windows installer, or bun run build:binary from source). From a checkout you
can also run it directly with bun run packages/server/bin/cli.ts <command>.
agentop --help # full usage
agentop --version # print version (and a notice if an update exists)Ports: a solo/member instance serves the web dashboard on 47292 (the URL you open) and the api + mcp on 47291 (in dev, Vite serves the web on 47292 and the api runs on 47291 — same split). A Team Mode central runs in Docker on 48080 by default. These are intentionally distinct so a member and a central can coexist on the same host.
| Command | Purpose |
|---|---|
start |
The control center — services, setup, logs, commands, help (same as bare agentop) |
setup |
Interactive first-run wizard (solo / central / member) |
server |
Start the web dashboard + api + Nay + background daemon (non-interactive) |
restart |
Restart a running mode so it picks up new code / config |
status |
At-a-glance: mode, services (server/central/machine) + health |
tui |
Live terminal dashboard (no browser) |
watch |
OpenTelemetry metrics daemon only (headless) |
central |
Manage the Team Mode central (wraps central.sh) |
member |
Join / leave / inspect a Team Mode central from this machine |
ci-push |
One-shot push of a GitHub Actions run's metrics to a central (per repo) |
autostart |
Start a mode with the system (systemd user service) |
upgrade |
Upgrade agentop to the latest release |
check-update |
Print an "update available" banner, else stay silent |
doctor |
Run the exposure preflight before publishing a central |
setup-token |
Reissue a central's one-time owner setup token |
reset-password |
Reset an account's password from the host (locked-out owner) |
Running bare agentop on an interactive terminal opens the
control center. Without a terminal it prints this help; --help always prints it.
The control center — one full-screen application, in the terminal's alternate buffer, so it
adds nothing to your scrollback no matter how long you use it. Bare agentop opens the same thing.
agentop # the usual way in
agentop start
agentop start --lang pt # force Portuguese for this run ▄▀█ █▀▀ █▀▀ █▄░█ ▀█▀ █ █▀ ▀█▀ █ █▀▀ █▀
█▀█ █▄█ ██▄ █░▀█ ░█░ █ ▄█ ░█░ █ █▄▄ ▄█ member · v1.7.3 · ● 1.7.4
services setup logs commands help contribute
━━━━━━━━━━
╭─ services ─────────────────────────────╮╭─ config ─────────────────────────────────────╮
│ ❯ agentistics native ● up ││ mode member │
│ agentistics central ○ stopped ││ endpoint http://198.51.100.199:48080 │
│ ││ history consolidate │
│ ││ language English │
╰────────────────────────────────────────╯╰──────────────────────────────────────────────╯
╭─ agentistics ────────────────────────────────────────────────────────────────── native ╮
│ native · pid 48213 · up 2h13m │
│ │
│ RUNTIMES ───────────────────────────────────────────────────────────────────────────── │
│ native ● up · pid 48213 · up 2h13m │
│ docker ○ stopped │
│ │
│ ADDRESSES ──────────────────────────────────────────────────────────────────────────── │
│ web http://localhost:47292 │
│ api http://localhost:47291 │
│ │
│ MACHINE ────────────────────────────────────────────────────────────────────────────── │
│ boot starts at boot │
│ history consolidate │
│ endpoint http://198.51.100.199:48080 │
│ Restart Rebuild & restart Stop Open in browser │
╰────────────────────────────────────────────────────────────────────────────────────────╯
q quit · ←→ screens · tab pane · ↑↓ move · enter actions · s stop · R restart
Naming: agentistics is the per-machine app; agentistics central is the team aggregator.
Both serve a web dashboard, so neither is labelled "the dashboard".
Move between them with ← / → — there are no digit shortcuts for screens, so the digits
always belong to whatever list is drawing them.
| Screen | What it is for |
|---|---|
| services | The cockpit: start / stop / restart, connect to or leave a central, enable a boot service |
| setup | The same solo / central / member wizard as setup, plus the history-preservation consent |
| logs | A tailing viewer, one source per running service |
| commands | The cheat sheet — every command, without leaving the app |
| help · contribute | What the keys do, and how to contribute |
The services list is the selection; the pane below is a view of it, so moving the cursor
repaints it. tab cycles the panes (services → config → actions) and the actions are
focus-scoped: with a service selected they act on that service, which is why there is no
"stop which?" submenu.
- One row per logical service, never per runtime.
agentisticsrun natively and the same program in a container are two runtimes of one service. A running service therefore offers no "start" at all — it offers Restart, Rebuild & restart (only where a rebuild could actually work here), Stop and Open in browser. A stopped one is dimmed and offers only the starts this machine can perform. - A service running under BOTH runtimes says so, in colour, with a word — and its verbs split
into
Stop (native)/Stop (docker). They read the same files and fight over the same port, so the conflict is never normalised away by showing just one. - A long action streams into the detail pane, titled with the verb you pressed, while the lists
stay standing beside it.
escputs the facts back. - The Docker option mounts the host's harness dirs read-only — run the machine in Docker or natively, not both. See Machine in Docker.
The footer always names the keys that work in the current focus; it is the only documentation the screen has, so a hint for a key that does nothing there is a bug.
Non-interactive stdin (a pipe, a systemd unit) skips all of this and behaves exactly like
server. q leaves without starting anything.
Restart a running mode so it picks up new code (after an upgrade / git pull) or a changed
config. Defaults to server.
agentop restart # = restart server
agentop restart server # bounce the systemd user service (agentop-server)
agentop restart watch # bounce the watch service
agentop restart central # bounce the central's container
agentop restart --all # bounce every service currently up
agentop restart central --rebuild # rebuild the image first, then restart
agentop restart central --rebuild --cache -n # …reusing the layer cache, answering the promptserver/watch bounce the installed systemd user service — if none is installed it
tells you to run it in the foreground or enable autostart first. --all bounces everything that is
up (local + central + machine), non-interactively.
--rebuild is a FULL rebuild. The Docker paths pass --no-cache, because a cached build can
hand you back the very image it was asked to replace — which is the one failure mode a rebuild
exists to prevent. That takes several minutes, and the command says so on the way in:
| Flag | Effect |
|---|---|
--cache |
Reuse Docker's layer cache instead — the fast path |
--no-cache |
The default for a rebuild; stated explicitly |
-y / --yes |
Re-run the central's interactive setup, without being asked |
-n / --no |
Do not re-run it — the default when there is no terminal to ask on |
Passing -y with -n (or --cache with --no-cache) is refused, not silently resolved. A
plain agentop central up is not a rebuild and keeps its cached build.
Non-interactive, at-a-glance report of this machine. Prints three blocks:
- CONFIG — the team mode (
solo/central/member) and, for a member, the central endpoint (from preferences). - SERVICES — detected live: the local server (
http://localhost:47291/api/health; shows the dashboard URL when up), the central container, and the machine container. - HEALTH — a one-line summary from
/api/healthwhen the server is up, elsen/a.
agentop statusHandy for a quick "is everything up and healthy?" without opening the dashboard.
Interactive first-run wizard. Walks you through picking a mode and wires up the
rest for you: solo (local only, nothing leaves the machine), central (host
the aggregator on this machine via central.sh init), or member (push this
machine's computed metrics to a central via member connect). It then offers to
enable autostart.
agentop setupNeeds a TTY. Ctrl-C is non-destructive — it aborts without touching your
preferences. For non-interactive/scripted member onboarding, use
agentop member connect directly.
Starts the web dashboard, api, Nay chat, MCP registration, and the OTel daemon —
everything in one process. Binds two ports: the web dashboard on 47292 (open this) and the
api + mcp on 47291. They share one request handler, so the dashboard's /api/* calls just work.
agentop server # web: http://localhost:47292 · api/mcp: http://localhost:47291
agentop server --port 4000 # api on 4000, web on 4001
agentop server --bg # detached, logging to ~/.agentistics
agentop server --central # run a central natively, no Docker| Flag | Default | Description |
|---|---|---|
--port <n> |
47291 |
The api + mcp port; the web dashboard is served on this + 1 (default 47292) |
--bg |
off | Start detached in the background; logs go to ~/.agentistics |
--central |
off | Run this process as a team central, natively — see below |
Runs the same server with AGENTISTICS_TEAM_CENTRAL=1, loading central.env (searched in
$AGENTISTICS_CENTRAL_ENV, ./central.env, then ~/.agentistics/central.env) for the secrets and
the database URL.
There is no bundled MongoDB on this path — set MONGO_URL to an external cluster (Atlas, or a
mongod you run yourself). For the all-in-one flow with Mongo included, use
agentop central up instead.
AGENTISTICS_TEAM_PASSWORDincentral.envselects the legacy shared-password login and masks the accounts sign-in. If you want accounts, remove it — the central will otherwise serve the old "team password" screen with no error anywhere.
A live multi-screen dashboard in the terminal — no browser needed. Built with
Ink, it updates the instant the web dashboard does, over the same
/api/events SSE stream.
agentop tui
agentop tui --lang pt # force Portuguese for this run agentistics · live coding-assistant analytics ● live
1 Overview 2 Projects 3 Sessions 4 Costs 5 Harnesses
USD 8,364.44 13.3B 262 113.4K 2d
cost tokens sessions messages streak
activity · last 30 days
▅▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▅▁▁▁█▃
Harnesses
Claude ██████████████████████████████ USD 8,363.48 13.3B tok
Codex ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ USD 0.01 27.6K tok
1-5/tab switch screen · f filter · ? help · q quit
| Key | Does |
|---|---|
1–5, tab |
Switch screen — Overview, Projects, Sessions, Costs, Harnesses |
f |
Filter by harness |
r |
Force a refresh |
? |
Keyboard help |
q, ctrl+c |
Quit |
There is no configuration wizard — it opens straight into Overview and filtering happens in-app. If no server is listening it starts one itself and stops it again on exit; a server that was already running is left alone.
Metrics match the web dashboard exactly: both price through calcCost(), Claude totals come from
stats-cache.json and every other harness from per-session sums. A metric a harness cannot
produce shows N/A rather than a misleading 0.
Needs an interactive terminal — piping it exits with a message instead of a crash.
Runs only the OpenTelemetry file watcher + OTLP metrics exporter (the same daemon
server runs in the background). Use this on a headless box that only needs to
feed Grafana/Datadog. See docs/opentelemetry.md.
agentop watchManage the Team Mode central — the Docker service that aggregates metrics from
many members. This is a thin wrapper over the repo's central.sh, so it needs to
run from an agentistics checkout (the compiled binary alone doesn't ship the
Compose stack). Full deployment details live in docs/DEPLOY.md.
agentop central <up|init|down|logs|status|restart|pull>| Action | What it does |
|---|---|
init |
(Re)generate central.env interactively — auto-generates the secrets with openssl, detects your Tailscale IP for the bind, writes the file chmod 600 |
up |
Build the image and (re)create the containers (--build --force-recreate); offers init first if central.env is missing |
restart |
Restart the app container without rebuilding |
logs |
Follow the app container logs |
status |
Show container + health status |
down |
Stop and remove the containers — keeps the Mongo data volume |
pull |
Rebuild from a fresh base image (run git pull first) |
agentop central init # generate central.env (interactive)
agentop central up # build + (re)create — most common
agentop central logs # tail the app logs
agentop central down # stop, keep the data volumeFrom a checkout you can equivalently use the package scripts
bun run init:central and bun run up:central, or call ./central.sh directly.
Configure this machine as a member that pushes computed metrics to a central.
Only aggregated metrics are sent — never chat content or raw transcripts. The
machine's display name is assigned by the central (baked into the minted token)
and resolved via /api/team/whoami; there is no name field on the machine.
agentop member connect --endpoint <url> --token <token> [--org <org>]
agentop member leave
agentop member statusVerifies the token against the central's whoami endpoint, then saves the member
config. On a bad token it prints an actionable error and writes nothing (no
half-configured state).
| Flag | Required | Description |
|---|---|---|
--endpoint <url> |
yes | Central base url, e.g. http://host:48080 |
--token <token> |
yes | Token minted for this machine in the central's Team Manager |
--org <org> |
no | Org override; defaults to the org on the token |
agentop member connect --endpoint http://100.64.0.2:48080 --token abc123Best-effort notifies the central (so it drops this member's data) and resets this machine back to solo. Succeeds locally even if the central is unreachable.
Prints the current mode / endpoint / org / user plus the live uploader state
(last sync timestamp and whether the token/endpoint are healthy).
mode: member
endpoint: http://100.64.0.2:48080
org: default
user: alice-laptop
last sync: 2026-07-01T12:34:56.000Z
state: ok
One-shot push of a GitHub Actions run's computed metrics to a central, attributed to
the repository it ran in. Meant to be the last step of a workflow that already runs Claude
Code (it does not run Claude) — the ephemeral runner populates ~/.claude, then ci-push
sends that run's session/token/cost aggregates before the runner is torn down. It reads
everything from the environment and takes no flags.
| Env var | Required | Description |
|---|---|---|
AGENTISTICS_CENTRAL_URL |
yes | Central base URL, e.g. https://central.example.com |
AGENTISTICS_CI_TOKEN |
no | Repo-bound static token (fallback when OIDC is unavailable) |
Auth is keyless GitHub OIDC by default: with permissions: id-token: write on the job,
ci-push fetches a short-lived GitHub-signed token itself (audience = AGENTISTICS_CENTRAL_URL)
and the central verifies it against GitHub's JWKS. No secret needed. If no OIDC token can be
fetched it falls back to AGENTISTICS_CI_TOKEN. The repo must first be registered on the
central (Settings → Team → Repositories, which allowlists the remote and, for the fallback,
mints the token).
# inside a GitHub Actions job, after the Claude Code Action step:
curl -fsSL "https://github.com/blpsoares/agentistics/releases/latest/download/agentop" -o agentop
chmod +x agentop
./agentop ci-pushci-push never fails your job — a push error (central down, unverifiable token) logs and
exits 0. It pushes computed metrics only, never chat. See
docs/github-actions.md for the full workflow + registration walkthrough.
Register a mode to start with the system. On Linux/WSL this installs a systemd
user service at ~/.config/systemd/user/agentop-<mode>.service, enables it
with systemctl --user enable --now, and runs loginctl enable-linger so it also
starts at boot without an active login. enable additionally installs a
~/.bashrc hook that runs agentop check-update on every
terminal open. macOS and Windows print the manual step instead.
agentop autostart <mode> <enable|disable|status>mode∈server·central·watchenable— register + start the service (and add the terminal update hook)disable— stop and remove the servicestatus— show enabled/active state; omit the mode to list all services
agentop autostart server enable # start the dashboard at boot
agentop autostart status # list every autostart service
agentop autostart watch disable # stop the otel daemon serviceDownload and install the latest agentop release in place. (update is an alias.)
agentop upgradeOn a central you upgrade the Docker stack instead — pull the repo and rebuild:
git pull && bun run up:central # or: agentop central pullOn a member running as a systemd service, restart it after upgrading:
agentop upgrade && systemctl --user restart agentop-serverPrints the "new version available" banner only when a newer release exists,
and stays completely silent otherwise — so it's safe to run on every shell start.
This is exactly what the ~/.bashrc hook installed by agentop autostart … enable runs.
agentop check-updateagentistics surfaces available updates in three places, all sourced from the same version check:
- On command run — most
agentopcommands print the update banner in parallel with startup (non-blocking);--versionappends the notice too. - On terminal / boot — the
~/.bashrchook added byautostart … enablerunsagentop check-updatewhen you open a shell (silent when you're current). - On the dashboard — a bell notification plus a mode-aware upgrade modal
showing the exact command for your role (a central shows
bun run up:central; a member showsagentop upgradethensystemctl --user restart agentop-server). A periodic (~6h) server re-check pushes the notification live over SSE.
Runs the exposure preflight: nine checks that decide whether this instance is safe to publish. Exits non-zero on any failure, so going live can be gated on one command instead of on remembering nine environment variables.
agentop doctor # check against the current profile
agentop doctor --exposed # check against the strict public bar
./central.sh doctor --exposed # from a repo checkout, INSIDE the container
agentop central doctor --exposed # same, from the standalone binaryOn a Docker central, prefer the central.sh / agentop central form. The command
evaluates the configuration the deployment will actually run with — it reads central.env when
present and prints which file it used — but the owner-MFA and machine-token checks also need
MongoDB, which is reachable only from inside the compose network. Run on the host, those two
report as unverified, which counts as a failure by design.
--exposed evaluates as if AGENTISTICS_EXPOSURE=public were already set, which is how you
verify readiness before flipping it.
What it checks:
| Check | Fails when |
|---|---|
local-shell |
/api/exec, /api/chat-tty, the host transcript readers or /api/mcp-action are still reachable |
session-secret |
The secret is missing, shorter than 32 chars, or equal to the dashboard password |
tls |
AGENTISTICS_TEAM_TLS is unset on a public profile |
bind-ip |
BIND_IP is not loopback on a public profile — the tunnel connects locally, so anything wider is a way in that bypasses it |
trust-proxy |
(warn) forwarded-IP trust does not match the deployment, so per-IP limits apply to everyone at once |
owner-mfa |
Any owner account has no TOTP enrolled |
cors |
A plaintext origin sits in AGENTISTICS_ALLOWED_ORIGINS |
mongo-auth |
(warn) the database has no credentials — acceptable only while its port stays unpublished |
machine-tokens |
(warn) no machine tokens have been minted yet |
A check that could not be verified — the database was unreachable, say — reports a failure, not a reassuring pass. See exposure.md for the full deployment runbook.
Reissues a central's one-time owner setup token — the token first boot prints, and which the dashboard asks for when it creates the first owner account.
agentop central setup-token # from anywhere
./central.sh setup-token # from a checkoutUse it when the boot that printed the token has scrolled away or its log rotated. It is refused
once an owner exists: past that point the way back in is reset-password, not
a fresh setup token.
Run it where the central runs — inside the container/host serving it, not on a member.
Resets an account's password from the host. This is the only way back in for a locked-out last owner, so it deliberately requires shell access to the machine running the central.
agentop central reset-password # list the accounts
agentop central reset-password --email ana@example.com # prompts for the new password
agentop central reset-password --email ana@example.com --password '<new>' --clear-mfa| Flag | Effect |
|---|---|
--email <address> |
Which account. Omit to list them |
--password <new> |
Set it non-interactively (subject to the password policy) |
--clear-mfa |
Also drop the enrolled second factor — for a lost authenticator |
Every reset is written to the audit log. --clear-mfa removes a security control, so on a public
profile treat it as a break-glass action and re-enrol immediately: owner-mfa is one of the checks
doctor --exposed fails on.