When you drive a Roscoe workflow over MCP from Claude, the
AI steps don't call a metered API. Claude answers them itself, so the
inference runs on the Claude subscription you already pay for. Drive the
same workflow standalone (roscoe run, or roscoe serve with no MCP client) and
the AI steps run server-side against your own ANTHROPIC_API_KEY or the
claude CLI instead.
This page spells out which steps run where, so you can pick the surface that bills the way you want.
The short version#
- Driving from Claude Code or the Claude desktop app (MCP):
ai_agentandai_judgenodes always hand their prompt back to Claude, which generates the response in its own context. That runs on your subscription, and no API key is involved. - Fan-out nodes (
consensus,round_robin,map): when the host can spawn isolated subagents (Claude Code or Claude Cowork), the fan-out is handed back too, so the reviewers, matchups, or branches run in parallel on your subscription. On a subagent host these nodes make no server-side model call: even the one-off resolution around_robinneeds togenerate(or extract a list from a prosecandidatesFrom) and the listmapextracts from a proseoverare handed back as a subagent too. Plain Claude desktop chat can't spawn subagents, so there they run server-side against your API key /claudeCLI. - Standalone (
roscoe run, orroscoe servewith no MCP client): every AI node runs server-side against your configured backend.
Where each node runs#
The sequence below traces one workflow end to end. Claude generates every
ai_agent / ai_judge reply itself over MCP on any surface, but only Claude
Code or Cowork also run the consensus / round_robin / map fan-out on
subagents; desktop chat and standalone runs send that fan-out server-side
instead (metered against your API key, or your Claude subscription via the
claude CLI when no key is set).
sequenceDiagram
participant You
participant Claude as Claude (MCP host)
participant Roscoe
participant API as Anthropic API
alt Over MCP (Code, Cowork, or desktop chat)
You->>Claude: start_workflow
Claude->>Roscoe: start_workflow
Roscoe-->>Claude: pendingStep (ai_agent)
Claude->>Claude: generate reply
Claude->>Roscoe: advance_run
Roscoe-->>Claude: pendingStep (consensus)
alt Claude Code or Cowork
Claude->>Claude: spawn subagents
Claude->>Roscoe: advance_consensus
else desktop chat
Roscoe->>API: call model
end
else Standalone (roscoe run/serve)
You->>Roscoe: roscoe run
Roscoe->>API: call model
end
| Surface | ai_agent / ai_judge |
Fan-out (consensus / round_robin / map) |
|---|---|---|
| Claude Code (CLI / IDE) | Subscription | Subscription, parallel fan-out |
| Claude Cowork | Subscription | Subscription, parallel fan-out |
| Claude desktop chat | Subscription | Server-side (see below) |
Standalone roscoe serve / roscoe run |
Server-side (see below) | Server-side (see below) |
Server-side runs use your configured
backend, and how it's billed depends on the
credential: if ANTHROPIC_API_KEY is set, that's the metered API (a real
charge); with no key, Roscoe shells out to the claude CLI, which runs on
your Claude subscription ($0 out of pocket). So a server-side run is metered
only when you've set an API key.
Correctness is identical across every row. Only where the inference runs,
and therefore how it's billed, changes. You self-report your surface with the
host argument on start_workflow; Claude Code fills it in for you.
Two kinds of AI node#
Single-call nodes: ai_agent, ai_judge. In MCP mode the runner pauses at
each of these and returns a pendingStep with the interpolated prompt. Claude
reads it, generates the response, and calls advance_run to continue. The model
call happens inside Claude's context, so it runs on the subscription on every
Claude surface, desktop chat included.
Fan-out nodes: consensus, round_robin, map. These need several
independent agents (consensus reviewers, round_robin pairwise matchups, or map
branches), each in its own context. Only a subagent-capable host can produce
that, which is why the fan-out handback is gated on Claude Code / Cowork.
round_robin and map may also need a one-call resolution step first:
round_robin to generate candidates or extract them from a prose
candidatesFrom, map to extract its list from a prose over. That call is
handed back as a single subagent too, so on a subagent host these nodes make
no server-side model call at all. The advance tool differs per node
(advance_consensus, advance_round_robin, advance_map), but the shape is
the same: the host runs the subagents and returns their raw text for Roscoe to
tally or record. (The consensus handback below is the template; the
round_robin and map node pages
document their own rounds.)
How the consensus handback works#
When a consensus node is reached over MCP and the host supports subagents, the
run pauses and returns a pendingStep with nodeType: "consensus" plus
everything needed to fan out: prompt, agentCount, quorum, and model.
- The host spawns exactly
agentCountindependent subagents and gives each the same prompt, run on the node'smodel. - It collects every subagent's raw JSON verdict and passes them to
advance_consensusasresults: [{ raw }, …], one entry per subagent. - Roscoe validates each verdict with the same rules the server-side path uses
and tallies the quorum itself. A gate node (a
booleanorconfidencevalidator) routes toapprovedorrejected; ananswerormost_consistentnode routes todecidedorundecided.
Roscoe, not the host, owns the tally, so the guarantees hold regardless of the client:
- A malformed or missing verdict counts as no-vote; it can't force an approval.
- The host must return exactly
agentCountresults. A padded or starved vote is rejected before it can advance, and the run stays paused for a retry. - The quorum math and per-agent approval rule are the same functions the server-side executor uses (see the consensus node reference).
Each reviewer is still recorded as its own consensus_agent entry in the run
trace, so the per-agent reasoning cards in the run viewer look the same either
way.
"Subscription," not "free": running on your plan means the calls draw on your Claude subscription instead of a separate metered API bill. It isn't zero-cost, and it's still subject to your plan's usage limits.
Worked example#
A workflow with a consensus node (agentCount: 3, quorum: 2) driven from
Claude Code:
- Claude Code calls
start_workflowwithhost: "claude_code". - The run reaches the consensus node, sees a subagent-capable host, and pauses
with a
consensuspendingStep. - Claude Code spawns 3 independent subagents and collects their 3 JSON verdicts.
- It calls
advance_consensuswith the 3 raw results. - Roscoe tallies (say 3 approvals ≥ quorum 2, so
approved) and the workflow advances. All three calls ran on the subscription; no API key was used.
See also#
- MCP — Claude integration — setup and the pause/resume loop.
- consensus node — full schema, quorum rules, outputs.
- round_robin node · map node — the other fan-out nodes that hand back.
- AI backends — what the server-side path uses.