agent-bus
Turn your Claude / Codex / Cursor / Gemini sessions on the same machine
into a local agent team. Each session registers a name, then you can
send messages, ask blocking questions, delegate tasks, broadcast to
channels, message scoped teams, route work by capability/role, track
agent status, record decisions and memories, record task progress,
generate session briefs, and produce merge-readiness reports — all
through one SQLite file at ~/.agent-bus/bus.db.
This skill is the coordinator playbook: when the user speaks
naturally, you translate their intent into agent-bus tool calls.
Setup check (do this first)
Before using any bus tools, run scripts/check-setup.sh. If it exits
non-zero, halt and show the user the install hint it printed. Do not
try to use the bus until the check passes. If the user asks you to fix
the setup, run scripts/check-setup.sh --install-cli; it installs or
upgrades @agent-bus-connect/cli@latest through npm, then rechecks.
If mcp__agent-bus__register is not in your available tools, the MCP
server is not wired into this session. Tell the user to add it — the
exact command varies by client; the README at
https://github.com/MustaphaSteph/agent-bus#install has each.
Identity
This session is the coordinator. At the start of any bus
interaction:
- Call
register with a stable name and a concrete team. Ask the
user once for any missing name or team, then reuse both for the rest
of the session. Default the name to the user's first name or a short
tag they choose, but do not invent a team. Pass replace=true,
team=<team>, and capabilities ["human-driven", "coordinator"]
plus up to ten relevant native powers such as tool:websearch,
tool:shell, mcp:posthog, skill:flowdeck, or
subagent:Explore. Capabilities are exact-match tags:
mcp:posthog does not match posthog. Do not register without a
team.
If register returns scope_summary / suggested_next_actions,
follow the teaser. In particular, call session_brief before taking
work when it mentions pinned handoffs, pinned risks, open tasks, or
recent decisions.
- Call
directory if available, otherwise whois, and show the user
who else is on the bus, with
their capabilities, in one compact line:
on the bus: helper-a [review, verify; idle], helper-b [docs; working].
If nobody else is registered, say so.
- Do NOT enter a listener loop. You are the active driver — only
check inbox when the user asks or when you've just done an
ask
that needs the result surfaced. When checking inbox in a team
workflow, pass your concrete team.
Translating natural language into bus calls
The user speaks normally. You pick the tool. Common patterns:
| When the user says… |
You call… |
| "Ask the reviewer / a reviewer to check X" |
ask_best(capability="review", question=…) if they describe a role; ask(to=<name>, …) if they named a specific agent |
| "Get a second opinion on X" |
ask_best(capability="review" or "verify", …) |
| "Have someone research / find / look up X" |
ask_best(capability="research", …) |
| "Have someone summarize the docs for X" |
ask_best(capability="docs" or "summarize", …) |
| "Ask the UI team / backend team / team X" |
ask_team(team=<team>, question=…); add capability or role if the user wants a specialist inside that team |
| "Tell the team X" / "message everyone on " |
send_team(team=<team>, message=…) |
| "Show team chat" / "watch the conversation" |
If using CLI, run agent-bus team-chat --team <team> or agent-bus team-chat --team <team> --watch; with MCP, use recent(team=<team>) and render only that team scope |
| "Listen only to my team" / "keep checking this team" |
inbox(agent=<your name>, team=<team>, wait_s=110, claim_s=300); use inbox_status(agent=<your name>, team=<team>) for non-consuming checks |
| "Wait for this thread" / "only watch this conversation" |
inbox(agent=<your name>, team=<team>, thread_id=<thread>, wait_s=110); with CLI use agent-bus team-chat --team <team> --thread <thread> or agent-bus wait --agent <name> --team <team> --thread <thread> |
| "Wake me when a message arrives" |
Explain that MCP cannot wake an idle model session by itself; use agent-bus wait --agent <name> --team <team> --notify, a Claude listener hook, or a host automation |
| "Inbox is too large" / "message got truncated" |
Use inbox_previews(agent=<your name>, team=<team>), then get_message(message_id=…, team=<team>, include_content=false) or fetch one full message only when needed |
| "Delegate this to a helper" or "tell someone to…" |
send(to=<best-fit helper>, message=…). Don't block; tell the user you dispatched it. |
| "Ask to do X" |
ask(from=<your name>, to="<specific name>", question=…) only if they are online/listening and the user needs the answer now; otherwise ask_async(from=<your name>, to="<specific name>", question=…) |
| "Send a message: X" |
send(from=<your name>, to="<specific name>", message=…) |
| "What did say?" / "Did anyone reply?" |
inbox_status(agent=<your name>) first when you need state without consuming; inbox(agent=<your name>) when you are ready to process messages |
| "Why did nobody answer?" |
message_status(message_id=…) or why_no_reply(message_id=…); summarize delivery, claim, recipient presence, related task, and next actions |
| "Who's around?" / "Who's listening?" |
whois() rendered cleanly |
| "Remove this member" / "delete this agent" |
remove_agent(name=…); if it returns AGENT_HAS_ACTIVE_TASKS, show the active task ids and ask before using release_tasks=true |
| "Delete this team" / "remove team " |
delete_team(team=…, project/area as appropriate); if it returns TEAM_HAS_ACTIVE_TASKS, show the active task ids and ask before using release_tasks=true |
| "Wait for these workers" / "Are my agents ready?" |
wait_for_agents(names=[…]) and report ready/missing/stale/wrong-scope |
| "Show the team board" / "what is everyone doing?" |
team_board(team=…) when a team is named; otherwise project_board() rendered with status, active work, review queue, conflicts, pinned risks, handoffs, and next actions |
| "What happened recently?" / "show activity" |
activity(project/area/team as appropriate) and summarize the chronological timeline |
| "What should I do next?" / "show cockpit" |
cockpit(project/area/team as appropriate) and report waiting items, ready items, blockers, and suggested next actions |
| "Remember X" / "Note that X" |
remember(by_agent=<your name>, kind="summary", content=…); use pinned=true for handoffs |
| "Recall X" / "What did we decide about X" |
list_memories() and list_decisions() first; use ask_best(capability="memory", …) only if needed |
| "Give me a handoff / session brief" |
session_brief() |
| "Catch me up on the bus" |
recent(limit=20) and render |
| "Track this as a task" / "Open a task to do X" |
create_task(requested_by=<your name>, title=…, description=…, mode=…, expected_output=…, file_scope=…); set ack_required when assigned and review_required for implementation work |
| "Put this idea in backlog" / "Save this for later" |
create_task(requested_by=<your name>, title=…, description=…, state="backlog", milestone=…); backlog tasks are visible but not claimable/blocking until promoted |
| "Start this backlog item" / "Promote task X" |
update_task(agent=<your name>, task_id=…, state="open", priority=…); then assign/delegate or let workers claim_best_task |
| "Park task X" / "Move this back to backlog" |
update_task(agent=<your name>, task_id=…, state="backlog"); this clears active holder/pending assignee fields |
| "Delegate this to " / "Assign this to " |
Prefer delegate(from=<your name>, to_agent=…, title=…, description=…, mode=…, expected_output=…, edit_scope=…); if the task already exists, use assign_task(task_id=…, to_agent=…); use allow_pending_agent=true when the worker is not registered yet |
| "Delegate this to the team" / "assign this to everyone on " |
delegate_team(from=<your name>, team=<team>, title=…, description=…, mode=…, expected_output=…, edit_scope=…); add capability, role, or max_recipients when the user wants only matching members |
| "What's on the task list?" |
list_tasks() and render the active ones |
| "Show the Kanban board" / "show done tasks" |
If using CLI, run agent-bus kanban / agent-bus done; with MCP, use list_tasks() filtered by state and render the same columns |
| "Did accept the task?" |
get_task(task_id=…) and inspect acknowledged_at / acknowledged_by; ask for acknowledge_task if missing |
| "Wait for this task" / "Any progress on task X?" |
wait_for_task(task_id=…, wait_s=110) when you can block, otherwise task_result(task_id=…) |
| "Review / approve this task" |
submit_review(reviewer=<your name>, task_id=…, approved=…); required reviews gate completion |
| "Hand this task to " |
handoff_task(from_agent=<current holder>, task_id=…, to_agent=…, reason=…, memory=…) |
| "Can these agents edit the same files?" |
check_scope_conflicts(file_scope=[…]) before assigning overlapping edit work |
| "Record progress / update phase" |
record_task_event(by_agent=<your name>, task_id=…, event_type="progress", message=…, phase=…) |
| "What are you working on now?" / "mark current work" |
now(agent=<your name>, task_id=…, phase=…, note=…) when updating your own visible status/task phase |
| "Move task X to testing / review / done" |
With MCP, use update_task plus record_task_event; with CLI, use agent-bus task-testing, agent-bus task-phase <id> review, or agent-bus task-done |
| "Show what happened on this task" |
task_result(task_id=…) and summarize task, events, test evidence, memories, and thread messages |
| "Cancel this task" |
cancel_task(agent=<your name>, task_id=…, reason=…) |
| "Record that tests passed/failed" |
record_test_result(by_agent=<your name>, command=…, status=…) |
| "Put to sleep" / "wake " |
sleep_agent(agent=…) / wake_agent(agent=…) |
| "Set blocked / waiting for review" |
set_agent_status(agent=…, status=…) |
| "Record this decision…" |
record_decision(by_agent=<your name>, decision=…, rationale=…) |
| "Final merge report" |
review_gate() first, then final_report(); render blockers, warnings, implemented work, gaps, risks, tests, and safe-to-commit/push flags |
When to choose ask vs send
ask (synchronous, blocks up to 110s) — when the user is
waiting for the answer to continue and the recipient is online/listening.
It fails fast for stale/paused recipients.
ask_async (non-blocking question) — when the answer can arrive
later or presence is uncertain. It returns the ask id and next actions
immediately; check inbox_status, message_status, or why_no_reply
later.
send (fire-and-forget) — when the user wants to delegate and
keep working. Tell them it's dispatched; offer to check the inbox
on demand.
delegate / delegate_team (tracked long work) — when ownership, progress,
acknowledgement, review, file scope, or final evidence matters. Use it
instead of ask for work that can outlive one 110s timeout.
- Board-visible work must be a task.
send, send_team, ask, and
ask_team are messages only; they do not create open_tasks or
active_tasks on project_board / team_board. If the user expects
work to appear on a board, use delegate_team for team-wide work,
delegate for one known worker, or create_task + assign_task.
- Ideas belong in backlog. Use
state="backlog" for future ideas,
deferred risks, and options discovered mid-session. Backlog tasks show
on Kanban and session briefs but are ignored by claim-best routing and
merge safety until a coordinator promotes them to open.
Delivery vs attention
Agent Bus is a durable local queue, not a pager. Messages are stored and
will be visible next time the recipient checks the bus, but MCP alone
cannot start another model session's next turn.
Attention comes from one of these:
- A session currently inside
inbox(wait_s); directory/whois show it
as listening.
- Claude Code's listener/Stop hook re-entering the inbox loop.
- A background CLI waiter such as
agent-bus wait --agent worker-a --team frontend --notify.
- A host automation or the human prompting the idle session.
If you wait twice and get no new message, stop blind polling. Check
directory/whois, inbox_status, and task state, then tell the user
whether the target is listening, online-but-idle, stale, or paused.
When to choose a specific name vs ask_best
- Specific name — user named the helper ("ask helper-a", "send
reviewer"). Use
ask/send directly.
- Role / capability — user described a skill ("a reviewer", "the
researcher", "someone who knows the schema"). Use
ask_best and
let the bus route. If ask_best fails with UNKNOWN_AGENT, surface
the error verbatim — the user may want to spin up a helper.
- Area / project — by default, routing and reads stay in the current
repo-derived project and
.agent-bus.json area. Use area: "*" or
project: "*" only when the user asks for cross-area/global routing.
- Team — if agents are registered with
team, prefer ask_team,
send_team, or team_board when the user names that workgroup. Use
team: "*" only when the user wants cross-team routing.
How to talk while calling tools
Be transparent in ONE short line before each call:
Asking helper-a (review): "is the token refresh race-free?"
Not:
I will now invoke the agent-bus MCP ask_best tool with the
parameter capability set to "review"...
When a reply lands, render it in plain English for the user. Don't
dump JSON. The user wants the answer, not the message envelope.
User-visible bus status
Do not leave the user staring at a silent bus wait. When you call
ask, ask_best, ask_team, wait_for_task, or intentional
inbox(wait_s) in an active user-facing session:
- Before waiting, say who or what you are waiting on in one short line.
- When the answer or task evidence arrives, immediately say:
Got <source>'s answer: <one-line summary>. Continuing locally with <next step>.
- After receiving the needed answer, stop waiting on the bus. Continue
the local task in this session unless the user explicitly asked you to
keep listening.
- If the wait times out but diagnostics show the task is still active,
say that clearly:
No reply yet, but task #N is still active; I will continue with what I have / check again only if needed.
- Do not chain repeated
inbox, inbox_status, message_status, or
why_no_reply calls just because one bus interaction completed.
Example:
Asking verifier for the export risk check.
Got verifier's answer: the main risk is canvas scale parity. Continuing locally by updating the test plan.
Project, area, and team addressing
By name still works (send / ask are direct addressed). ask_best,
directory, recent, and task reads default to the current
project/area/team. If the user asks broadly ("any reviewer anywhere"),
pass project: "*", area: "*", and/or team: "*" intentionally.
For multi-folder repos, use areas to prevent accidental chatter. Agents
working in one area should normally route to agents in the same area.
A coordinator at the repo root can use area: "*" to see or route
across all areas when the user wants cross-area coordination.
Use teams when multiple groups share the same project or area but should
mostly coordinate among themselves, such as ios-ui, api, review,
or a temporary feature squad. Team is neutral metadata; it does not
create roles, prompts, or behavior rules.
Manager workflow defaults
- Use
project_board() as the task board: show idle, working,
blocked, waiting_review, sleeping, active tasks, review queue,
scope conflicts, pinned risks, handoffs, and suggested next actions.
- Use
team_board(team=…) when the user is managing one workgroup
inside a broader project.
- When creating tasks, set
mode conservatively:
investigate_only for analysis, propose_patch for patch sketches,
edit_files only when edits are intended, and test_only for
verifier sessions.
- Set
expected_output so replies are comparable. Prefer:
Summary / Files inspected / Findings / Suggested fix / Risks / Test plan / Confidence.
- Set
file_scope when multiple agents may edit. Keep ownership
disjoint and project-specific, such as one glob per component,
package, app, service, or docs lane.
- Prefer
edit_scope for files a worker may modify and read_scope
for files a verifier may inspect. A broad verifier read_scope should
not block a worker's edit ownership.
- Set
ack_required=true when assigning work. A claimed task is not
operationally accepted until the worker records acknowledge_task.
- Use
wait_for_agents before assuming planned workers are online. Use
assign_task(..., allow_pending_agent=true) when planning assignments
before a worker session has registered.
- Set
review_required=true for implementation work that should be
checked by a verifier. The task cannot be completed until a reviewer
records submit_review(approved=true).
- Set
independent_review=true together with review_required=true
when another agent is available to review implementation work. Do not
set it for solo-agent work unless the user accepts that a different
reviewer is required; self-review by the holder or pending assignee
fails with REVIEW_SELF_FORBIDDEN.
- Use
check_scope_conflicts before assigning overlapping edit_files
or propose_patch work. Split ownership when conflicts are real.
- Use
handoff_task when a worker stops mid-task; it records a pinned
handoff memory and can reassign the task in one step.
- Record durable decisions with
record_decision when the team settles
an approach. Use list_decisions before reopening an old debate.
- Convert deliverable chat into a task or decision. If a thread produces
a concrete implementation/review/documentation action, create or
update a task. If it settles an approach, record a decision.
- Record durable handoffs, summaries, risks, todos, and blockers with
remember. Pin handoffs that the next agent should see first. Use
session_brief at the start of a fresh session or before handing work
to another agent.
- Record explicit build, lint, unit test, browser smoke, and manual
verification evidence with
record_test_result; include caller-
supplied git_ref and cwd when available so reviewers know what
code state was tested. Final reports surface these rows.
- Record progress or phase changes with
record_task_event so managers
can tell "agent did not answer ask" apart from "task is still active".
- Use phases consistently:
planning, editing, testing, review,
and done. The CLI Kanban maps state plus phase into Todo,
Accepted, Doing, Testing, Review, and Blocked lanes. Do not
invent new task states for phases; keep the state machine stable.
- Use
deadline_at for hard target times and checkin_at for expected
progress updates. Boards and cockpit surface overdue/check-in-due
tasks at read time; no scheduler is required.
- Use
team-chat/recent(team=...) for discussion history and human
visibility. Use delegate_team, team_board, kanban, and done
for tracked work. A team chat message alone is not a task.
- If an inbox result is too large or likely to truncate, switch to
inbox_previews and get_message(include_content=false) before
reading a full message body. Prefer sending file paths or task
artifacts for very large briefs.
reply works for both asks and normal messages. For kind="ask", it
answers the pending ask. For kind="msg", it infers the thread and
creates a real threaded reply (kind="reply", reply_to = the thread
root) that renders as a thread in the cockpit. For task assignments,
use the task tools.
- Use
activity when the user asks what happened recently. Use
cockpit when the user asks what the manager should do next. Use
now for your own current-work updates instead of sending a vague
status message.
- Use
wait_for_task for long-running work instead of repeatedly
polling inbox; it returns latest task evidence plus a timeout flag.
- After a bus reply or task update gives enough information to proceed,
summarize what arrived and continue your local work. Do not keep
waiting for unrelated bus messages.
- Use
task_result before verifier review and handoff; it bundles task
state, task events, test results, memories, and thread messages.
- Use memory intentionally as the loop notebook. Record settled
decisions, current risks, done work, next actions, and handoff notes.
Prefer
record_decision for decisions; use
remember(kind="risk", pinned=true) for active risks,
remember(kind="summary") for durable done-work context,
remember(kind="todo") for next actions that are not formal tasks,
and remember(kind="handoff", pinned=true) before a session exits.
New sessions should call session_brief before taking work.
- Use event triggers instead of vague memory judgment:
- Debate settled or PM picked an approach ->
record_decision.
- Completed task revealed a reusable gotcha ->
remember(kind="lesson", task_id=...) in one transferable sentence.
- Risk/blocker will outlive the task ->
remember(kind="risk", pinned=true).
- Session stops, switches owner, or hands off ->
remember(kind="handoff", pinned=true) with a Next: line.
- Tests/review evidence exists -> do not duplicate it into memory; use
record_test_result, task events, and reviews.
- Treat "done" as a verifier gate for implementation tasks: code/work
finished,
record_test_result evidence captured, required
submit_review(approved=true) recorded, and review_gate /
final_report says safe. Do not claim final completion from chat
confidence alone.
- Use
cancel_task when work is superseded or intentionally stopped.
- Use
review_gate and final_report before commit/push/deploy
decisions.
- Before changing shared repo state during multi-agent review, announce
intent on the active task/thread: commit, push, publish, rebase,
merge, or amend. Check for recent task/message activity first.
For an existing project, let the user or current agent decide the team
shape. A common pattern is one coordinator, one or more area-focused
workers, and an optional reviewer/tester, but the bus should not assume
or enforce those roles. Use task mode, expected_output,
file_scope, edit_scope, and read_scope to describe each task
instead of relying on naming conventions.
For repeated app folders, use agent-bus team init-folder --project <unique-project> --area <area> inside each new app subfolder. This
creates only neutral project/area scope. Agent roles, prompts, task
strategy, and implementation behavior belong to the user or the active
agent session, not to the bus itself.
When users want several teams inside one project folder, have each
session register with the same project/area and a chosen team, for
example team: "ios-ui" or team: "api". The bus will route and board
within that scope when tools receive the team filter.
Hard rules
- Do not auto-poll the inbox between user turns. Only check inbox when
the user asks ("any replies?") or after an
ask that returns one
you should surface.
- Do not keep calling bus tools after you got the answer needed for the
current step. Tell the user what arrived, then continue the local task.
- Do not enter a listener loop. You are not a worker; you are the
driver. (For listener-mode sessions, see the separate
/listen
workflow, not this skill.)
- If the user wants you to pause bus translation, stop interpreting
their messages as bus commands but stay registered.
- If a tool call fails, surface the error code (
UNKNOWN_AGENT,
ASK_TIMEOUT, ASK_CYCLE, NAME_TAKEN, TASK_NOT_CLAIMABLE,
TASK_INVALID_TRANSITION, TASK_FORBIDDEN) and the recovery hint.
- Don't fabricate helper names. If
whois shows nobody with the role
the user asked for, say "no helper is on the bus right now"
and ask if they want to spin one up.
- Helper agents must not deploy, push, publish, or modify shared
production resources unless the user explicitly approves.
When to load more context
For deeper detail, read these references on demand:
references/tools.md — the 65 MCP tools with input/output shapes
and every error code. Load when you need the exact contract for a
rare tool (e.g. subscribe, send_channel, send_team,
ask_team, team_board, assign_task, record_decision,
record_task_event, task_result, record_test_result,
remember, session_brief, review_gate).
references/patterns.md — the listener loop, verifier prompt,
ack/retry pattern, channel fan-out, task delegation. Load when the
user asks "set up a listener", "make this reliable", "broadcast
to…", or anything you can't answer from this top-level page.
Don't pre-load the references. Pull them only when the immediate
intent calls for them.
Failure modes worth knowing
| Symptom |
Cause |
What you do |
UNKNOWN_AGENT on send/ask |
recipient name typo or never registered |
tell the user, suggest whois to see who's available |
NAME_TAKEN on register |
name held by another active session |
pass replace: true (with user's consent) or pick a different name |
ASK_TIMEOUT |
recipient didn't reply in time |
tell the user, suggest re-sending as send or asking the user to nudge the recipient session |
ASK_CYCLE |
mutual deadlock — recipient has an active opposite ask to you |
inspect the ask id in the error with message_status, answer it first, or switch to ask_async/send; stale asks older than the active ask window no longer block |
AGENT_HAS_ACTIVE_TASKS / TEAM_HAS_ACTIVE_TASKS |
cleanup target still owns active work |
show task ids; only pass release_tasks=true with explicit approval |
REVIEW_SELF_FORBIDDEN |
independent review rejects self-review by the holder/pending assignee |
ask a different agent to review, or disable independent_review for solo work |
| The user names a helper that isn't on the bus |
not registered |
offer to spin up a listener (/listen <name> in Claude Code, or paste agent-bus listen-prompt <name> output into Codex/Cursor) |
| Setup check fails |
MCP not installed / wrong version |
print install hint; if the user approves, run scripts/check-setup.sh --install-cli, then retry |
1---2name: agent-bus3description: Coordinate work across Claude/Codex/Cursor sessions on the same machine via a local message bus. Use to delegate to helpers, get a second opinion, ask specialists by capability, or track shared tasks.4---56# agent-bus78Turn your Claude / Codex / Cursor / Gemini sessions on the same machine9into a local agent team. Each session registers a name, then you can10send messages, ask blocking questions, delegate tasks, broadcast to11channels, message scoped teams, route work by capability/role, track12agent status, record decisions and memories, record task progress,13generate session briefs, and produce merge-readiness reports — all14through one SQLite file at `~/.agent-bus/bus.db`.1516This skill is the **coordinator playbook**: when the user speaks17naturally, you translate their intent into agent-bus tool calls.1819## Setup check (do this first)2021Before using any bus tools, run `scripts/check-setup.sh`. If it exits22non-zero, halt and show the user the install hint it printed. Do not23try to use the bus until the check passes. If the user asks you to fix24the setup, run `scripts/check-setup.sh --install-cli`; it installs or25upgrades `@agent-bus-connect/cli@latest` through npm, then rechecks.2627If `mcp__agent-bus__register` is not in your available tools, the MCP28server is not wired into this session. Tell the user to add it — the29exact command varies by client; the README at30<https://github.com/MustaphaSteph/agent-bus#install> has each.3132## Identity3334This session is the **coordinator**. At the start of any bus35interaction:36371. Call `register` with a stable name and a concrete `team`. Ask the38 user once for any missing name or team, then reuse both for the rest39 of the session. Default the name to the user's first name or a short40 tag they choose, but do not invent a team. Pass `replace=true`,41 `team=<team>`, and capabilities `["human-driven", "coordinator"]`42 plus up to ten relevant native powers such as `tool:websearch`,43 `tool:shell`, `mcp:posthog`, `skill:flowdeck`, or44 `subagent:Explore`. Capabilities are exact-match tags:45 `mcp:posthog` does not match `posthog`. Do not register without a46 team.47 If `register` returns `scope_summary` / `suggested_next_actions`,48 follow the teaser. In particular, call `session_brief` before taking49 work when it mentions pinned handoffs, pinned risks, open tasks, or50 recent decisions.512. Call `directory` if available, otherwise `whois`, and show the user52 who else is on the bus, with53 their capabilities, in one compact line:54 `on the bus: helper-a [review, verify; idle], helper-b [docs; working]`.55 If nobody else is registered, say so.563. Do NOT enter a listener loop. You are the active driver — only57 check inbox when the user asks or when you've just done an `ask`58 that needs the result surfaced. When checking inbox in a team59 workflow, pass your concrete `team`.6061## Translating natural language into bus calls6263The user speaks normally. You pick the tool. Common patterns:6465| When the user says… | You call… |66|---|---|67| "Ask the reviewer / a reviewer to check X" | `ask_best(capability="review", question=…)` if they describe a role; `ask(to=<name>, …)` if they named a specific agent |68| "Get a second opinion on X" | `ask_best(capability="review" or "verify", …)` |69| "Have someone research / find / look up X" | `ask_best(capability="research", …)` |70| "Have someone summarize the docs for X" | `ask_best(capability="docs" or "summarize", …)` |71| "Ask the UI team / backend team / <team> team X" | `ask_team(team=<team>, question=…)`; add `capability` or `role` if the user wants a specialist inside that team |72| "Tell the <team> team X" / "message everyone on <team>" | `send_team(team=<team>, message=…)` |73| "Show team chat" / "watch the <team> conversation" | If using CLI, run `agent-bus team-chat --team <team>` or `agent-bus team-chat --team <team> --watch`; with MCP, use `recent(team=<team>)` and render only that team scope |74| "Listen only to my team" / "keep checking this team" | `inbox(agent=<your name>, team=<team>, wait_s=110, claim_s=300)`; use `inbox_status(agent=<your name>, team=<team>)` for non-consuming checks |75| "Wait for this thread" / "only watch this conversation" | `inbox(agent=<your name>, team=<team>, thread_id=<thread>, wait_s=110)`; with CLI use `agent-bus team-chat --team <team> --thread <thread>` or `agent-bus wait --agent <name> --team <team> --thread <thread>` |76| "Wake me when a message arrives" | Explain that MCP cannot wake an idle model session by itself; use `agent-bus wait --agent <name> --team <team> --notify`, a Claude listener hook, or a host automation |77| "Inbox is too large" / "message got truncated" | Use `inbox_previews(agent=<your name>, team=<team>)`, then `get_message(message_id=…, team=<team>, include_content=false)` or fetch one full message only when needed |78| "Delegate this to a helper" or "tell someone to…" | `send(to=<best-fit helper>, message=…)`. Don't block; tell the user you dispatched it. |79| "Ask <specific name> to do X" | `ask(from=<your name>, to="<specific name>", question=…)` only if they are online/listening and the user needs the answer now; otherwise `ask_async(from=<your name>, to="<specific name>", question=…)` |80| "Send <specific name> a message: X" | `send(from=<your name>, to="<specific name>", message=…)` |81| "What did <name> say?" / "Did anyone reply?" | `inbox_status(agent=<your name>)` first when you need state without consuming; `inbox(agent=<your name>)` when you are ready to process messages |82| "Why did nobody answer?" | `message_status(message_id=…)` or `why_no_reply(message_id=…)`; summarize delivery, claim, recipient presence, related task, and next actions |83| "Who's around?" / "Who's listening?" | `whois()` rendered cleanly |84| "Remove this member" / "delete this agent" | `remove_agent(name=…)`; if it returns `AGENT_HAS_ACTIVE_TASKS`, show the active task ids and ask before using `release_tasks=true` |85| "Delete this team" / "remove team <team>" | `delete_team(team=…, project/area as appropriate)`; if it returns `TEAM_HAS_ACTIVE_TASKS`, show the active task ids and ask before using `release_tasks=true` |86| "Wait for these workers" / "Are my agents ready?" | `wait_for_agents(names=[…])` and report ready/missing/stale/wrong-scope |87| "Show the team board" / "what is everyone doing?" | `team_board(team=…)` when a team is named; otherwise `project_board()` rendered with status, active work, review queue, conflicts, pinned risks, handoffs, and next actions |88| "What happened recently?" / "show activity" | `activity(project/area/team as appropriate)` and summarize the chronological timeline |89| "What should I do next?" / "show cockpit" | `cockpit(project/area/team as appropriate)` and report waiting items, ready items, blockers, and suggested next actions |90| "Remember X" / "Note that X" | `remember(by_agent=<your name>, kind="summary", content=…)`; use `pinned=true` for handoffs |91| "Recall X" / "What did we decide about X" | `list_memories()` and `list_decisions()` first; use `ask_best(capability="memory", …)` only if needed |92| "Give me a handoff / session brief" | `session_brief()` |93| "Catch me up on the bus" | `recent(limit=20)` and render |94| "Track this as a task" / "Open a task to do X" | `create_task(requested_by=<your name>, title=…, description=…, mode=…, expected_output=…, file_scope=…)`; set `ack_required` when assigned and `review_required` for implementation work |95| "Put this idea in backlog" / "Save this for later" | `create_task(requested_by=<your name>, title=…, description=…, state="backlog", milestone=…)`; backlog tasks are visible but not claimable/blocking until promoted |96| "Start this backlog item" / "Promote task X" | `update_task(agent=<your name>, task_id=…, state="open", priority=…)`; then assign/delegate or let workers `claim_best_task` |97| "Park task X" / "Move this back to backlog" | `update_task(agent=<your name>, task_id=…, state="backlog")`; this clears active holder/pending assignee fields |98| "Delegate this to <agent>" / "Assign this to <agent>" | Prefer `delegate(from=<your name>, to_agent=…, title=…, description=…, mode=…, expected_output=…, edit_scope=…)`; if the task already exists, use `assign_task(task_id=…, to_agent=…)`; use `allow_pending_agent=true` when the worker is not registered yet |99| "Delegate this to the <team> team" / "assign this to everyone on <team>" | `delegate_team(from=<your name>, team=<team>, title=…, description=…, mode=…, expected_output=…, edit_scope=…)`; add `capability`, `role`, or `max_recipients` when the user wants only matching members |100| "What's on the task list?" | `list_tasks()` and render the active ones |101| "Show the Kanban board" / "show done tasks" | If using CLI, run `agent-bus kanban` / `agent-bus done`; with MCP, use `list_tasks()` filtered by state and render the same columns |102| "Did <agent> accept the task?" | `get_task(task_id=…)` and inspect `acknowledged_at` / `acknowledged_by`; ask for `acknowledge_task` if missing |103| "Wait for this task" / "Any progress on task X?" | `wait_for_task(task_id=…, wait_s=110)` when you can block, otherwise `task_result(task_id=…)` |104| "Review / approve this task" | `submit_review(reviewer=<your name>, task_id=…, approved=…)`; required reviews gate completion |105| "Hand this task to <agent>" | `handoff_task(from_agent=<current holder>, task_id=…, to_agent=…, reason=…, memory=…)` |106| "Can these agents edit the same files?" | `check_scope_conflicts(file_scope=[…])` before assigning overlapping edit work |107| "Record progress / update phase" | `record_task_event(by_agent=<your name>, task_id=…, event_type="progress", message=…, phase=…)` |108| "What are you working on now?" / "mark current work" | `now(agent=<your name>, task_id=…, phase=…, note=…)` when updating your own visible status/task phase |109| "Move task X to testing / review / done" | With MCP, use `update_task` plus `record_task_event`; with CLI, use `agent-bus task-testing`, `agent-bus task-phase <id> review`, or `agent-bus task-done` |110| "Show what happened on this task" | `task_result(task_id=…)` and summarize task, events, test evidence, memories, and thread messages |111| "Cancel this task" | `cancel_task(agent=<your name>, task_id=…, reason=…)` |112| "Record that tests passed/failed" | `record_test_result(by_agent=<your name>, command=…, status=…)` |113| "Put <agent> to sleep" / "wake <agent>" | `sleep_agent(agent=…)` / `wake_agent(agent=…)` |114| "Set <agent> blocked / waiting for review" | `set_agent_status(agent=…, status=…)` |115| "Record this decision…" | `record_decision(by_agent=<your name>, decision=…, rationale=…)` |116| "Final merge report" | `review_gate()` first, then `final_report()`; render blockers, warnings, implemented work, gaps, risks, tests, and safe-to-commit/push flags |117118## When to choose ask vs send119120- **`ask` (synchronous, blocks up to 110s)** — when the user is121 waiting for the answer to continue and the recipient is online/listening.122 It fails fast for stale/paused recipients.123- **`ask_async` (non-blocking question)** — when the answer can arrive124 later or presence is uncertain. It returns the ask id and next actions125 immediately; check `inbox_status`, `message_status`, or `why_no_reply`126 later.127- **`send` (fire-and-forget)** — when the user wants to delegate and128 keep working. Tell them it's dispatched; offer to check the inbox129 on demand.130- **`delegate` / `delegate_team` (tracked long work)** — when ownership, progress,131 acknowledgement, review, file scope, or final evidence matters. Use it132 instead of `ask` for work that can outlive one 110s timeout.133- **Board-visible work must be a task.** `send`, `send_team`, `ask`, and134 `ask_team` are messages only; they do not create `open_tasks` or135 `active_tasks` on `project_board` / `team_board`. If the user expects136 work to appear on a board, use `delegate_team` for team-wide work,137 `delegate` for one known worker, or `create_task` + `assign_task`.138- **Ideas belong in backlog.** Use `state="backlog"` for future ideas,139 deferred risks, and options discovered mid-session. Backlog tasks show140 on Kanban and session briefs but are ignored by claim-best routing and141 merge safety until a coordinator promotes them to `open`.142143## Delivery vs attention144145Agent Bus is a durable local queue, not a pager. Messages are stored and146will be visible next time the recipient checks the bus, but MCP alone147cannot start another model session's next turn.148149Attention comes from one of these:150151- A session currently inside `inbox(wait_s)`; `directory`/`whois` show it152 as `listening`.153- Claude Code's listener/Stop hook re-entering the inbox loop.154- A background CLI waiter such as155 `agent-bus wait --agent worker-a --team frontend --notify`.156- A host automation or the human prompting the idle session.157158If you wait twice and get no new message, stop blind polling. Check159`directory`/`whois`, `inbox_status`, and task state, then tell the user160whether the target is listening, online-but-idle, stale, or paused.161162## When to choose a specific name vs ask_best163164- **Specific name** — user named the helper ("ask helper-a", "send165 reviewer"). Use `ask`/`send` directly.166- **Role / capability** — user described a skill ("a reviewer", "the167 researcher", "someone who knows the schema"). Use `ask_best` and168 let the bus route. If `ask_best` fails with `UNKNOWN_AGENT`, surface169 the error verbatim — the user may want to spin up a helper.170- **Area / project** — by default, routing and reads stay in the current171 repo-derived project and `.agent-bus.json` area. Use `area: "*"` or172 `project: "*"` only when the user asks for cross-area/global routing.173- **Team** — if agents are registered with `team`, prefer `ask_team`,174 `send_team`, or `team_board` when the user names that workgroup. Use175 `team: "*"` only when the user wants cross-team routing.176177## How to talk while calling tools178179Be transparent in ONE short line before each call:180181> Asking helper-a (review): "is the token refresh race-free?"182183Not:184185> I will now invoke the agent-bus MCP `ask_best` tool with the186> parameter `capability` set to `"review"`...187188When a reply lands, render it in plain English for the user. Don't189dump JSON. The user wants the answer, not the message envelope.190191## User-visible bus status192193Do not leave the user staring at a silent bus wait. When you call194`ask`, `ask_best`, `ask_team`, `wait_for_task`, or intentional195`inbox(wait_s)` in an active user-facing session:196197- Before waiting, say who or what you are waiting on in one short line.198- When the answer or task evidence arrives, immediately say:199 `Got <source>'s answer: <one-line summary>. Continuing locally with <next step>.`200- After receiving the needed answer, stop waiting on the bus. Continue201 the local task in this session unless the user explicitly asked you to202 keep listening.203- If the wait times out but diagnostics show the task is still active,204 say that clearly: `No reply yet, but task #N is still active; I will205 continue with what I have / check again only if needed.`206- Do not chain repeated `inbox`, `inbox_status`, `message_status`, or207 `why_no_reply` calls just because one bus interaction completed.208209Example:210211```text212Asking verifier for the export risk check.213Got verifier's answer: the main risk is canvas scale parity. Continuing locally by updating the test plan.214```215216## Project, area, and team addressing217218By name still works (`send` / `ask` are direct addressed). `ask_best`,219`directory`, `recent`, and task reads default to the current220project/area/team. If the user asks broadly ("any reviewer anywhere"),221pass `project: "*"`, `area: "*"`, and/or `team: "*"` intentionally.222223For multi-folder repos, use areas to prevent accidental chatter. Agents224working in one area should normally route to agents in the same area.225A coordinator at the repo root can use `area: "*"` to see or route226across all areas when the user wants cross-area coordination.227228Use teams when multiple groups share the same project or area but should229mostly coordinate among themselves, such as `ios-ui`, `api`, `review`,230or a temporary feature squad. Team is neutral metadata; it does not231create roles, prompts, or behavior rules.232233## Manager workflow defaults234235- Use `project_board()` as the task board: show `idle`, `working`,236 `blocked`, `waiting_review`, `sleeping`, active tasks, review queue,237 scope conflicts, pinned risks, handoffs, and suggested next actions.238- Use `team_board(team=…)` when the user is managing one workgroup239 inside a broader project.240- When creating tasks, set `mode` conservatively:241 `investigate_only` for analysis, `propose_patch` for patch sketches,242 `edit_files` only when edits are intended, and `test_only` for243 verifier sessions.244- Set `expected_output` so replies are comparable. Prefer:245 `Summary / Files inspected / Findings / Suggested fix / Risks /246 Test plan / Confidence`.247- Set `file_scope` when multiple agents may edit. Keep ownership248 disjoint and project-specific, such as one glob per component,249 package, app, service, or docs lane.250- Prefer `edit_scope` for files a worker may modify and `read_scope`251 for files a verifier may inspect. A broad verifier `read_scope` should252 not block a worker's edit ownership.253- Set `ack_required=true` when assigning work. A claimed task is not254 operationally accepted until the worker records `acknowledge_task`.255- Use `wait_for_agents` before assuming planned workers are online. Use256 `assign_task(..., allow_pending_agent=true)` when planning assignments257 before a worker session has registered.258- Set `review_required=true` for implementation work that should be259 checked by a verifier. The task cannot be completed until a reviewer260 records `submit_review(approved=true)`.261- Set `independent_review=true` together with `review_required=true`262 when another agent is available to review implementation work. Do not263 set it for solo-agent work unless the user accepts that a different264 reviewer is required; self-review by the holder or pending assignee265 fails with `REVIEW_SELF_FORBIDDEN`.266- Use `check_scope_conflicts` before assigning overlapping `edit_files`267 or `propose_patch` work. Split ownership when conflicts are real.268- Use `handoff_task` when a worker stops mid-task; it records a pinned269 handoff memory and can reassign the task in one step.270- Record durable decisions with `record_decision` when the team settles271 an approach. Use `list_decisions` before reopening an old debate.272- Convert deliverable chat into a task or decision. If a thread produces273 a concrete implementation/review/documentation action, create or274 update a task. If it settles an approach, record a decision.275- Record durable handoffs, summaries, risks, todos, and blockers with276 `remember`. Pin handoffs that the next agent should see first. Use277 `session_brief` at the start of a fresh session or before handing work278 to another agent.279- Record explicit build, lint, unit test, browser smoke, and manual280 verification evidence with `record_test_result`; include caller-281 supplied `git_ref` and `cwd` when available so reviewers know what282 code state was tested. Final reports surface these rows.283- Record progress or phase changes with `record_task_event` so managers284 can tell "agent did not answer ask" apart from "task is still active".285- Use phases consistently: `planning`, `editing`, `testing`, `review`,286 and `done`. The CLI Kanban maps state plus phase into `Todo`,287 `Accepted`, `Doing`, `Testing`, `Review`, and `Blocked` lanes. Do not288 invent new task states for phases; keep the state machine stable.289- Use `deadline_at` for hard target times and `checkin_at` for expected290 progress updates. Boards and cockpit surface overdue/check-in-due291 tasks at read time; no scheduler is required.292- Use `team-chat`/`recent(team=...)` for discussion history and human293 visibility. Use `delegate_team`, `team_board`, `kanban`, and `done`294 for tracked work. A team chat message alone is not a task.295- If an inbox result is too large or likely to truncate, switch to296 `inbox_previews` and `get_message(include_content=false)` before297 reading a full message body. Prefer sending file paths or task298 artifacts for very large briefs.299- `reply` works for both asks and normal messages. For `kind="ask"`, it300 answers the pending ask. For `kind="msg"`, it infers the thread and301 creates a real threaded reply (`kind="reply"`, `reply_to` = the thread302 root) that renders as a thread in the cockpit. For task assignments,303 use the task tools.304- Use `activity` when the user asks what happened recently. Use305 `cockpit` when the user asks what the manager should do next. Use306 `now` for your own current-work updates instead of sending a vague307 status message.308- Use `wait_for_task` for long-running work instead of repeatedly309 polling `inbox`; it returns latest task evidence plus a timeout flag.310- After a bus reply or task update gives enough information to proceed,311 summarize what arrived and continue your local work. Do not keep312 waiting for unrelated bus messages.313- Use `task_result` before verifier review and handoff; it bundles task314 state, task events, test results, memories, and thread messages.315- Use memory intentionally as the loop notebook. Record settled316 decisions, current risks, done work, next actions, and handoff notes.317 Prefer `record_decision` for decisions; use318 `remember(kind="risk", pinned=true)` for active risks,319 `remember(kind="summary")` for durable done-work context,320 `remember(kind="todo")` for next actions that are not formal tasks,321 and `remember(kind="handoff", pinned=true)` before a session exits.322 New sessions should call `session_brief` before taking work.323- Use event triggers instead of vague memory judgment:324 - Debate settled or PM picked an approach -> `record_decision`.325 - Completed task revealed a reusable gotcha -> `remember(kind="lesson",326 task_id=...)` in one transferable sentence.327 - Risk/blocker will outlive the task -> `remember(kind="risk",328 pinned=true)`.329 - Session stops, switches owner, or hands off -> `remember(kind="handoff",330 pinned=true)` with a `Next:` line.331 - Tests/review evidence exists -> do not duplicate it into memory; use332 `record_test_result`, task events, and reviews.333- Treat "done" as a verifier gate for implementation tasks: code/work334 finished, `record_test_result` evidence captured, required335 `submit_review(approved=true)` recorded, and `review_gate` /336 `final_report` says safe. Do not claim final completion from chat337 confidence alone.338- Use `cancel_task` when work is superseded or intentionally stopped.339- Use `review_gate` and `final_report` before commit/push/deploy340 decisions.341- Before changing shared repo state during multi-agent review, announce342 intent on the active task/thread: commit, push, publish, rebase,343 merge, or amend. Check for recent task/message activity first.344345For an existing project, let the user or current agent decide the team346shape. A common pattern is one coordinator, one or more area-focused347workers, and an optional reviewer/tester, but the bus should not assume348or enforce those roles. Use task `mode`, `expected_output`,349`file_scope`, `edit_scope`, and `read_scope` to describe each task350instead of relying on naming conventions.351352For repeated app folders, use `agent-bus team init-folder --project353<unique-project> --area <area>` inside each new app subfolder. This354creates only neutral project/area scope. Agent roles, prompts, task355strategy, and implementation behavior belong to the user or the active356agent session, not to the bus itself.357358When users want several teams inside one project folder, have each359session register with the same project/area and a chosen `team`, for360example `team: "ios-ui"` or `team: "api"`. The bus will route and board361within that scope when tools receive the team filter.362363## Hard rules364365- Do not auto-poll the inbox between user turns. Only check inbox when366 the user asks ("any replies?") or after an `ask` that returns one367 you should surface.368- Do not keep calling bus tools after you got the answer needed for the369 current step. Tell the user what arrived, then continue the local task.370- Do not enter a listener loop. You are not a worker; you are the371 driver. (For listener-mode sessions, see the separate `/listen`372 workflow, not this skill.)373- If the user wants you to pause bus translation, stop interpreting374 their messages as bus commands but stay registered.375- If a tool call fails, surface the error code (`UNKNOWN_AGENT`,376 `ASK_TIMEOUT`, `ASK_CYCLE`, `NAME_TAKEN`, `TASK_NOT_CLAIMABLE`,377 `TASK_INVALID_TRANSITION`, `TASK_FORBIDDEN`) and the recovery hint.378- Don't fabricate helper names. If `whois` shows nobody with the role379 the user asked for, say "no <role> helper is on the bus right now"380 and ask if they want to spin one up.381- Helper agents must not deploy, push, publish, or modify shared382 production resources unless the user explicitly approves.383384## When to load more context385386For deeper detail, read these references on demand:387388- `references/tools.md` — the 65 MCP tools with input/output shapes389 and every error code. Load when you need the exact contract for a390 rare tool (e.g. `subscribe`, `send_channel`, `send_team`,391 `ask_team`, `team_board`, `assign_task`, `record_decision`,392 `record_task_event`, `task_result`, `record_test_result`,393 `remember`, `session_brief`, `review_gate`).394- `references/patterns.md` — the listener loop, verifier prompt,395 ack/retry pattern, channel fan-out, task delegation. Load when the396 user asks "set up a listener", "make this reliable", "broadcast397 to…", or anything you can't answer from this top-level page.398399Don't pre-load the references. Pull them only when the immediate400intent calls for them.401402## Failure modes worth knowing403404| Symptom | Cause | What you do |405|---|---|---|406| `UNKNOWN_AGENT` on send/ask | recipient name typo or never registered | tell the user, suggest `whois` to see who's available |407| `NAME_TAKEN` on register | name held by another active session | pass `replace: true` (with user's consent) or pick a different name |408| `ASK_TIMEOUT` | recipient didn't reply in time | tell the user, suggest re-sending as `send` or asking the user to nudge the recipient session |409| `ASK_CYCLE` | mutual deadlock — recipient has an active opposite ask to you | inspect the ask id in the error with `message_status`, answer it first, or switch to `ask_async`/`send`; stale asks older than the active ask window no longer block |410| `AGENT_HAS_ACTIVE_TASKS` / `TEAM_HAS_ACTIVE_TASKS` | cleanup target still owns active work | show task ids; only pass `release_tasks=true` with explicit approval |411| `REVIEW_SELF_FORBIDDEN` | independent review rejects self-review by the holder/pending assignee | ask a different agent to review, or disable `independent_review` for solo work |412| The user names a helper that isn't on the bus | not registered | offer to spin up a listener (`/listen <name>` in Claude Code, or paste `agent-bus listen-prompt <name>` output into Codex/Cursor) |413| Setup check fails | MCP not installed / wrong version | print install hint; if the user approves, run `scripts/check-setup.sh --install-cli`, then retry |