Skip to main content
pflow provides a CLI for running workflows, managing MCP servers, and configuring settings.
Who runs these commands? Most pflow commands are run by your AI agent, not by you directly. You handle setup (installation, API keys, MCP servers), then your agent uses pflow to build and run workflows. This reference documents all commands so you understand what your agent is doing. See Using pflow for what to expect day-to-day.

Command structure

Command groups

pflow (default)

Run workflows by name or file

pflow list / find / describe

Find saved workflows and inspect them by saved name or file path

pflow skill

Publish workflows as AI agent skills

pflow guide / probe

Learn the surface and test single nodes

pflow mcp

Manage MCP server connections

pflow settings

Configure API keys and node filtering

pflow ui

Interactive browser canvas for a workflow

pflow mermaid

Generate a Mermaid flowchart from a workflow

pflow guide

Get AI agent entry guidance

Main command

The default pflow command runs workflows. Your agent uses this to run saved workflows or workflow files it has created.

Run a saved workflow

Run from a file

No built-in natural language mode. pflow executes workflow files and saved workflows. Your AI agent builds workflows using pflow’s MCP tools or CLI primitives — pflow doesn’t have its own natural language interface.

Resume a failed run

When a run fails partway — an LLM/HTTP/MCP step times out, a transient error survives retries — pflow resume continues from the failed step instead of re-running the whole workflow. It restores the already-completed upstream steps’ outputs from the saved trace (it does not re-run them) and walks forward from the failed step.
The failed run prints the exact command to use (To resume from the failed step: pflow resume <execution-id>). A resumed run is a new run with its own trace, linked to the original. The failed step runs again from the start, so if it already partly side-effected (an HTTP POST that sent but timed out on the response), resuming re-fires it — at-least-once execution. A side-effecting step (shell/code/agent/file-ops/mcp) asks for confirmation at a terminal and refuses for non-interactive agents unless you pass --force; an idempotent llm step resumes silently. See pflow guide resume for the full behavior (loop restart, gate re-prompting, top-level granularity, interrupted-run handling).

Answer a paused gate

An approval gate reached in a non-interactive run — a pipe, CI, an MCP call, a browser-launched run — doesn’t fail and doesn’t hang. The run pauses, saves its state to the trace, and exits with code 4 with a resume token on stdout:
The gate’s content follows on stderr — an approval’s resolved preview, or an escalation’s question, options, and recommendation — so a calling process can compose the answer from the output alone. With --output-format json, the paused document carries status: "paused", execution_id, paused_node_id, gate_request, and resume_command. Answer it later — hours or days on — and the run continues from the gated step without re-running anything upstream:
Nothing upstream re-runs — completed steps are restored from the paused trace. An approval gate fires before its step, so an approved step runs for the first time (no confirmation prompt, no re-fired side effect); an answered escalation continues at the next step with the decision folded in, so the agent step is never re-paid. Answering consumes the token: the resumed attempt supersedes the paused run, and a second answer refuses and names the newer attempt. Resuming without an answer flag refuses and prints the pending question with the exact command. The edited-workflow refusal and --force apply the same as a failed resume.
Durable pause needs the trace. A gate under --no-trace, inside a parallel batch item, in a sub-workflow child, or in an inline/piped workflow (no file to reload) can’t pause — it fails at the gate instead. Save the workflow to a file and run it by name or path so its gates can pause.

Global options

Older natural-language workflow generation flags have been removed. Use the current global options shown above, or let your AI agent build .pflow.md workflows directly.

Parameter syntax

Pass parameters to workflows using key=value syntax:
Type inference:
  • true / false → boolean
  • 10 → integer
  • 3.14 → float
  • '["a","b"]' → JSON array
  • '{"key":"val"}' → JSON object
  • Everything else → string

Stdin input

Pipe data into workflows that declare an input with stdin: true:
The workflow must have an input marked to receive stdin:
Piped data routes to this input automatically. CLI parameters override stdin if both are provided:
For workflow chaining, use the -p flag to output results for the next workflow:

Stdout output

Workflows that declare multiple outputs mark one with stdout: true to pick which output lands on process stdout in text mode:
Redirecting or piping the CLI in text mode now writes only the marked output to stdout:
Single-output workflows don’t need the marker — their one output is unambiguous. Workflows with multiple declared outputs and no stdout: true stream the first declared output and print a warning on stderr naming the other outputs and the three ways to change the routing: add the marker, pass -o, or switch to JSON mode. The validator enforces that at most one output per workflow is marked.

Output modes

Text mode (default)

Human-readable output with live progress streamed to stderr and results on stdout. Works the same way in a terminal, CI log, agent bash tool, or subprocess capture:
Progress lines and execution summary go to stderr. Declared workflow outputs go to stdout.

JSON mode

Structured output on stdout for machine parsing:
All workflow results, metrics, and errors serialize to a single JSON object on stdout. Progress and execution summary go to stderr (suppressed with -p). Minimal stderr output when you want the cleanest possible data stream:
Suppresses the “Workflow output:” header, the execution summary, and stderr warnings. Data still goes to stdout (same as default mode). Useful for piping into tools that should only see the result.

Exit codes

Runtime warnings remain visible in stderr, JSON output, traces, and reports; they do not make a completed workflow a process failure.

Validation mode

Validate a workflow without running it:
Agents use this to check workflows before running them — pflow catches template errors, type mismatches, and missing inputs during validation, so problems surface immediately instead of after step 5 fails. Exit code 0 means valid.

Dry-run mode

Preview what a workflow would do without running it. --dry-run walks the graph using the same cache lookup the engine uses at runtime, but never invokes a node — no shell commands, LLM calls, HTTP requests, file writes, or trace files:
Cached nodes render with , would-execute nodes with , and a divider marks the cache boundary:
When everything is cached, there’s no boundary. When nothing is cached, the divider reads nothing cached — full run. For would-execute LLM nodes, the plan surfaces the cost from the most recent cache entry — labeled because pricing may have drifted. Per-node duration annotations appear on any would-execute node whose last run took at least 1 second; faster nodes stay bare:

JSON output

Top-level shape: {workflow, plan, summary, diagnostics}.

Flag combinations

Exit 0 on a successful plan, 1 on planner-level failures (missing input, compile error, unresolvable sub-workflow, cycle, max depth exceeded).

Iteration and caching

pflow caches node outputs automatically. When your agent re-runs a workflow file, unchanged nodes return instantly from a persistent cache — only nodes whose configuration or inputs changed will re-execute.
The cache is content-addressed — same node config plus same resolved inputs produces the same cache key, regardless of when or how the workflow was run. Cache entries expire after 24 hours. The cache lives at ~/.pflow/cache/cache.db.

Run a single node

The --only flag runs just the named node against a frozen snapshot of the most recent full run. Every other node’s output is restored from that run — not re-executed — so a side-effecting upstream node like shell: git push does not run again. It needs a prior full run to snapshot from (otherwise it errors). Targeting a node inside a sub-workflow is not supported.
Without -o, --only streams the targeted node’s result to stdout instead of the workflow’s full-run outputs. Pass -o <key> when you need a specific named output. This is how agents iterate on a specific node without re-running the full workflow.

Bypass memo cache reads

Use --no-cache to bypass pflow memo-cache reads, so nodes execute again. Memo cache writes still happen, so the next run without --no-cache benefits from the results:
Use this when a node has external side effects (API calls, file writes) that should run again, or when memoized results seem stale. It does not disable LLM provider prompt caching declared with ## Cache / prompt_cache:, OpenAI automatic prompt caching, or Gemini implicit caching.

Per-node caching

Only llm nodes cache by default — their output is purely a function of their declared inputs. Every other node type (shell, code, http, file ops, mcp, agent) defaults to NOT caching, because they side-effect or read external state (git branch, date, environment variables, files, network). So a node like git branch --show-current re-runs every time with no annotation needed:
Reports include rendered prompts, responses, cost data, error summaries with fix suggestions, and anomaly warnings. Report output directories are replaced as generated snapshots. Custom report directories must be empty or already contain pflow’s .pflow-report.json marker. Disable traces with --no-trace for faster execution (the --report flag overrides --no-trace).

UI command

Serve an interactive browser canvas for a workflow — the visual counterpart to pflow mermaid. Where mermaid emits static text, pflow ui opens a local browser canvas: collapsible sub-workflow, batch, and loop containers, click-to-read prompts and params, ${ref} data-flow lines, and a source pane.
The canvas updates in place — no page reload — as the workflow’s .pflow.md is edited on disk, so you can watch it take shape (while keeping the current zoom and selection) as you, or an AI agent, build it. An edit that doesn’t validate is held: the last valid version stays on screen with an error banner until the source parses again. The server blocks until Ctrl+C, so run it in the background while you edit. The canvas also shows runs in progress. Run a workflow in another terminal — or have your agent run it — and the open canvas lights each node as it starts and finishes: running, succeeded, cached, failed, or stopped, with a hover chip showing that node’s duration and cost. It works the same for a finished run: open the run selector to replay any past run on the graph, or click a node to see what that run produced — its resolved inputs, output, cost, and tokens. With no workflow argument, the catalog marks which workflows are running now and when each last ran. Runs on a standard install. If pflow ui reports a missing dependency, add the server extra: uv tool install 'pflow-cli[ui]'. The full view is described by the URL, so you can share or screenshot an exact state — for example ?workflow=<name-or-path>&focus=<node-id>&direction=TD. focus= highlights a node and reveals its connections; node= centers the camera on it. An agent can interact with every open Viewer showing a workflow:
Name a target the way it reads in the .pflow.md: a step, input, or output by its name (process_content, source_file), or a connection as source -> target (gen.response -> summarize.prompt) — there’s no separate notation to learn. If a name matches more than one thing — the same step inside two sub-workflows, or an input and output that share a name — the command lists qualified addresses to pick from instead of guessing, and an unknown name returns the closest real matches. So you point, read the reply, and re-point. --say "text" narrates the point aloud in every open Viewer with a persistent on-canvas caption (text-to-speech via the configured tts_model/tts_voice; needs a Gemini API key). Delivery direction goes in [brackets] — e.g. --say "[excited] this is the LLM call" — bracketed tags shape the voice and are stripped from the caption; everything outside brackets is spoken and shown. If synthesis fails (no key, network), the point and caption still land and the reason appears in the report as narration unavailable: .... A --say command waits for the previous clip to finish before it points, so running several in a row produces a self-pacing narrated walkthrough with no dead air — the next line synthesizes while the current clip is still playing, and each command returns as soon as its own clip starts. --no-wait points immediately instead (the new clip interrupts the playing one). If the browser blocks autoplay (a fresh window before any click), the next --say holds the walkthrough — reporting note: narration is blocked in the Viewer… — until a click on the caption’s ▶ button plays the blocked line and unlocks sound; after ~2 minutes it continues with captions only. Each narrated target keeps its caption box on the canvas with a Replay button once the clip finishes; a new --say to the same target replaces that box, and clear-focus closes them all and stops the voice. These commands target port 8765 by default (pass --port N for another instance). Point commands exit nonzero when the target is unresolved/ambiguous or no Viewer received the command. focus --open opens a Viewer only when no window for that workflow is connected.

Mermaid command

Generate a Mermaid flowchart from a workflow. Shows the graph topology — nodes, edges, conditional branches, error routes, inputs, outputs — that’s otherwise scattered across individual node directives in the .pflow.md file. For an interactive, collapsible canvas instead of static text, see the UI command.
The command validates the workflow first (same checks as --validate-only). On validation failure, it shows diagnostics and exits with code 1. On success, it outputs Mermaid syntax to stdout.
Mermaid renders natively in GitHub, VS Code, and most markdown viewers — no extra tooling needed. The .md output wraps the diagram in a markdown document with the workflow’s title and description, ready to commit or share. Sub-workflow nodes (type: workflow) expand into subgraph blocks showing their internal structure. Use --depth 0 to render them as opaque nodes, or --depth 2 to expand nested sub-workflows:

Guide command

The pflow guide command provides the entry guidance for AI agents using pflow.
Without topics it renders the same entry content as pflow --help. Topic composition is introduced in Task 77.