headcleaner

headcleaner

Enables document conversion to Markdown or OKF format, and provides 14 okf_* tools for OKF bundle operations via MCP.

Category
访问服务器

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 lint reviews 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 --clean runs 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 14 okf_* tools to any MCP agent host (Claude Code, Cursor, etc.) — install with uv pip install "headcleaner[mcp]"
  • Diagnostics: headcleaner doctor checks Python, PATH, OfficeCLI, output permissions, and the @slug registry, then prints a GO/NO-GO verdict
  • Adapter plugins: Third-party packages register formats through the headcleaner_plugin entry-point group
  • zsv CSV: World's-fastest SIMD CSV parser (~10-100x stdlib) when zsv is on PATH
  • Trust attestation: headcleaner attest builds a Merkle root + ed25519 signature; verify checks 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, optional rejection_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 in packaging/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

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选