@holon-run/agentinbox
v1.3.1
Published
Local event subscription and delivery service for agents.
Readme
AgentInbox
AgentInbox is the local event inbox and activation service for agents.
It connects external and local event sources, stores them as durable streams, routes them by subscription, and lets agents read, watch, acknowledge, and reply through one boundary.
AgentInbox is not an agent runtime. It sits between outside systems and local
agent runtimes.
In practice, that means AgentInbox can:
- share one GitHub or Feishu source across multiple local agents
- materialize those events into durable inboxes
- activate terminal-backed sessions in
tmuxoriTerm2, or Holon agents through runtime-provided webhook triggers, without embedding connector logic in the agent runtime
Event Flow
At a high level, AgentInbox sits between external events and the current
agent session:

Review Workflow
One concrete workflow is reviewer / developer collaboration around a PR:
sequenceDiagram
participant D as Developer Agent
participant G as GitHub / CI
participant A as AgentInbox
participant R as Reviewer Agent
D->>G: Open PR / Push fix
G->>A: PR opened / CI started
A->>R: Wake reviewer
R->>G: Leave review comment
G->>A: Review comment created
A->>D: Wake developer
D->>G: Push fix
G->>A: CI completed
A->>D: Wake developer
A->>R: Wake reviewer
R->>G: Approve / MergeAgentInbox is what lets both agents stay in the loop without polling GitHub
manually or relying on the agent runtime to expose its own notification API.
Status
AgentInbox is on the stable v1 release line.
- the local control plane, daemon model, inbox model, and activation targets are implemented
- GitHub repo, GitHub repo CI, Feishu bot, and local event ingress source adapters are implemented
- filtering and source breadth are still evolving
- first-run onboarding is currently skill-first rather than wizard-first
v1 Upgrade Notes
v1.0.0-beta.0 was the first release on the final v1 storage and API boundary,
and 1.0.0 keeps that same boundary.
- pre-v1 local databases are archived and replaced with a fresh v1 database
- old local state is not imported into the new v1 database
- canonical public surfaces are now host + stream registration, entry/thread inbox reads, and handle-scoped delivery operations
- pre-v1 compatibility shims such as legacy source-kind registration aliases, raw inbox-item read paths, and deprecated remote-module aliases are no longer part of the supported surface
If you are upgrading from any pre-v1 build, expect AgentInbox to archive the
existing local database under ~/.agentinbox/ and start with a fresh v1
database.
Install
Requires:
- Node.js 20 or newer
uxc0.15.3 or newer if you want to use GitHub or Feishu adapters: https://github.com/holon-run/uxc
Install globally:
npm install -g @holon-run/agentinboxOr run directly:
npx @holon-run/agentinbox --helpIf you are developing from source:
npm install
npm run build
node dist/src/cli.js --helpRecommended Onboarding
If you are using Codex, Claude Code, or Holon, start with the bundled AgentInbox skill:
- repo copy:
skills/agentinbox/SKILL.md - docs site copy:
https://agentinbox.holon.run/skills/agentinbox/SKILL
If you use the community skills installer, you can install the bundled skill
directly:
npx skills add holon-run/agentinbox --skill agentinbox -a codex -a claude-code -a holonThat skill is the recommended onboarding path. It can guide the agent through:
- checking or installing
agentinbox - checking or installing
uxc - importing GitHub auth from the local
ghCLI viauxc auth credential import github --from gh - registering the current runtime/session as an agent, including Holon webhook activation when running in Holon
- adding GitHub sources and standing subscriptions using the docs-site examples
Quick Start
Start the local daemon:
agentinbox daemon startRegister the current runtime/session:
agentinbox agent register
agentinbox agent register --agent-id agent-alpha
agentinbox agent register --agent-id agent-alpha --webhook-url <external-trigger-url>
agentinbox agent register --notify-lease-ms 600000 --min-unacked-items 5
agentinbox agent currentTerminal-backed runtimes attach a terminal activation target. In Holon, the
no-arg form uses HOLON_AGENT_ID and HOLON_EXTERNAL_TRIGGER_URL when present;
otherwise pass --webhook-url explicitly.
notifyLeaseMs and minUnackedItems are target-facing notification policy:
they control how often a target may be reminded and how many unacked items must
accumulate before AgentInbox notifies it. Service-wide activation batching
(windowMs, maxItems) and terminal gating heuristics remain daemon-level
policy, not per-agent knobs.
Create a local source and publish an event:
agentinbox host add local_event local-demo
agentinbox source add <host_id> events local-demo
agentinbox subscription add <source_id>
agentinbox subscription add <source_id> --agent-id <agent_id>
agentinbox source schema <source_id>
agentinbox subscription add <source_id> --shortcut pr --shortcut-args-json '{"number":373}'
agentinbox subscription add <source_id> --tracked-resource-ref pr:373 --cleanup-policy-json '{"mode":"manual"}'
agentinbox subscription add <source_id> --filter-file ./filter.json
cat filter.json | agentinbox subscription add <source_id> --filter-stdin
agentinbox source event <source_id> --native-id demo-1 --event local.demo
agentinbox inbox read
agentinbox inbox read --agent-id <agent_id>
agentinbox inbox ack --agent-id <agent_id> --through <last_entry_id>The HTTP POST /subscriptions endpoint always returns
{ "subscriptions": [...] }, even when only one subscription is created. That
keeps shortcut expansion consistent for external callers.
When acking a reviewed batch, prefer --through <last_entry_id> over --all.
That preserves the boundary of the items you actually inspected. Use
ack --all only when you have intentionally verified that every current
unacked item should be cleared.
Send a direct text message into an agent inbox:
agentinbox inbox send --agent-id <agent_id> --message "Please review PR #87"
agentinbox inbox send --agent-id <agent_id> --message "CI failed on main" --sender operatorSchedule reminder messages with timers:
agentinbox timer add --agent-id <agent_id> --at <RFC3339_TIMESTAMP> --message "Check the morning build"
agentinbox timer add --agent-id <agent_id> --every 24h --message "Review today's open PRs"
agentinbox timer add --agent-id <agent_id> --cron "0 8 * * *" --timezone Asia/Shanghai --message "Daily triage"
agentinbox timer list
agentinbox timer list --agent-id <agent_id>
agentinbox timer pause <schedule_id>
agentinbox timer resume <schedule_id>
agentinbox timer remove <schedule_id>Update an existing source in place:
agentinbox source update <source_id> --config-json '{"channel":"infra"}'
agentinbox source update <source_id> --clear-config-refPause and resume a managed remote source:
agentinbox source pause <remote_source_id>
agentinbox source resume <remote_source_id>Remove a task-specific subscription without deleting the whole agent:
agentinbox subscription remove <subscription_id>For implementation-backed sources, inspect resolved subscription capabilities before adding task-scoped subscriptions:
agentinbox source schema <source_id>If the source advertises subscription shortcuts, prefer them over manually repeating the equivalent filter, tracked resource ref, and cleanup policy.
Docs
Public docs live in the mdorigin site under docs/site.
- docs site:
https://agentinbox.holon.run - docs home:
docs/site/README.md - onboarding with the agent skill:
docs/site/guides/onboarding-with-agent-skill.md - getting started:
docs/site/guides/getting-started.md - review workflows:
docs/site/guides/review-workflows.md - skill docs:
skills/README.md - CLI reference:
docs/site/reference/cli.md - source types:
docs/site/reference/source-types.md - architecture:
docs/site/concepts/architecture.md - event bus design:
docs/site/concepts/eventbus-backend.md - event filtering RFC:
docs/site/rfcs/event-filtering.md
Preview the docs site locally:
npm run docs:devBuild the Cloudflare deploy bundle:
npm run docs:index
npm run docs:buildDevelopment
Run tests:
npm testBuild the CLI:
npm run buildBuild docs directory indexes:
npm run docs:indexGenerate new SQLite migrations after schema changes:
npm run db:migrations:generateAgentInbox now initializes SQLite state from a single v1 baseline migration in
drizzle/migrations. If startup detects a pre-v1 local database, it archives
that database next to the DB path (for example,
~/.agentinbox/agentinbox.sqlite.pre-v1.<timestamp>.bak) and starts with a
fresh v1 database; pre-v1 local data is not imported.
License
Apache-2.0
