Agent-Driven Repo Mesh Setup
This page is written for an AI coding agent (Claude Code, Codex, Hermes, or similar) that has been told to set up Repo Mesh across one or more machines that already run ADHDev. Follow the numbered steps in order and execute each step exactly as written — some are shell commands, some are MCP tool calls (see the box right below).
For human readers: hand this page to your agent and say "set up Repo Mesh following the mesh setup guide" — the agent will do the discovery, propose the config, and stop for your approval at each step that writes something. You approve; it does the rest.
This is the automated shortcut. For the concepts behind it read Repo Mesh; for a hands-on manual walkthrough read Tutorial: Your First Real Task.
The shape of the flow: machines already set up → create the mesh → mesh_init proposes config → you approve → launch a coordinator.
MCP tools vs. CLI commands — they are not interchangeable
Every mesh_* name in this page (mesh_plan_onboarding, mesh_create, mesh_add_node, mesh_init, mesh_status, …) is an MCP tool — call it through your agent's tool interface, not the shell. There is no adhdev mesh init or adhdev mesh_status command; running a mesh_* name at the shell fails with "unknown command."
Some of these steps also have a CLI equivalent (adhdev mesh plan, adhdev mesh create, adhdev mesh add-node) that does the same thing without an MCP client — those are shown in ```bash blocks throughout. Anything shown in a plain, unlabeled code block (no bash) is an MCP tool call, not a shell command. The CLI equivalents stop at Step 2 — mesh_init (Step 3) and everything after it (slots, MAGI, the coordinator toolset) has no CLI form; it is MCP-only.
What this guide assumes
You need a working ADHDev install on every machine that will host a mesh node. If a machine is not yet set up, run Agent-Driven New Machine Setup on it first and come back here.
Single machine vs. multi-machine
| Single-machine mesh | Multi-machine mesh | |
|---|---|---|
| Works in | Standalone and Cloud | Cloud only |
| Nodes | Git worktrees of one repo on one machine | Workspaces across several machines |
| Account needed | No (standalone) | Yes — same account on every daemon |
A single-machine mesh is real and fully functional in the self-hosted standalone build: worktree nodes, the task queue, Refinery, MAGI, and MCP mesh mode all run locally. What standalone cannot do is relay between machines — coordinating several same-account daemons is the Cloud feature.
Rule of thumb for the agent: if the user wants worktree parallelism on one box, standalone is enough. If they name two or more machines, they need Cloud sign-in on each (see Multi-machine).
Step 0 — Verify the prerequisites
0a. Is the daemon up on this machine?
adhdev statusExpected: the daemon reports healthy — standalone on localhost:3847, or the machine shown online against api.adhf.dev in Cloud mode.
If not: stop and run Agent-Driven New Machine Setup first. Do not continue against a dead daemon — every later step needs it.
0b. Is the workspace a Git repository with a remote?
Repo Mesh identifies a mesh by its repo identity, which comes from the Git remote. Run this in the workspace you intend to add:
git rev-parse --show-toplevel
git remote -vExpected: a repo root path, and at least one remote. If there is no remote, Step 2's discovery will fail with remote_not_found — you can still pass an identity by hand at mesh-create time (--identity), but a real remote is the normal path.
0c. Do you have the mesh tools?
This is the step that most often gets skipped, and nothing after it works without it. Your mesh_* tools come from the ADHDev MCP server running in mesh mode. There are two ways to get there, and they are ordered:
- Standard mode first — a plain MCP registration gives you three bootstrap tools:
mesh_plan_onboarding,mesh_create,mesh_add_node. That is exactly enough to create a mesh. - Mesh mode second — once a mesh exists, re-register with
--repo-mesh <mesh_id>to get the full coordinator toolset.
Mesh mode refuses to start if no mesh exists yet, so you cannot skip straight to it.
Check for a ghost mesh before trusting an existing .mcp.json
If this workspace already has a .mcp.json with --repo-mesh <mesh_id> in it, don't assume that mesh is real — it can be a leftover from a previous session whose mesh was later deleted. Confirm it first:
adhdev mesh listIf the mesh_id in .mcp.json isn't in that list, treat the existing registration as a ghost config: it will fail to start in mesh mode (or silently point at nothing). Delete or replace it with the mesh_id you get from Step 2 below rather than trying to reuse it.
Register standard mode in your MCP client config. The server name is yours to choose; adhdev is conventional:
{
"mcpServers": {
"adhdev": {
"command": "adhdev",
"args": ["mcp"]
}
}
}For Codex, the equivalent registration is a CLI call rather than a JSON edit:
codex mcp add adhdev -- adhdev mcpThe MCP server needs a live daemon
adhdev mcp pings the daemon before registering any tools and exits with code 1 if it can't reach one. Local mode targets the standalone daemon on port 3847 (adhdev standalone); IPC mode targets the cloud daemon (adhdev daemon). If the MCP server dies on startup, re-check Step 0a — it is almost always a daemon that isn't running.
Useful flags, should you need them:
| Flag | Meaning |
|---|---|
--mode <local|ipc> | Transport. local = standalone daemon, ipc = cloud daemon |
--port <n> | Daemon port. Defaults: local 3847, ipc 19222 |
--password <pass> | Standalone daemon password, if you set one |
--repo-mesh <mesh_id> | Switch to mesh mode (Step 2c) |
Equivalent environment variables: ADHDEV_PASSWORD, ADHDEV_MESH_ID, ADHDEV_MCP_TRANSPORT.
Restart the client after editing MCP config
MCP servers are read at client startup. After any registration change, start a fresh agent session — an already-running session will not pick up the new tools.
Step 1 — Inventory the machines
If the user wants a multi-machine mesh, confirm every machine is online before building the mesh, so you don't add a node you can't reach.
adhdev statusRun this on each machine, or check the Cloud dashboard's machine list. Every intended host must show online under the same account.
If a machine is missing: send it through Agent-Driven New Machine Setup. Cloud sign-in on that machine is a human step — the agent cannot do it.
If the user only has one machine: that's fine, continue. You'll build worktree nodes instead of remote nodes in Step 2b.
Step 2 — Build the mesh
2a. Plan first (read-only, writes nothing)
Always start with the dry-run. mesh_plan_onboarding performs only filesystem reads and local Git queries — no fetch, no config write, no branch or worktree creation.
MCP tool call (through your agent's tool interface, not the shell):
mesh_plan_onboarding(workspace: "<absolute path to repo>")CLI equivalent, which prints the same plan:
adhdev mesh plan
adhdev mesh plan --json # complete machine-readable planExpected: a plan whose kind is one of create_mesh_and_onboard, add_existing_workspace, or clone_new_worktree, plus a discovery block (repo identity, branch, clean/dirty) and a list of steps each marked read-only or approval-required. The CLI closes with: "Nothing was written."
Read the plan before acting. It tells you which of the next three tools to call, and it will surface blockers up front rather than halfway through.
Common failure codes and what they mean:
| Code | Meaning |
|---|---|
not_git_repository | Wrong directory — point workspace at the repo root |
remote_not_found | No Git remote; see Step 0b |
dirty_workspace | Uncommitted changes — commit or stash, then re-plan |
nested_worktree | You're inside a worktree of a worktree; use the main checkout |
compatible_mesh_exists | A mesh for this repo already exists — add a node instead of creating one |
detached_head | Check out a branch first |
2b. Create the mesh and add nodes
Follow whatever the plan told you.
Creating a new mesh (plan kind create_mesh_and_onboard) — MCP tool call:
mesh_create(name: "<mesh name>", add_current: true)add_current: true registers the current workspace as the mesh's first node in the same call. The response contains the mesh_id you'll need everywhere below.
mesh_create(add_current: true) does not set providerPriority
Unlike mesh_add_node, mesh_create has no provider_priority parameter. The first node it registers has no policy.providerPriority until you set one — see the callout at the end of this step.
CLI equivalent:
adhdev mesh create my-project --add-currentAdding an existing workspace as a node (plan kind add_existing_workspace) — use this for a second machine, or a second checkout. MCP tool call:
mesh_add_node(workspace: "<absolute path>", mesh_id: "<mesh_id>")Optional: read_only: true for a node that should never be given write tasks, and provider_priority: ["claude-cli", "codex-cli"] to fix which agent runs there — see the providerPriority callout below for why this matters.
CLI equivalent:
adhdev mesh add-node mesh_abc123 --worktree --provider-priority claude-cli,codex-cliCreating a worktree node (plan kind clone_new_worktree) — this is how you get parallelism on a single machine. It actually runs git worktree add. MCP tool call (no CLI equivalent):
mesh_clone_node(source_node_id: "<node_id>", branch: "<new branch name>")Optional base_branch — defaults to the current HEAD.
Confirm providerPriority before moving on
mesh_launch_session fails closed (missing_provider_priority) when called without an explicit type on a node whose policy.providerPriority is empty — and neither mesh_create(add_current: true) nor mesh_clone_node sets it. Check every node you just created:
mesh_status()If a node's providerPriority is missing, either pass provider_priority when you register it via mesh_add_node, always call mesh_launch_session with an explicit type for that node, or set the policy through the dashboard's Repo Mesh policy editor / a committed .adhdev/mesh.json. mesh_init (Step 3) recommends a providerPriority list from detected CLI providers, but it is advisory only — it does not write it to node policy for you.
Verify what you built:
adhdev mesh show mesh_abc123
adhdev mesh status mesh_abc123show lists the nodes; status probes each one for health.
2c. Re-register the MCP server in mesh mode
Now that a mesh exists, switch your client to mesh mode to unlock the full coordinator toolset. Update the MCP config, replacing the placeholder with your real mesh_id:
⏸ Your agent runtime may block this edit — don't work around it
Editing .mcp.json changes which tools a future session gets, so some agent runtimes gate it behind a separate approval (distinct from ordinary file edits). If you are an agent and this edit is blocked: do not try to bypass the gate. Stop, and hand the human the exact one-line diff to .mcp.json (or the YAML block for Hermes) plus the command to run, so they can apply it themselves. Retrying, escalating, or finding another way to write the same bytes defeats the point of the safety check.
{
"mcpServers": {
"adhdev-mesh": {
"command": "adhdev",
"args": ["mcp", "--mode", "ipc", "--repo-mesh", "mesh_abc123"]
}
}
}For Hermes, the same thing in YAML under mcp_servers — locate the file with hermes config path:
mcp_servers:
adhdev-mesh:
command: adhdev
args:
- mcp
- --mode
- ipc
- --repo-mesh
- mesh_abc123
enabled: trueFor Codex:
codex mcp add adhdev-mesh -- adhdev mcp --mode ipc --repo-mesh mesh_abc123Then restart the agent session. In mesh mode the tool surface is fully replaced — the standard session tools go away and the mesh coordinator tools appear.
Standalone users
Use --mode local instead of --mode ipc. IPC mode talks to the cloud daemon; local mode talks to the standalone daemon on port 3847.
Step 3 — Let mesh_init propose the repo config
This is the init step — the one that reads your repo and writes sensible defaults so you don't hand-author config files.
mesh_init is an MCP tool, not a CLI command — there is no adhdev mesh init. Call it through your agent's tool interface. It is a two-stage tool: it previews by default and only writes when you explicitly say so.
3a. Preview (default — writes nothing)
MCP tool call (no CLI equivalent):
mesh_init()That's it. write defaults to false, so this run is a dry-run: the response comes back with dryRun: true and each proposed config carries written: false.
It proposes three repo-level config files:
| File | What it configures |
|---|---|
.adhdev/refine.json | Refinery validation — the commands that must pass before a branch converges |
.adhdev/worktree_bootstrap.json | What to run in a freshly created worktree (dependency install) |
.adhdev/change-impact.json | Change-impact analysis settings |
It also returns a providerPriority recommendation, which is advisory only — mesh_init never applies it for you.
How the verification commands are chosen. mesh_init reads your package.json scripts and matches them against four categories: typecheck, test, lint, build. A script whose name equals a category, or starts with <category>:, becomes a suggested command as npm run <script>. Suggestions are merged with any mesh-level project commands, de-duplicated, and capped at 4.
Non-npm repos get no suggestions
The detection only matches npm scripts named exactly typecheck / test / lint / build or prefixed typecheck: / test: / etc. A repo that uses cargo test, go test, poetry run pytest, a bare tsc --noEmit, or a script named something else (check, vitest) gets zero suggestions and a skippedReason: "no_suggestion". That is expected, not a failure — write .adhdev/refine.json by hand for those repos.
3b. Review with the human ⏸ HUMAN STEP
⏸ HUMAN STEP — show the proposal before writing
Present the proposed refine, worktreeBootstrap, and changeImpact blocks to the user and get an explicit approval. These files land in the repo and become the gate that decides whether future work converges — a wrong test command here silently blocks every merge later.
Ask specifically about the refine validation commands: are these the commands that actually have to pass in this repo? That is the one field a human should always eyeball.
3c. Write (only after approval)
MCP tool call:
mesh_init(write: true)mesh_init never clobbers an existing config. If a file is already there it comes back skippedReason: "already_exists" and is left untouched. To deliberately replace it:
mesh_init(write: true, overwrite: true)There is also mesh_reinit, which is the same operation with overwrite defaulting to true — use it when you intend a refresh, so the intent is explicit in the call.
Verify: the response reports dryRun: false and written: true per file. Confirm on disk:
ls .adhdev/Commit these files. They are repo config — the whole point is that every node and every future coordinator reads the same rules.
Step 4 — Models, limits, and MAGI
Everything in this step has a working default. Only change what the user actually cares about, and only ask when the answer would change the outcome.
4a. Node slots — which agent and model runs where
A slot binds a provider (and optionally a model and thinking level) to a difficulty class. Inspect what a node has now:
mesh_node_slots_list(node_id: "<node_id>")If a node has no explicit slots, sensible ones are derived from its provider priority and the per-mesh difficulty presets, which default to:
| Difficulty | Model | Thinking level |
|---|---|---|
easy | haiku | low |
medium | sonnet | medium |
difficult | opus | high |
freeform is the fourth valid difficulty and deliberately has no preset.
Leave this alone unless the user asks. The derived defaults are correct for most meshes. Set slots explicitly when the user wants cost control (pin cheap work to a small model) or has a provider that only exists on one machine.
Like mesh_init, this tool is dry-run by default:
mesh_node_slots_set(node_id: "<node_id>", slots: [...]) # preview
mesh_node_slots_set(node_id: "<node_id>", slots: [...], write: true) # applySlots are replaced wholesale
slots is not merged into what's there — it replaces the node's entire slot list. Always run mesh_node_slots_list first and build your new array from the current one, or you will silently drop configuration. Run the dry-run and compare currentSlots against proposedSlots before writing.
Per slot: provider is required; model, thinkingLevel, difficulty (array), capability (array), and maxParallel are optional. An empty difficulty means the slot handles all difficulties.
4b. Policy limits — take the defaults
Mesh policy governs checkpoints, push approval, retries, and concurrency. The defaults are deliberately permissive on concurrency and conservative on safety, and you should not touch them during setup. Notably:
maxParallelTasksis effectively unlimited by default; the dashboard intentionally hides this control.requireApprovalForPushdefaults to true — pushes ask first.requirePostTaskCheckpointdefaults to true — work is checkpointed after each task.delegatedWorkerAutoApprovedefaults to true — worker sessions don't stall on their own tool prompts.
Ask the user only about this one: whether they want push approval to stay on. Everything else, take the default and move on. Policy is set through the dashboard's Repo Mesh policy editor or a committed .adhdev/mesh.json, not through a mesh setup tool.
4c. MAGI — optional, worth turning on if you use more than one agent
MAGI asks the same question of several agents at once and compares the answers. It is a cross-verification feature, and the axis that makes it work is agent/vendor diversity — different models fail in different ways, so two vendors disagreeing is the signal you're buying.
This is about which CLIs you have installed, not how many machines you own. If two or more different agents are available — say claude-cli and codex-cli — a MAGI panel is fully valid on a single machine. Most developers already have several CLIs installed, so this is worth offering rather than skipping. Spreading the panel across machines adds independence on top, but it is a bonus, never a prerequisite.
Ask the user whether they want it. If they run more than one agent vendor, recommend it; if they only have one CLI installed, skip it and say why.
Mechanically, MAGI requires at least 2 independent (node, provider) targets and never silently degrades to a single agent. A target is identified by node and provider together, so two different providers on one node are two distinct targets and satisfy the requirement. MAGI additionally raises an advisory note when a panel has fewer than 2 distinct providers or fewer than 2 distinct nodes — that is a hint about how correlated your panel is, not a failure. The configuration that actually matters is two different vendors; a panel of one provider replicated twice is the weak case, whether or not it spans machines.
If the user wants it, bind a panel to a task kind. Valid kinds are claim_audit, rca, design, and freeform:
mesh_magi_kind_panel_list() # what's configured now
mesh_magi_kind_panel_set(task_kind: "rca", slots: [...]) # preview
mesh_magi_kind_panel_set(task_kind: "rca", slots: [...], write: true)Same two rules as node slots: dry-run by default, and the slot list replaces the panel wholesale. Each slot needs a provider; nodeId, model, capabilityTags, and n (replica count, default 1) are optional. A nodeId must name a node of this mesh or the call is rejected.
Panels are stored per mesh and are machine-local — they live in ~/.adhdev/meshes.json, not in the repo.
Step 5 — Launch the coordinator
The coordinator is the session that holds the mesh tools and hands work to the nodes.
A coordinator cannot launch itself
There is no mesh_launch_coordinator tool and no adhdev mesh subcommand that starts one. If you are an agent reading this, you cannot complete this step by calling a tool — hand it to the human, or use Path B below.
Path A — Dashboard (the normal way) ⏸ HUMAN STEP
⏸ HUMAN STEP — the human clicks this
- Open the Repo Mesh page (
/mesh) in the dashboard. - If the mesh has no host pinned yet, set the host daemon — this is a separate, deliberate action from launching.
- Pick a CLI provider from the dropdown.
- Click Launch Host.
The daemon registers the mesh MCP server for that provider automatically and opens the coordinator session as a dashboard tab. If the chosen provider needs manual MCP setup, the UI shows a config block to paste — apply it and start a fresh CLI session.
Failures surface as explicit codes worth knowing: mesh_coordinator_node_not_found (no workspace resolved), mesh_coordinator_provider_priority_unusable (no usable agent on that node), mesh_coordinator_mcp_registration_failed (registration failed, so the session was not launched — a deliberate fail-closed).
Path B — MCP mesh mode (no dashboard)
If you already did Step 2c, you are effectively a coordinator: your session holds the mesh-mode tool surface. Confirm it:
mesh_status()Expected: an aggregate snapshot listing your nodes. If the tool doesn't exist, the mesh-mode registration didn't take — recheck Step 2c and restart the session.
Step 6 — Smoke test
Prove the loop works before handing the mesh to real work. Enqueue one small, safe task:
mesh_enqueue_task(...)An idle node claims queued work — that is the intended path. mesh_send_task targets a specific session directly instead; use it only when you mean to bypass the queue.
Watch it move:
mesh_view_queue()
mesh_status()Expected: the task moves from queued to claimed to completed, and mesh_git_status shows the change on the node that ran it.
Completion is evidence-based — git status, checkpoints, and ledger events, not the agent's self-report. If a task reports success, confirm the side effect before believing it.
For a fuller first task with real substance, follow Tutorial: Your First Real Task.
What the human actually did
- Pasted this page into an agent.
- Signed in on each machine — once per machine, browser approval (Cloud only).
- Approved the
mesh_initconfig proposal.- Clicked Launch Host in the dashboard. 4′. Conditional: if the agent's runtime blocked the
.mcp.jsonedit in Step 2c, applied the one-line diff the agent handed over.Everything else — Git discovery, mesh creation, worktree nodes, config detection, slot defaults — the agent did.
Troubleshooting
mesh_*tools don't exist in the session — the MCP server isn't in mesh mode, or the session predates the config change. Recheck Step 2c and start a fresh session; MCP config is read at client startup.- MCP server exits immediately — it pings the daemon before registering tools and exits 1 when it can't reach one. Run
adhdev status. Local mode needsadhdev standalone; ipc mode needsadhdev daemon. - Mesh mode refuses to start — mesh mode requires an existing mesh. Run
adhdev mesh listto confirm the ID, and create one via standard mode first if there isn't one. .mcp.jsonalready has a--repo-mesh <id>but mesh mode won't start /adhdev mesh listdoesn't show it — that's a ghost config from a deleted mesh (see the callout in Step 0c). Confirm withadhdev mesh listand replace the id with a real one from Step 2.adhdev mesh initsays unknown command —mesh_initis an MCP tool, not a CLI subcommand. Call it through your agent's tool interface once you're registered in mesh mode (Step 2c), not at the shell.- The agent's runtime blocks editing
.mcp.json— expected for some runtimes (Step 2c); the agent should hand you the exact diff rather than trying to bypass the block. mesh_launch_sessionfails withmissing_provider_priority/ "no providerPriority policy" — the node has nopolicy.providerPriorityand you didn't pass an explicittype. Either callmesh_launch_sessionwithtypeset, or setprovider_priorityon the node (re-add viamesh_add_node, or edit mesh policy).mesh_init's providerPriority suggestion is advisory only — it does not get applied automatically.dirty_workspacefrom the plan — commit or stash, then re-plan. Onboarding deliberately refuses to build nodes on top of uncommitted work.compatible_mesh_exists— a mesh for this repo already exists. Usemesh_add_nodeagainst it instead ofmesh_create.mesh_initwrote nothing — either the files already exist (skippedReason: "already_exists"— passoverwrite: trueif you mean to replace them) or nothing was detected (skippedReason: "no_suggestion"— a non-npm repo; author the config by hand).- A node shows probe-failed in
adhdev mesh status— that machine's daemon is offline, or it's a multi-machine mesh on standalone. Cross-machine coordination requires Cloud. - MAGI errors with
magi_kind_not_configured— bind a panel to that task kind first withmesh_magi_kind_panel_set. There is no automatic fallback panel. - MAGI errors with
magi_insufficient_targets— fewer than 2 independent (node, provider) targets are available. The usual fix is installing or enabling a second agent CLI; a second machine is not required. MAGI will not run with one target.
Where to go next
- Repo Mesh — the concepts: nodes, missions, queue, ledger, Refinery
- Tutorial: Your First Real Task — a full manual walkthrough
- MCP Server — the complete tool reference and all registration forms
- Multi-machine — linking laptop + desktop + work box (Cloud only)
- Agent-Driven New Machine Setup — get a new machine ready to join
