Maildir for AI agents — version-controlled message passing powered by jj.
AI agents need to talk to each other. Message queues are overkill. Slack bots are fragile. jj-mailbox is the Unix way: write a file, commit, push. Done.
| Approach | Setup | Cross-machine | History | Conflict-safe |
|---|---|---|---|---|
| Slack bot-to-bot | Medium | ✅ | ❌ | N/A |
| Redis/NATS | Heavy | ✅ | ❌ | N/A |
| Shared filesystem | Zero | ❌ | ❌ | ❌ |
sessions_send (OpenClaw) |
Zero | ❌ (single gateway) | ❌ | ❌ |
| jj-mailbox | One git remote | ✅ | ✅ (jj op log) | ✅ (first-class) |
Same conversation, two views. Slack gives you chat. jj-mailbox gives you an audit trail.
Agents chatting naturally in #copycat — instant, familiar.
📬 Demo 2 — jj-mailbox (demo repo)
Same exchange as structured JSON, Git-tracked, persistent — queryable forever.
Machine A Machine B
┌─────────────────┐ ┌─────────────────┐
│ Agent Alice │ │ Agent Bob │
│ (OpenClaw) │ │ (OpenClaw) │
│ │ │ │
│ inbox/alice/ │ │ inbox/bob/ │
│ agents/alice/ │ │ agents/bob/ │
│ shared/ │ │ shared/ │
└────────┬────────┘ └────────┬────────┘
│ jj git push/fetch │
└───────────┬────────────────┘
│
Git Remote
(GitHub, etc.)
- Sending = write a JSON file to
inbox/{recipient}/new/ - Receiving = read files from
inbox/{self}/new/ - Syncing =
jj git fetch+jj git push(automated by sync daemon) - Watching = instant local inbox notification via
jj-mailbox watch - Conflicts = jj handles them as first-class objects — both messages are preserved, never lost
Prerequisites: jj, git, a git remote (GitHub, GitLab, etc.)
# Install
git clone https://github.com/MiaoDX/jj-mailbox.git
export PATH="$PWD/jj-mailbox/bin:$PATH"
# Initialize and register
jj-mailbox init ~/my-mailbox
cd ~/my-mailbox
jj git remote add origin git@github.com:yourname/agent-mailbox.git
jj-mailbox register alice "Research specialist"
jj git push --all
# Send and receive
jj-mailbox send bob "Need review" "Please review the design doc."
jj-mailbox inbox
jj-mailbox read
# Optional: instant local inbox notifications
JJ_MAILBOX_AGENT=bob jj-mailbox watch --exec "jj-mailbox read"For cross-machine setup, sync daemon, watch mode, and OpenClaw integration, see the Full Guide.
# Local (no Docker)
bash examples/two-agents-demo/run.sh
# Docker
cd docker && docker compose up -d
docker compose exec alice jj-mailbox send bob "Hello" "Hi from Alice!"
docker compose exec bob jj-mailbox inboxThere's also a live LLM demo where two agents have a real conversation powered by LLMs.
Messages are JSON files. Directories are mailboxes. jj is the transport. See spec/PROTOCOL.md.
mailbox-repo/
├── agents/{name}/profile.json # who is this agent?
├── inbox/{name}/new/*.json # unread messages
├── inbox/{name}/processed/ # read messages
└── shared/ # shared workspace
Five levels of tests — from pure bash to LLM-powered agents — all in CI:
|
Test Suite — 10 deterministic tests, no API keys needed |
Agent Conversation — threaded multi-turn with refs chain verification
|
| Level | Test | Requires |
|---|---|---|
| 1 | Core CLI (init, send, read, status) | bash, jj |
| 2a | Scripted 3-turn agent conversation | Python |
| 2b | smolagents CodeAgent integration | LLM API key |
| 3a | OpenAI function-calling tool use | LLM API key |
| 4 | Comparison benchmark vs Slack-style | Python |
| 5 | OpenClaw 5-agent Docker integration | Docker |
- Full Guide — cross-machine setup, sync, OpenClaw integration
- Protocol Spec — message format, sync protocol, scaling boundaries
- Why jj? — why jj over plain git, design principles, inspiration
- Contributing — how to contribute, AI-assisted PRs welcome
Contributions are welcome — whether you're a human, or an AI agent running with Claude Code, Codex, Gemini, OpenCode, or OpenClaw. This is a project about AI agent coordination, after all.
- Good first issues — a good place to start
- Help wanted — larger tasks looking for contributors
See CONTRIBUTING.md for how to run tests, structure commits, and submit PRs.
MIT





