Skip to main content
Glama

agent-mesh

Run a 24/7 multi-agent AI team on a single Claude Code subscription — no API keys, no per-token bills, no idle burn.

License: MIT MCP Transport

Everyone builds multi-agent systems against metered APIs, where a fleet of agents idling in a loop is a cloud bill with a heartbeat. This project comes from the opposite direction, and it's the part almost nobody exploits:

Claude Code runs on a flat subscription. A persistent CLI session that does nothing costs nothing. So don't orchestrate stateless API calls — keep sessions alive in tmux, connect them through a hub, and wake them event-driven the moment a message lands. The result is a standing team of specialist agents — a manager, a product owner, implementers, a watchdog — that sleeps for free and spends attention only when there is work.

Three primitives make that work, and this repo provides or documents all three:

  1. The hub (this package): a central registry + instant message delivery, exposed as an MCP server. Agents connect by URL — no install, no polling.

  2. Persistent sessions: each agent is a long-lived Claude Code CLI session in tmux, resumable across restarts (see the Playbook).

  3. The wake pattern: agents don't loop — they arm a file monitor that wakes their session when a relevant line arrives. Idle = silent = free.

            +------------------------------+
            |  Docker container (hub)      |
            |  agent-mesh serve --http     |
            |  MCP over HTTP/SSE  :8765    |
            |  central registry + inboxes  |
            |  push on arrival (no poll)   |
            +-------------+----------------+
            127.0.0.1:8765 |  (localhost only)
        +------------------+------------------+
   tmux: manager       tmux: dev-agent     tmux: watchdog
  (Claude Code CLI)   (Claude Code CLI)   (Claude Code CLI)
   sleeping…           working…            sleeping…
        ▲ woken by a monitor on message arrival — not by a polling loop

Setup

The host machine runs the hub once; agents just point at it.

1 — Run the hub (one machine)

git clone https://github.com/NG-Bullseye/agent-mesh.git
cd agent-mesh
docker compose up -d --build
curl -s http://localhost:8765/health   # {"ok": true, "agents": 0}

The container binds to 127.0.0.1:8765 — reachable from this machine only.

2 — Connect an agent (no install)

Register the hub with Claude Code (user scope — available in every project):

claude mcp add --transport sse --scope user agent-mesh http://localhost:8765/sse

Or per project via a .mcp.json in the repo root:

{
  "mcpServers": {
    "agent-mesh": { "type": "sse", "url": "http://localhost:8765/sse" }
  }
}

That's it. The agent now has the mesh tools. For a fully scripted setup (including the global CLAUDE.md note), paste SETUP_PROMPT.md into a Claude Code session. To build a full standing team — launchers, wake wiring, liveness — follow docs/PLAYBOOK.md.

Related MCP server: gptqueue

MCP tools

Tool

Description

mesh_register

Connect this agent to the central registry (name, role)

mesh_send

Send a message (to, message, from_agent, optional private) — delivered instantly if the target is listening

mesh_listen

Block until one DIRECT message arrives (name, timeout_s) — event-driven, no polling

mesh_ping

Liveness check for an agent (agent)

mesh_who

List all live agents in the registry

mesh_request

Send a request and block for the reply (to, message, from_agent, timeout_s)

mesh_reply

Reply to a request (nonce, text) — resolves the requester's pending call

mesh_pending

List an agent's outstanding requests (name)

Request/reply

mesh_request sends and blocks on a reply Future. The receiving agent sees the message via mesh_listen with a reply_to nonce, then calls mesh_reply with that nonce — the requester's call resolves immediately.

Production patterns

These rules come from a mesh of eight specialist agents running this way in production; every one of them was paid for by an incident:

  • DIRECT is a task trigger, GROUP is awareness. Only a message addressed to you creates an obligation. Broadcasts inform; they never demand a reply. Mixing the two buries real work under chatter.

  • Every DIRECT message creates a reply debt. An agent never ends its turn with a received DIRECT unanswered — reply, or ACK with an ETA. Debts live in a pending ledger that survives context compaction, not in vibes.

  • Dispatch ≠ send. A dispatch is a delegation handshake: it expects a reply within a timeout and escalates to the manager agent (with exponential re-ping backoff) if none arrives. Status updates use plain sends — dispatching status creates false escalations.

  • A live daemon is not a live brain. Registry heartbeats prove the plumbing. To know the model is responsive, ping it with a nonce the LLM itself must echo back. The gap between those two is exactly the failure mode you will actually have.

  • The truth about a stuck agent is its terminal, not the registry. When an agent goes quiet, capture its tmux pane before believing any status table.

  • Compact, never clear. Clearing a session kills its armed monitors — the agent goes deaf, silently. Long-lived sessions get compacted (summarized) instead; monitors survive compaction.

The wake pattern

The piece that makes flat-rate agents viable. Two layers, deliberately split:

Layer

What it does

Can it wake the session?

shell loop

filters a stream/log, appends matching lines to a notify file

no — it only produces lines

session monitor

the agent's own file-watch, armed at session init, on that notify file

yes — wakes the session per line

The shell loop produces, the session monitor consumes and wakes. An idle agent holds no open LLM call and burns nothing; the first relevant line brings it back with full context. mesh_listen is the same idea over the hub: the blocked call resolves on delivery — a socket read, not a poll.

How it works

The hub is a single asyncio process. Each registered agent has an in-memory asyncio.Queue as its inbox. mesh_send drops an item into the target's queue; a waiting mesh_listen is parked on queue.get() and wakes the moment the item lands. There is no broker, no database, no polling loop — state lives in the hub process for as long as it runs.

Group broadcasts (non-private sends) are fanned out to every other agent's inbox as scope: "group" items. A fixed-window rate gate limits direct sends per sender→target; over-limit sends are denied only when AGENT_MESH_GATE_ENFORCE=1.

State is intentionally ephemeral: restarting the container clears inboxes and the registry, like restarting a switch. This keeps the hub a single, dependency-free artifact. Scope is one host (localhost bind); a networked multi-machine mesh would add auth and is out of scope here.

Endpoints

Path

Purpose

/sse

MCP transport (point agents here)

/health

{"ok": true, "agents": N}

/agents

JSON list of live agents

Config env vars

Variable

Default

Description

AGENT_MESH_GATE_ENFORCE

0

Set to 1 to hard-deny over-rate sends

AGENT_MESH_GATE_LIMIT

40

Max direct sends per sender→target per 10s window

Running without Docker

pip install .
agent-mesh serve --http --port 8765   # or `serve` for stdio
agent-mesh health                      # check a running hub

License

MIT — see LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to discover each other and exchange typed messages through a Redis-backed queue via MCP tool calls, with support for registration, heartbeat, and queue management.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server for inter-session communication between Claude Code instances. Built on NATS JetStream, it provides room-based messaging, direct agent communication, presence tracking, and message history.
    Apache 2.0
  • A
    license
    A
    quality
    D
    maintenance
    MCP server for inter-agent communication. Gives multiple Claude Code sessions a shared message board, agent registry, and orchestration layer — backed by a cloud relay so agents can coordinate across machines, repos, and teams.
    8
    40 npm
    MIT