A local communication bus for the coding agents on your machine.
You probably run more than one coding agent — Claude Code in a terminal, Codex in another, Cursor in a window. Each one is an island: it has no idea the others exist, what they're working on, or what they've already figured out. The vendors are quietly building one-way bridges (Codex imports Claude Code transcripts; Claude Desktop has an internal session bus) — but each wants to be the orchestrator, so nobody ships the neutral layer.
agent-bus is that layer: one small MCP server that every agent registers, giving each of them eyes on — and a channel to — all the others. No daemon, no accounts, no cloud. It reads the session stores the agents already write to disk, and relays through the headless CLIs they already ship.
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Claude Code │ │ Codex │ │ Cursor │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ MCP (stdio) │ │
└────────────────────┼────────────────────┘
┌──────┴──────┐
│ agent-bus │
└──────┬──────┘
┌─────────────────┼──────────────────┐
session stores headless CLIs handoff briefs
(~/.claude, …) (claude -p, codex exec) (~/.agent-bus)
| Tool | What it does |
|---|---|
list_sessions |
Every session across every agent, newest first, with liveness (attached / recent / idle) |
search_sessions |
Full-text search across all agents' transcripts |
read_session |
Normalized user/assistant transcript of any session, from any agent |
ask_agent |
Ask another agent a question, headless and blocking, and get its answer — optionally within an existing thread's context |
handoff_session |
Package a session into a markdown brief and hand it to another agent — either as a ready-to-run command, or by seeding a live target session that acknowledges and waits for you |
So from inside any agent you can say things like:
- "What are my other agents working on right now?"
- "Ask Codex what it concluded about the flaky auth test."
- "Hand this session off to Claude Code and have it pick up where we left off."
It's an MCP server, not a skill and not a service. Each agent speaks MCP natively; registering agent-bus adds its five tools to that agent's toolbox. There is nothing to start and nothing running in the background: MCP stdio servers are spawned by the agent as a child process when a session opens, spoken to over stdin/stdout, and killed when the session ends. Concurrent agents each spawn their own instance — shared state is just the files on disk.
- Discovery reads the stores each agent already maintains: Claude Code's
~/.claude/projects/**/*.jsonl, Codex's~/.codex/sessionsrollouts +session_index.jsonl, Cursor'sstate.vscdbSQLite (read-only, immutable mode). - Asking shells out to the callee's own headless mode —
claude -p [--resume <id>],codex exec [resume <id>]— so answers come from a real session of that agent, resumable later, in its own history. - Handoff distills the source transcript into a brief under
~/.agent-bus/handoffs/, then either hands you the launch command or seeds the target session for you and returns its resume command.
Requires Node 18+, macOS (session-store paths are macOS-specific for now), and whichever agents you use on the machine.
One command — detects which hosts are installed, registers the bus with each, merges with any existing MCP config, takes backups before rewriting anything, and is safe to re-run:
npx -y agent-bus install # registers with Claude Code, Codex, and Cursor
npx -y agent-bus install --dry-run # preview what would change, modify nothingUpgrades are automatic when registered via npx (npx -y resolves the latest published version each spawn); re-run install only if registration instructions change.
Manual registration
claude mcp add --scope user agent-bus -- npx -y agent-bus
codex mcp add agent-bus -- npx -y agent-bus
# Cursor: add to ~/.cursor/mcp.json → { "mcpServers": { "agent-bus": { "command": "npx", "args": ["-y", "agent-bus"] } } }From a clone (for development): git clone https://github.com/rishabhjava/agent-bus && cd agent-bus && npm install, then node cli.mjs install — it registers the clone's path instead of npx.
Codex note: Codex prompts for approval on an MCP server's first tool call ("always allow" persists it). Headless
codex execcannot answer that prompt — to use the bus headlessly, setdefault_tools_approval_mode = "auto"under[mcp_servers.agent-bus]in~/.codex/config.toml.
New sessions of each agent pick the tools up automatically. Smoke-test without any agent:
npm run smoke # list tools, list sessions, read one per agent
node test/smoke.mjs ask claude # cheap round-trip through claude -pLetting agents talk to each other is letting untrusted inputs talk to each other, so the bus is deliberately paranoid:
- Provenance headers — every relayed prompt is prefixed with a notice that it comes from a peer agent, not the human, and should be treated as untrusted input.
- Loop guard — a relay-depth counter propagates through the child process tree (
AGENT_BUS_DEPTH) and hard-refuses at depth 2, so two agents can never recursively prompt each other into a token bonfire. - No permission laundering — the bus never widens the callee's permissions: Codex calls run sandboxed read-only unless explicitly allowed to write, and Claude calls run headless under its default permission mode.
- Prototype, built and verified on one machine in one sitting. Parsers for the vendors' session formats are defensive but the formats are undocumented and will drift.
ask_agentwaitstimeout_sseconds for the callee (default 240; minimum 30;0means no bus-side timeout — wait until the callee exits). Two caveats the bus cannot lift: the host running the tool call may cancel long MCP calls on its own clock (Claude Code honorsMCP_TOOL_TIMEOUT; Codex has per-servertool_timeout_secin~/.codex/config.toml), and if the bus process dies mid-ask it kills its delegated child processes rather than orphan them — the answer is lost either way. For work longer than a few minutes,handoff_sessionis the durable path.- Cursor is read-only (discovery + handoff source) until its headless CLI is present.
- Asking a thread that is currently open interactively does not inject into the live TTY — the callee answers out-of-band, from a snapshot of that thread's context. With Claude Code, the exchange isn't even a separate session: it lands in the same session file as a parallel branch (same session id, different parent chain), which the live view never displays. Observed in practice when a Codex session used
ask_agenton the live Claude Code session that was building this project — the answer was correct, and the live session only learned about the exchange by reading its own transcript off disk. True live injection needs harness cooperation; that's the interesting next problem.
MIT