Skip to main content

Reusable CLI workflows from shell, LLM, HTTP, and MCP nodes

Project description

pflow

pflow

License Python 3.10+ CI Docs

pflow helps your agent build workflows it can reuse. It composes pre-built nodes — LLM calls, shell commands, HTTP requests, MCP tools — into a .pflow.md file. Save it, and it becomes a command that runs the same process every time.

Saved workflows can be published as Skills with pflow skill save, making them available across Claude Code, Cursor, and other platforms.

pflow demo

What a workflow looks like

I use pflow for my own releases. This workflow analyzes git commits since the last tag, classifies each one with an LLM (70 concurrent calls), and generates a CHANGELOG.md entry, a Mintlify docs update, and a release context file. It runs in about a minute.

pflow generate-changelog since_tag=v0.5.0

The whole thing is a .pflow.md file — markdown that renders as documentation on GitHub and executes as a CLI command. Here are a few steps from the full workflow:

### get-latest-tag

Detect the most recent git tag to use as the changelog baseline.

- type: shell

```shell command
git describe --tags --abbrev=0 2>/dev/null || echo 'v0.0.0'
```

### resolve-tag

Pick the starting tag: either user-provided or auto-detected.

- type: code
- inputs:
    since_tag: ${since_tag}
    latest_tag: ${get-latest-tag.stdout}

```python code
since_tag: str
latest_tag: str

result: str = since_tag.strip() if since_tag.strip() else latest_tag.strip()
```

### analyze-commits

Classify each commit as user-facing or internal. Runs in parallel.

- type: llm

```yaml batch
items: ${get-commits-enriched.result}
parallel: true
max_concurrent: 70
```

### notify-slack

Post the release summary to Slack.

- type: mcp-composio-slack-SLACK_SEND_MESSAGE
- channel: ${slack_channel}
- markdown_text: ${create-summary.result}

Data flows between steps through template variables — ${get-latest-tag.stdout} feeds one step's output into the next.

Four node types in one workflow: a shell command, inline Python, 70 parallel LLM calls, and a Slack message via MCP in three lines.

More examples: release announcements, vision scraper

Once saved, this runs the same way every time — same steps, same order, same data flow between them.

How your agent uses pflow

pflow has 8 node types: shell, code (Python), http, file operations, llm calls, mcp tools, and an agent node that delegates repository work to Claude or Codex.

Before anything runs, validation catches errors — wrong template references, missing inputs, type mismatches. Your agent handles the whole lifecycle:

# Check if a workflow already exists
pflow find "generate changelog from git history"

# Nothing fits — get a step-by-step creation guide
pflow guide

# Find building blocks for the workflow
pflow mcp find "analyze git commits, classify with llm, post to slack"

# Build, run, iterate (validation runs automatically)
pflow workflow.pflow.md since_tag=v0.5.0

# Save to your library
pflow save ./workflow.pflow.md --name generate-changelog

# Publish frequently-used workflows as Skills
pflow skill save generate-changelog

Workflows can call other workflows — the changelog you build today becomes a building block for a release workflow tomorrow.

# JSON output works with standard tools
pflow --output-format json generate-changelog \
  | jq -r '.result.version' | xargs git tag

# Chain workflows together
pflow -p generate-changelog | pflow -p release-announcements

# Schedule workflows like any command
0 9 * * MON pflow generate-changelog

Built for agents

When something goes wrong, pflow tells the agent what to do:

✗ Static validation failed:
  • Node 'fetch-data' (type: http) does not output 'email'

Available outputs from 'fetch-data':
  ✓ ${fetch-data.response} (dict|str)
  ✓ ${fetch-data.status_code} (int)
  ✓ ${fetch-data.response_headers} (dict)
  ✓ ${fetch-data.response_time} (float)
  ✓ ${fetch-data.error} (str)

Tip: Try using ${fetch-data.response} instead

The agent sees what went wrong, sees every available output with its type, and gets a suggested fix. No stack traces, no guessing. (source)

I develop pflow by having agents build workflows and identifying where they get stuck. These error messages are a direct result.

pflow is CLI-first because agents in Claude Code, Cursor, and similar tools always have bash. No MCP configuration needed — just run commands. (MCP server mode is available too if you need it.)

Honest scope

pflow is for workflows where you know the steps — tasks your agent figured out once and you want to capture. If you're exploring or need your agent to adapt on the fly, let it. pflow captures the path after you've found it.

Getting started

Requires Python 3.10+ on macOS, Linux, or Windows. On Windows, shell steps run through Git Bash — install Git for Windows (workflows use one POSIX shell dialect on every platform, so they stay portable). See the quickstart for API key setup and detailed configuration.

# Recommended
uv tool install pflow-cli

# Or with pipx
pipx install pflow-cli

# Or with pip
pip install pflow-cli

# Verify
pflow --version

Tell your agent to run pflow guide — it gets everything it needs to discover, run, and build workflows.

Or configure pflow as an MCP server for environments without terminal access:

{
  "mcpServers": {
    "pflow": {
      "command": "pflow",
      "args": ["mcp", "serve"]
    }
  }
}

Full documentation at docs.pflow.run.

I want your feedback

I've been building pflow since mid-2025. The thesis I'm testing: agents are more effective when they can compose known building blocks into reusable workflows, rather than writing code from scratch each time.

I might be wrong. Try it and tell me:

  • Is the .pflow.md format helpful, or would you rather just read/write Python?
  • After trying it — would you rather just let your agent handle the whole task from scratch each time? Write scripts? Use some other framework?
  • What's the first workflow you'd build?

Open a discussion or file an issue.

Or get started → Get started

License

Functional Source License (FSL-1.1-ALv2) — free for all use except offering pflow as a competing cloud hosted service. Becomes Apache-2.0 after 2 years.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pflow_cli-0.15.0.tar.gz (3.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pflow_cli-0.15.0-py3-none-any.whl (2.6 MB view details)

Uploaded Python 3

File details

Details for the file pflow_cli-0.15.0.tar.gz.

File metadata

  • Download URL: pflow_cli-0.15.0.tar.gz
  • Upload date:
  • Size: 3.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.6.14

File hashes

Hashes for pflow_cli-0.15.0.tar.gz
Algorithm Hash digest
SHA256 1bd06db1d9c24cda5c09380ae5d909c22cbbeb652b177d6360f4307d40a456bf
MD5 824adf23601781bd4d451e29f4492b61
BLAKE2b-256 5212758b0f9de6b73fb391313324203a83f4c9c844e231d5526efabcfba93436

See more details on using hashes here.

File details

Details for the file pflow_cli-0.15.0-py3-none-any.whl.

File metadata

  • Download URL: pflow_cli-0.15.0-py3-none-any.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.6.14

File hashes

Hashes for pflow_cli-0.15.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8805d51e3410b1daa8e144954d224771b4ee34ede389c1e207c4743974f6f33c
MD5 3db87728926874c2b6d608d7b2c46fd9
BLAKE2b-256 e77b01d39d332139d4e378be1a1c4417dddde7753eef3f08666404f831f8f1c5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page