Decentralized agent-to-agent communication — publish results, wait for peers, no broker required
Project description
agent2agent
Decentralized agent-to-agent communication. Agents publish results and wait for each other — no broker, no cloud, no orchestrator required.
Agent A → agent_publish(name="researcher", result="…")
Agent B → agent_wait(name="researcher") # blocks until A is done, then returns A's result
Works on a single laptop out of the box. Scales to remote teams by swapping the backend.
Why this exists
The default way developers work with agents today is parallel — multiple Claude Code sessions open at once, sub-agents spawned mid-task, background jobs running alongside foreground work. But those agents have no way to talk to each other. If Agent B's work depends on Agent A's output, your options are:
- Serialize everything (kills the parallelism benefit), or
- Copy-paste results manually between sessions, or
- Build your own ad-hoc coordination layer every time.
agent2agent is that coordination layer, kept deliberately minimal. Five tools:
| Tool | What it does |
|---|---|
agent_start(name, task) |
Announce that you're running |
agent_publish(name, result) |
Broadcast your output |
agent_wait(name, timeout) |
Block until another agent publishes |
agent_status() |
See all agents and their states |
agent_clear(name) |
Reset a slot for reuse |
vs. Google's Agent2Agent (A2A) protocol
Google's A2A protocol solves a different problem: how do remote agent services discover and call each other over HTTP. It's designed for enterprise environments where agents run as separate hosted services behind auth layers.
agent2agent solves the problem A2A explicitly doesn't cover: agents already running on the same machine (or sharing a backend) that need to hand off results.
| agent2agent | Google A2A | |
|---|---|---|
| Model | Shared state (publish/wait) | RPC (request/response) |
| Transport | SQLite, Postgres, or email | HTTPS + JSON-RPC |
| Setup | uvx agent2agent |
Run agent servers + service discovery |
| Blocking wait | agent_wait() ✓ |
Async callbacks only |
| Works offline | ✓ | ✗ |
| Decentralized | ✓ (no broker) | ✗ (requires agent card registry) |
| Lines of code | ~200 | — |
The key distinction: A2A assumes agents are remote services. agent2agent assumes agents are parallel processes that share a medium — whether that's a local file, a database, or a mailbox.
Step-by-step: parallel Claude CLI agents
The common case — you have multiple claude sessions open and want them to hand off results.
1. Install once, globally:
pip install agent2agent
2. Add to ~/.claude/settings.json:
{
"mcpServers": {
"agent2agent": {
"command": "agent2agent"
}
}
}
3. Open two terminal panes (tmux, iTerm, whatever).
4. In pane 1 — the producer agent:
agent_start(name="researcher", task="scraping competitor prices")
... do your work ...
agent_publish(name="researcher", result="<your output here>")
5. In pane 2 — the consumer agent (can start before or after pane 1):
agent_wait(name="researcher") ← blocks here until pane 1 publishes
... use the result ...
6. Check on both from anywhere:
agent_status()
That's it. No server to start, no config beyond step 2. The SQLite file at ~/.agent_bus.db is the shared medium — both Claude processes see it automatically.
Backends
Option 1 — Local SQLite (default, zero config)
The simplest setup. State lives in ~/.agent_bus.db. Every agent on the same machine shares it automatically.
uvx agent2agent # run the MCP server
# or
pip install agent2agent
Add to ~/.claude/settings.json:
{
"mcpServers": {
"agent2agent": {
"command": "uvx",
"args": ["agent2agent"]
}
}
}
Override the DB path with an env var:
{
"mcpServers": {
"agent2agent": {
"command": "uvx",
"args": ["agent2agent"],
"env": { "AGENT_BUS_DB": "/shared/volume/agents.db" }
}
}
}
Option 2 — Postgres (remote, push-based)
Point AGENT_BUS_DB at a Postgres connection string. All agents on any machine with DB credentials become peers. Uses LISTEN/NOTIFY internally — agent_wait wakes up instantly when another agent publishes, with near-zero latency instead of the 500ms poll cycle.
pip install "agent2agent[postgres]"
{
"mcpServers": {
"agent2agent": {
"command": "uvx",
"args": ["agent2agent[postgres]"],
"env": { "AGENT_BUS_DB": "postgresql://user:pass@host/agents" }
}
}
}
The schema is one table — easy to self-host on any Postgres instance (Supabase, Railway, your own VPS).
Option 3 — Email (async, across any network)
For agents that don't share a filesystem or database, email works as a transport. An agent publishes by sending an email; the waiting agent polls its inbox. Latency is seconds rather than milliseconds, but it requires no shared infrastructure — just two email addresses.
Good for long-running async workflows (overnight runs, remote cloud agents, cross-org handoffs) where sub-second latency doesn't matter. Email backend is not yet built into this package; contributions welcome.
Usage pattern
Agent A (producer):
agent_start(name="scraper", task="scraping product pages")
... do work ...
agent_publish(name="scraper", result=json.dumps({"products": [...]}))
Agent B (consumer, depends on A):
data = agent_wait(name="scraper") # returns immediately if A already finished
... use data["result"] ...
agent_publish(name="summarizer", result="Done: 42 products found")
You (observer):
agent_status() # shows all agents, tasks, and current state
Data model
One table, five columns:
CREATE TABLE agents (
name TEXT PRIMARY KEY,
task TEXT,
result TEXT,
published INTEGER, -- unix timestamp; NULL = still running
started_at INTEGER NOT NULL
)
Default DB path: ~/.agent_bus.db. Override with AGENT_BUS_DB=/path/to/file.db.
Communication latency: ~250ms average on SQLite (polls every 500ms), near-zero on Postgres (push via LISTEN/NOTIFY).
Open problems
- Fan-out:
agent_waitblocks on a single producer.agent_wait_all(names=[...])that unblocks when all named agents finish would be useful. - Pub/sub: each name is a single slot — multiple consumers for the same result (broadcast) isn't supported.
- Expiry: records accumulate indefinitely. A TTL or
agent_clear_all()would help in long-running setups. - Result streaming: results are published atomically. No way to stream partial output from a running agent.
- Email backend: async transport for agents with no shared infrastructure — not yet implemented.
- SQLite push: SQLite backend still polls; filesystem-watch (kqueue/inotify) could drop SQLite latency to ~5ms.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent2agent-0.2.0.tar.gz.
File metadata
- Download URL: agent2agent-0.2.0.tar.gz
- Upload date:
- Size: 8.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2314cc237f541affc4f40ad69a81cb2c611b43fd12bf26d69d43e6ceeab8a27e
|
|
| MD5 |
80ffe810c4ab25b467994322fd894d1c
|
|
| BLAKE2b-256 |
9bda4207f8987e2a855bd35a7be79c56e727777464b45f85cf311dc3c5460a7d
|
File details
Details for the file agent2agent-0.2.0-py3-none-any.whl.
File metadata
- Download URL: agent2agent-0.2.0-py3-none-any.whl
- Upload date:
- Size: 9.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0e33c6f6005281f7a3120b449dbee994b2a859ef2020b539a488b75dae9b058
|
|
| MD5 |
c335ac3e9e9dd8ecdd9eb48cf93e07b3
|
|
| BLAKE2b-256 |
2c0596d80835b999467e0e7d003b8a648c556cde2d3b901ccb60fac83ae649a2
|