Rename the eleven MCP tool names (bridge_ack/ask/list/poll/profiles/reply/ send/spawn/status/stop/whoami) to their fleet_* names across the Markdown documentation. fleet_* is written as the normal name; one deprecation note in README.md says bridge_* still works for one release. docs/MCP-Contract.md is renamed only inside section 6 (lines 210-293): sections 1-5 and 7-11 are stale pre-build design text (CB-609) and are deliberately left with old names so dead text does not look maintained. Also renames e2e/bridge_ask_transcript.md to e2e/fleet_ask_transcript.md to match its content. CLAUDE.md, wiki/, plugin/skills/setup/SKILL.md and .claude/skills/port-to-opencode/SKILL.md are owned by other units and are untouched.
6.9 KiB
v1.0.0 — One leader, one host, complete
This is the first release of bridged.
bridged lets one main Claude Code session (the leader, on your Pro/Max subscription)
run a team of workers — extra Claude Code sessions on a cheaper or local model, and
non-Claude agents too. The leader's own session is never touched: it stays on subscription,
with a clean environment.
This release finishes a full scope — it does not stop halfway. The scope is one leader on one machine, running many workers. Everything that setup needs is now built, tested, and used daily: who-is-who, the subscription line, messages in both directions, worker start and stop, security, and monitoring. Nothing on the single-machine path is left as a known gap.
This is also how the code is shaped: PrimaryRegistry holds exactly one leader. Running
across many machines is the next big step (see What comes next below) — not a missing piece
of this one.
One gateway for all messages
- Everyone talks through the same door. The leader and every worker connect to the same
MCP server and use only its tools:
fleet_whoami·fleet_profiles·fleet_spawn·fleet_list·fleet_status·fleet_send·fleet_reply·fleet_ask·fleet_poll·fleet_ack·fleet_stop. - You are who your connection says you are. The bridge finds out who is calling from the
connection itself, never from a name the caller sends. So a worker cannot pretend to be
someone else, and
fleet_whoamitells each agent its own role — no guessing. - The subscription line cannot be crossed. Only a spawned worker gets
ANTHROPIC_BASE_URL; the leader never does. Each worker profile has a list of allowed model hosts, checked before anything starts. - Messages wait for the right moment. The bridge sends one message per turn, only when the other side is ready — no hammering a busy agent.
Worker lifecycle
- Start → work → stop. Each worker gets its own git worktree (its own copy of the repo)
with the same setup as the leader —
CLAUDE.md, skills, hooks — so it commits on its own branch and opens its own PR. Ready-made playbooks ship in the repo:.claude/skills/implementerand.claude/skills/reviewer. - Fast failure, not a silent hang. Starting a worker waits until it is really connected.
If it never connects, you get a clear error (
PeerUnreachableException) instead of a stuck send. - Workers don't live forever. Idle workers are cleaned up (
idle_ttl), long sessions have a turn limit (context_cap), shutdown drains work first, and workers left behind by an old daemon are found and removed at startup. - Predictable placement. Each worker gets its own tab in a shared worker space, in the same order every time.
No reply gets lost
MCP only lets the client call the server, so the bridge could push to a worker but the leader had to ask for its replies. That gap is now closed on a single machine:
- Replies are kept, never dropped. If a reply arrives and nobody is waiting, the bridge holds it until the leader picks it up.
- Replies can survive a restart. With a broker (LavinMQ or RabbitMQ) set up, held replies
live on the broker, so a daemon restart does not lose them — they come back, and repeats are
filtered out by
msgId. Nobroker:in the config → replies are held in memory instead. - The leader gets a tap on the shoulder. When a reply lands, the bridge nudges the leader's own pane — only when the leader is free, and only a few times. If the leader is on another machine, this quietly falls back to pick-up mode; the reply still waits.
- Workers can ask questions. With
fleet_ask, a worker can pause mid-task, ask the leader something, and continue the same task with the answer.
More than one kind of worker
Workers are started through a small plug-in interface (PeerLauncher). Two plug-ins ship:
one for Claude Code and one for opencode (tested live against opencode 1.18.5). The
opencode one proves the interface is neutral — it uses nothing Claude-specific. Each worker
only sees the tools its own launcher gives it.
Security & operations
- Auth. Default is
loopback-trust: only same-machine callers are trusted. Or set a bearertoken. Unknown callers count asANONYMOUS— nobody is trusted by accident. If the config would expose the daemon to the network without a token, it refuses to start. Workers never need the token, so turning auth on cannot lock them out. - Rules + audit log. The role rules are checked on both doors (REST and MCP). A worker may only act as itself. The audit log is JSON and never contains message text.
- Monitoring.
/healthzfor liveness,/metricsfor Prometheus — no extra libraries. - Runs as a service. launchd (macOS) and systemd (Linux) files are included. If herdr isn't up yet at boot, the daemon waits up to 30 seconds and then runs in a reduced mode instead of crash-looping.
- CI. Every push builds and tests on the Gitea runner, including the broker test against
a real broker. Only the live-herdr test stays local (
-Pcontract).
What you need
Java 25 · Maven · herdr 0.8.0 (protocol 19) · optionally LavinMQ or RabbitMQ for restart-proof replies · macOS (launchd) or Linux (systemd). For TLS, put a reverse proxy in front — the daemon does not do TLS itself, by design.
Tested
mvn clean install is green at 84081b2: 399 tests, coverage 75.6% of instructions /
64.5% of branches. Live end-to-end runs under e2e/: a worker asking the leader a
question, one leader running several workers at once on a bug hunt, and a 30-turn
back-and-forth conversation. The bridge is used on itself — worker-run code reviews have led
to real committed fixes in this repo.
What comes next
The single-machine story is done. The next big step stretches the same rules across machines:
- Many machines (CB-308). A leader on machine A with workers on machines B and C — built
on this release's broker layer, with one gateway per machine. The design is written
(
docs/CB-308-Multi-Host-Federation.md); the open question is trust between machines. - Many leaders. Today the bridge holds exactly one leader. The next idea is a small council — for example one Claude and one Codex — that can discuss a problem together, compare answers, and agree on a decision before the work is handed to workers. This needs leader-to-leader messages and a simple way to settle disagreement, neither of which exists yet.
- Third-party launcher plug-ins. Loading launcher plug-ins from outside the project needs a trust model first, because a launcher runs with daemon rights and can hand secrets to workers.
One thing we chose not to build, so it isn't read as a gap: the originally planned heavy
message envelope (CB-201). Connection identity already routes every reply to the right place,
so only a small QUESTION message kind and a turn_id were added.