Skip to main content
Glama

agentbus

test

Lets coding agents on the same machine message each other. Claude Code, pi, opencode, kiro-cli, codex, antigravity, hermes, crush, and anything else that speaks MCP show up as named peers you can address from any of the others.

$ agentbus list
cc-acme-frontend   claude   idle    ~/Code/acme-frontend
ki-acme-backend    kiro     idle    ~/Code/acme-backend
pi-acme-security   pi       idle    ~/Code/acme-security

$ agentbus send cc-acme-frontend "PR #98 is green, go ahead and merge"
Sent to cc-acme-frontend (msg 8d04afbb).

Setup

pip install agentbus-cli
agentbus install

Related MCP server: claude-peers

Usage

Inside Claude Code it's a prompt mention: @ki-acme-backend what's the status. Inside the others it's a tool call the model makes on its own (send_to_claude, list_claude_sessions, check_messages). agentbus install looks at what's actually on your machine and wires each one up: a config entry for MCP-based clients, a symlinked adapter for pi and opencode. Run agentbus doctor afterward to check it took.

Manual MCP setup

agentbus install is the automated version of this. For a host it doesn't recognize yet, or if you'd rather wire it up yourself, any MCP host that can spawn a stdio server should point at:

No install step at all, via uv (note the --from: the PyPI package is agentbus-cli, the command it provides is agentbus, so a bare uvx agentbus-cli doesn't resolve, uv will tell you as much):

{
  "mcpServers": {
    "agentbus": {
      "command": "uvx",
      "args": ["--from", "agentbus-cli", "agentbus", "mcp"]
    }
  }
}

That's the zero-install default. Once pip install agentbus-cli (or uv add agentbus-cli inside a project of your own) has actually put it on your PATH, it's just:

{
  "mcpServers": {
    "agentbus": {
      "command": "agentbus",
      "args": ["mcp"]
    }
  }
}

Working from a local checkout instead, before a change has made it into a release, same uvx idea, point --from at the directory (or git+https://github.com/ekinertac/agentbus for unreleased master):

{
  "mcpServers": {
    "agentbus": {
      "command": "uvx",
      "args": ["--from", "/path/to/agentbus", "agentbus", "mcp"]
    }
  }
}

The host's own name over MCP decides the address prefix (ki-, cx-, ag-, …), picked up automatically from the standard MCP initialize handshake, or falls back to the generic ab- prefix if the host isn't one we recognize yet (see the client table above). Add an "env": { "AGENTBUS_NAME": "whatever" } to any of these entries to pick the name yourself instead of deriving it from the working directory.

Once it's wired up, the host gets three tools: list_claude_sessions, send_to_claude, and check_messages. A host that runs its own hooks can also call agentbus drain from one to pull messages automatically instead of waiting on the model to call check_messages; kiro's own config (written by agentbus install kiro) does exactly this. See docs/protocol.md for the wire format underneath all of this.

Why this exists

Claude Code sessions on the same machine can already message each other, that part is a real, documented feature (SendMessage, ListAgents). The wire protocol underneath it isn't published anywhere, though, so agentbus reverse-engineers that and speaks it from the outside, making a pi or kiro or codex session look like just another Claude Code session to everyone else. No new protocol, no daemon, no server to run: it rides the one Claude Code already ships.

See docs/protocol.md for the reverse-engineered wire format, if you want to speak it directly or write your own adapter.

Supported clients

client

how

prefix

Claude Code

native, nothing to install

cc-

pi

adapter symlinked into its extensions dir

pi-

opencode

plugin shim + config entry

oc-

kiro-cli

MCP server + agent config (hooks don't run in its TUI, see below)

ki-

codex

MCP server, TOML config block

cx-

antigravity-cli

MCP server, JSON config

ag-

hermes (NousResearch)

MCP server, driven through hermes mcp

generic (see below)

crush (Charm)

MCP server, JSON config (legacy crush.json format)

cr-

any other MCP host

MCP server, config format varies

generic

An unrecognized host still works, it just gets a generic prefix instead of a short one. Adding a short prefix for a new host means confirming what it actually reports as its MCP client name first: every host so far has surprised us here except crush (kiro reports Q DEV CLI, codex reports codex-mcp-client, hermes reports the unusably generic mcp), so this is never assumed. See docs/roadmap.md for the client backlog and what's been ruled out.

Delivery model

Claude Code, pi, and opencode can interrupt a running turn, so a message lands immediately. A plain MCP host cannot be interrupted by anything: there is no MCP call that pushes into a live turn. Messages to those hosts are spooled and either surfaced automatically by a host hook (where the host actually runs hooks, which kiro's own TUI turns out not to, see kirodotdev/Kiro#11620) or pulled by the model calling check_messages, which every MCP-based client is told to do at the top of its turn.

Security

This is a local IPC channel with the same trust boundary as anything else running as your user: auth tokens are per-session, socket directories are mode 0700, and a sender's identity is checked against the connecting process's own uid, not just what it claims. None of that changes what a message actually is once it arrives: text injected into another agent's context, the same as anything else that agent reads. Treat a peer session the way you'd treat any other untrusted input source, don't wire up a peer you wouldn't want steering your other sessions, and don't build anything on top of this that turns a received message into an action without a human somewhere in the loop for anything destructive.

Zero dependencies, on purpose

The Python side is stdlib only: this has to run on whatever python a host already has, not one you install just for this. pi and opencode's adapters are TypeScript because their listener has to run inside those hosts' own process to interrupt a live turn, which borrows the host's own runtime rather than shipping one.

Tests

python3 -m unittest discover -s tests -t .
cd adapters/ts && bun test

Both the Python and TypeScript implementations of the wire protocol are checked against the same cases in tests/vectors.json, so a change to one that isn't mirrored in the other fails that language's suite.

License

MIT

Related MCP Connectors

Related MCP Servers