Agent Mesh — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Agent Mesh (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Run a 24/7 multi-agent AI team on a single Claude Code subscription — no API keys, no per-token bills, no idle burn.
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:
exposed as an MCP server. Agents connect by URL — no install, no polling.
in tmux, resumable across restarts (see the Playbook).
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 loopThe host machine runs the hub once; agents just point at it.
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.
Register the hub with Claude Code (user scope — available in every project):
claude mcp add --transport sse --scope user agent-mesh http://localhost:8765/sseOr 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](SETUP_PROMPT.md) into a Claude Code session. To build a full standing team — launchers, wake wiring, liveness — follow [docs/PLAYBOOK.md](docs/PLAYBOOK.md).
| 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) |
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.
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:
to you creates an obligation. Broadcasts inform; they never demand a reply. Mixing the two buries real work under chatter.
with a received DIRECT unanswered — reply, or ACK with an ETA. Debts live in a pending ledger that survives context compaction, not in vibes.
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.
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.
agent goes quiet, capture its tmux pane before believing any status table.
agent goes deaf, silently. Long-lived sessions get compacted (summarized) instead; monitors survive compaction.
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.
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.
| Path | Purpose |
|---|---|
/sse | MCP transport (point agents here) |
/health | {"ok": true, "agents": N} |
/agents | JSON list of live agents |
| 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 |
Setup in einem Schritt (idempotent, startet keinen Dienst): bash bootstrap.sh
pip install .
agent-mesh serve --http --port 8765 # or `serve` for stdio
agent-mesh health # check a running hubMIT — see LICENSE.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.