Skip to main content
Glama

agentbus

A message bus and live dashboard for MCP-capable agents that run in separate consoles: OpenCode, Kimi Code, Claude Code, Gemini CLI, Cursor, Codex, VS Code, or anything else that speaks MCP. One daemon, any number of agents, a browser page that shows who said what to whom as it happens, and a tone on every message.

Why a bus, and why recv blocks

An MCP server cannot push to an idle agent; the model only acts when it calls a tool. agentbus works around that with a blocking recv tool: the agent parks inside the call and the daemon releases it the moment a message for it lands. That is what makes delivery feel instant instead of polled.

Related MCP server: backchannel

Install

pip install -e .

Python 3.11 or newer. Pulls in the official mcp SDK (2.x), Starlette, uvicorn and httpx.

Run

agentbus serve --open

What

Where

Dashboard

http://127.0.0.1:8765/

MCP endpoint (streamable HTTP)

http://127.0.0.1:8765/mcp

Message log

~/.agentbus/bus.db (use --db :memory: for a throwaway bus)

Connect a console

Every console gets a name. The name is bound to the connection through an X-Agent header, so the model can never send as the wrong agent. Print the exact snippet for your client:

agentbus config --agent alice --client opencode
agentbus config --agent bob   --client kimi

Supported --client values: opencode, kimi, claude, gemini, cursor, codex, vscode, json (generic mcpServers entry), and stdio for clients that can only launch local MCP processes. The stdio entry runs agentbus stdio --agent NAME, a tiny MCP server that forwards every call to the daemon. A client that cannot set headers at all can put the name in the URL instead: http://127.0.0.1:8765/mcp?agent=alice.

Then tell each agent how to behave, for example:

You are alice on the bus. After every step call recv. When messages arrive, act on them, reply with send, then call recv again.

The daemon also sends those instructions to every client that shows MCP server instructions to its model.

What the agents see

Tool

Arguments

Returns

send

target, text

sent #N to target, or error: ...

recv

wait_seconds (default 30, max 600), since (optional)

{"messages": [{seq, ts, sender, target, text}], "next_since": N}

peers

none

{"you": name, "paused": bool, "agents": [{agent, state, since}]}

history

limit

{"messages": [...]}

target is an agent name or * for everyone. A bare recv returns only messages the agent has not seen yet; since=N replays everything after sequence N. Every problem comes back as a string starting with error: so the model can read it and change course.

Clients enforce their own tool-call timeouts. The config snippets set a long one where the client has a setting for it (OpenCode timeout, Kimi toolTimeoutMs, Gemini timeout, Codex tool_timeout_sec, Claude Code MCP_TOOL_TIMEOUT). If your client cuts recv off early, ask the agent to pass a smaller wait_seconds and simply call again.

Notes from testing with real clients

  • OpenCode (1.18) connects with the JSON snippet and its opencode mcp list shows the bus as connected. Without the timeout setting it aborted a 120-second recv with "MCP error -32001: Request timed out"; the model then retried with 25 seconds and everything worked. With timeout set as in the snippet, long waits are fine.

  • Kimi Code (0.40) only loads project-level .kimi-code/mcp.json after you trust the folder in the interactive prompt, so headless kimi -p runs in a fresh folder see no bus tools. Put the snippet in the user-level ~/.kimi-code/mcp.json instead, or open the folder once interactively and accept the trust prompt. (In the test run Kimi noticed the missing tools, read the config, and drove the MCP endpoint by hand with curl; the message still arrived, which says something nice about the protocol.)

The dashboard

agentbus dashboard: Kimi Code and OpenCode exchanging messages, plus an operator broadcast

  • One column per agent, with a presence dot: solid means active, breathing means parked in recv, grey means idle.

  • Each message is an arrow from the sender's column to the target's, with the text underneath. Broadcasts are dashed across every column.

  • A tick appears under a message when its target picks it up.

  • A short tone plays per message, pitched by sender. Browsers block audio until you click the page once. The tab title shows an unread count while the tab is hidden.

  • The compose box at the bottom sends as operator to one agent or everyone.

  • The pause button makes every send fail with an error the agents can read, which is the quickest way to stop two agents that are ping-ponging.

From a shell or any HTTP client

agentbus send --agent alice --to bob "build is green"
agentbus send --agent alice --to bob --file report.txt   # posts a summary line (paste-aware)
agentbus recv --agent bob --wait 60
agentbus recv --agent bob --tail 10                       # last 10, no cursor needed
agentbus tail --agent bob                                 # live-follow the bus (Ctrl-C to stop)
agentbus history --limit 50 --grep v73                    # filter the log
agentbus peers

Route

Purpose

POST /api/send {sender, target, text}

send (sender also accepted from X-Agent)

GET /api/recv?wait=30&since=N

long-poll; identity from X-Agent or ?agent=

GET /api/peers

presence (state, last activity, read cursor per agent)

GET /api/history?limit=50&since=N

recent messages, or everything after a sequence cursor

GET /api/profile / PUT /api/profile {blob}

durable per-agent state — compaction handoff

GET /api/profiles

everyone's profiles

POST /api/paste {text}

long content out of band; returns {id, chars}

GET /api/paste/{id}

fetch a paste

POST /api/pause {paused: true}

pause or resume

GET /events

server-sent events feed used by the dashboard

GET /health

liveness

Presence is touched by any authenticated request (X-Agent), so polling counts as being alive — no heartbeat messages needed. Profiles survive restarts (SQLite); agents that compact their context re-read their profile plus history?since= and are back in one call.

curl -X POST http://127.0.0.1:8765/api/send \
  -H "content-type: application/json" \
  -d '{"sender":"ci","target":"*","text":"deploy finished"}'

Safety valves

  • Rate limit: 60 messages per minute per agent (the operator is exempt). Over the limit, send returns error: rate limit ....

  • Pause: see above.

  • The daemon binds to 127.0.0.1. --host 0.0.0.0 lets agents on other machines join; there is no authentication, so only do that on a network you trust.

Development

pip install -e ".[dev]"
python -m pytest -q

Design notes live in docs/superpowers/specs/, the implementation plan in docs/superpowers/plans/.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    A real-time inter-agent switchboard, delivered as one centralized streamable-HTTP MCP server. Any MCP-capable agent can message, coordinate, and stay ambiently aware of others.
    AGPL 3.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for async messaging between AI coding agents, enabling cross-harness and cross-machine communication with Slack-like semantics and mail-shaped delivery.
    2
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Cross-agent messaging for MCP clients, enabling agents to discover one another, exchange threaded messages, and resume work in a persistent project room.
    19
    1
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    MCP server that gives AI agents a live, tmux-backed messaging mesh for instant message delivery without polling.
    7
    -