taskflow

Using taskflow on Claude Code

Install taskflow as a Claude Code plugin and orchestrate multi-phase workflows via MCP.

Claude Code is a natural home for taskflow: it already thinks in terms of subagents, and taskflow gives those subagents a declarative graph to run inside. The plugin registers the MCP server plus a routing skill; its protocol layer needs no MCP SDK.

This page walks through the whole arc: install the plugin, confirm the MCP server is live, run a flow through a tool call, and understand the permission and long-running-flow model.

Install

taskflow is distributed through the shared plugin marketplace. Add the marketplace, then install the plugin:

Requires Node.js ≥ 22.19.0.

Install the taskflow plugin
claude plugin marketplace add heggria/taskflow
claude plugin install claude-taskflow@taskflow

That single plugin install does three things at once:

Registers the MCP server. The plugin declares a taskflow server launched via npx -y -p claude-taskflow claude-taskflow-mcp, so Claude Code can reach the runtime over stdio. The npx pin binds the exact code that runs — nothing to install globally.

Installs the routing skill. A bundled skill teaches Claude Code when to reach for the taskflow tools, so you don't have to remember their names.

Avoids an MCP SDK dependency. The protocol layer speaks JSON-RPC 2.0 over stdio. Delivery packages still depend on taskflow's internal packages, and core peers on typebox.

Restart your Claude Code session if it was already running, so the new plugin is picked up.

Verify the install

Before running anything, confirm both the plugin and its MCP server registered cleanly:

Verify the plugin and MCP server
claude plugin list   # claude-taskflow@taskflow should appear, enabled
claude mcp list      # taskflow should appear, enabled

If either is missing, the plugin install step didn't complete — re-run it and check for errors.

Run your first flow

On Claude Code, you don't invoke taskflow through a slash command — you invoke it through an MCP tool. The model decides when to call it, guided by the bundled skill. So the most natural way to start is to just describe the work.

Just ask

Try one of these in a Claude Code session:

Describe the work in plain language
> List my saved taskflows.
> Verify this flow, then run it: {name:"review-changes", phases:[...]}
> Run the "review-changes" taskflow with dir set to src.

The skill routes the request to the right tool. If a flow is saved in the current project, the model calls taskflow_run with the saved name; if you pasted an inline definition, it passes that instead.

Call the tool directly

If you want to be explicit — useful in scripts or when you know the exact shape — the tool is taskflow_run. It accepts either a saved flow name or an inline define:

Run a saved flow via taskflow_run
{
  "name": "review-changes",
  "args": { "dir": "src" }
}
Run an inline flow via taskflow_run
{
  "define": {
    "name": "quick-review",
    "phases": [
      {
        "id": "discover",
        "type": "agent",
        "agent": "scout",
        "task": "List changed source files under src/. Output ONLY a JSON array of {path} objects.",
        "output": "json"
      },
      {
        "id": "review-each",
        "type": "map",
        "over": "{steps.discover.json}",
        "as": "file",
        "agent": "security-reviewer",
        "task": "Review {file.path} for security risks. Return one paragraph.",
        "dependsOn": ["discover"],
        "concurrency": 4
      },
      {
        "id": "summarize",
        "type": "reduce",
        "from": ["review-each"],
        "agent": "writer",
        "task": "Combine these reviews into one prioritized summary:\n{steps.review-each.output}",
        "dependsOn": ["review-each"],
        "final": true
      }
    ]
  }
}

Either form runs the same DAG. The tool returns only the final output — the intermediate transcripts from discover, review-each, and summarize stay inside the runtime and never enter your context.

Only the phase marked final: true is returned. Everything else is context-isolated by design.

Check a flow before spending tokens

Before running a DAG, you can ask Claude Code to verify it statically. This catches cycles, dangling dependsOn, unknown phase references, and malformed configs — all at zero token cost:

Verify a flow via taskflow_verify
{
  "name": "review-changes"
}

Or render the DAG as a diagram to eyeball its shape:

Compile a flow to a diagram via taskflow_compile
{
  "name": "review-changes"
}

taskflow_compile returns the DAG grouped into topological layers as a text outline, plus an inline SVG image for clients that render images.

How subagents run

Each phase's subagent runs as an isolated claude -p session — a real Claude Code headless process, not a pi process. The server discovers saved flows and agents from its launch cwd, so the project you start it in determines which flows are visible.

Permission mapping

Claude Code has no OS-level sandbox in headless (-p) mode — a tool call is either whitelisted or denied. The runner maps each phase's tool whitelist to a permission mode:

Taskflow requires Claude Code 2.1.169 or newer for --safe-mode. Older CLIs fail closed with an unknown-option error, so upgrade before using this adapter.

Phase toolsPermission modeWhat it means
Read-only or omitted; no mutating/unknown requested toolmatching --tools + --allowedTools listsBuilt-ins are restricted and pre-approved; explicit lists stay narrow. --safe-mode disables non-managed customizations, disk setting sources and non-managed hooks are disabled; administrator-managed policy hooks may still run. Note there's no read-only shell — Bash is not granted.
Known mutating tool requestedRejected by defaultFor trusted flows, PI_TASKFLOW_CLAUDE_UNSAFE_BYPASS=1 opts into bypassPermissions while retaining a narrow --tools set. Unknown names always fail closed.

Unsafe mode is an explicit operator opt-in, not the default. Even after opting in, prefer a throwaway worktree (cwd: "worktree"). The Claude child receives only platform/runtime, proxy/CA, and supported Claude-provider environment variables; unrelated application secrets are removed.

Long-running flows

taskflow_run is synchronous by default. For a long flow, set mode: "background"; the MCP call returns a durable runId immediately. Use taskflow_runs to list, inspect, wait for, or cancel that worker.

Then inspect the run afterward with taskflow_peek:

Peek at a phase's stored output via taskflow_peek
{
  "runId": "run_2026-07-04_abc123",
  "phaseId": "summarize"
}

Omit phaseId to list every phase with its status and output size. Output is hard-truncated (default 4000 chars) so a peek never floods your context.

taskflow_peek is the one intentional exception to taskflow's context isolation. It pulls intermediate output into your conversation — use it for debugging, not as part of your normal flow.

Approvals in MCP mode

MCP-driven runs are non-interactive, so an approval phase auto-rejects (fail-closed for the approval decision). Prefer a gate (agent review) in flows you run through the taskflow_* tools; use approval only in flows a human runs interactively.

Tool reference

Here's the full MCP surface the plugin exposes:

ToolPurpose
taskflow_runRun a saved flow (by name) or an inline definition (by define). Returns the final output + a runId.
taskflow_runsList background runs, or status / wait / cancel one by runId.
taskflow_resumeFork a failed or paused run into a new immutable child run, with optional one-phase overrides.
taskflow_versionReport package version, build commit, schema version, build time, and host.
taskflow_listList saved flows discoverable from the cwd, with library metadata when available.
taskflow_showShow a saved flow's definition plus its library sidecar metadata.
taskflow_saveSave a flow to the library with optional purpose, tags, and notes.
taskflow_searchSearch the library before authoring. Returns ranked reusable flows.
taskflow_verifyStatically verify a flow (cycles, refs, configs) at zero cost.
taskflow_compileRender the DAG as a text outline + inline SVG.
taskflow_peekInspect a stored phase's output for post-hoc debugging.
taskflow_traceRead a run's append-only event timeline.
taskflow_replayReplay recorded decisions offline with no model calls.
taskflow_why_staleExplain dependency staleness at zero tokens.
taskflow_recomputeReport the stale frontier (MCP is dry-run only).
taskflow_reconcile_workspaceExplicitly accept an inspected/repaired resolve-only workspace after a dirty-unknown write.

You rarely need to memorize these. The bundled skill tells Claude Code which tool fits the request — "verify this flow", "show me the diagram", "run it" all route correctly on their own.

Alternative: register the MCP server manually

If you'd rather not use the plugin, install the package and register its claude-taskflow-mcp bin yourself:

Manual MCP registration
pnpm add -g claude-taskflow
claude mcp add taskflow -- claude-taskflow-mcp

Verify it registered:

Verify manual registration
claude mcp list   # taskflow … enabled

The server behaves identically to the plugin version — it just doesn't come with the routing skill or the one-command update path.

Remove

If you need to take taskflow off a machine:

Remove the taskflow plugin
claude plugin uninstall claude-taskflow@taskflow   # if installed as a plugin
claude mcp remove taskflow                          # if registered manually

This unregisters the MCP server and removes the skill. Any saved flow definitions on disk are left untouched.

Next

Last updated on

Was this helpful?

Help us improve the docs or ask a question in the community.

On this page