Skip to content

CLI overview

folio is the primary command-line interface. It is a thin wrapper over the Python SDK, so every verb has a one-to-one SDK equivalent. JSON to stdout, errors to stderr with a non-zero exit code.

Synopsis

folio <verb> [SHEET] [OPTIONS]

SHEET is a path to a sheet directory. Most verbs take it as the first positional argument.

Verbs

VerbWhat it does
folio initScaffold a new sheet directory with starter contract.yaml / records.jsonl / README.md / skills/getting-started.md.
folio validateValidate contract.yaml, records.jsonl, and (optionally) README.md frontmatter.
folio queryRun a DuckDB SELECT against the sheet’s records view.
folio listList records as a paginated JSON envelope (or TOON).
folio countCount records, optionally with a WHERE-clause filter.
folio upsertInsert or update records by primary key.
folio deleteDelete records by primary key id.
folio materializeRun derivations. Returns the §10.6 envelope.
folio statusPer-target counts for derived fields.
folio provenanceLatest entry or full append-only history for one cell.
folio serveStart the Viewer (alias for folio-viewer serve).
folio scriptDiscover and run reusable scripts under sheet/scripts/.
folio skillList, render, and validate packaged procedures under sheet/skills/.
folio exportExport the sheet — datapackage (Frictionless descriptor) or claude-skills (Claude Code-compatible SKILL.md set).

Global behaviour

Output format

Most verbs print machine-readable JSON to stdout. Pipe to jq:

Terminal window
folio query ./customers "SELECT id, country FROM records LIMIT 5" | jq

Exit codes

CodeMeaning
0Success.
1A FolioError (validation, lock timeout, permission denied, …). The error message is on stderr.
2Usage error (Typer rejected the arguments).

Actor

Write verbs (upsert, delete, materialize, script run for write contexts) require --actor. Folio doesn’t default to agent:cli because audit trails should name a real principal.

--help everywhere

Every verb prints a help text with options:

Terminal window
folio --help
folio materialize --help

Examples

Terminal window
# Bootstrap a new sheet
folio init --name my-sheet
folio validate ./my-sheet
# Validate, list, query
folio validate ./customers
folio list ./customers --limit 10
folio query ./customers "SELECT country, COUNT(*) AS n FROM records GROUP BY 1"
# Mutate
echo '{"id":"cust_999","company_name":"X","country":"FR"}' \
| folio upsert ./customers --file - --actor agent:human
folio delete ./customers --ids cust_999 --actor agent:human
# Derive and inspect
folio materialize ./customers --actor agent:demo
folio status ./customers
folio provenance ./customers cust_001 country_code --history
# Run a reusable script (args are positional, passed to the script after the sheet path)
folio script list ./customers
folio script run ./customers country_to_code '{"country":"Japan"}'
# Discover and render a packaged operating procedure
folio skill list ./customers
folio skill show ./customers refresh-country-codes
# Export, serve
folio export datapackage ./customers --stdout > customers.datapackage.json
folio serve ./customers --port 3000 --actor agent:human

Where to next

  • Per-verb pages from the sidebar (validate, query, …).
  • Python SDK overview — every verb’s underlying API.
  • MCP overview — the same SDK exposed as MCP tools.