Skip to main content
ClaudeWave
EN, English
ExaDev / MCP Servers · Official registry

agent-comms

Cross-harness communication mesh for LLM agents. Rooms, DMs, presence, and visibility.

  • 34 stars
  • 10 forks
  • 8 open issues
  • Language: TypeScript
  • License: MIT
  • updated

Install

Claude Code CLI
git clone https://github.com/ExaDev/agent-comms
  1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
  2. Replace any <placeholder> values with your API keys or paths.
  3. Restart Claude. The MCP server and its tools appear automatically.

Clone https://github.com/ExaDev/agent-comms and follow its README for install instructions.

README

MCP Servers overview

Full README on GitHub

Agent Comms

GitHub npm Release CI

Cross-harness communication mesh for LLM agents: rooms, DMs, presence, and visibility over TCP with zero filesystem dependencies.

npm downloads chart, log scale GitHub stars chart, log scale

Why

LLM agents on the same machine are isolated silos. A Claude Code session cannot see a pi session running in the next terminal. A Codex agent cannot ask a Claude agent to review its work. Each harness manages its own context, tools, and state, with no shared communication layer between them.

Agent Comms gives them one. Any agent, in any harness, can register itself, discover other agents, join rooms, send direct messages, and coordinate work, all over a lightweight TCP mesh on localhost.

The project began as a filesystem-based bus (~/.agents/bus/), where agents read and wrote JSON files to communicate. This worked but brought real problems: orphaned files from crashed agents, polling overhead, concurrent write races, and complex stale-agent detection. The key insight that shaped the current design was that each MCP server instance is already a running process. The bridge processes themselves can form the mesh, with no daemon, no filesystem, and no polling.

How it works

Each bridge instance is a peer in a TCP mesh on localhost. The first instance to start binds the well-known port (19876) and introduces later instances to the mesh; peers also find each other through first contact on UDP. Every instance establishes direct data connections with every other peer, and one of them, elected by gossiped claim, holds the coordinator role that runs the machine's housekeeping.

graph LR
    subgraph Agent A ["Agent A (pi)"]
        A_LLM["LLM"]
        A_Bridge["pi bridge"]
    end
    subgraph Agent B ["Agent B (Claude Code)"]
        B_Bridge["Claude bridge"]
        B_LLM["LLM"]
    end
    A_LLM -- "agent_comms(send, ...)" --> A_Bridge
    A_Bridge -- "TCP localhost" --> B_Bridge
    B_Bridge -- "channel notification" --> B_LLM

All state is held in memory and synchronised between peers. Delivery events are pushed directly over TCP: no polling, no filesystem, no daemon process. Events that accumulate for an agent while its process is down are carried in the replicated delivery queues and replayed to it on return, so a restarted bridge is woken for what it missed rather than finding it only in history.

Coordinator pattern
sequenceDiagram
    participant P1 as Peer 1 (first to start)
    participant P2 as Peer 2
    participant P3 as Peer 3
    P1->>P1: binds port 19876, then claims the coordinator role once no holder has announced itself
    P2->>P1: connect to 19876
    P1-->>P2: peer list [P1]
    P2->>P1: establish data connection
    P3->>P1: connect to 19876
    P1-->>P3: peer list [P1, P2]
    P3->>P1: establish data connection
    P3->>P2: establish data connection
    Note over P1,P3: All peers now connected directly
    rect rgb(255, 230, 230)
        Note over P1: Port holder and coordinator is killed
        P2->>P3: lowest device-id claims the coordinator role at a raised term
        P2->>P2: race to bind 19876
        P3->>P3: race to bind 19876
        Note over P2,P3: the operating system's bind picks one port winner
        P3->>P2: loser re-introduces itself to the winner
    end
  • Well-known port 19876 on localhost: the compatibility first-contact address and introduction path, not the coordinator role

  • The first instance to bind it answers every later instance that connects there with the peer list; it is not a router

  • On graceful shutdown, the port holder names its longest-running peer as successor and hands the listener over before closing

  • On a crash, every surviving peer independently races to rebind the port; the operating system's exclusive bind picks the single winner, and the losers re-introduce themselves to it

Either way, direct peer-to-peer data connections are untouched, so messages between survivors keep flowing throughout, and first contact keeps finding peers while nothing answers the port.

The coordinator role is separate from the port. It carries the machine's single-authority duties: the stale-agent PID probe, the one offline announcement for a departed peer, and the default cc-peer front. It is held by claim rather than by binding anything, using wire-mesh's gossiped, term-based coordinator-frame: a higher term always supersedes a lower one, equal terms break by lowest device-id, and exactly one peer holds the role once the claims have spread. Claims travel only over sessions between peers on the same machine, since every duty the role carries is a fact about one machine.

  • A store claims the role only when it knows of no holder and is alone as far as it can tell: it bound the well-known port, or nothing on the port answered and it could not bind it either. When first contact is running, a holder that never held the port may still be about to announce itself, so the store first waits the ordinary network deadline for that announcement and claims only if none came; a store arriving at an existing mesh therefore never takes the role from its holder

  • Both ends of every session between two stores on the machine tell each other which claim they accept as the session opens, so a joiner learns the holder instead of claiming over it, whichever side dialled

  • Claims are read only from trusted sessions on the machine: never from a session that may cross machines (an addListener listener, a connectToRemote dial, or a dial at any address other than a loopback one, such as a peer first contact heard over LAN broadcast), and never from a session on the well-known port before it has introduced itself

  • Two meshes that each elected a holder while apart (joined later by first contact, say) converge on one: the lower claim is superseded and its holder stops its duties

  • When the holder departs, the survivor with the lowest device-id among the stores it has a session to claims at once at a raised term; any other survivor claims itself if, after the ordinary network deadline, the holder it accepts is still one it has no session to, which covers a successor that has gone too and a claim naming a device that never joined

  • The holder need not be the peer that bound the port, and a graceful shutdown hands on only the port listener: survivors recover the role from the departure itself

While the role is vacant, between the holder's loss and the successor's claim, no stale-agent probe runs and no cc-peer front is serving local Claude Code sessions that have no bridge of their own; the new holder restarts both as it takes the role. Every store's own session on the relay hub is unaffected, so messages from other machines keep arriving throughout.

First contact without a coordinator

The well-known port is one way for peers to find each other, not the only one. Every bridge also runs a small presence on UDP port 19877: it announces its own data port in a beacon (sent at start and every 30 seconds) and broadcasts one probe at start, which any peer that hears it answers with a fresh beacon so a newcomer does not wait for the next interval. A peer that hears a beacon dials the announced data port directly, and every established connection shares the peers it knows, so the connections form transitively with no rendezvous at all. A mesh therefore forms and heals whether or not anything answers the well-known port.

Beacons and probes go to a multicast group joined on the loopback interface (239.255.19.77) and to the limited broadcast address, never to a unicast address. Bridges on one machine share the same UDP port, and a unicast datagram to a shared port reaches only one of the sockets bound to it, so a reply addressed to a prober could land on the answerer instead. Loopback multicast reaches every bridge on the host whatever the state of the network, and broadcast reaches other machines on the LAN. A host whose loopback interface cannot carry multicast still discovers peers over broadcast, and reports the failure on the bridge's error channel.

Identity

Each bridge derives its peer ID from the device-id of its own keypair (SHA-256 of the raw public key): ECDSA P-256, self-signed, generated locally. The key material persists per bridge slot (~/.agent-comms/identity---.json, owner-only permissions), so the device-id — and with it the agent ID, room memberships, and peers' ability to keep delivering to the agent — survives restarts. Mesh state itself stays in-memory; the only thing on disk is the local key credential, the same trust model as an SSH key. A lock file guards the slot: a second live bridge in the same harness and directory runs with an ephemeral identity rather than duplicating the peer ID, and a stale lock self-heals by probing the recorded PID.

Topics
agentsclaude-codecommunicationcross-harnessllmmcpmeshpipresencereal-timeroomstcptypescript
Frequently asked

What people ask about agent-comms

What is ExaDev/agent-comms?

ExaDev/agent-comms is mcp servers for the Claude AI ecosystem. Cross-harness communication mesh for LLM agents. Rooms, DMs, presence, and visibility. It has 34 GitHub stars and its last recorded update is dated 2026-10-22.

How do I install agent-comms?

You can install agent-comms by cloning the repository (https://github.com/ExaDev/agent-comms) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is ExaDev/agent-comms safe to use?

Our security agent has analyzed ExaDev/agent-comms and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.

Who maintains ExaDev/agent-comms?

ExaDev/agent-comms is maintained by ExaDev. The last recorded GitHub activity is dated 2026-10-22, with 8 open issues.

Are there alternatives to agent-comms?

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.