# Claude integration

Connect Roscoe to Claude and you can build, run, and manage workflows by asking. From an ordinary chat, Claude can turn a plain-language description into a new workflow, edit one you already have, start a run, or check how a past run went, all using Roscoe's tools behind the scenes. Setup takes one step.

Connecting Roscoe to Claude lets it drive your workflows, giving you two things. First, you drive it in plain language: describe what you want and Claude writes or adjusts the workflow for you, with no YAML to write by hand. Second, it runs on the Claude plan you already have. When Claude drives a run, your AI steps run on your existing Claude subscription, with no separate API key to set up and no extra bill to reconcile.

The connection uses MCP, the Model Context Protocol: an open standard Claude uses to talk to outside tools. You don't need to know how it works. Connect once, from the desktop app's **Settings** or with a single command (see [Install](#install)), and Claude gains 30 Roscoe tools it can call on your behalf. Each call is scoped to one project or to your global workflows, so one connection serves everything on your machine.

Roscoe works with any MCP client, including **Claude Code** (the command-line tool) and the **Claude desktop app**. For the full list of tools, see [the MCP tools reference](/docs/reference/mcp-tools).

## Install

There are two routes:

### Compiled binary

```bash
roscoe install-mcp
```

This registers a user-global `roscoe` entry in `~/.claude.json`. Claude Code reads MCP servers from its top-level `mcpServers` key, so one install works in **every** project on your machine. The entry points at the binary's own `process.execPath`:

```json
{
  "mcpServers": {
    "roscoe": {
      "command": "/Users/you/.roscoe/bin/roscoe",
      "args": ["mcp"]
    }
  }
}
```

User scope is the right default: the entry is identical for every project, and the machine-specific binary path stays in `~/.claude.json` (which is per-machine and never committed) rather than in a shared file.

Pass `--project` to write a project-local `.mcp.json` at the current directory instead. A project `.mcp.json` records the same absolute `process.execPath`, so it's machine-specific: don't commit it to share with teammates, since their binary lives elsewhere. User scope avoids that problem entirely.

#### The `/roscoe` slash command

The default user-global install also drops a `/roscoe` slash command at `~/.claude/commands/roscoe.md` (the same file `roscoe init` writes). In Claude Code or Cowork you can then type `/roscoe <workflow-name>` to start a workflow, or `/roscoe` alone to list what's available and pick one. It's a thin entry point that tells Claude which `mcp__roscoe__*` tools to call. The command file is namespaced to Roscoe and refreshed on every install, so it stays current with the binary.

This is skipped for `--project`, `--path`, and `--client claude-desktop`: the Claude **desktop app** doesn't read `~/.claude/commands` (it has no slash commands), so the command benefits Code / Cowork users only. The install is best-effort: a failure never fails the MCP registration.

#### Claude desktop app

To register with the Claude desktop app instead, pass `--client claude-desktop`:

```bash
roscoe install-mcp --client claude-desktop
```

This writes the same `roscoe` entry (identical `mcpServers` shape) to the desktop app's own config file (creating the directory if the app hasn't been launched yet):

- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Linux:** `~/.config/Claude/claude_desktop_config.json` (or `$XDG_CONFIG_HOME/Claude/…`)
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`, or, for a Microsoft Store install of Claude Desktop, the per-package path under `%LOCALAPPDATA%\Packages\Claude_*\LocalCache\Roaming\Claude\`. `install-mcp` writes to whichever the installed app reads.

Restart the desktop app afterward. `--client claude-code` is the default, and `--project` only applies to Claude Code: Claude Desktop has no project-local config.

> **`cwd` in the desktop app:** unlike Claude Code, the desktop app has no IDE working directory to pass automatically, so project-scoped tools resolve to your **global** workflows (`~/.roscoe`) unless you tell Claude which project directory to use. Mention an absolute path (e.g. "use my workflows in `~/dev/projectA`") and Claude forwards it as the `cwd` argument.

### From source (dev)

The repo ships a `.mcp.json` at the root that runs the CLI directly via Bun:

```json
{
  "mcpServers": {
    "roscoe": {
      "command": "bun",
      "args": ["apps/cli/src/index.ts", "mcp"]
    }
  }
}
```

Restart Claude Code after either change and the tools become available.

## How execution works

Standalone runs call the LLM themselves; MCP runs hand the work to Claude. At every `ai_agent` or `ai_judge` node the runner pauses and returns a `pendingStep` containing the full prompt and the list of valid transitions. Claude Code reads the prompt, generates a response, and calls `advance_run` to continue. The runner records the response, advances the state machine, and either runs to completion or returns the next `pendingStep`.

`human` nodes pause until `resume_run` is called with a chosen transition. Claude must wait for the user to pick one. Never advance a human node autonomously.

`consensus` nodes depend on the client. From Claude Code or Cowork (hosts that can spawn isolated subagents), the runner hands the fan-out back: Claude runs the `agentCount` reviewers in parallel and returns their verdicts via `advance_consensus`, and Roscoe tallies the quorum. That runs on your Claude subscription, no API key required.

From plain Claude desktop chat (no subagents) the node runs server-side instead and needs `ANTHROPIC_API_KEY` or the `claude` CLI on `PATH`. See [the subscription docs](/docs/running/subscription).

### Per-call project scoping

The MCP server is long-lived and project-agnostic. One server can serve calls scoped to any repo on your machine. Every project-scoped tool takes exactly one scope argument: either `cwd` (absolute path to any directory inside the target project) or `global: true`.

With `cwd`, the server resolves it to the git root and isolates workflows + runs to that project. Claude Code passes the user's IDE working directory automatically, so a session in `~/dev/projectA` lists projectA's workflows even if `roscoe serve` was started from elsewhere. Two parallel calls with different `cwd`s see different projects without interference. See the MCP tools reference for the full contract and validation errors.

Passing **neither** `cwd` nor `global` is a loud error (`CWD_REQUIRED`); the server never silently guesses a project.

#### Global mode (no project directory)

The **Claude desktop app** has no project/working directory, so there's nothing to pass as `cwd`. In that case pass `global: true` instead: all operations target the global store (`~/.roscoe/workflows`). Repo-scoped (`source: "repo"`) operations are unavailable in global mode, so a workflow tool's `source`/`target_source` can be omitted: it defaults to the global store. (`move_workflow`'s `to` still names an explicit destination.)

The server advertises this convention via its MCP `instructions`, so Claude generally picks the right scope on its own. Runs started in global mode are tracked in a shared global namespace, isolated from project runs (and they don't capture per-commit git metadata).

### Build one by asking

> **You:** Make a workflow that handles a customer refund. Check the request
> against our 30-day return policy, and if it's a close call, have three AIs vote
> before it's approved.

Claude turns that into a real workflow, checks it, and saves it with
`create_workflow`. Want a change later? Say so:

> **You:** Pause for a person to sign off on any refund over $500.

Claude edits the file with `update_workflow`. You never open the YAML yourself.

### Run one

> **You:** Run the approval-flow workflow.

Behind the scenes Claude:

1. Calls `list_workflows` to find `approval-flow`.
2. Calls `start_workflow` with its id. The runner executes script / condition nodes, pauses at the first `ai_agent` node, and returns a `pendingStep` with the prompt.
3. Reads the prompt, drafts a response, calls `advance_run` with it.
4. Repeats until the run hits a `human` node, at which point Claude lists the valid transitions and asks **you** which one to take.
5. You answer; Claude calls `resume_run` with your choice; the run completes.

## Tools at a glance

Names plus one-line purposes. Full input/output schemas are in the MCP tools reference.

### Workflow CRUD

| Tool                       | Purpose                                                                                        |
| -------------------------- | ---------------------------------------------------------------------------------------------- |
| `list_workflows`           | List all workflows with `source` and `shadowed` flags                                          |
| `get_workflow`             | Read one workflow's full config                                                                |
| `create_workflow`          | Write a new workflow YAML; refuses on collision                                                |
| `update_workflow`          | Replace an existing workflow with a validated new config                                       |
| `delete_workflow`          | Delete a workflow file (requires literal `confirm: true`)                                      |
| `move_workflow`            | Move a workflow between Global and Project sources                                             |
| `duplicate_workflow`       | Copy a workflow under a new id, optionally to the other source                                 |
| `rename_workflow`          | Rename a workflow's id (file stem) and `name` field                                            |
| `list_workflow_references` | List workflows that reference a given one via `subworkflow`; check before deleting or renaming |

### Authoring helpers

| Tool                  | Purpose                                                              |
| --------------------- | -------------------------------------------------------------------- |
| `get_workflow_schema` | Returns the JSON Schema, executor list, and configured models        |
| `validate_workflow`   | Dry-run schema + integrity validation (no FS writes)                 |
| `lint_workflow`       | Validation plus warnings (dead states, unknown models, unreachables) |

### Run lifecycle

| Tool                  | Purpose                                                                       |
| --------------------- | ----------------------------------------------------------------------------- |
| `start_workflow`      | Start a run; returns `{ runId, status, pendingStep? }`                        |
| `get_run_status`      | Current status plus the `pendingStep` if paused at an AI node                 |
| `advance_run`         | Supply Claude's response to an `ai_agent` / `ai_judge` pause                  |
| `advance_consensus`   | Supply host subagents' verdicts to a `consensus` pause (Claude Code / Cowork) |
| `advance_round_robin` | Supply host subagents' matchup verdicts to a `round_robin` pause              |
| `advance_map`         | Supply host subagents' branch/reduce results to a `map` pause                 |
| `resume_run`          | Resume a `human` pause with a chosen transition (wait for user)               |
| `cancel_run`          | Cancel a running or paused workflow                                           |

`start_workflow` accepts optional `spending_cap_usd` and `spending_cap_tokens`.
When set, the run is stopped (status `cancelled`, `stop_reason`
`spending_cap_exceeded`) once its running total cost or token count exceeds the
cap. That bounds `consensus` / `map` / `round_robin` fan-out and nested
sub-workflows, and subscription runs too. Caps are off unless supplied (or
declared as a default in the workflow YAML). `advance_run` accepts an optional
`usage` object (`inputTokens` / `outputTokens` / `cacheCreationTokens` /
`cacheReadTokens` / `costUsd`); supply it when you know the real figures so a
subscription handback node records its exact API-equivalent cost instead of an
estimate. The run-status / advance payloads carry the cost rollup
(`totalCostUsd`, `meteredCostUsd`, `subscriptionEquivCostUsd`, `billingMode`,
token totals).

### Run observability

| Tool              | Purpose                                                           |
| ----------------- | ----------------------------------------------------------------- |
| `list_runs`       | Recent runs newest-first; filter by workflow, status, since, kind |
| `get_run_history` | Full per-node trace with timestamps, IO, errors, child sub-runs   |

### Verification

| Tool            | Purpose                                                                       |
| --------------- | ----------------------------------------------------------------------------- |
| `test_workflow` | Run end-to-end with mocked AI/human responses and auto-cleanup of the run row |

### Docs

| Tool          | Purpose                                                                                               |
| ------------- | ----------------------------------------------------------------------------------------------------- |
| `list_docs`   | Enumerate documentation pages                                                                         |
| `get_doc`     | Fetch the markdown source of one page                                                                 |
| `search_docs` | Free-text search across the docs (ranked snippets)                                                    |
| `ask_docs`    | Natural-language question → ranked full heading sections within a char budget (knowledge-base lookup) |
| `answer_docs` | Natural-language question → synthesized prose answer with citations (wraps `ask_docs` + LLM backend)  |

### Skills

| Tool            | Purpose                                                                   |
| --------------- | ------------------------------------------------------------------------- |
| `list_skills`   | Find agent skills (SKILL.md convention) on this machine, across harnesses |
| `convert_skill` | Convert a skill's markdown + scripts into a Roscoe workflow               |

## See also

- [the MCP tools reference](/docs/reference/mcp-tools) — full tool schemas and examples.
- [the subscription docs](/docs/running/subscription) — where AI inference runs, and the consensus handback.
- [LLM backends](/docs/configuration/llm-backends) — the backend that server-side runs use.
- [Workflow sources](/docs/configuration/workflow-sources) — the `source` parameter on workflow tools.
