mdproof runs the commands in your docs, runbooks, and smoke tests, then verifies the result with assertions.
Use one .md file for documentation, operational steps, and CI checks.
Best for README example verification, CLI and API smoke tests, deploy runbooks, and agent-generated workflows.
mdproof executes shell steps from a Markdown file and checks the output with assertions like exit_code, jq, substring matching, regex, and snapshots.
That makes Markdown useful for more than prose:
- Your README examples can become runnable checks.
- Your deploy runbooks can become executable verification steps.
- Your smoke tests can stay readable by humans and writable by agents.
Instead of splitting documentation and tests across different formats, mdproof keeps them in one place.
### Step 1: Create a user
```bash
curl -s -X POST http://localhost:8080/users -d '{"name":"alice"}'
```
Expected:
- jq: .id != null
- jq: .name == "alice"The test is the documentation. When it fails, the error points to the exact step and expectation that broke.
flowchart LR
A["README or runbook in Markdown"] --> B["mdproof runs each shell step"]
B --> C["Assertions verify output and exit status"]
C --> D["Humans and agents fix code or docs from a precise failure"]
- Docs stop drifting: examples in
README.mdordocs/*.mdcan be verified in CI. - Runbooks become safer: the same file an operator reads can be executed during deploy verification.
- Agents fit naturally: agents already write Markdown well, so they can generate or repair tests without learning a test framework API.
- Review stays simple: a Markdown diff is easier to inspect than a custom test harness for many workflow-style checks.
- Failures are traceable: mdproof reports the Markdown file and line that failed, so humans and agents can jump straight to the broken step.
1. Install:
curl -fsSL https://raw.githubusercontent.com/runkids/mdproof/main/install.sh | sh2. Write a test (api-proof.md):
# API Smoke Test
## Steps
### Step 1: Health check
```bash
curl -sf http://localhost:8080/health
```
Expected:
- exit_code: 0
- jq: .status == "ok"
### Step 2: Create item
```bash
curl -s -X POST http://localhost:8080/items \
-H "Content-Type: application/json" \
-d '{"name":"test"}'
```
Expected:
- jq: .id != null
- jq: .name == "test"3. Run it:
mdproof sandbox api-proof.md # auto-provisions a container β api-proof.md
ββββββββββββββββββββββββββββββββββββββββββββββββββ
β Step 1 Health check 52ms
β Step 2 Create item 18ms
ββββββββββββββββββββββββββββββββββββββββββββββββββ
2/2 passed 80ms
When a check fails, mdproof reports where it came from:
β source-aware-assert-proof.md
ββββββββββββββββββββββββββββββββββββββββββββββββββ
β Step 1 Assertion failure 1ms
FAIL runbooks/fixtures/source-aware-assert-proof.md:13 Step 1: Assertion failure
Assertion runbooks/fixtures/source-aware-assert-proof.md:13 expected output
ββ expected: expected output
ββββββββββββββββββββββββββββββββββββββββββββββββββ
0/1 passed 1 failed 1ms
| Use Case | How |
|---|---|
| AI agent test loop | Agent writes .md β mdproof runs β JSON report β agent fixes code β re-run. Never leaves Markdown. |
| CLI tool E2E testing | Build β run β assert output. Especially good for Go/Rust single-binary CLIs. |
| API smoke testing | curl + jq: assertions. No Postman, no SDK. The test IS the docs. |
| Deployment verification | Post-deploy runbook: health checks, DB migration, service connectivity. Ops can read it, CI can run it. |
| README code verification | --inline mode ensures code examples in docs never go stale. |
Not a fit for: unit tests (use go test/pytest), browser UI (Playwright), perf benchmarks, or complex programmatic fixtures.
|
For AI Agents
|
For Humans
|
curl -fsSL https://raw.githubusercontent.com/runkids/mdproof/main/install.sh | shirm https://raw.githubusercontent.com/runkids/mdproof/main/install.ps1 | iexbrew install runkids/tap/mdproofTip: Run
mdproof upgradeto update to the latest version. It auto-detects your platform and handles the rest.
go install github.com/runkids/mdproof/cmd/mdproof@latestA runbook is a standard Markdown file with step headings, bash code blocks, and Expected: assertions.
# Deploy Verification
## Steps
### Step 1: Check health
```bash
curl -sf http://localhost:8080/health
```
Expected:
- exit_code: 0
- jq: .status == "ok"
### Step 2: Create resource
```bash
curl -s -X POST http://localhost:8080/items \
-d '{"name":"test"}'
```
Expected:
- jq: .id != null
- Should NOT contain error| Type | Syntax | Example |
|---|---|---|
| Substring | plain text | - hello world |
| Negated | No/Should NOT prefix |
- Should NOT contain error |
| Exit code | exit_code: N |
- exit_code: 0 |
| Regex | regex: prefix |
- regex: v\d+\.\d+ |
| jq | jq: prefix |
- jq: .status == "ok" |
| Snapshot | snapshot: prefix |
- snapshot: api-response |
No Expected: section β exit code decides (0 = pass).
- Persistent session β all steps share one bash process;
exportvars persist across steps and---sub-commands - Container-first β strict mode (default) refuses to run outside containers; use
mdproof sandboxor--strict=false - Hooks β
--build(once),--setup/--teardown(per runbook),-step-setup/-step-teardown(per step) - Directives β
<!-- runbook: timeout=30s retry=3 depends=2 -->for per-step control - Sub-commands β
---separator splits a code block into independent subshells with shared env - Isolation β
--isolation per-runbookgives each runbook a fresh$HOMEand$TMPDIR - Step filtering β
--steps 1,3,5or--from Nto run a subset;--fail-fastto stop early - Coverage β
--coveragereports assertion coverage;--coverage-min Nfor CI gating - Inline testing β
--inlineextracts<!-- mdproof:start/end -->blocks from any.md - Source-aware failures β failed assertions, command exits, and parser errors point back to Markdown file + line
- Snapshots β
snapshot:assertions with-uto update
| Writing Runbooks | Full assertion reference, directives, inline testing, persistent sessions, source tracking |
| CLI Reference | All flags, subcommands, sandbox mode, usage examples, failure output |
| Advanced Features | Hooks, configuration, reports, coverage, CI integration, architecture |
mdproof ships with skills/SKILL.md β install it once, and your AI agent knows the full syntax.
# Claude Code (via https://github.com/runkids/skillshare)
skillshare install runkids/mdproof
# Manual: copy skills/SKILL.md to your agent's skill directoryMIT

