Reference

Two invocation surfaces, one squad

This plugin and its companion MCP server give you two different ways to reach the same squad — pick based on whether your host dispatches agents directly or only calls tools.

Surface 1 — direct agent dispatch (this plugin)

Installing hve-squad-plugin registers agents/squad/ and skills/squad/ directly with the host (Copilot CLI, VS Code, or the desktop app). The host's own runSubagent/task mechanism dispatches the Squad Coordinator and its cast in-process, under the hve-squad:squad-* namespace. No server process, no network call — everything runs as agents and skills the host already knows how to load.

Surface 2 — tool-call invocation via @hve-squad/mcp

This plugin's .mcp.json also registers the companion Peter-N91/hve-squad-mcp server over stdio. This is the same host — Copilot CLI, VS Code, and the desktop app all support MCP tool-calling natively, alongside their own agent-dispatch surface, not instead of it. Surface 2 is not reserved for some other client that lacks agents; it gives the same session an additional entry point: the model can autonomously call squad_research, squad_plan, squad_review, squad_architect, or squad_run mid-conversation, without anyone naming an agent first.

In delegated mode (the current, Phase 0 execution model), each tool call returns the Squad Coordinator persona, the matched routing row, and a framed dispatch request; the calling host's own agent loop is what actually runs runSubagent/task against it. The MCP server itself calls no model and holds no credentials — it is a router, not a runtime.

A genuinely different host — Copilot Studio or M365 Copilot — instead reaches hve-squad-mcp through its separate embedded/remote HTTP mode, a distinct Azure-hosted deployment documented in that repository's own host/RUNBOOK.md. That mode is not wired through this plugin's .mcp.json at all.

flowchart TD subgraph Plugin["hve-squad-plugin (this repo)"] A["agents/squad/*.agent.md
(27 agents)"] S["skills/squad/ + invocations/
(squad skill, 7 invocation skills)"] H["hooks.json
(enforcement backstop)"] M[".mcp.json
registers @hve-squad/mcp"] end subgraph Host["Copilot CLI / VS Code / desktop app (one session, two paths)"] HD["Direct agent-dispatch path
(user or agent names hve-squad:squad-*)"] HM["Autonomous tool-call path
(model calls squad_* mid-conversation)"] end subgraph MCPServer["Peter-N91/hve-squad-mcp (stdio, delegated mode)"] T["5 coarse tools:
squad_research, squad_plan,
squad_review, squad_architect, squad_run"] end subgraph Remote["Copilot Studio / M365 (separate deployment, not via this plugin)"] R["hve-squad-mcp embedded/HTTP mode"] end HD -- "direct dispatch" --> A A --> S S --> H HM -- "tool call" --> T T -- "returns persona + routing row
+ framed dispatch request" --> HM HM -- "same host's runSubagent/task
runs the actual dispatch" --> A M -.->|"registers (stdio)"| T

What's actually pinned, and what isn't

The delegated-mode server does not ship or use a bundled copy of the squad's agent personas at all — its own source code says so explicitly: the systemPrompt a tool call returns is a short, hand-written paraphrase of just the Dispatch Discipline rule, deliberately not a copy of the real .agent.md content. The host then runs its own dispatch against the real, tag-pinned agent files this plugin installed — so which @hve-squad/mcp version answered the tool call has no bearing on which persona actually runs. There is no "two copies of the cast that can drift" risk here.

What was actually missing (now fixed): .mcp.json used to reference a bare @hve-squad/mcp, which npx resolves to whatever is currently @latest — meaning two installs on two different days could silently run different server code, with no reproducibility guarantee. This plugin now pins an exact, tested version (@hve-squad/mcp@0.7.0 at time of writing). Bumping this pin is a deliberate action, separate from rebuilding this plugin's own agent content — the generator (Build-SquadPlugin.ps1's -McpVersion) never silently re-pins it on an unrelated content rebuild.

What remains an open, smaller consideration: the coarse routing metadata (tools.catalog.yml / generated/mcp-tools.schema.json, which do ship inside the npm package) is generated from hve-squad-mcp's own copy of squad-routing.instructions.md at its last release. If hve-squad's routing table changes and the pinned MCP version isn't bumped to match, a tool call's reported tier/council/gates could go slightly stale relative to the plugin's current agents — a routing-table staleness question, not an agent-content mismatch. The mitigation is the same discipline as above: re-test and deliberately re-pin when you know routing changed, rather than chasing @latest.