The console for the machines your agents live on.

AgentPod puts a small Go agent on each machine where your agents run. It dials out to a hub, and from one console you read each runtime's files, tail its logs, open a terminal and check its health.

Example fleet. Names and machines are invented.

How it works

  1. Install apn on a machine

    One install script on a server, a laptop or a container. The node agent dials out to your hub over a WebSocket, so it needs no inbound port and works from behind NAT.

  2. It finds the agents there

    A descriptor per harness detects what is running and where its config and logs live. v0.1.98 has descriptors for:

    • Hermes
    • OpenClaw
    • Claude Code
    • Codex
    • OpenCode
    • Pi
    • Muse Code
    • Kilo
  3. You work from the console

    Adopt a station, then use its panels: files, logs, terminal, health, start and stop, cleanup, changesets. A request for a capability the station has not declared is refused at the hub.

A descriptor means AgentPod can detect that harness. What it can do with each one depends on the harness and how the host is set up, so the panels are not the same for every harness. AgentPod detects Muse Code and Kilo; their capabilities beyond detection have not been checked.

What it's like to use

Say you have a Hermes agent on a VPS and Codex on a laptop that sits behind your home router. Both machines have dialled out to your hub, so both show up in one fleet. The laptop's agent stopped answering: you open its station, tail the log, and open a terminal to look around, without forwarding a port. Before you restart it you check the changeset to see what it actually changed in its working tree. Then the VPS is low on disk: you plan a cleanup, read the plan, and only then apply it.

Run it yourself

The latest release is v0.1.98. Its downloads are the node agent (apn) and the fleet CLI, for Linux and macOS on amd64 and arm64, with a SHA256SUMS file.

First: check a machine, no hub needed

apn scan checks the agent runtimes on a host for the two ways they get taken over: a listener bound to every interface, and credential files other users can read. It needs no hub, no account and no network, and exits 0, 1 or 2, so it works in cron.

# the released binary, run where it lands; nothing else is installed
curl -fsSLO https://github.com/SuperJackfruitLabs/agentpod/releases/latest/download/agentpod-node-linux-amd64
curl -fsSLO https://github.com/SuperJackfruitLabs/agentpod/releases/latest/download/SHA256SUMS
sha256sum --ignore-missing -c SHA256SUMS
chmod +x agentpod-node-linux-amd64
./agentpod-node-linux-amd64 scan

Swap the suffix for linux-arm64, darwin-amd64 or darwin-arm64; on macOS check with shasum -a 256 --ignore-missing -c SHA256SUMS. A check that cannot determine an answer reports unknown and says why. It is never reported as a pass.

Then: enroll a machine with a hub

Create an enrollment token in the console (single use, valid for an hour), then run one command on the host. It downloads the right binary, installs a service and enrolls.

curl -fsSL https://github.com/SuperJackfruitLabs/agentpod/releases/latest/download/install.sh \
  | sudo bash -s -- https://hub.example.com <TOKEN>

Without root, add --user after -s -- to install under your login session (a systemd user unit on Linux, a LaunchAgent on macOS). apn status exits 0 once the service runs and the hub accepts it.

The hub

The hub is a Bun service over Postgres and the console is a static site. Neither has a release download; they run from source. Since v0.1.92 the hub does not sign anyone in itself: it will not start without five ORG_PLANE_* settings and a credential from an external account service, and that service is not public source. So enrolling needs a hub you already have access to. Standing up your own from the README is not a working path for current releases.

Where it runs today