essaim
v0.7.0
Published
Spawn N coordinated Claude Code agents — orchestrator + behavior catalog. Pairs with @swoofer/promptweave + mcp-coordinator.
Downloads
291
Maintainers
Readme
essaim
Spawn N coordinated Claude Code agents on your repo. Pick a preset, the orchestrator does the rest.
Problem · How it works · Quickstart · Architecture · BCE · Phases · Effort · CLI · Templates · Quota · Config · Related
The Problem
When multiple developers each use an AI coding agent in parallel on the same repo, things break:
- Regressions — Agent A rewrites a module that Agent B was depending on
- Duplicated work — Two agents implement the same feature from different directions
- Architectural drift — Agents make local decisions that conflict with each other's designs
- Wasted reconciliation time — Developers spend hours untangling what the agents did
Each agent works in isolation. None of them know what the others are doing.
essaim fixes this by giving agents a shared nervous system — they announce intentions before coding, conflicts are detected before a single line is written, and agents see each other's actions in real-time to agree on an approach.
How It Works
Developer A Developer B
| |
| announce_work | announce_work
v v
+--------------+ +--------------+
| Agent α | <-- MQTT -->| Agent β |
| (essaim) | push-based | (essaim) |
+--------------+ +--------------+
| MCP HTTP / SSE |
+---------------+---------------+
|
+----------v----------+
| mcp-coordinator |
| MCP tools + SQLite |
| MQTT broker |
+---------------------+The consultation cycle — announce → detect → consult → resolve — runs in the agent-loop without a sidecar. Agents call announce_work before coding; the coordinator scores impact and opens a thread on score ≥ 90; MQTT pushes the thread to affected peers between turns; the thread closes on consensus, timeout, or gray-zone auto-resolve.
essaim ships the orchestrator (agent-loop, preset runner, phase scheduler) and the behavior catalog (32 behaviors, 21 presets, 3 composition rules). The coordination server lives in mcp-coordinator; the prompt assembly engine in @swoofer/promptweave. essaim wires them together and ships the CLI.
Quickstart
Prerequisites
- Node.js >= 20
claudeCLI on PATH (install from claude.ai/code)ANTHROPIC_API_KEYenvironment variable set
Install
npm install -g essaimStart the coordinator
essaim delegates all coordination state to mcp-coordinator. Start it once:
mcp-coordinator server start --daemonRun your first swarm
# Initialize your project (installs hooks + MCP config)
essaim init ~/my-project
# Launch 3 coordinated agents on a bug hunt
essaim run swarm -p ~/my-project --agents 3
# Or run a single agent without orchestration
essaim solo gardien -p ~/my-projectThe
swarmpreset runs discover → execute phases. Agents discover issues in read-only mode, share findings via the coordinator, then work-steal tasks from the shared pool until the pool is drained.
Architecture
essaim (this package)
|
+-- @swoofer/promptweave (BCE engine: assembles prompts from YAML behaviors)
|
+-- mcp-coordinator (coordination server: MCP tools, SQLite, MQTT broker, dashboard)essaim owns the catalog (32 behaviors, 21 presets, 3 composition rules, 6 hook scripts), the orchestrator (phase scheduler, effort router, work-stealing loop), and the CLI. @swoofer/promptweave owns the BCE engine (resolver, validator, assembler). mcp-coordinator owns everything coordination-side: 26 MCP tools, impact scoring, MQTT broker + topic protocol, SQLite, and the dashboard at http://localhost:3100/dashboard.
For the tool reference, scoring layers, MQTT topics, dashboard panels, and server-side config, read mcp-coordinator's README. This file documents only essaim's own surface.
BCE — Behavior Composition Engine
Every agent prompt, hook, and MCP config is assembled, not written. essaim ships a catalog of reusable YAML modules; @swoofer/promptweave resolves the preset, validates, composes, and emits prompt.md + hooks/*.sh + .mcp.json for each agent.
32 behaviors 21 presets 3 composition rules 6 hook scripts 3 workflow phasesThree behavioral layers
Behaviors contribute numbered sections that sort deterministically into a final prompt.
| Layer | Sections | Responsibility | Sample behaviors |
|-------|----------|----------------|------------------|
| Foundation | 000-009 | Who I am, which project | project-context, user-brief, coordinator-rules |
| Patterns | 010-029 | How I coordinate | announce-before-write, conflict-resolution, worktree-isolation, sequential-wait |
| Mission | 030-050 | What I actually do | bug-hunting, test-writing, refactoring, code-review, debate, quiz, translation, sequential pipelines — 21 in total |
| Transversal | 050-099 | Constraints and style | activity-tracking, read-only-mode, audit-output |
Composition rules
Three rules adapt behaviors automatically based on what's assembled.
| Rule | Trigger | Action |
|------|---------|--------|
| announce-readonly-adaptation | announce-before-write + read-only-mode | Section 020 becomes "before your analysis" instead of "before modifying" |
| sequential-then-announce | sequential-wait + announce-before-write | Injects section 012: "wait -> announce -> code" |
| solo-mode-strip | coordinator-rules.solo_mode = true | Strips announce / conflict-resolution entirely; agent works alone |
Gating a sequential pipeline on artifacts
A resolved thread does not prove the predecessor's file is on disk: resolution and
writing are not ordered, and the coordinator's timeout sweeper can resolve a thread
that produced nothing at all. Gate on the artifact, not the status — give
sequential-wait the files you expect and it will poll for them before treating an
input as missing:
params:
sequential-wait:
expect_files: ["tmp/decouverte/features.yaml", "tmp/decouverte/risques.yaml"]
retry_attempts: 3 # default
retry_delay_seconds: 10 # defaultThe producing side owes the other half of the contract: write the artifact, read it back, and only then resolve — a mission prompt that resolves before it writes will have its output silently dropped by the consumer.
List the templates the CLI ships with via essaim list. To preview what a template assembles (prompt + agent plan) without burning tokens, use essaim run <template> --dry-run. Behaviors, presets, and composition rules live under behaviors/, presets/, and compositions/ in this repo — browse them directly to author or edit.
Read-only audits with a fixed write surface
read-only-mode is strict: agents read, analyze, and communicate via MCP threads, but write nothing — no Write, no Edit, no created files. To carve out an exception for a specific audit report (without lifting the rest of the no-write fence), pair it with audit-output:
essaim solo gardien -p . \
--set 'audit-output.paths=["MIGRATION_AUDIT.md","docs/risks.md"]'gardien ships with audit-output.paths = ["AUDIT.md"] by default; override with --set for any other artifact path. The pair (read-only-mode + audit-output) renders as "no writes — except these exact paths". Presets that need pure read-only communication (debat, revue-reviewer, chaine-review, arene-*) include only read-only-mode and write nothing at all.
Briefing a run with free-form context
Every preset includes the user-brief behavior in slot 001-user-brief (right after project identity, before any coordination rules). It's a free-form "system-prompt prefix" the operator can fill at launch time, no preset edit required. Both fields are optional — when neither is set, nothing renders.
essaim run raid -p . --agents 3 \
--set user-brief.brief='We are migrating the checkout from Stripe v3 to v4. Payment-touching code under src/payments/ must NOT be modified without a feature flag.' \
--set user-brief.constraints='["No breaking changes to /api/v1/*","Keep Node 18 compat","Each agent commits in its own worktree, no cross-merge"]'The brief lands once per agent prompt and is visible across every phase (discover / review / execute) because user-brief is not phase-tagged. Confirm with essaim run <template> --dry-run (the assembled prompt size will jump by the brief's length).
Dispatch caveat (maitre, revue): in lead/worker presets, the lead's brief does NOT auto-propagate to dispatched workers — the dispatch travels through announce_work(plan: ...), not through the worker's prompt. Set the brief on the worker preset too (maitre-worker, revue-reviewer) — every agent reads its own copy.
Work-stealing Phases
BCE behaviors can declare an optional phase. When a preset contains phased behaviors, the orchestrator executes each phase sequentially with different tool permissions.
PHASE TOOLS LOOP PURPOSE
-----------------------------------------------------------------
discover read_only no Scan code, list findings
review none no Dedup against existing threads
execute full yes Work-stealing — one task at a time
(no phase) full no One-shot (backward-compat)Tasks stay open (keep_open: true) until atomically claimed via the coordinator's /api/claim-task. MQTT pushes claimed / completed between turns; agents back off (3×10s grace) before declaring the pool drained. Crashed agents have claims auto-released on heartbeat timeout. phase-review dedups discoveries into NEW | DUPLICATE | ENRICHES before they hit the pool.
Effort Profiles
Model selection is phase-aware: each phase requests an effort level, the orchestrator maps it to a model + thinking keyword + turn budget. critical: discoveries auto-promote low to mid. Lead-worker presets propagate the level into dispatched prompts. Per-phase overrides supported (phase-discover.effort=mid).
| Level | Model | Thinking | maxTurns | Cost | Use case |
|-------|-------|----------|---------:|------|----------|
| low | claude-haiku-4-5 | none | 15 | $ | Coordination chatter, trivial review |
| mid | claude-sonnet-4-6 | think | 8 | $$ | Discover, standard execute, dispatched work |
| high | claude-opus-4-6 | think-hard | 20 | $$$ | Complex execute with thinking headroom |
| max | claude-opus-4-6 | ultrathink | 60 | $$$$ | Architecture debates, deep reasoning |
| auto | resolved by context | — | — | — | read_only/no-tools -> low; loop -> high; else mid |
CLI
essaim ships a CLI binary. All commands:
| Command | Description |
|---------|-------------|
| essaim run <template> [-p path] [--agents N] [--timeout min] [--set k=v] [--set-file k=path] [--dry-run] [--base-ref ref] [--coordinator-url url] [--max-quota-pct pct] [--cleanup] | Launch coordinated agents using a template. --dry-run previews the assembled prompts + agent plan without launching. --set-file behavior.param=path reads the param value verbatim from a file (no shell quoting, wins over --set on conflict). |
| essaim pipeline -f <file> [--coordinator-url url] [--max-quota-pct pct] [--dry-run] | Run a sequence of template runs across per-step repos, strictly sequential, stop on first failure. See Pipelines. |
| essaim solo <template> [-p path] [--timeout min] [--set k=v] [--set-file k=path] | Launch a single agent without orchestration |
| essaim scan <path> | Auto-detect project language, structure, test framework |
| essaim init [path] [--url url] [--name name] [--modules list] | Install hooks + MCP config on a project |
| essaim list | List the templates the CLI ships with |
| essaim self-update | Update to the latest release |
Examples
essaim scan ~/my-project # detect language, tests, modules
essaim run raid -p ~/my-project --dry-run # preview assembled prompts, no launch
essaim run raid -p ~/my-project --agents 3 # bug hunt
essaim run swarm -p ~/my-project --agents 4 # refactoring
essaim solo gardien -p ~/my-project # read-only audit
essaim run raid -p ~/my-project --set bug-hunting.modules='["src/auth"]'Pipelines
Chain several template runs across different repos in one command. Each step is an
essaim run on its own project path (same --set / --set-file / --modules
handling), with optional shell hooks around it. Steps run strictly sequentially
and the pipeline stops on the first failure (a non-zero step, before-hook, or
after-hook); remaining steps are recorded as skipped.
# pipeline.yaml — paths are relative to this file's directory
name: decouverte-complete
steps:
- name: analyse
template: mekova-decouverte
project: ../specs
set:
discovery-synth.projet: commandes-boulangerie
set_file:
user-brief.brief: tmp/brief-decouverte.txt # value read verbatim, wins over set
timeout_minutes: 20
- name: proto
template: mekova-prototype
project: ../code
modules_file: tmp/proto/modules.txt # one id per line — or modules: [a, b]
set_file:
user-brief.brief: tmp/brief-proto.txt
hooks:
before: ["cp ../specs/specs/x/ecrans.md tmp/proto/ecrans.md"]
after: ["npm run build"] # non-zero after-hook fails the stepessaim pipeline -f pipeline.yaml --dry-run # preview every step, no launch
essaim pipeline -f pipeline.yaml --coordinator-url http://localhost:3100Hooks run with cwd = the step's project. A consolidated report
(reports/pipeline-<name>-<timestamp>.md, next to the pipeline file) lists each
step's status, duration, and hook failures; the command exits 1 if any step failed.
Not in v1: parallel steps, conditionals, artifact templating — that judgment stays in the caller.
Portable Templates
Language-agnostic templates. essaim scan auto-detects the stack; the template generates prompts tuned to the result.
| Template | Pattern | Agents | Phases |
|----------|---------|--------|--------|
| raid | Bug hunt | 2-3 | discover -> execute |
| melee | Parallel test writing | 2-6 | discover -> execute |
| swarm | Volume refactoring | 3-6 | discover -> execute |
| chaine | Sequential pipeline | 3 | one-shot, staggered |
| relais | Relay improvements | 3 | one-shot, staggered |
| revue | Authors + cross reviewers | 4-8 | one-shot |
| maitre | Lead + workers | 3-5 | one-shot (lead dispatches) |
| gardien | Read-only audit | 1 | one-shot |
| debat | Architecture debate | 3 | one-shot, keep_open |
| arene | Code quiz / trivia | 3 | one-shot, keep_open |
| carrefour | Intentional conflict test | 2-3 | one-shot |
| babel | Documentation translation | 2 | sequential |
For per-template descriptions and the preset roles each one wires together, run essaim list presets or read compositions/ in this repo.
Anthropic Quota Pre-flight
run and solo check your Anthropic workspace quota before launching N agents, to avoid 429 storms mid-session.
essaim run raid -p ~/my-app --agents 4 --max-quota-pct 90
# Aborts if workspace utilization >= 90%- Reads usage from the Anthropic API using the key in the environment.
- Threshold via
--max-quota-pctflag orMAX_QUOTA_PCTenv var (default95). - Back-off when the usage endpoint itself returns 429.
essaim emits the resulting token_usage and quota_update events to the coordinator; the dashboard widget is rendered by mcp-coordinator.
Token Observability
Every agent turn is logged via the tokens component logger (input_tokens, output_tokens, cache_read, cache_creation, thinking, model, turn index). A per-run reports/YYYY-MM-DD-<run-id>.md aggregates totals by agent / phase / effort, and surfaces deduped: N from phase-review. Live gauges live in the mcp-coordinator dashboard.
Configuration
essaim init writes a per-project .claude/ (.coordinator-env, settings.json for MCP registration, BCE-assembled hooks/). The variables essaim itself reads are below; server-side COORDINATOR_* env vars belong to mcp-coordinator (see its README).
| Variable | Example |
|----------|---------|
| COORDINATOR_URL | http://localhost:3100 |
| COORDINATOR_AGENT_ID / _NAME / _MODULES | alice-12345 · Alice · src/auth,src/users |
| MAX_QUOTA_PCT | 95 (overrides the pre-flight default) |
| LOG_LEVEL | debug / info / warn / error |
Resolution priority: CLI flag → env var → config.json → default. If the coordinator has JWT auth on, essaim init provisions a token into .coordinator-env and essaim attaches it to every MCP HTTP and MQTT request automatically.
Structured Logging
JSON to stdout via Pino. Component loggers: orchestrator, agent-loop, phase-scheduler, work-stealing, effort, quota, tokens. Control verbosity with LOG_LEVEL=debug|info|warn|error; pretty-print with NODE_ENV=development.
Development
# Tests
npm test # 302/303 unit tests pass on macOS/Linux; one Windows-only chmod test is skipped there
npm run test:watch
# CLI in dev
npm run dev -- list
npm run dev -- run raid -p ~/my-project --dry-run
# Build
npm run buildessaim is exercised by its own catalog — the swarm template was used to refactor essaim's own source during development, producing a working dogfood loop.
Related Projects
| Package | Role |
|---------|------|
| mcp-coordinator | Coordination server: 26 MCP tools, SQLite, embedded MQTT broker, live dashboard. essaim agents talk to it over MCP HTTP; push events arrive over MQTT. |
| @swoofer/promptweave | BCE engine: resolves presets, validates behavior YAML, composes outputs. essaim feeds it the catalog; promptweave returns prompt.md, hooks, and MCP config. |
Support
Solo maintainer. If this project saves you time, consider supporting development:
A star on the repo also helps surface the project to other developers.
License
MIT
