On this page
CLI reference
CLI reference
CLI reference
One page, every command. New here? Start with the quickstart to learn by doing — this page is the cheat sheet you keep open afterwards.
All examples assume a bundle at ./kb created with init (paths like kb and big.md come straight from verified runs — adapt them to your own files).
Global flags
These work on every command, including with no subcommand:
| Flag | What it does |
|---|---|
--help | Show help for the CLI or a specific command (okfsmith ingest --help). |
--version | Print the version (e.g. 0.3.0) and exit. |
--format json | Where supported (list, read, validate, graph, sync): emit machine-readable JSON instead of rich text. |
--no-llm | Where supported (ingest, sync, chat): run fully deterministic, no LLM involved. |
--install-completion | Install shell completion for the current shell. |
--show-completion | Print the completion script instead of installing it. |
okfsmith init
Create a new, empty OKF bundle in BUNDLE.
okfsmith init [OPTIONS] {bundle}
okfsmith init ./kb
Real output — init scaffolds exactly two files, index.md and log.md, nothing else:
Initialized OKF bundle in kb
index: /path/to/kb/index.md
log: /path/to/kb/log.md
Next: add sources with 'okfsmith ingest kb <file-or-dir> --no-llm'.
Common options
| Flag | What it does |
|---|---|
--force | Scaffold even if the bundle exists and is non-empty (asks for confirmation). |
--yes, -y | Answer "yes" to the --force prompt — for non-interactive use. |
okfsmith ingest
Ingest documents into BUNDLE as draft concepts.
okfsmith ingest [OPTIONS] {bundle} {sources}...
# Deterministic, no-LLM path — the recommended first run
okfsmith ingest ./kb big.md --no-llm
# Ingest a whole directory tree
okfsmith ingest ./kb ./docs --recursive --no-llm
Real output (the table and summary line are exactly what you see):
Ingest summary — sectioning (no LLM)
┏━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━┓
┃ File ┃ SHA-256 ┃ Concepts ┃ Status ┃
┡━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━┩
│ big.md │ 34a0dca378f8 │ 18 │ ok │
└────────┴──────────────┴━━━━━━━━━━┴━━━━━━━━┘
ingested 18 concept(s) from 1 file(s) into kb
Common options
| Flag | What it does |
|---|---|
--no-llm | Deterministic sectioning, no LLM needed. Start here. |
--dry-run | Parse and plan only — write nothing. |
--quiet, -q | Only warnings, errors, and the final summary line. |
--recursive | Recurse into subdirectories when a SOURCE is a directory. |
--provider, --model, --api-base, --api-key | LLM extraction settings (default path when --no-llm is not passed). See Providers & API keys. |
Advanced
- Re-ingesting the same file is deduplicated via per-file SHA-256 (manifest-tracked). - `--no-llm` files below ~1000 characters are **skipped** with `skipped (below 1000-char minimum; stub prevention)` — tiny files are never ingested. - Without `--no-llm`, `ingest` calls an LLM; if none is reachable it **errors** — there is no silent fallback. See [Ingesting documents](ingesting.html) and [Troubleshooting](troubleshooting.html) (`llm-unavailable`). - `--model` cannot be combined with `--no-llm`.okfsmith sync
Incrementally sync a bundle with its source documents — only new, changed, renamed, or deleted files are processed. This is the command to reach for when your sources keep changing: run it after every edit instead of re-ingesting everything.
okfsmith sync [OPTIONS] {bundle} {sources}...
# One-shot: ingest what's new, update what's changed, drop what's deleted
okfsmith sync ./kb ./docs --no-llm
# Keep watching: re-sync whenever sources change (Ctrl-C stops)
okfsmith sync ./kb ./docs --no-llm --watch --interval 10
# Preview without writing anything
okfsmith sync ./kb ./docs --no-llm --dry-run
Real output (the table and summary line are exactly what you see):
Sync summary — kb
┏━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ File ┃ Change ┃ Concepts ┃ Detail ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ src/guide.md │ added │ 1 │ 1 concept(s) │
│ src/notes.md │ added │ 1 │ 1 concept(s) │
└──────────────┴────────┴──────────┴──────────────┘
sync: 2 added, 0 updated, 0 renamed, 0 removed, 0 unchanged, 0 skipped, 0 failed → kb
How it works
Each source file is fingerprinted with SHA-256 and recorded in <bundle>/.okfsmith/sync-state.json. On every run, sync diffs the live files against that state and classifies each file:
| Change | What happens |
|---|---|
added | Ingested (LLM or --no-llm path, same as ingest). |
updated | Old concepts are replaced — re-ingested under the same ids, never duplicated as name-2. |
renamed | Detected by identical content hash; concepts keep their ids and history, only the resource provenance is updated. |
removed | Concepts are deleted from the bundle. |
unchanged | Skipped entirely — no parsing, no LLM calls. |
Additions are applied before deletions, so a rename or replace can never leave the bundle momentarily empty. Writes are atomic and resumable: if a sync is interrupted (Ctrl-C, power loss), the state is marked incomplete and the next run picks up where it stopped — already-ingested concepts are adopted, never duplicated.
A few safety rules worth knowing:
- Pre-flight on updates. If a changed file's new content would be skipped (unparseable, below the ~1000-char minimum, sectioning fails), the old concepts are kept instead of being wiped — you get a
skippedrow, not data loss. - Shared content is reference-counted. Two identical files share one set of concepts; deleting one source only drops the concepts when the last file with that content is gone.
- Deletions are scoped.
sync ./kb ./docsonly ever removes concepts that came from./docs— other source trees are untouched. - Unreadable files fail per-file (
failedrow) instead of aborting the whole run.
See Syncing sources for the full guide, including --watch mode, --format json for scripts, and the state-file format.
okfsmith list
List concepts in the bundle: id, type, title, trust tier, temporal validity.
okfsmith list [OPTIONS] {bundle}
okfsmith list ./kb
# JSON output only, for scripts
okfsmith list ./kb --format json | jq '.concepts[].id'
# Only human-reviewed concepts
okfsmith list ./kb --tier human-reviewed
Real output (trimmed — the real table had 18 rows):
Concepts in kb
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━┓
┃ ID ┃ Type ┃ Title ┃ Trust tier ┃ Valid ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━┩
│ big/first-bundle │ Draft │ First Bundle │ unverified │ — │
│ big/installation │ Draft │ Installation │ unverified │ — │
│ big/trust-tiers │ Draft │ Trust Tiers │ unverified │ — │
│ ... │ ... │ ... │ ... │ ... │
└────────────────────┴───────┴──────────────┴────────────┴───────┘
18 concept(s)
The Valid column shows the temporal status: — for concepts with no temporal fields, current / expired / future / superseded otherwise (see Temporal model). JSON output adds temporal_status per concept.
Common options
| Flag | What it does | |
|---|---|---|
| `--format <text\ | json>` | Output format (default text). |
--type <str> | Only concepts of this type. | |
--tier <str> | Only this trust tier: unverified, machine-confirmed, human-reviewed. |
Advanced
- `--no-llm` ingested concepts are `type: Draft`, tier `unverified`. - Concept ids look like `okfsmith read
Print a concept: frontmatter as YAML, then the body.
okfsmith read [OPTIONS] {bundle} {concept_id}
okfsmith read ./kb big/first-bundle
okfsmith read ./kb big/first-bundle --format json
Real output (frontmatter, then body):
---
type: Draft
title: First Bundle
description: Draft concept extracted without LLM; needs review
resource: big.md
generated:
by: okfsmith/0.3.0
at: '2026-09-26T12:18:20.100846+00:00'
status: draft
tags:
- draft
- no-llm
---
Run `okfsmith init ./kb` to create a new bundle, then ingest documents.
When a concept carries temporal frontmatter (or is superseded by another concept), text output appends a one-line badge such as [temporal: superseded by policy/refunds-v2] or [temporal: expired (valid_until 2025-06-30 has passed)]; plain current concepts print exactly as before. JSON output adds temporal_status.
Common options
| Flag | What it does | |
|---|---|---|
| `--format <text\ | json>` | Output format (default text). |
Advanced
- Unknown concept ids produce an error — `read` never fabricates a concept.okfsmith search
Full-text search over a bundle: id, title, description, tags, and body, ranked with BM25 (stdlib-only, no new dependencies). The same engine powers the MCP server's search tool and chat's /search, so all three rank identically. See Searching a bundle for the query syntax (phrases, exclusions, stemming) and scoring details.
okfsmith search [OPTIONS] {bundle} {query}
okfsmith search ./kb "knowledge graph"
okfsmith search ./kb "quarterly revenue" --tier human-reviewed -n 5
okfsmith search ./kb "api design" --format json
# Replay the search as of a past instant (validity + supersession at that time)
okfsmith search ./kb "refund policy" --as-of 2025-06-01
# Also show superseded concepts (hidden by default, never deleted)
okfsmith search ./kb "refund policy" --include-superseded
Results print as a Score | ID | Type | Title | Tier | Valid table (IDs never truncated) plus an N result(s) line; zero results exit 0 with 0 result(s) and a stderr hint. An empty query is a usage error (exit 2).
Retrieval is conflict-aware (see Temporal model): current concepts rank first, concepts outside their validity window are demoted but still shown (marked expired / future), and superseded concepts are hidden unless --include-superseded is given (shown last, marked superseded→<id>). JSON rows carry temporal_status and superseded_by; the envelope adds as_of (the instant evaluated) and superseded_hidden (how many superseded results were filtered out).
Common options
| Flag | What it does | |
|---|---|---|
--limit <n> / -n | Maximum results (default 10, must be ≥ 1). | |
| `--format <text\ | json>` | Output format (default text). |
--type <str> | Only concepts of this type. | |
--tier <str> | Only this trust tier: unverified, machine-confirmed, human-reviewed. | |
| `--as-of <date\ | datetime>` | Replay search at an ISO-8601 instant: validity windows and supersession chains are evaluated then, not now. |
--include-superseded | Also show superseded concepts (demoted, ranked last). |
okfsmith validate
Validate a bundle against OKF v0.2 (E001–E004 / W001–W020).
okfsmith validate [OPTIONS] {bundle}
okfsmith validate ./kb
# Treat warnings as failures (exit code != 0 if any warning exists)
okfsmith validate ./kb --strict
# Machine-readable, for CI
okfsmith validate ./kb --format json
Real output — a conformant bundle exits with code 0 (verified with --strict too):
Errors (0)
┏━━━━━━┳━━━━━━┳━━━━━━━━━┓
┃ Code ┃ File ┃ Message ┃
┡━━━━━━╇━━━━━━╇━━━━━━━━━┩
└──────┴──────┴━━━━━━━━━┘
Warnings (0)
┏━━━━━━┳━━━━━━┳━━━━━━━━━┓
┃ Code ┃ File ┃ Message ┃
┡━━━━━━╇━━━━━━╇━━━━━━━━━┩
└──────┴──────┴━━━━━━━━━┘
Conformant: no errors, no warnings.
Common options
| Flag | What it does | |
|---|---|---|
| `--format <text\ | json>` | Output format (default text). |
--strict | Treat warnings as failures. |
okfsmith graph
Show the concept link graph (nodes, edges, orphans, dead links).
okfsmith graph [OPTIONS] {bundle}
okfsmith graph ./kb
# Interactive viewer — writes <bundle>/viz.html by default
okfsmith graph ./kb --format html
# Mermaid diagram to stdout
okfsmith graph ./kb --format mermaid
Real output:
18 concept(s), 0 link(s), 0 dead link(s).
Orphans (0):
(none)
Dead links (0):
(none)
Common options
| Flag | What it does | |||
|---|---|---|---|---|
| `--format <text\ | json\ | mermaid\ | html>` | Output format (default text). html writes an interactive visualization — colorblind-safe palette, backlinks, search. |
--output <path> | Write to a file instead of stdout. |
Advanced
- Default HTML output lands at `okfsmith doctor
Check the environment: dependencies, extras, Ollama, writability.
okfsmith doctor
That's it — doctor takes no arguments, just run it whenever something looks wrong.
Real output (this machine: no Ollama, no mcp/ocr extras — trimmed):
okfsmith doctor
┏━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Check ┃ Status ┃ Detail ┃
┡━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ python >= 3.10 │ OK │ 3.12.3 │
│ okfsmith │ OK │ 0.3.0 │
│ extra: mcp │ MISSING │ Install the 'mcp' extra: pip install │
│ │ │ 'okfsmith[mcp]' ... │
│ extra: ocr │ MISSING │ Install the 'ocr' extra: pip install │
│ │ │ 'okfsmith[ocr]' ... │
│ ollama │ WARN │ not reachable at http://localhost:11434 — use │
│ │ │ --no-llm or set OPENAI_API_KEY │
│ llm api key │ OK │ set (hidden) (via OKFSMITH_API_KEY) │
│ tmp writable │ OK │ /tmp │
└────────────────┴━━━━━━━━━┴━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┘
doctor takes no options other than --help. If anything here looks wrong, head to Troubleshooting.
okfsmith chat
Chat with a bundle in natural language (Claude Code / Gemini CLI style).
okfsmith chat [OPTIONS] [bundle]
The bundle is optional — if you omit it, the current directory is used (when it is a bundle).
# Extractive mode: keyword-matched answers, zero setup, no LLM
okfsmith chat ./kb --no-llm
# Generative answers via a hosted provider preset (needs OKFSMITH_API_KEY set)
okfsmith chat ./kb --provider openrouter --model anthropic/claude-sonnet-4
# Non-interactive: pipe slash commands
printf '/list\n/exit\n' | okfsmith chat ./kb
Real startup banner (ASCII logo first, then the version line):
███ █ █ █████ ████ █ █ █████ █████ █ █
█ █ █ █ █ █ ██ ██ █ █ █ █
█ █ ███ ████ ███ █ █ █ █ █ █████
█ █ █ █ █ █ █ █ █ █ █ █
███ █ █ █ ████ █ █ █████ █ █ █
okfsmith chat v0.3.0
Bundle: kb (18 concepts) · extractive mode
Extractive mode — no LLM reachable. Answers are keyword-matched excerpts. Start
Ollama, set OKFSMITH_API_KEY + OKFSMITH_PROVIDER, or pass --provider, for
generative answers.
Tips for getting started:
1. Ask questions about your documents.
2. Type /help for chat commands.
3. Type /ingest <path> to add more documents.
kb ›
Common options
| Flag | What it does |
|---|---|
--no-llm | Extractive mode: keyword-matched excerpts, no LLM involved. |
--provider <str> | Hosted provider preset (15 presets: ollama, lmstudio, openai, groq, mistral, deepseek, openrouter, together, fireworks, deepinfra, anyscale, perplexity, xai, gemini, agentrouter). |
--model <str> | Model id for generative answers. |
--api-base <url> | Any OpenAI-compatible endpoint (overrides --provider). |
--api-key <str> | API key — prefer OKFSMITH_API_KEY, since --api-key lands in shell history. |
Full REPL walkthrough on Interactive chat; providers and keys on Providers & API keys.
okfsmith mcp
Serve the bundle over MCP (Model Context Protocol) so agents can read it.
okfsmith mcp [OPTIONS] {bundle}
# Default stdio transport — for Claude Code / Desktop config
okfsmith mcp ./kb
# Server-sent events
okfsmith mcp ./kb --transport sse
# Streamable HTTP
okfsmith mcp ./kb --transport streamable-http
Requires the optional extra (flagged MISSING by doctor):
pip install "okfsmith[mcp]"
Without the extra, the command tells you exactly what to do:
error [missing-extra]: The MCP server requires the 'mcp' extra: install it with `pip install "okfsmith[mcp]"`.
hint: Install it with: pip install "okfsmith[mcp]" (or pipx: pipx install "okfsmith[mcp]", or uvx: uvx --with "okfsmith[mcp]" okfsmith mcp ./kb)
Common options
| Flag | What it does | ||
|---|---|---|---|
| `--transport <stdio\ | sse\ | streamable-http>` | Transport (default stdio). |
The server exposes eight MCP tools — index, list, search, get, neighbors, traverse, provenance, diff. These are tools for connected agents; search is also a CLI command (okfsmith search), while get remains MCP-only (the CLI analogue is read). Client config examples for Claude Code/Desktop, Cursor, Copilot, and Gemini are on MCP server.
okfsmith eval
Score a bundle against a golden Q&A set — the RAG Triad, per question, with retrieval-vs-generation diagnosis for every failure.
okfsmith eval ./kb --init-sample
okfsmith eval ./kb --no-llm
okfsmith eval ./kb --format json
okfsmith eval ./kb --fail-under 70
| Flag | What it does | |
|---|---|---|
--init-sample | Write a starter <bundle>/eval/golden.json from the bundle's own concepts, then exit. | |
--top-k / -n | Concepts retrieved per question (default 5). | |
--fail-under <0-100> | CI gate: exit 1 when the overall score misses it (exit 0 = pass). | |
--metric-threshold <0-1> | Per-metric pass bar (default 0.6 context relevancy / faithfulness, 0.4 answer relevancy). | |
--no-llm | Force heuristic scoring even when a provider is configured. | |
--model / --provider / --api-base / --api-key | LLM judge backend (same plumbing as chat). | |
--as-of <date> | Replay retrieval at a past/future instant. | |
--include-superseded | Also retrieve superseded concepts. | |
| `--format text\ | json` | Human table + diagnosis, or the full machine-readable report. |
The report scores each question per metric with 🤖 (llm-judge) or ⚙ (heuristic) markers, then prints the diagnosis for every failing question. Malformed golden files fail as error [golden-invalid] / error [golden-schema] — never a traceback. Full guide on Evaluating bundles.
Exit codes
| Exit | Meaning |
|---|---|
0 | Success — validate prints Conformant: no errors, no warnings. |
1 | Validation failed (errors, or warnings under --strict); or a general command error. |
2 | CLI usage error — e.g. No such command for okfsmith get. |
Next: MCP server → — bundle built, now serve it to agents.