headcleaner
Enables document conversion to Markdown or OKF format, and provides 14 okf_* tools for OKF bundle operations via MCP.
README
headcleaner
Walk a folder, convert every document to Markdown (with frontmatter), OKF v0.2 (with frontmatter), or both — with an omp-style animated TUI.
headcleaner convert ~/Documents/inbox --format both --output ~/Documents/inbox.clean
headcleaner is a Python CLI that scans a directory you provide, identifies each document by extension, runs the appropriate extraction engine (OfficeCLI for Office formats, pdfplumber for PDFs, BeautifulSoup for HTML, etc.), and emits clean normalized output — either side-by-side Markdown and OKF, or just one.
- Output formats:
--format md(Markdown),--format okf(OKF v0.2 bundle),--format both(default) - Engine coverage: 7 formats out of the box (XLSX, DOCX, PPTX, PDF, HTML, HTM, TXT) — see docs/FORMAT_MATRIX.md for the 16-format v1.0 roadmap
- TUI: omp-inspired animated terminal (box-drawing panels, neon palette, powerline separators)
- Linter:
headcleaner lintreviews the converted Markdown / OKF for formatting issues - Per-message PST: one OKF concept per email (via readpst) so review/sign-off works file-by-file
- office_oxide backend: Pure-Rust Python bindings for Office formats (~100x faster than OfficeCLI)
- Heuristic cleanup:
headcleaner convert --cleanruns a 12-stage any2md-inspired cleanup pipeline - all2md fallback: Auto-handles 38 extra formats (Jupyter, LaTeX, reST, sourcecode, etc.) when all2md is installed
headcleaner mcp: Run headcleaner as an MCP server exposing 14okf_*tools to any MCP agent host (Claude Code, Cursor, etc.) — install withuv pip install "headcleaner[mcp]"- Diagnostics:
headcleaner doctorchecks Python, PATH, OfficeCLI, output permissions, and the@slugregistry, then prints a GO/NO-GO verdict - Adapter plugins: Third-party packages register formats through the
headcleaner_pluginentry-point group - zsv CSV: World's-fastest SIMD CSV parser (~10-100x stdlib) when
zsvis on PATH - Trust attestation:
headcleaner attestbuilds a Merkle root + ed25519 signature;verifychecks it - Local browse:
headcleaner serve <bundle>exposes a FastAPI UI for browsing + search - Honest defaults: OKF trust fields filled with
unverified/human:pending, never invented
Install
# 1. The Office engine — single binary, no Office install needed
npm install -g @officecli/officecli
# 2. The CLI itself (Python ≥3.12, uv-managed)
uv tool install headcleaner
# Or for development:
git clone <this repo>
cd headcleaner-cli
uv sync
uv run headcleaner --help
For other install methods (curl | bash, pip, brew, Windows PowerShell), see docs/INSTALL.md.
Quick start
headcleaner ~/Documents/inbox --format both --output ./clean
This produces:
clean/
├── manifest.json # run summary: per-file status, engine, sha256
├── REPORT.md # count, average time, and error rate by engine
├── _md/ # plain Markdown (one file per source)
│ ├── notes.docx.md
│ ├── q3.pdf.md
│ └── ...
└── okf/ # OKF v0.2 bundle (one concept per source)
├── index.md # auto-generated directory index
├── notes.md # OKF concept: type=Document
├── q3.pdf.md
└── ...
CLI reference
headcleaner convert <INPUT_DIR> [OPTIONS]
Options:
-f, --format {md,okf,both} Output format(s) [default: both]
-o, --output DIR Output directory [default: ./out]
--ocr Enable Tesseract OCR for scanned PDFs
--officecli-timeout <secs> Timeout per OfficeCLI subprocess call (default: 60)
--include, -i GLOB Include glob (may be repeated)
--exclude, -e GLOB Exclude glob (may be repeated)
--jobs, -j N Parallel worker processes (default: 1 = sequential)
--no-cache Re-convert every file (skip the SHA-256 cache)
--no-continue-on-error Stop on the first failure
--obsidian-compat Add Obsidian-friendly flat fields to OKF frontmatter
--clean Run the 12-stage heuristic cleanup pipeline (any2md-inspired) on each body
--tui / --no-tui Force / disable the animated TUI (default: auto-detect TTY)
--no-okf-index Skip OKF directory index.md generation
Other commands: headcleaner doctor [--output-dir DIR] Run install and permission diagnostics headcleaner templates List supported formats headcleaner agents Show engine install status headcleaner watch IN [--webhook-url URL] Re-convert on file changes (Ctrl+C to stop) headcleaner lint <DIR> Review converted Markdown / OKF for formatting issues headcleaner lint <DIR> --fix Auto-repair safe issues to <DIR>.fixed/ headcleaner serve <DIR> Local HTTP browser for the OKF bundle headcleaner notion-import <EXPORT.zip> <OUT> Reverse a Notion workspace export headcleaner attest <DIR> Compute Merkle root + optional ed25519 signature headcleaner verify <DIR> Verify an attestation against the bundle
## Why OKF?
OKF (Open Knowledge Format, v0.2) is just **markdown + YAML frontmatter in a directory hierarchy**. That means:
- Every concept is a single `.md` file you can `cat`, `grep`, edit in any text editor
- Bundles live in git — pull requests, diffs, blame all work
- Obsidian, Notion, MkDocs, Hugo, Jekyll all consume OKF natively
- Required frontmatter key is just `type` — anything beyond that is producer freedom
See [docs/OKF_NOTES.md](docs/OKF_NOTES.md) for the OKF v0.2 specifics this CLI emits.
## Trust stance (honest defaults)
We never auto-claim review. Every emitted OKF concept gets:
- `status: unverified`
- `verified: human:pending`
- `generated: human:<user>@<host>` (OKF §7 actor convention)
- `stale_after: <today + 180d>`
- `sources: [{uri: file://..., sha256: ...}]`
A human can grep `human:pending` later to find concepts needing review. See [docs/OKF_NOTES.md](docs/OKF_NOTES.md) for the full contract.
## Supported formats
See [docs/FORMAT_MATRIX.md](docs/FORMAT_MATRIX.md) for the full engine × library table. At a glance:
| Format | Engine | Library |
|---|---|---|
| `.docx`, `.xlsx`, `.pptx` | OfficeCLI binary | (native DOM) |
| `.pdf` | pdfplumber (text-layer), pytesseract if `--ocr` | pdfplumber / pytesseract |
| `.html`, `.htm` | BeautifulSoup | beautifulsoup4 |
| `.txt` | chardet + read | chardet |
| `.md`, `.markdown` | pass-through + frontmatter inject | stdlib |
| `.csv`, `.tsv` | Sniffer dialect + GFM table (zsv SIMD when installed) | stdlib `csv` (or `zsv` binary) |
| `.json` | pretty-print + fenced block | stdlib `json` |
| `.eml` | headers + text/html body + attachments | stdlib `email` |
| `.epub` | per-chapter HTML → MD | ebooklib (+ bs4 fallback) |
| `.rtf` | control-word stripping | striprtf (+ regex fallback) |
| `.odt`, `.ods`, `.odp` | paragraph/row extraction + GFM tables | odfpy (+ raw-XML fallback) |
| `.msg` | Outlook headers + body + attachments | extract-msg |
| `.pst` | **per-message** (one OKF concept per email) | readpst (libpst) + libpff-python fallback |
| `.docx`, `.xlsx`, `.pptx` | **office_oxide** (primary, ~100x faster), OfficeCLI binary (fallback) | office_oxide 0.1.8 (PyO3) |
| `.ipynb`, `.latex`, `.rst`, sourcecode, `.enex`, `.chm`, etc. (38 formats) | all2md (when installed) | all2md 1.12 |
| `.doc`, `.xls`, `.ppt` | clear error path | needs `libreoffice --convert-to` first |
## Live mode
```bash
headcleaner watch ~/inbox --output ~/out --webhook-url https://hooks.slack.com/...
Re-runs the conversion automatically when files change under ~/inbox.
Each re-run POSTs the manifest to the webhook URL (optional). Press
Ctrl+C to stop.
Obsidian vault sync
headcleaner convert ~/inbox --format okf \
--output ~/Documents/MyVault/Concepts \
--obsidian-compat
Adds Obsidian-friendly flat fields (source, sha256, generated_by,
verified_by, stale_on) to the OKF frontmatter so the concept shows
up correctly in Obsidian's property panel. Original OKF fields stay
intact for round-tripping.
Review (human sign-off)
Auto-conversion sets verified: human:pending. The headcleaner review
TUI walks every pending concept in a bundle and lets a human flip each
to:
- approved →
verified: human:reviewed,status: verified,reviewed_at,reviewed_by,reviewed_via - rejected →
verified: human:rejected,status: rejected, optionalrejection_reasons[] - skipped → leaves the concept as
pending
headcleaner review ./out/okf
# Textual TUI: a=approve, r=reject, s=skip, n=next, p=prev, q=quit
If Textual isn't available (e.g. headless CI), a plain-mode REPL falls back automatically.
Distribution
- PyPI:
pip install headcleaner(built via uv, published via OIDC trusted publishing on tag push) - Homebrew:
brew install headcleaner(formula inpackaging/homebrew/) - Docker:
docker pull ghcr.io/local/headcleaner(multi-stage image with tesseract) - Windows:
winget install headcleaner,scoop install headcleaner,choco install headcleaner - Static binary:
pip install pyinstaller && pyinstaller packaging/pyinstaller/headcleaner.spec
Full release checklist in RELEASE.md.
CLI surface
headcleaner view <bundle> (add --tui to browse in the terminal) renders an OKF bundle as a single self-contained HTML graph (no backend, opens in any browser). See docs/VIEWER.md for full options.
headcleaner convert IN_DIR [flags] # walk + convert
headcleaner watch IN_DIR [flags] # live mode + webhooks
headcleaner review BUNDLE # human sign-off TUI/REPL
headcleaner attest BUNDLE [--private-key PEM] # Merkle root + optional ed25519 sig
headcleaner verify BUNDLE [--public-key PEM] # verify an attestation
headcleaner serve BUNDLE [--host] [--port] # local HTTP browser for the bundle
headcleaner glob DIR # interactive include REPL (Textual)
headcleaner notion-import EXPORT.zip OUT # reverse a Notion workspace export
headcleaner lint DIR [--fix] # OKF + MD rule checks
headcleaner doctor [--output-dir] # dependency and permission preflight
headcleaner agents [stdout] # emit AGENTS.md
headcleaner templates # list supported formats
Documentation
| Document | Purpose |
|---|---|
| README.md | this file — install, quick start, CLI reference |
| docs/INSTALL.md | all install paths (curl, pip, brew, PowerShell, uv, Docker) |
| docs/USAGE.md | detailed usage guide with worked examples |
| docs/ARCHITECTURE.md | how the pipeline fits together, where to extend |
| docs/FORMAT_MATRIX.md | every supported format × engine × library |
| docs/OKF_NOTES.md | OKF v0.2 contract this CLI emits + trust policy |
| docs/SCHEMA.md | OKF frontmatter JSON Schema and editor/CI integration |
| docs/PLUGINS.md | third-party adapter entry-point protocol |
| docs/TROUBLESHOOTING.md | common errors and fixes |
| docs/FAQ.md | frequently asked questions |
| docs/CONTRIBUTING.md | how to add a new format / engine / emitter |
| docs/CHANGELOG.md | release history |
| docs/ENHANCEMENTS.md | 44+ shipped enhancements + future ideas |
| vscode-extension/README.md | HeadCleaner VS Code extension (Concept Explorer + Trust Inspector) |
Troubleshooting
officecli not found — install with npm install -g @officecli/officecli. Run headcleaner agents to verify.
PDF with no extractable text — your PDF is image-only. Re-run with --ocr (requires pytesseract + Tesseract binary on PATH).
Hidden files skipped — intentional. Files starting with . are dropped by the walker.
OKF index.md missing for root — auto-generated when the bundle has ≥1 concept. Use --no-okf-index to opt out.
More — see docs/TROUBLESHOOTING.md.
Development
git clone <this repo>
cd headcleaner-cli
uv sync
uv run pytest # 314 tests, ~14s
uv run headcleaner convert ./tests/fixtures --format both --output ./out
Architecture
src/headcleaner/
├── walk.py # recursive folder walker
├── router.py # extension → engine dispatch
├── normalize.py # CanonicalDoc + OKF/MD frontmatter builders
├── lint.py # post-conversion linter (OKF + Markdown)
├── run.py # pipeline orchestrator
├── cli.py # Click CLI (headcleaner command)
├── tui.py # Textual TUI (omp-style)
├── engines/
│ ├── base.py # Adapter ABC
│ ├── officecli.py
│ ├── pdf.py
│ ├── html.py
│ └── txt.py
└── emit/
├── markdown.py
├── okf.py
├── okf_index.py
└── manifest.py
Adding a new format: drop a module in engines/, register the adapter in router.py, add a row to docs/FORMAT_MATRIX.md. See docs/CONTRIBUTING.md for the full extension guide.
License
Apache-2.0
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。