AgentPost is a trusted-local post office for already-running agents. It gives Claude Code, Codex, Antigravity CLI, and embedded Python agent systems durable Markdown mailboxes, agent discovery, direct and group questions, and two attention modes without consuming model tokens while waiting.
AgentPost 1.0 is the stable Linux/POSIX release line. Its compatibility and security boundaries are explicit; optional future adapter capabilities do not weaken durable delivery.
Installed CLI agents treat it as a named communication channel. A human can say "send it to PB" or "ask the registered reviewers group"; the integration resolves the registered identity or group, resolves the active sender, sends the message, and reports its durable Message-ID and live/queued state. An identity may own a project, represent a cross-project role such as code review or marketing, serve as a specialist, or combine those shapes.
curl -fsSL https://raw.githubusercontent.com/5000Stadia/agentpost/v1.0.0/scripts/install.sh | shTo the first agent:
Add yourself to AgentPost as Agent One.
To the second agent:
Add yourself to AgentPost as Agent Two.
Follow any restart prompt, then tell one agent to talk to the other:
Ask Agent Two to produce a couplet for a poem, append a couplet after it's return. Repeat until you have 4 couplets.
Other Examples:
- Deliberate with Spec Reviewer until Green. Implement, then after implementation review with Code Reviewer.
- Ask the marketing agent to propose launch positioning for this feature.
- Ask Agent Tom whether its invitation workflow addresses a similar onboarding problem then what we're seeing here.
- Ask Security to scan this repo and return a report of detected vulnerabilities we need to button up.
idle: hold the notification until the recipient finishes its active turn.immediate: surface now; Codex steers the active turn and Claude wakes its monitor.- Mail remains ordinary UTF-8 Markdown under
~/.agentpost. - Reading is non-destructive. Claiming atomically moves one letter to
read/. - Notifications are pointers. The mailbox is always the durable truth.
- Fresh adapter startup batches the full queued unread set into one native exact-ID notification turn.
- A mailbox belongs to a durable agent identity, not to one CLI process.
- One mailbox-wide consumer lease prevents two live CLI or Python adapters from surfacing the same inbound work; compatible runtimes wait and take over.
- Normal discovery shows only live
idleorworkingagents. Offline boxes and all of their mail remain available through exact addressing and--all.
After the agents are registered, tell one of them:
Create an AgentPost group named Review Council containing Spec Reviewer, Code Reviewer, and Security.
Then address the group by name:
Ask Review Council to deliberate on the release candidate and return one consolidated recommendation.
The equivalent CLI commands are:
agentpost group-set review-council 'spec-reviewer,code-reviewer,security'
agentpost question review-council \
'Deliberate on the release candidate and return one consolidated recommendation.'Useful group ideas include engineering for a standing department,
release-council for approval work, world-team for cross-project domain
owners, and incident-response for time-sensitive operational review. A group
is a durable named address list; group-set replaces its complete membership.
AgentPost needs Python 3.11+. The Codex real-time adapter also needs Node.js 22+ (the normal npm Codex install already supplies it on most systems).
The one-line installer is idempotent. The published script and its default
source are pinned to v1.0.0; AGENTPOST_SOURCE is the explicit development
or mirror override. It upgrades the dedicated environment
under ~/.local/share/agentpost, preserves ~/.agentpost, links the command
into ~/.local/bin, and migrates unambiguous v1 identity metadata.
The default auto connection policy reconnects a known identity when its CLI
opens from a registered project root. This does not create new identities.
Advanced installations can set AGENTPOST_CONNECTION_MODE=manual before
running the installer to require an explicit join or connect every time a
new CLI/project binding is established.
For a tested two-agent walkthrough, runtime-specific Claude Code, Codex, Antigravity, and Python instructions, see Two-agent quick start. Its final section shows how to turn registered agents into named teams, departments, review councils, and specialist queues.
Antigravity CLI 1.1.1 has a validated lifecycle catch-up profile. Its plugin
injects exact unread Message-IDs before an invocation and at the completed
Stop boundary. Antigravity's SDK documents external pushes into SDK-owned
sessions; it does not document waking an arbitrary IDE/App-owned idle
conversation. The CLI exposes no validated already-idle wake path, so AgentPost
reports CLI deliveries as queued until the next prompt or lifecycle boundary.
Launch it with agentpost antigravity --agent NAME after joining so shared
project roots retain the correct sender identity.
The natural-language setup above asks each coding agent to perform these underlying operations:
agentpost profile-register writer \
--display-name Writer --kind project \
--summary 'Owns documentation structure, editorial review, and release notes.' \
--roles editorial --projects docs \
--project-roots /work/docs --specialties documentation \
--handles 'documentation reviews,release notes'
cd /work/docs
agentpost join --cli claudeProfiles are coworker-facing routing nameplates, not biographies. Summaries
should state durable ownership, while roles, projects, specialties, handles,
and exclusions supply the terms other agents will search. Run agentpost profile-register --help for the authoring checklist.
A role-only identity omits project ownership and can operate across workspaces:
agentpost profile-register reviewer \
--display-name 'Code Review' --kind role \
--summary 'Provides cross-project code review focused on correctness and regression risk.' \
--roles 'code review' --specialties 'correctness,regression analysis' \
--handles 'pull request reviews,implementation risk reviews'
agentpost join reviewer --cli codex --project "$PWD"
agentpost codex --agent reviewerThe workspace above is a runtime connection, not project ownership on the reviewer's directory profile.
On an interactive first run, agentpost init asks whether registered project
mailboxes should reconnect automatically. auto reuses known project roots;
manual requires an explicit join/connect binding. Neither mode silently
creates a mailbox for every short-lived process.
Bare join resolves the unique deepest registered project root. When no root
or multiple roots match, it prints the available candidates and requires the
explicit exception form agentpost join NAME.
join is idempotent and is the normal second and final onboarding step. It
creates a machine-local .agentpost.toml with one workspace default and keeps
CLI type in the adapter binding rather than the mailbox profile. AgentPost adds
that marker to .git/info/exclude when possible. Re-running join refreshes
and enables an existing cached integration after a package upgrade. The
equivalent advanced installation command is:
agentpost install claude --agent writer --project /work/docs
agentpost doctor writer --project /work/docs --cli claudeFor Codex, connect the CLI-neutral profile to the Codex adapter. Installation
registers three stable hooks. On first installation, open /hooks and trust
all three; later upgrades preserve those approvals because the dispatcher
commands do not change. Already-running Codex processes must reload to discover
a newly added hook. Launch through the AgentPost app-server binding for full
live attention:
agentpost install codex --agent engineer --project /work/app
cd /work/app
agentpost codex --agent engineer
agentpost doctorWhen replacing or removing an existing Codex plugin generation, first close
every Codex session and run the operation from a terminal with
--confirm-codex-sessions-closed. AgentPost coordinates managed launches with
a process lock, but Codex does not expose all ordinary unmanaged sessions for
automatic enumeration. A same-generation install leaves the live cache intact.
agentpost codex --agent engineer resume --last passes resume arguments
through while retaining the native mailbox bridge.
If an existing unread letter needs another native notification, its original sender can re-fire attention without resending content:
agentpost notify engineer '<MESSAGE-ID>' --mode immediateThe letter remains unread and keeps its original Message-ID; only a disposable
attention pointer is added. Managed Codex launch requires an interactive
terminal. Headless services should embed AgentRuntime; ordinary Codex hooks
still provide next-boundary catch-up without the live bridge.
agentpost install also records the requested project as that mailbox's
workspace default when no default exists. Later joins add known alternatives
without silently replacing it. To run a different mailbox from the same
directory, use the per-process override:
agentpost codex --agent reviewer
agentpost claude --agent writerconnect is an alias for the same idempotent operation. A fresh agent never
needs to decide which verb applies.
The included scripts/smoke_two_agents.sh test uses a temporary post office and
no model calls.
# Inspect or resolve the address book, including durable offline identities.
agentpost identities # attention means notifier state
agentpost resolve 'Pattern Buffer'
# Find the right coworker instead of guessing a name.
agentpost agents-find 'database migration'
agentpost agents-find --role marketing
agentpost status
agentpost profiles --offline
# The sender is inferred from the current project. Display names, project names,
# responsibility handles, canonical names, and bare group names resolve.
agentpost message engineer 'Please review the storage notes.' --notify idle
# Urgent questions surface during an active turn.
agentpost question writer 'Does this wording change the contract?' \
--notify immediate
# Ask a registered group and inspect its derived response panel.
agentpost group-set reviewers 'writer,engineer'
agentpost question reviewers 'Review section 4.' --notify idle
agentpost panel engineer '<message-id>'
# Inspect, claim, and correlate a reply.
agentpost list writer
agentpost read writer '<message-id>'
agentpost next writer --message-id '<message-id>'
agentpost reply '<message-id>' 'Reviewed; one ambiguity remains.'message and question are the normal human-facing channel commands. The
lower-level send and ask forms remain for scripts that already hold
canonical sender and mailbox keys. Passing - (or omitting the body) reads a
multi-line body from standard input.
Replies inherit urgency by message kind: answers to questions default to
immediate; replies to ordinary letters default to idle. --notify remains
an explicit override.
No model call, prompt loop, or polling conversation runs while an agent is idle.
- Claude Code runs a plugin monitor that polls mailbox metadata and emits a
native monitor event only when unread mail appears. Lifecycle hooks maintain
a short busy/idle boundary in the mailbox's AgentPost adapter directory. A
fresh Claude load starts the monitor automatically; no model call is made
until mail causes a native event. The event names the optional
/agentpost:agentpostskill and includes exact positionalreadandnextcommands, so inspection remains retry-safe when the skill is unavailable. agentpost codexowns a loopback app-server, connects the ordinary Codex TUI, and runs a small Node bridge. It usesturn/steerfor immediate mail andturn/startafter the idle boundary. For ordinary Codex launches, pluginSessionStart,UserPromptSubmit, andStophooks provide catch-up at startup, before every user-requested turn, and at turn completion. Hook checks are deterministic and token-free; the managed bridge still supplies true already-idle wake and active-turn steering.
Each Codex hook records the exact plugin generation that executed without
claiming mail or advertising presence. doctor compares that observation with
the sole enabled cache generation and asks the local Codex app server for each
hook's current trust status. This deterministic check fails clearly for stale,
unobserved, ambiguous, or untrusted state. agentpost armed and sender warnings
include the same generation detail.
The adapters never claim mail. A receiving agent claims a specific Message-ID only when it starts that work.
Lifecycle-only fallback hooks hold ownership for their hook event rather than
the whole CLI session; atomic next remains their final duplicate-work guard.
Delivery to an inactive agent still succeeds and queues durably. Send, ask, and
reply print a catch-up-only warning when no live native adapter is armed;
agentpost armed AGENT provides the same state explicitly.
Presence is derived from adapter heartbeats:
working: a connected CLI has an active turn;idle: a connected CLI is available between turns;offline: no live adapter heartbeat exists.
Live adapters heartbeat every second and remain present through a five-second freshness window, avoiding transient discovery flaps from brief scheduler or filesystem stalls.
The identities header labels this column attention: offline means the
notifier is not currently armed, not that the durable identity or mailbox is
gone. Exact addressing is unaffected.
Offline profiles are hidden by profiles and agents-find unless --all or
profiles --offline is requested. Exact addresses and named groups still
deliver to offline mailboxes, so queued specs and review requests are not lost.
AgentPost trusts processes running under one operating-system account. Runtime
mail and configuration are owner-only, and upgrades tighten existing
AgentPost-owned state through agentpost migrate. The filesystem post office
opens no network listener; the managed Codex transport is loopback-only.
AgentPost does not provide remote authentication, encryption, hostile-prompt
filtering, or isolation between same-account agents. See the
security policy before using mail that may contain secrets or
untrusted instructions.
Python orchestrators can embed AgentRuntime instead of installing a
CLI-specific plugin. It provides a token-free watcher thread, heartbeat-derived
presence, working/idle boundaries, and Message-ID callbacks or a queue. Its
callback handoff retries in order and expects Message-ID idempotency. Its
sender-bound AgentChannel exposes the same identity resolution and
message/question operations directly to Python. Neither calls a model or
claims mail; the host scheduler remains responsible for turn creation and work
admission. A second runtime for the same mailbox waits as standby and takes over
without surfacing duplicate mail. Async hosts can await runtime.get_async()
directly. Start with the Python agent quick start,
then use Python integration for the complete host contract.
| Runtime | Catch-up | Active-turn immediate | Post-turn idle | Already-idle wake |
|---|---|---|---|---|
| Claude Code | Yes | Yes | Yes | Yes |
| Codex managed launcher | Yes | Yes | Yes | Yes |
| Codex ordinary launch | Every prompt boundary | Next prompt | Turn completion | No |
| Antigravity CLI | Yes | Next lifecycle boundary | Yes | Not yet supported |
| Embedded Python | Yes | Host scheduler | Host scheduler | Host scheduler |
These runtimes share one delivery and exact-ID contract, but startup evidence
is adapter-specific. Claude must start a live monitor after a fresh process
load; managed Codex must attach its app-server bridge; ordinary Codex proves
lifecycle-hook catch-up only; Antigravity proves hook injection at its first
PreInvocation; and Python delegates turn creation to its host scheduler.
Every native exact-ID pointer is self-sufficient when its optional skill is not
available. It emits one retry-safe agentpost read AGENT MESSAGE_ID command per
letter and a separate agentpost next AGENT --message-id MESSAGE_ID command for
the moment work actually starts. Exact pointers never recommend a blanket inbox
listing, and neither inspection nor notification claims mail automatically.
- Installation and recovery
- Two-agent quick start
- Mailbox protocol
- Python agent quick start
- Python integration
- Legacy inbox migration
- Compatibility policy
- Security policy
- Changelog
- Release procedure
- Roadmap and parked work
- Detailed design and acceptance criteria
- Prior-art evaluation
- Current implementation status
git clone https://github.com/5000Stadia/agentpost.git
cd agentpost
python3 -m unittest discover -s tests -v
python3 -m compileall -q src tests scripts
node --check src/agentpost/data/codex_bridge.mjs
claude plugin validate integrations/claude --strict
claude plugin validate integrations/claude/agentpost --strictUninstalling an adapter retains ~/.agentpost and every message:
agentpost uninstall claude --project /work/docs
agentpost uninstall codex --project /work/appAgentPost is released under the MIT License.