# Running on your Claude subscription

When you drive a Roscoe workflow over [MCP](/docs/running/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_agent` and
  `ai_judge` nodes 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 a `round_robin` needs to `generate`
  (or extract a list from a prose `candidatesFrom`) and the list `map` extracts
  from a prose `over` are handed back as a subagent too. Plain Claude desktop
  **chat** can't spawn subagents, so there they run server-side against your
  API key / `claude` CLI.
- **Standalone (`roscoe run`, or `roscoe serve` with no MCP client):** every AI
  node runs server-side against your configured
  [backend](/docs/configuration/llm-backends).

## 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).

```mermaid
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](/docs/configuration/llm-backends), 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](/docs/nodes/round-robin) and [map](/docs/nodes/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`.

1. The host spawns exactly `agentCount` independent subagents and gives each the
   same prompt, run on the node's `model`.
2. It collects every subagent's raw JSON verdict and passes them to
   `advance_consensus` as `results: [{ raw }, …]`, one entry per subagent.
3. Roscoe validates each verdict with the same rules the server-side path uses
   and tallies the quorum itself. A gate node (a `boolean` or `confidence`
   validator) routes to `approved` or `rejected`; an `answer` or
   `most_consistent` node routes to `decided` or `undecided`.

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 `agentCount` results. 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](/docs/nodes/consensus)
  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:

1. Claude Code calls `start_workflow` with `host: "claude_code"`.
2. The run reaches the consensus node, sees a subagent-capable host, and pauses
   with a `consensus` `pendingStep`.
3. Claude Code spawns 3 independent subagents and collects their 3 JSON
   verdicts.
4. It calls `advance_consensus` with the 3 raw results.
5. 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](/docs/running/mcp) — setup and the pause/resume loop.
- [consensus node](/docs/nodes/consensus) — full schema, quorum rules, outputs.
- [round_robin node](/docs/nodes/round-robin) · [map node](/docs/nodes/map) — the other fan-out nodes that hand back.
- [AI backends](/docs/configuration/llm-backends) — what the server-side path uses.
