Skip to main content
Glama

mesh

The cross-agent communicator. A standalone coordination layer for fleets of agents working the same repository — presence, resource locks, and durable messaging — exposed as a single zero-dependency MCP server.

mesh is the communication primitive extracted from the machine's hub daemon and reimplemented as a self-contained plugin. No daemon to keep alive, no port to bind, no toolchain to build: just node. State is a single JSON file under a repo-scoped .mesh/ directory, guarded by an OS-atomic lock so multiple agents (and multiple processes) can coordinate safely.

Why

When several agents share one codebase they trip over each other: two edit the same file, a plan waits on an answer that never arrives, a crashed worker leaves a lock wedged forever. mesh gives them three things and nothing else:

  • Awareness — who is alive, on what branch, doing what.

  • Claims — atomic, leased resource locks with a monotonic fence token, a fair FIFO queue, and self-healing when a holder dies.

  • Messaging — durable, ULID-ordered messages with per-agent read cursors, broadcast (*), and topic subscriptions.

A dead agent never wedges the mesh: liveness has a TTL, leases expire, and locks held by the dead are reaped and promoted to the next waiter automatically.

Related MCP server: ACDP

Install (as a Claude Code plugin)

/plugin marketplace add yesitsfebreeze/mesh
/plugin install mesh@mesh

The plugin registers one MCP server (mesh) exposing nine tools. State is written to .mesh/ in the current project (add it to .gitignore).

The tool surface

Every agent identifies itself with a stable agent_id.

Awareness

tool

purpose

register

Announce presence and refresh liveness (heartbeat). Re-registering after death bumps an epoch.

roster

List known agents, their liveness (alive / stale / dead), and the claims each holds.

register takes agent_id, branch, prompt_ptr, optional role and ttl_seconds (default 60). An agent is alive within its TTL, stale for a 30s grace window after, then dead — at which point it is hidden from the roster (unless include_stale: true) and its locks become reapable.

Claims (leased, fenced locks)

tool

purpose

claim

Atomically acquire — or queue for — a resource lock.

release

Relinquish a held claim or cancel a queued ticket.

claims

Inspect current locks and queues.

claim { "agent_id": "a", "resource": "feature:auth", "mode": "exclusive",
        "lease_seconds": 120, "wait": "queue", "note": "wiring login" }
// -> { "status": "granted", "claim_id": "01K…", "fence": 7, "lease_expires_at": "…" }
  • modeexclusive (default) or shared. Shared holders co-exist; an exclusive request is denied/queued while any holder is present.

  • lease_seconds — the lock auto-expires after this (default 120). Re-claim by the same holder is an idempotent renewal — same claim_id, same fence.

  • waitno_wait (default) returns denied if held; queue appends a FIFO ticket and returns queued with a queue_position.

  • fence — a per-resource monotonically increasing token, bumped on every grant/promotion. Use it to reject stale writers (fencing tokens, à la Kleppmann).

On release the next queued ticket is promoted (and, for shared, a run of consecutive shared waiters is promoted together). When a holder's agent dies or its lease lapses, the lock is reaped on the next touch and the queue advances — no manual cleanup.

Messaging (durable, ordered, cursored)

tool

purpose

post

Send a durable message — to an agent_id, * (broadcast), or topic:<name>.

inbox

Peek pending messages without advancing the cursor.

read

Advance the read cursor up to a message id (acknowledge consumption).

post  { "agent_id": "a", "to": "topic:build", "subject": "green",
        "body": "main is green", "ttl_seconds": 3600 }
inbox { "agent_id": "b", "topics": ["build"] }   // -> { messages: [...], cursor, unread }
read  { "agent_id": "b", "up_to": "01K…" }        // -> { cursor, remaining }

Messages are ULID-keyed, so the delivery log is totally ordered. Each agent has its own cursor: inbox shows everything addressed to it above its cursor; read moves the cursor forward (monotonic — it never goes backwards). Addressing: direct (to: "b"), broadcast (to: "*", delivered to all), or topic (to: "topic:x", delivered only to agents that pass topics: ["x"]). Optional ttl_seconds makes a message self-expire.

Maintenance

tool

purpose

gc

Drop TTL-expired messages and sweep dead claims; returns { reclaimed }.

Reaping also happens opportunistically inside roster and claims, so gc is only needed to reclaim expired messages eagerly.

Standalone use (without Claude Code)

It is a plain MCP stdio server — drive it from anything that speaks JSON-RPC:

node bin/mesh-mcp.mjs        # reads JSON-RPC lines on stdin, replies on stdout
MESH_DIR=/path/to/.mesh node bin/mesh-mcp.mjs   # override the state directory

Or import the core directly:

import { Mesh } from "@yesitsfebreeze/mesh";
const mesh = new Mesh(".mesh");
mesh.register({ agent_id: "a", branch: "main", prompt_ptr: "demo" });
mesh.claim({ agent_id: "a", resource: "feature:x" });

The Mesh constructor accepts an injectable clock (() => unixSeconds) as its second argument, which makes lease/liveness behavior deterministic in tests.

State & concurrency

  • All state lives in .mesh/state.jsonroster, claims, messages, log, cursors, events, fence_floor. Delete the directory to reset.

  • Every mutation runs under an OS-atomic lock directory (mkdir succeeds for exactly one process) and is persisted with a temp-file + atomic rename, so concurrent agents and processes never corrupt the file. A stale lock from a crashed holder is stolen after 5s.

Test

npm test        # node --test — 12 behavioral-parity cases, zero dependencies

License

MIT

Install Server
A
license - permissive license
B
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yesitsfebreeze/mesh'

If you have feedback or need assistance with the MCP directory API, please join our Discord server