Tools

The surface is deliberately coarse. Each squad tool maps 1:1 to a row in the squad's routing table — not to one of the ~200 agents. The Squad Coordinator owns routing; these tools are shortcuts into it.

Squad tools

These come from tools.catalog.yml, the source of truth for the surface. The build fails if any of them maps to a routing intent that is not a real routing row, or to a role that is not a bundled agent.

ToolPrimary roleScopeRemote
squad_researchSquad ResearcherSquad.Researchadvisory
squad_planSquad LeadSquad.Planadvisory
squad_reviewSquad ReviewerSquad.Reviewadvisory
squad_architectSystem Architecture ReviewerSquad.Architectadvisory
squad_runSquad CoordinatorSquad.Runpipeline
squad_federateSquad Federation CoordinatorSquad.Federatepipeline

The advisory four

squad_research, squad_plan, squad_review, and squad_architect each run a single-stage dispatch and land no impactful action. That is why they are exposed remotely even when the async pipeline is off — the default remote posture is advisory-only.

squad_run — the full advisory pipeline

squad_run is the catch-all. It routes data-driven across the real roster — researcher → lead → council members → tester — and the council synthesizes a most-restrictive-wins verdict of Go, Go-With-Conditions, or Stop. It honours mode: interactive pauses per stage, autopilot runs through to one compiled artifact.

It is safe by construction. It holds at a non-bypassable Human Gate and never auto-releases. An operator holding the distinct Squad.Operate app role releases a held run through the out-of-band POST /admin/approve route — never through a tools/call — after which a squad_status poll drives it to completion. Approvals are audited with approver and timestamp, and tenant-scoped.

squad_federate — sub-squads

The federation meta layer routes across named sub-squads. It carries a dedicated scope rather than reusing Squad.Run, because a caller authorized to run one squad is not thereby authorized to drive a whole federation. Same safety class as squad_run, so it inherits the same gate and durable run-state prerequisites.

The discovery gate

Both catch-all tools take an optional discovery depth, mirroring the /squad and /squad-federation prompt arguments. It drives the gate hve-squad@0.15.0 added on the inverse trigger to the intake gate: the intake gate validates a requirement artifact when one exists, the discovery gate fires when none does — a request that states a goal rather than a settled task — and brainstorms the brief the intake gate then validates.

discoveryDispatchesProduces
quickanalystthe brief (the recommended default)
standarddesigner (DT Coach), then analystframing, solution themes, brief
deepdesigner, then challenger and experimenter, then analystframing, themes, objections, riskiest assumption, brief
skipnothinga Depth: skip verdict recording the declination

The gate is offered, never automatic: validating a document is something an agent does alone, and ideation is not. Every dispatched role interviews the user one question at a time and stops rather than inventing an answer it could not get; only analyst writes a file, so one session leaves one artifact.

The remote path never runs it. An embedded run has nobody to interview, so no offer is made and an explicit discovery is ignored rather than honoured — the caller's payload becomes the intake gate's input instead. An unattended run is gated by validation, not by ideation.

Utility tools

These are transport-level utilities, not routing intents, so they are not in the catalog and do not participate in the drift check. Each is off unless the operator turns its feature on.

ToolScopeEnabled byWhat it does
squad_statusSquad.Runpipeline Polls a run the caller started. Reuses the run scope — you may inspect runs you are authorized to start.
squad_render_pptxSquad.RenderSQUAD_MCP_ENABLE_RENDER_PPTX Renders deck content YAML to a .pptx with in-image python-pptx and returns a short-lived, tenant-scoped user-delegation SAS link. No model call; the SAS is never logged.
squad_memory_readSquad.MemorySQUAD_MCP_ENABLE_MEMORY Reads the project's .copilot-tracking/squad/ memory.
squad_historySquad.MemorySQUAD_MCP_ENABLE_MEMORY Lists and reads the .copilot-tracking tree a run wrote — the artifact side of the same project.
squad_memory_writeSquad.MemoryWriteSQUAD_MCP_ENABLE_MEMORY Compare-and-swap write-back of one memory entry. Separate scope from read, so a read grant cannot mutate.
squad_memory_syncSquad.MemoryWriteSQUAD_MCP_ENABLE_MEMORY Batch compare-and-swap — flushes a whole run's artifacts, each under its own CAS token.
squad_business_planSquad.BusinessSQUAD_MCP_ENABLE_BUSINESS_TOOLS One advisory dispatch against a real cast persona, returning a sectioned business plan.
squad_backlogSquad.BacklogSQUAD_MCP_ENABLE_BUSINESS_TOOLS Produces a validated JSON backlog contract — epics → stories → tasks plus a flattened workItems[].

Why squad_backlog is JSON, not prose

The native Azure DevOps and Jira connectors need one call per work item with typed fields. A prose handoff forces the orchestrating agent to parse English, which is the dominant failure mode: one giant work item, lost acceptance criteria, invented parents. With the JSON contract the agent iterates workItems in order, creates parents first, and links children by matching parentRef against the ids it recorded — no title matching, no guessing. The server validates and normalizes the model's JSON and fails cleanly if it cannot.

The trust boundary is unchanged. Neither business tool writes to Azure DevOps or Jira. This server produces the plan; the certified native connector performs every write on the end user's own connection, under that connector's auth, DLP, and throttles.

Scopes are default-deny

Every tool requires an explicit OAuth scope; absent the scope the call is denied. Scopes are least-privilege by design — a render grant does not imply research, a memory read grant does not imply a memory write, and none of them imply Squad.Operate, the distinct operator role that releases a held run. Audience binding is enforced separately from scope: a token minted for another resource is rejected outright.