craft-cli: a Craft Docs CLI made for AI agents
Open-sourcing craft-cli - a Bun-compiled CLI that makes a Craft Docs vault as easy for an AI agent to read and edit as a local markdown folder.
It is a Bun-compiled single binary, built first and foremost for AI coding agents. The goal is to make a Craft Docs vault as pleasant to read and edit from Claude Code, Codex, or OpenCode as a local markdown folder is from inside Obsidian - not to replace the Craft UI for humans. Every design choice below follows from that goal.
Why agents need their own CLI
Craft has a solid REST API, but agents do not think in HTTP round-trips. A single document read can take up to 4.5 seconds over the wire. A ten-step workflow that searches the vault, reads a few notes, patches a block, and verifies the result will burn 25 seconds of wall-clock time before the model even starts reasoning. For a human in the Craft app that latency is invisible. For an agent planning its next move, it is the difference between “works” and “unusable”.
The problem is the mismatch between how agents plan work and how remote calls amortize. craft-cli exists to collapse that gap.
Hybrid mode, in one sentence
Read as much as possible from the local database. Write through the API to keep things consistent and standardized.
That is the whole architecture.
Reads go through Craft’s on-disk stores: the SQLite FTS5 index and the per-document PlainTextSearch JSON files that the Craft desktop app maintains for its own in-app search. These are the same data structures that make search instant inside Craft. The CLI queries them directly, which is how a vault search drops from 2,271 ms over the REST API to 1.3 ms locally.
Writes go through the REST API. The API is the only authoritative source for block hierarchy and the only path that triggers cross-device sync. Writing through it keeps the vault consistent between devices and keeps the local stores correct - Craft regenerates them within about one second of any mutation.
There is no mirroring layer, no cache to invalidate, no staleness to manage. The local stores are always fresh because Craft itself keeps them fresh.
* Hybrid mode assumes the Craft desktop app is installed and running, because it is the process that keeps the local stores in sync. On Linux, headless servers, or any host without the app, use API-only mode (next section).
API-only mode: opinionated agentic wrapper
When the local stores are not available, craft-cli runs in API-only mode. But it is not a thin passthrough - it is an opinionated layer on top of the REST API, shaped specifically for what agents need when they are reasoning about a knowledge vault.
Examples of the kinds of opinions baked in:
- Backlink extraction on retrieval. The Craft REST API does not expose backlinks. craft-cli reconstructs them on every document fetch via title-based search plus
block://URI filtering. For an agent traversing a vault, this turns a single document read into a context-rich view of where the doc is referenced - exactly the kind of adjacency signal that lets a model decide what to load next. - Hybrid search defaults. craft-cli defaults to
regexpsmode for document search (RE2) and works around the API’s silent-drop behavior on short underscored tokens. Agents can rely on the results being faithful to the query. - Unified write path with an undo net. Every write goes through a mutation journal at
~/.cache/craft-cli/journal.db, recording the block tree before and after.craft undo,craft diff, andcraft logwork against it. A misstep is recoverable without asking the user to restore from a backup. craft patch- a find-and-replace that operates at block granularity, intentionally mirroring the editing semantics of Claude Code’sEdittool. Agents already know this shape.- Compact output. Every command supports
--jsonand a dense default format. The CLI is built to consume little of the model’s context window.
API-only mode also works as a drop-in mode on macOS if you do not want local-store reads for some reason: craft mode api persists it, CRAFT_MODE=api overrides per process, --api per command.
Speed
Benchmarks on my personal vault of ~1,200 documents and ~46,000 blocks:
| Operation | REST API | craft-cli (local) | Speedup |
|---|---|---|---|
| Search vault for a term | 2,271 ms | 1.3 ms | 1,700x |
| Read document content | 4,561 ms | 0.7 ms | 6,300x |
| Check if doc changed | 3,247 ms | 0.5 ms | 6,600x |
| List all documents | 1,489 ms | 184 ms | 8x |
Average speedup across read operations lands around 3,600x. Reads that used to cost a full context window’s worth of latency are now effectively free.
Quick start
git clone https://github.com/pa1ar/craft-cli.git ~/dev/craft-cli
cd ~/dev/craft-cli && ./install.sh
craft setup --url "https://connect.craft.do/links/.../api/v1" --key "pdk_..."
craft whoami
craft docs search "LTM|memory"
On Linux or any host without the Craft desktop app, run craft mode api once to persist API-only mode. The journal still works - it lives in ~/.cache/craft-cli/journal.db and is cross-platform.
Notes
This is a personal tool, published as-is. I am not affiliated with Craft and do not plan to maintain Homebrew or npm distributions. If the Craft team wants to adopt or fork this into an official CLI, they are welcome to.
The library half is already in use inside the Raycast Craft extension and several of my own agent workflows across the 1ar labs stack.
- Project page: craft-cli
- GitHub: github.com/pa1ar/craft-cli