Skip to main content
Glama

MCP Agent Bus

A local, event-driven MCP message bus for coordinating multiple AI coding-agent sessions on the same machine. One session can hand a task to another — the other runs it and sends the result back — with zero infrastructure: no cloud, no database, no network service. Just Node.js and the local filesystem.

A small, self-contained tool I built while working with multiple AI coding-agent sessions, shared openly so other teams can adopt the same pattern.

Why

When you work with AI coding agents you often have several sessions open at once (different windows, different models). By default they can't see each other — you copy-paste between windows by hand. MCP Agent Bus gives them a shared "post office": any session can drop a message addressed to another, which picks it up instantly and replies.

Related MCP server: claude-intercom-mcp

How it works

Everything is local. The "post office" is just a folder of JSON files:

<MCP_AGENT_BUS_DIR>/
  inbox/<session>/*.json   # direct messages, one folder per session
  broadcast/*.json         # announcements to everyone
  cursors/<session>...     # per-session "already read" bookmark
  • One MCP process per session, all sharing the same folder.

  • Atomic writes (temp file + rename) so readers never see a partial file.

  • Consume-once: reading an inbox removes the message.

  • Event-driven via fs.watch (with a slow safety poll), so delivery is effectively instant and there's no busy-polling.

Requirements

  • Node.js >= 18

  • An MCP-capable agent client (e.g. Cursor / cursor-agent).

Install

git clone <this-repo> mcp-agent-bus
cd mcp-agent-bus
./scripts/setup.sh

setup.sh installs dependencies, writes a project-local .cursor/mcp.json pointing at this checkout, and installs the always-on rule. Then reload your agent client.

Manual install

npm install

Then register the server with your MCP client using examples/mcp.json.template (replace <ABSOLUTE_PATH_TO_REPO> with this checkout's path):

{
  "mcpServers": {
    "mcp-agent-bus": {
      "command": "node",
      "args": ["<ABSOLUTE_PATH_TO_REPO>/src/server.mjs"],
      "env": { "MCP_AGENT_BUS_DIR": "<ABSOLUTE_PATH_TO_REPO>/bus" }
    }
  }
}

Tools

Tool

Purpose

bus_send(to, from, text, subject?)

Send a direct message to another session's inbox.

bus_receive(me, block?, timeout_ms?)

Fetch & consume your messages; optionally block until one arrives.

bus_peek(me)

Look at your inbox without consuming.

bus_broadcast(from, text)

Post an announcement visible to all sessions.

bus_read_broadcasts(me)

Read announcements newer than your last read.

bus_list_sessions()

List sessions that currently have an inbox.

Message shape

{
  "id": "1725183600000-a1b2c3d4",
  "type": "direct",
  "to": "backend",
  "from": "frontend",
  "subject": "handoff",
  "text": "please run the end-to-end tests",
  "ts": "2026-09-01T10:00:00.000Z"
}

Two ways to receive work

  • Interactive (human in the loop): your active session calls bus_receive, you see the task, it's done with normal tools, and you reply with bus_send.

  • Autonomous (headless worker): run src/worker.mjs in a plain terminal. It watches an inbox and, for each task, runs a fresh headless agent (cursor-agent -p) and replies automatically:

MCP_AGENT_BUS_DIR="$PWD/bus" WORKER_CWD="$PWD" \
  node src/worker.mjs backend --model <your-model>

Safety: the worker runs tasks with cursor-agent -p ... --force (auto-approves shell/file actions). Only run it for senders you trust. The agent command is configurable via the AGENT_CMD env var.

Configuration

Env var

Default

Meaning

MCP_AGENT_BUS_DIR

~/.cursor/mcp-agent-bus

Where the mailbox lives.

AGENT_SESSION_NAME

—

Convenience: each session's own name.

WORKER_CWD

current dir

Working directory the worker runs tasks in.

AGENT_CMD

cursor-agent

The agent CLI the worker invokes.

Development

npm test     # unit tests (node:test), no external services
npm run lint # eslint (flat config)

The core mailbox logic lives in src/mailbox.mjs and is fully unit-tested in isolation; src/server.mjs is a thin MCP wrapper around it.

Limitations

  • Single machine. It coordinates sessions on one host; it is not a cross-machine or team-wide bus.

  • One receiver per session name — don't run a headless worker and an interactive receive on the same name (they'd fight over the inbox).

  • Messages are consumed — for a durable record, pair the bus with a shared notes file.

License

MIT

Available Tools

6 tools
bus_broadcastBroadcast a message to all sessionsA

Post a message visible to every session via bus_read_broadcasts. Use for global announcements (e.g. "deploying now", "main is frozen").

ParametersJSON Schema
NameRequiredDescriptionDefault
fromYesYour own session name
textYesMessage body

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It discloses the core action (broadcast to all sessions) and the read counterpart, but it does not mention whether messages are persistent, if there are limits, or what the return behavior is. For a simple fire-and-forget write, this is adequate but not deep.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two tight sentences, front-loading the action in the first sentence and providing a concrete use case in the second. There is no filler, and every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 2-parameter tool with no output schema and no annotations, the description covers the purpose, target audience, and usage context. It does not mention response values or error cases, but these are unlikely to be critical for a broadcast operation and the tool's simplicity lowers the bar.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already describes both parameters fully ('Your own session name' and 'Message body') with 100% coverage. The description adds no parameter-level nuance beyond what the schema provides, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Post' and clearly defines the resource as 'a message visible to every session', which distinguishes it from the targeted bus_send and read-only siblings like bus_peek/bus_receive. The explicit mention of 'via bus_read_broadcasts' also anchors it in the API family.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says 'Use for global announcements' and gives concrete examples ('deploying now', 'main is frozen'), which tells an agent exactly when to choose this tool. It does not name the targeted alternative (bus_send) or state when not to use it, but the global-announcement framing makes the intent clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bus_list_sessionsList sessions that have an inboxA

List known session names (those with an inbox directory).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It usefully discloses that only sessions with an inbox directory are listed, which is a behavioral filter. However, it does not explicitly state that the operation is read-only, nor does it describe the return format or potential side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the verb and resource, no filler. Every word adds information, making it an efficient and well-structured description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, zero-parameter listing tool with no output schema, the description conveys what is listed and the defining criterion. It does not spell out the exact return shape or error behavior, but the complexity level makes this a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero properties, so there are no parameters to document. The description adds the only relevant semantic—the 'inbox directory' criterion—which provides enough meaning for a zero-parameter tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and resource ('known session names') and adds the filter criterion '(those with an inbox directory)'. This clearly distinguishes it from sibling tools like bus_send and bus_receive, which handle messages rather than session enumeration.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly name alternatives or exclusion conditions, but it gives clear context that this tool enumerates sessions rather than sending/receiving messages. The role in the bus tool family is self-evident, so an agent can infer when to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bus_peekPeek inbox without consumingA

Return pending messages for your session WITHOUT removing them.

ParametersJSON Schema
NameRequiredDescriptionDefault
meYesYour own session name

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description must convey all behavioral traits. It explicitly discloses the key non-destructive behavior ('WITHOUT removing them'), which is critical. However, it does not mention what happens if no messages are pending, or whether it returns a list or single message, but the main safety aspect is covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, direct sentence with no fluff, and the key behavior (without removing) is front-loaded. It earns its place entirely, making it concise and structured effectively.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no output schema), the description is mostly complete. It addresses the primary concern (non-destructive) and identifies the session parameter. However, it could briefly mention the return format or behavior on empty, but not critical at this complexity level.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides 100% coverage for the single parameter 'me', explaining it as 'Your own session name'. The description adds no further meaning beyond what the schema offers, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool returns pending messages without removing them, identifying the verb and resource. However, it does not differentiate from siblings like bus_receive or bus_read_broadcasts, so the agent may not know which sibling to use for different scenarios.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies a use case: when you want to inspect messages without consuming them. But it lacks explicit guidance on when not to use this tool or which sibling to use for actually consuming messages, leaving some ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bus_read_broadcastsRead new broadcasts since you last checkedA

Return broadcasts newer than your last read, then advance your read cursor. Non-consuming for other sessions.

ParametersJSON Schema
NameRequiredDescriptionDefault
meYesYour own session name

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses that the tool advances the read cursor as a side effect and that it does not consume broadcasts for other sessions, which is valuable behavioral context beyond the tool name. It does not mention permissions, errors, or idempotency, but for a single-parameter read-with-cursor tool this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, each carrying distinct information—the return behavior and the cursor side effect plus the non-consuming guarantee. No filler, front-loaded with the core action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity tool with no output schema or annotations, the description explains what is returned (broadcasts newer than last read) and the side effect (cursor advance) plus the non-consuming property. It is complete enough for an agent to call it correctly; missing details like output format are not essential given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides 100% description coverage for the only parameter ('me'), so the description does not need to add parameter details. It adds no extra semantic beyond the schema, but the schema is sufficient; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Return broadcasts newer than your last read') and a unique side effect ('advance your read cursor'). It distinguishes this from sibling read tools like bus_peek (which likely doesn't advance a cursor) and bus_receive by describing per-session cursor behavior, so an agent can identify it correctly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies a use case—polling for new broadcasts since a session's last read—and notes that it is non-consuming for other sessions. However, it does not explicitly compare against siblings like bus_peek or bus_receive, nor state when to prefer one over the other, leaving the agent to infer the choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bus_receiveReceive messages (blocks until one arrives or timeout)A

Fetch and CONSUME pending messages for your session. If none are waiting and block=true, this blocks (event-driven) until a message arrives or timeout_ms elapses. Returns a JSON array of messages (may be empty on timeout).

ParametersJSON Schema
NameRequiredDescriptionDefault
meYesYour own session name, e.g. "backend"
blockNoBlock until a message arrives (default true)
timeout_msNoMax time to block in ms (default 60000, max 600000)

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden. It discloses that messages are consumed, that it blocks conditionally, that it is event-driven, and that an empty array can be returned on timeout. This is strong coverage for a simple receive tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences deliver all essential information: action, blocking behavior, and return value. Every phrase earns its place, and the title reinforces the key blocking semantics without duplication.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers purpose, consumption, blocking behavior, timeout, and return format, which is sufficient for a simple tool with no output schema. Minor gaps remain, such as explicitly stating what happens with block=false, but this is inferable from the conditional phrasing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all parameters. The description adds valuable relational context by explaining how 'block' and 'timeout_ms' interact when no messages are pending, which goes beyond the individual parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses specific language ('Fetch and CONSUME pending messages for your session') that identifies the exact verb, resource, and scope. It clearly distinguishes this from sibling tools like bus_peek by emphasizing the consuming/destructive nature.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides clear context for when to call the tool: retrieve pending messages, optionally blocking until one arrives. It does not explicitly name alternatives or exclusion cases, but the 'CONSUME' wording implicitly tells the agent not to use this for inspection-only scenarios.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

bus_sendSend a direct message to another sessionA

Send a message to a specific session inbox. The recipient sees it on their next bus_receive. Use for handoffs and requests between agent sessions.

ParametersJSON Schema
NameRequiredDescriptionDefault
toYesRecipient session name, e.g. "backend"
fromYesYour own session name, e.g. "frontend"
textYesMessage body
subjectNoOptional short subject

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It discloses the key delivery model: 'The recipient sees it on their next bus_receive,' which tells the agent that sending is asynchronous and queue-based. However, it does not mention failure behavior, durability guarantees, whether the recipient must exist, or what the tool returns, leaving gaps in behavioral transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences. It front-loads the primary action, then the key behavioral consequence, then the intended use case. Every sentence contributes unique value with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core purpose, the delivery behavior, and the intended usage context. With no annotations and no output schema, it could briefly mention the return value or error cases, but for a simple send tool with fully documented parameters, the essential information needed to invoke it correctly is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds no parameter-specific information beyond what the schema already provides; the schema accurately describes each parameter (to, from, text, subject). The description's references to 'specific session inbox' and 'handoffs' are contextual but do not add meaning to individual parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Send a message to a specific session inbox.' It clearly distinguishes from siblings by emphasizing 'specific session' (as opposed to broadcast) and explicitly identifies the use case as 'handoffs and requests between agent sessions,' making its role unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when to use the tool: 'Use for handoffs and requests between agent sessions.' It doesn't explicitly name alternative tools like bus_broadcast, but the targeted-session phrasing implies when this tool is appropriate instead of broadcasting. No exclusions or when-not-to-use guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv1.0.0
    • First observedbus_broadcast
    • First observedbus_list_sessions
    • First observedbus_peek
    • First observedbus_read_broadcasts
    • First observedbus_receive
    • First observedbus_send

TDQS

A4.3/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a distinct purpose: sending to a specific session, receiving/consuming, peeking without consuming, broadcasting to all, reading broadcasts with cursor advancement, and listing sessions. No two tools appear to do the same thing.

Naming Consistency5/5

All tools follow a consistent 'bus_<verb_noun>' pattern (e.g., bus_send, bus_receive, bus_read_broadcasts). Names are lowercase with underscores, making them predictable and easy to reason about.

Tool Count5/5

Six tools is well-scoped for a messaging bus, covering send, receive, peek, broadcast, read broadcasts, and session listing without unnecessary additions. Each tool earns its place.

Completeness5/5

The tool surface covers the core lifecycle of inter-agent messaging: sending, receiving (consuming), peeking, broadcasting, reading broadcasts, and discovering sessions. No obvious gaps that would cause agent failures.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Enables local messaging between Claude Code, Codex, Pi, and other coding-agent sessions on the same machine, allowing them to discover each other, send updates, ask questions, and reply.
    8
    14 npm
    2
    AGPL 3.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables real-time, file-based messaging between terminal AI agents (like Claude Code, Gemini CLI) allowing them to collaborate on tasks directly without a server or network, using JSON files and atomic rename for coordination.
    23 PyPI
    MIT