taskflow
Guides & RecipesUsing taskflow on Codex

Using taskflow on Codex

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

Codex is a natural home for taskflow: it already thinks in terms of subagents, and taskflow gives those subagents a declarative graph to run inside. On Codex, taskflow ships as a plugin that registers an MCP server plus a routing skill, so the model can call it the moment it sees a multi-step task.

This page walks through the whole arc: install the plugin, confirm the MCP server is live, run a flow through a tool call, and configure things for long-running work.

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
codex plugin marketplace add heggria/taskflow
codex plugin add taskflow@taskflow

That single plugin add does three things at once:

Registers the MCP server. The plugin's .mcp.json declares a taskflow server launched via npx codex-taskflow-mcp, so Codex can reach the runtime over stdio.

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

Sets a sane default timeout. The server ships with a 30-minute (1800 second) tool-call timeout, because DAGs can take a while.

Restart your Codex 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
codex plugin list   # taskflow@taskflow should appear, enabled
codex mcp list      # taskflow should appear, enabled

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

Run your first flow

On Codex, 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 Codex 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 Codex 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"
}

Long-running flows

taskflow_run is synchronous by default, which is ideal when you want the final result in the current turn. For a long DAG, set mode: "background"; Codex receives a durable runId immediately and the worker continues independently.

The plugin ships a 30-minute default tool-call timeout to accommodate this. If your flows run longer, override it in your Codex config:

~/.codex/config.toml
[mcp_servers.taskflow]
tool_timeout_sec = 3600

This timeout applies to foreground calls. For longer work, prefer background mode instead of relying on an oversized request timeout.

Start background work with taskflow_run { name: "...", mode: "background" }, then use taskflow_runs to list, inspect, wait for, or cancel it. A failed or paused run can be continued with taskflow_resume, which forks immutable history into a new child run.

Codex reports token usage but not cost. A Codex flow may use budget.maxTokens; any budget.maxUSD is rejected before execution. The budget is an observed-usage stop-loss, not a zero-overshoot maximum: ordinary calls are admitted serially, while active race branches may overshoot together.

Every child uses --ephemeral --ignore-user-config --ignore-rules and clears mcp_servers, so unrelated parent MCP OAuth failures, plugins, and rules cannot change a phase. The child environment keeps platform/proxy/CA and Codex/OpenAI provider variables only. Add an intentional task variable by name with the comma-separated PI_TASKFLOW_CHILD_ENV_ALLOW operator setting.

Inspect a run after the fact

Every taskflow_run returns a runId. If something went wrong — a gate blocked, a phase produced odd output — you can inspect a single phase's stored output without re-running the whole flow:

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.

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.
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 in the current project.
taskflow_showPrint a saved flow's JSON definition.
taskflow_verifyStatically verify a flow (cycles, refs, configs) at zero cost.
taskflow_compileRender an inline SVG and text outline plus verification status.
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.
taskflow_saveSave a reusable flow and optional library metadata.
taskflow_searchSearch and rank reusable flows.

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

Codex does not enforce tools as a strict name whitelist. Read-only sets map to -s read-only; mutating or omitted sets map to -s workspace-write. Thinking maps to model_reasoning_effort (off/none/minimalnone, max/ultraxhigh); unsupported values fail before spawn.

Remove

If you need to take taskflow off a machine:

Remove the taskflow plugin
codex plugin remove taskflow@taskflow

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