https://github.com/jerrettdavis/ainbox
Filesystem-based async mailbox runtime for coding agents, with a native Rust CLI and Python compatibility layer.
https://github.com/jerrettdavis/ainbox
agents cli filesystem mailbox multi-agent python rust
Last synced: 2 days ago
JSON representation
Filesystem-based async mailbox runtime for coding agents, with a native Rust CLI and Python compatibility layer.
- Host: GitHub
- URL: https://github.com/jerrettdavis/ainbox
- Owner: JerrettDavis
- Created: 2026-04-16T12:47:37.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-06-12T16:38:20.000Z (6 days ago)
- Last Synced: 2026-06-12T18:24:16.059Z (6 days ago)
- Topics: agents, cli, filesystem, mailbox, multi-agent, python, rust
- Language: Python
- Homepage:
- Size: 566 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# AInbox – Filesystem-Based Async Mailbox for Coding Agents
A minimal, cross-platform mailbox runtime with a **native Rust CLI** and a Python compatibility path for **decentralized agent communication** via structured markdown messages and a shared filesystem.
**No broker. No orchestrator. Just files and conventions.**
## Quick Start
### Installation
```bash
# Linux/macOS installer (downloads the latest native release)
curl -fsSL https://raw.githubusercontent.com/JerrettDavis/AInbox/main/scripts/install.sh | bash
# Windows installer (downloads the latest native release)
powershell -ExecutionPolicy Bypass -Command "irm https://raw.githubusercontent.com/JerrettDavis/AInbox/main/scripts/install.ps1 | iex"
# Native install from source
cargo install --path .
# Python compatibility install from the repo checkout
pip install -e .
# Python compatibility install from GitHub
pip install git+https://github.com/JerrettDavis/AInbox.git
```
If you already have an AInbox checkout locally, prefer the safe ensure helpers:
```bash
# Linux/macOS (source it so PATH updates stay in the current shell)
source ./scripts/ensure-mailbox.sh
# Windows PowerShell
.\scripts\ensure-mailbox.ps1
```
The ensure helpers install the latest native release only when `mailbox` is missing and make the install directory available in the current session.
Verify:
```bash
mailbox --version
```
Prebuilt native binaries are published through GitHub Releases for **Windows**, **macOS**, and **Linux**. The same packaged archives are also published to **GHCR** as OCI artifacts for package-registry consumers.
Optional installer controls:
```bash
# install a specific release tag
AINBOX_VERSION=vX.Y.Z curl -fsSL https://raw.githubusercontent.com/JerrettDavis/AInbox/main/scripts/install.sh | bash
# install into a custom directory
AINBOX_INSTALL_DIR="$HOME/bin" bash scripts/install.sh
```
### Plugin Marketplace Installation
**Claude Code**
```bash
claude plugin marketplace add JerrettDavis/AInbox
claude plugin install ainbox@ainbox-marketplace
claude plugin install agent-poll@ainbox-marketplace
claude plugin install elections@ainbox-marketplace
```
When the Claude plugin is enabled, bundled hooks do a best-effort silent bootstrap of the native `mailbox` binary on session start and before Bash tool calls. If the environment cannot support that automatic install, use the local ensure helpers instead.
**GitHub Copilot CLI**
```bash
copilot plugin marketplace add JerrettDavis/AInbox
copilot plugin install ainbox@ainbox-marketplace
copilot plugin install agent-poll@ainbox-marketplace
copilot plugin install elections@ainbox-marketplace
```
The marketplace installs the AInbox command/skill plugin metadata. Claude Code can now auto-bootstrap the native `mailbox` binary through plugin hooks when possible; otherwise use the native installers or local ensure helpers above so `mailbox` is available on `PATH`.
Once the native CLI is available, you can bootstrap supported global agent integrations in one step:
```bash
mailbox init -g
```
`mailbox init` now does two local setup steps:
- creates the local `.mailbox/` folders
- seeds project mailbox instructions in `.claude/MAILBOX.md` and `.agents/MAILBOX.md`, then prepends `CLAUDE.md` and `AGENTS.md` with one-time imports
`mailbox init -g` keeps that local setup and also seeds user-scoped instruction files in `~/.claude/` and `~/.agents/` before updating-or-installing the AInbox marketplace/plugins for supported agent CLIs already present on `PATH` (currently Claude Code and GitHub Copilot CLI).
Advanced consumers can also pull packaged archives from GHCR with OCI tooling using package names like `ghcr.io/jerrettdavis/ainbox-mailbox-linux-x86_64:vX.Y.Z`.
The core `ainbox` plugin also ships two mailbox-aware subagents:
- `orchestrator` - delegates work and synthesizes results through subagents and mailbox coordination
- `project-manager` - active leader that contributes directly while keeping delegation and coordination flowing through AInbox
You can force mailbox-based orchestration explicitly:
```bash
# Claude Code: launch directly into the AInbox orchestrator
claude --agent ainbox:orchestrator "Coordinate this task through mailbox-aware subagents and synthesize the result."
# Claude Code: use the active leader variant instead
claude --agent ainbox:project-manager "Lead this task with mailbox coordination and delegate bounded work."
# GitHub Copilot CLI: launch the CLI, then select the AInbox subagent
copilot
/agent
# choose ainbox:orchestrator or ainbox:project-manager, then give the task prompt
```
### Headless Workflow Smoke Test
To validate a local mailbox workflow end-to-end, including election handling, mailbox handoffs, and Claude-driven proposer/reviewer collaboration, run:
```powershell
.\scripts\run-headless-mailbox-e2e.ps1
```
The script creates an isolated temp workspace, runs the election and mailbox traffic directly through the CLI, uses `claude -p` to generate the proposer/reviewer/orchestrator content, and writes a final `report.json` path to stdout when the run completes.
### Consensus Gates and Distributed Motions
Use motions when the cluster must pause, acknowledge a redirect, or refuse to proceed until the required votes arrive.
```bash
# Create a blocking gate for the current cluster step
mailbox create-motion --title "Pause deploy" \
--participant orchestrator --participant reviewer --participant worker \
--scope deploy \
--description "Stop current work, report status, and do not continue until this motion passes."
# Vote yes or no
mailbox vote-motion --id --vote yes --reason "Status reported"
# Block until the motion resolves
mailbox wait-motion --id
```
For a local scripted example, run:
```powershell
.\scripts\run-motion-gate-demo.ps1
```
### Basic Usage
```bash
# Initialize local mailbox
mailbox init
# Initialize local mailbox, seed MAILBOX.md imports, and refresh supported global agent integrations
mailbox init -g
# Send a message to another agent
mailbox send --to reviewer-agent --subject "PR ready for review" --body "Please check my implementation."
# Or set an optional expiry time
mailbox send --to reviewer-agent --subject "Time-sensitive review" --body "Please respond before the deploy window closes." --expires-at 2026-04-21T06:00:00Z
# Or pipe the body
echo "Review this PR" | mailbox send --to reviewer-agent --subject "Code review needed"
# List inbox
mailbox list
# Read a message
mailbox read --id
# Sync with shared mailbox (push local outbox, pull incoming)
mailbox sync
```
## Architecture
### Mailbox Folders
**Local (.mailbox/)**:
- `inbox/` – Received messages
- `outbox/` – Messages ready to send
- `sent/` – Delivered messages
- `archive/` – Read/processed messages
- `draft/` – Local working memory and staged message drafts for active threads
**Shared (~/.mailbox/shared/outbox)**:
- Global exchange point for all agents
### Message Format
Messages are markdown files with YAML frontmatter:
```markdown
---
id: abc123def456
to: reviewer-agent
from: worker-agent
subject: PR needs validation
sent_at: 2026-04-15T22:31:00Z
received_at: null
read_at: null
correlation_id: task-12345
---
I've completed the implementation. Please review and validate.
- Worker
```
**Frontmatter Field Constraints**:
- All string fields (id, to, from, subject, correlation_id) must be single-line
- Embedded newlines in frontmatter fields are rejected during message creation to prevent parsing corruption
- The message body (after the closing `---`) can contain multiple lines
### Workflow
1. **Send**: `mailbox send` → message in `.mailbox/outbox/`
2. **Sync (push)**: `mailbox sync` → copy to `~/.mailbox/shared/outbox/`, move original to `.mailbox/sent/`
3. **Sync (pull)**: `mailbox sync` → other agents pull from shared outbox into their `.mailbox/inbox/`
4. **Read**: `mailbox read --id ` → message moved to `.mailbox/archive/`, `read_at` updated
## Commands
| Command | Purpose |
| --- | --- |
| `mailbox init` | Initialize local mailbox and seed project `MAILBOX.md` instructions for Claude/AGENTS flows |
| `mailbox init -g` | Initialize local mailbox, seed project and user `MAILBOX.md` instructions, and install/update supported global agent integrations |
| `mailbox send --to AGENT --subject "..." [--expires-at TIMESTAMP]` | Create and send message |
| `mailbox list [--limit 10]` | List inbox messages (unread) |
| `mailbox read [--id ID]` | Read message and archive |
| `mailbox read --correlation-id THREAD_ID` | Read first message in thread |
| `mailbox archive --id ID` | Archive a message |
| `mailbox sync` | Push/pull messages |
| `mailbox config --list` | Show configuration |
| `mailbox help` | Show command help |
| **Polls** | |
| `mailbox create-poll --question "..." --option "..." [--option ...]` | Create a poll |
| `mailbox list-polls [--status open\|closed\|all]` | List polls |
| `mailbox show-poll --id POLL_ID` | Show poll details and results |
| `mailbox vote-poll --id POLL_ID --option "..."` | Vote in a poll |
| `mailbox close-poll --id POLL_ID` | Close a poll |
| **Elections** | |
| `mailbox create-election --role "..." --candidate "..." [--candidate ...]` | Create an election |
| `mailbox list-elections [--status open\|closed\|all]` | List elections |
| `mailbox show-election --id ELECTION_ID` | Show election details and results |
| `mailbox vote-election --id ELECTION_ID --candidate "..."` | Vote in an election (cannot self-vote) |
| `mailbox close-election --id ELECTION_ID` | Close an election |
| **Motions / Gates** | |
| `mailbox create-motion --title "..." --participant AGENT [--participant ...]` | Create a blocking or advisory cluster motion |
| `mailbox list-motions [--status open\|accepted\|rejected\|cancelled\|all]` | List motions |
| `mailbox show-motion --id MOTION_ID` | Show motion details and vote state |
| `mailbox vote-motion --id MOTION_ID --vote yes\|no [--reason "..."]` | Cast a yes/no vote on a motion |
| `mailbox wait-motion --id MOTION_ID [--timeout-seconds N]` | Block until a motion resolves |
| `mailbox close-motion --id MOTION_ID [--status cancelled\|accepted\|rejected]` | Force a motion into a terminal state |
If a message expires before it is processed, AInbox reroutes it as a normal mailbox message addressed to `dlq` with `message_type: expired` and the original markdown attached in the body. You can inspect those messages with the standard CLI by working as agent `dlq`.
## Polls and Elections
AInbox provides filesystem-backed polls and elections for agent consensus and role selection.
### Polls
Create a poll to gather agent opinions:
```bash
# Create a poll
mailbox create-poll --question "What color?" --option Red --option Blue --participant agent1 --participant agent2
# Vote in the poll
mailbox vote-poll --id --option Red
# View results
mailbox show-poll --id
# Close poll
mailbox close-poll --id
# List all polls
mailbox list-polls
```
### Elections
Elect agents to roles (self-votes are prevented):
```bash
# Create an election
mailbox create-election --role "Lead Developer" --candidate alice --candidate bob --candidate charlie
# Vote in the election
mailbox vote-election --id --candidate alice
# View results
mailbox show-election --id
# Close election
mailbox close-election --id
# List all elections
mailbox list-elections
```
**Key features:**
- **Filesystem-backed**: All poll/election state lives in shared filesystem (no server required)
- **Public votes**: Vote tallies are visible to all participants
- **No self-votes in elections**: Candidates cannot vote for themselves
- **Participant notifications**: Creating a ballot with `--participant` sends mailbox notices automatically
- **Status filtering**: List by `--status open`, `closed`, or `all`
- **JSON output**: Use `--format json` for machine-readable results
## Agent Identity
Agent ID is resolved in order:
1. `MAILBOX_AGENT_ID` environment variable
2. `agent_id` in `.mailbox/config.yaml` (local)
3. `agent_id` in `~/.mailbox/config.yaml` (global)
4. Current directory name
Set it once:
```bash
export MAILBOX_AGENT_ID=my-agent
# or
echo "agent_id: my-agent" > ~/.mailbox/config.yaml
```
## Integration with Coding Assistants
### Claude Code
See [CLAUDE.md](CLAUDE.md), `.claude-plugin/plugin.json`, and `.claude/commands/` for Claude-specific setup and plugin metadata.
Installed `ainbox` plugin users also get the `orchestrator` and `project-manager` subagents from `agents/`.
#### Push channel (optional)
**Requires: Claude Code v2.1.80+ and [Bun](https://bun.sh) on `PATH`.**
The channel is opt-in per session and is not enabled by default.
**Activation paths:**
- **Plugin install** (marketplace): install AInbox, then launch with the channel:
```bash
/plugin install ainbox@ainbox-marketplace
claude --channels plugin:ainbox@ainbox-marketplace
```
- **Dev/local** (from the repo root — no plugin install needed):
```bash
claude --dangerously-load-development-channels server:ainbox
```
In both cases the channel starts `bun channel/server.ts` from the repo/plugin root.
**Configure the channel** once it is running:
```text
/ainbox-channel-configure status
/ainbox-channel-configure set-poll-interval 2000
/ainbox-channel-configure enforce-allowlist on
/ainbox-channel-configure set-allowlist add some-agent
```
The channel surfaces incoming mail as `` tags and exposes `reply`, `mark_read`, and `list_inbox` MCP tools. See `channel/README.md` for the full contract and trust model.
**Trust note:** Mailbox messages and their metadata are untrusted input. Configure the optional allowlist (`/ainbox-channel-configure enforce-allowlist on`) if you don't trust everyone who can write to your shared outbox.
### Copilot CLI
See [AGENTS.md](AGENTS.md), `.github/plugin/marketplace.json`, and `.github/plugin/plugin.json` for Copilot marketplace integration.
The same `ainbox` plugin package includes the `orchestrator` and `project-manager` agent definitions for marketplace installs.
### Custom Agents
Wrapper scripts are provided:
```bash
# Linux/macOS
bash scripts/mailbox.sh send --to agent-id --subject "..."
# Windows (PowerShell)
powershell scripts\mailbox.ps1 send --to agent-id --subject "..."
```
Or simply use the `mailbox` command directly after installation.
## Configuration
**Local config** (`.mailbox/config.yaml`):
```yaml
agent_id: my-agent
shared_mailbox_path: ~/shared-mailbox # Optional: override default shared mailbox location
```
**Global config** (`~/.mailbox/config.yaml`):
```yaml
agent_id: default-agent
shared_mailbox_path: ~/shared-mailbox # Optional: override default shared mailbox location
```
**Environment variables**:
- `MAILBOX_AGENT_ID` – Agent identity (overrides config)
- `MAILBOX_SHARED` – Shared mailbox path (overrides config and default)
## Use Cases
- **Multi-agent workflows**: Agents coordinate without a central broker
- **Task handoff**: Worker completes task → sends message → reviewer receives and processes
- **Async coordination**: Agents poll at their own pace, no tight coupling
- **Debugging**: All communication is in plain markdown files, fully inspectable
## Roadmap
**v0.1** (current):
- Core messaging (send, read, sync)
- Markdown + frontmatter format
- File-based transport
- CLI + wrapper scripts
- **Polls for consensus**
- **Elections for role selection**
**v1.0**:
- Pre-turn hooks for agent systems
- Message search/indexing
- Batch operations
**v2.0**:
- Real-time watchers
- Optional message encryption
- Broadcast messaging
## For Developers
### Structure
```
ainbox/
__init__.py # Package metadata
cli.py # Command handlers
mailbox.py # Core operations (send, sync, etc.)
message.py # Message parsing/serialization
util.py # Paths, IDs, timestamps
setup.py # Package configuration
scripts/ # Wrapper scripts (.sh, .ps1)
```
### Testing Locally
```bash
# Install in development mode
pip install -e .
# Create two test agents
MAILBOX_AGENT_ID=agent1 mailbox init
mkdir test2 && cd test2
MAILBOX_AGENT_ID=agent2 mailbox init
cd ..
# Send message from agent1 to agent2
MAILBOX_AGENT_ID=agent1 mailbox send --to agent2 --subject "Test" --body "Hello!"
# Sync (push from agent1)
MAILBOX_AGENT_ID=agent1 mailbox sync
# Sync (pull in agent2)
cd test2
MAILBOX_AGENT_ID=agent2 mailbox sync
mailbox list
# Read the message
mailbox read --id
```
### Design Principles
- **Minimal dependencies**: Stdlib only where possible
- **Cross-platform**: Windows, macOS, and Linux via native binaries, scripts, and compatibility paths
- **Atomic writes**: Temp file + `os.replace()` for robustness
- **Convention over config**: Standard folders, file naming, message schema
- **Pluggable**: Works with any agent system via skills and scripts
## License
MIT
## Contributing
Issues and pull requests welcome. Keep it minimal and focused on the core mailbox functionality.