---
title: mdflow — repeatable agent work
url: https://mdflow.dev/
description: A Git-native control plane for repeatable local agent work, using Markdown flows, behavioral evals, and proposal-first evolution.
---

# mdflow

A Git-native control plane for repeatable agent work. Define each job as Markdown, run it on the CLI engine you already use, inspect its inputs, and gate prompt revisions with behavioral evals. Keep one flow per repeatable job in a project's `flows/` roster, with frontmatter for configuration and a Markdown body for the prompt.

## When to use mdflow

Use it when a code review, release-note draft, issue-triage task, or other recurring agent job should be readable, reusable, diffable, and shared with a team. Flows are local files you can review in Git. Bare `md` opens a searchable Flow Workbench for project, global, installed, and PATH flows. Workflows execute only through the local CLI; the website serves read-only documentation and source facts.

## Install and get oriented

mdflow runs on [Bun](https://bun.sh). If Bun is missing, the interactive launcher offers to install it; non-interactive environments must install Bun first. The selected engine CLI must also be installed and authenticated. Installing packages or configuring an engine changes the environment and is not part of read-only inspection.

The official npm package is [mdflow](https://www.npmjs.com/package/mdflow).

```bash
npm install -g mdflow
md --version
md doctor --json
md roster --json
```

For one-off package invocation, use `npx mdflow`. After approving local setup, `npx mdflow init --yes` creates a deterministic starter roster without an engine invocation. `md init --guided` instead launches engine-guided setup; do not treat those two commands as having the same cost or consent. Install the companion agent skill with `npx skills add johnlindquist/mdflow`.

The source facts describe mdflow **4.9.0**, not necessarily the version installed on your machine. Run `md --version` and inspect the installed CLI's help when making compatibility decisions.

## Engines and resolution

The built-in default is **pi**. Supported engine names from the current source facts: `claude`, `copilot`, `codex`, `gemini`, `droid`, `opencode`, `pi`, `cursor-agent`, `agy`, `grok`, `kimi`.

Resolution, most explicit first:

1. --engine flag — deprecated aliases: --_command/-_c, --tool
2. MDFLOW_ENGINE env var
3. filename (task.claude.md) — must name a real engine
4. frontmatter engine: — deprecated aliases: tool:/_tool: (they warn)
5. config engine: — project config beats ~/.mdflow/config.yaml
6. default: pi — implicit picks are announced on stderr

## Inspect before execution

- `md doctor --json` provides static diagnostics, installed-engine readiness, and effect-labelled next actions without fetching imports, running code, or writing files.
- `md explain <flow.md> --json` resolves a prompt and invocation without launching the engine. File, URL, and context-provider imports may still resolve.
- `md eval <flow.md> --plan` reports the planned eval invocation count before consent. Executing the suite is a separate operation.
- `md evolve plan <flow.md>` previews evolution readiness, cost, capabilities, and writes. A proposal does not apply itself.

## Permissions, security, and costs

The operation contract distinguishes `FREE` (no engine invocation), `LOCAL_WRITE` (local changes), and `ENGINE` (provider-backed work). `FREE` is not a universal promise of zero side effects or network access: dry-run and explanation can resolve imports. Use doctor for strictly static inspection.

- A real flow run, eval run, proposal run, and source mutation require separate consent.
- Eval sidecars are executable local TypeScript; static plans do not import them, but real eval runs do.
- Hook sidecars are executable local TypeScript and must be reviewed before use.
- Evolution creates a private proposal; applying it is a separate explicit source mutation.
- Engine context isolation is not a filesystem, network, process, environment, or credential sandbox.
- Dry-run skips engines, inline commands, and executable fences, but file, URL, and context-provider imports may still resolve.
- Registry install adds one flow, not trusted eval or hook sidecars.
- A suite's presence is not verification; Verified requires a current fingerprint-bound full-run receipt.
- Compatibility stamps are managed by successful local runs, not by diagnostics.

Review a flow like executable code. Use least-privilege credentials and, for untrusted flows, a disposable environment with restricted access. The CLI is free under the MIT license; external engines and providers may charge. See [pricing and costs](https://mdflow.dev/pricing.md) and [the security policy](https://mdflow.dev/SECURITY.md).

## Agent interfaces

Workflows execute only through the local CLI; the website serves read-only documentation and source facts. Flow UX Protocol v1 uses `protocolVersion: 1`. Check the installed version and JSON protocol version rather than scraping terminal output. `md doctor --json`, `md roster --json`, and `md explain <flow.md> --json` expose structured inspection; `md <flow.md> --events` performs a real run with an NDJSON event stream. `md <flow.md> --json` emits a single result object instead. Real execution needs separate consent.

The public read-only machine interface is `GET /facts.json`: a static source-facts snapshot, including command and operation descriptions, with no authentication or mutations. Request `Accept: application/json`. Its [OpenAPI 3.1 description](https://mdflow.dev/openapi.json) has interface version `1.0.0`; the payload has `contract.contractVersion: 1`. These versions are separate from the source CLI version `4.9.0`. Discover it through the [API catalog](https://mdflow.dev/.well-known/api-catalog). This snapshot describes the source published with the site, not your project's state or readiness.

The response carries `X-API-Version: 1` and discovery `Link` headers. Additive fields are allowed within v1; clients should tolerate unknown fields. Breaking representation changes require a new URL and a new major specification version rather than silently changing existing fields.

Site-handled JSON failures use RFC 9457 `application/problem+json`: missing resources return 404, unsupported methods return 405 (`Allow: GET, HEAD`), and unsupported response representations return 406. Public hosting can return its own errors or cached content; see [HTTP usage and hosting](https://mdflow.dev/docs/) and the [privacy page](https://mdflow.dev/privacy/). The [full public CLI reference](https://mdflow.dev/docs/public-api.md) separately defines local CLI fields, event ordering, and errors.

## Commands

- `md doctor [--json]` — Inspect project readiness and safe next actions without execution.
- `md init [--guided] [--engine <e>] [--yes] [--agents] [--print-guide]` — Initialize a project flow roster.
- `md create [intent] [--global] [--dry-run]` — Create a flow and a fail-closed draft eval suite.
- `md capture` — Print the guide for capturing the current agent conversation as a flow.
- `md explain <flow.md> [--json]` — Resolve one flow without launching its engine.
- `md render <flow.md> [--json|--out <path>|--open]` — Inspect, write, or open a rendered flow explanation.
- `md hooks add|list|remove <flow.md> [event...]` — Manage executable lifecycle hook sidecars.
- `md eval <flow.md> [--plan] [--yes] [--json]` — Plan or run a flow's behavioral eval suite.
- `md feedback <flow.md> <message> | list|show|distill|dismiss|reopen|forget` — Manage durable evolution evidence.
- `md complain <flow.md> <message>` — Compatibility alias for feedback.
- `md evolve plan|status|propose|show|apply|reject|retry|rollback|history|prune` — Manage proposal-first flow evolution.
- `md install <url|gh:org/repo/path@ref> [--global]` — Install one flow into the registry.
- `md remove <name>` — Remove an installed registry flow.
- `md list [--project|--global]` — List installed registry flows.
- `md roster --json | roster sync [--check] [--agents] [--json]` — Inspect flows or synchronize the managed operator card.
- `md catalog [--json]` — Machine-readable catalog of every discoverable flow (project, global, installed, PATH).
- `md setup` — Configure shell integration.
- `md logs` — Show flow log locations.
- `md help [command]` — Show CLI or command help.

## Keep improvements reviewable

Record a problem with `md feedback <flow.md> "<message>"`, review an eval that can expose it, and inspect `md evolve plan <flow.md>` before approving a proposal. Evolution works off-path. A reviewed proposal changes source only through a separate `md evolve apply <run-id>` decision. Eval-suite presence alone does not prove correctness; proof must be current and bound to the relevant content.

Read [the deep dive](https://mdflow.dev/evolve-deep-dive/) and [the normative evolution specification](https://mdflow.dev/docs/evolve.md).

## Documentation and project information

- [mdflow Evolve — change with proof](https://mdflow.dev/evolve-deep-dive/) — [Markdown](https://mdflow.dev/evolve-deep-dive.md)
- [About mdflow](https://mdflow.dev/about/) — [Markdown](https://mdflow.dev/about.md)
- [Contact and security — mdflow](https://mdflow.dev/contact/) — [Markdown](https://mdflow.dev/contact.md)
- [Privacy — mdflow](https://mdflow.dev/privacy/) — [Markdown](https://mdflow.dev/privacy.md)
- [Documentation and agent interfaces — mdflow](https://mdflow.dev/docs/) — [Markdown](https://mdflow.dev/docs.md)
- [Agent skill](https://mdflow.dev/skills/mdflow/SKILL.md) and [skill SHA-256 index](https://mdflow.dev/.well-known/agent-skills/index.json)
- [Concise resource index](https://mdflow.dev/llms.txt) and [full source documentation](https://mdflow.dev/llms-full.txt)
- [GitHub repository](https://github.com/johnlindquist/mdflow), [issues](https://github.com/johnlindquist/mdflow/issues), and [MIT license](https://github.com/johnlindquist/mdflow/blob/main/LICENSE)
