craft-cli
A Craft Docs CLI made for AI agents. Hybrid local reads, API writes, opinionated defaults.
craft-cli 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. The CLI also exports a TypeScript library that the Raycast Craft extension and other downstream tools use instead of talking to the REST API directly.
Why agents need their own CLI
Craft ships 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 about the result. 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".
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 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, and 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 this 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:
- 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 (RE2) for document search and works around the API's silent-drop behavior on short underscored tokens, so agents can trust that the results are faithful to the query. - Unified write path with an undo net. Every write
passes through a mutation journal at
~/.cache/craft-cli/journal.db, recording block tree state before and after.craft undo,craft diff, andcraft logall work against it, giving agents a git-like safety net on a platform that otherwise has no version history. -
craft patch- find-and-replace 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, so the CLI consumes 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 (contentHash) | 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.
Install (paste this to your AI agent)
To install craft-cli, paste the block below into your AI coding agent (Claude Code, Codex, OpenCode, Cursor, etc.). The agent will handle clone, build, install, authentication, and skill registration.
You are installing craft-cli (https://github.com/pa1ar/craft-cli) for me. Follow these steps in order. Stop and ask me if anything is ambiguous, otherwise proceed end-to-end.
1. RUNTIME CHECK
Check whether `bun` is on PATH. If yes, continue.
If not:
- If I have a stated package-manager preference, use that.
- Otherwise, install Bun: `curl -fsSL https://bun.sh/install | bash` (do not switch to npm/pnpm/yarn — this project is Bun-first; the build script and binary path assume Bun).
2. CLONE + BUILD + INSTALL
git clone https://github.com/pa1ar/craft-cli.git ~/dev/craft-cli
cd ~/dev/craft-cli && ./install.sh
If `install.sh` fails or is unavailable, fall back to:
bun install && bun run build
mkdir -p ~/.local/bin && ln -sf "$PWD/dist/craft" ~/.local/bin/craft
Verify `~/.local/bin` is on PATH. Add it to my shell rc if missing (detect zsh vs bash from $SHELL).
3. AUTHENTICATE
Ask me for the Craft API URL and API key. I get them from Craft → Imagine → New API Connection. The URL looks like `https://connect.craft.do/links/XXX/api/v1`, the key starts with `pdk_`.
Then run: craft setup --url "<URL>" --key "<KEY>"
4. MODE (Linux / headless only)
If this host has no Craft desktop app (any Linux box, any remote/headless server), persist API-only mode: `craft mode api`. On macOS with the Craft app installed, skip this — hybrid mode is the default and is faster.
5. VERIFY
craft whoami # confirms auth works
craft docs ls --limit 3 # confirms reads work
6. SKILL REGISTRATION
The repo ships an agent skill at `skill/SKILL.md` — full command surface, recipes, caveats. Register it with this host so you can load it on demand:
- Claude Code: `install.sh` already symlinked it to `~/.claude/skills/craft-cli`. Done.
- Codex CLI: symlink `~/dev/craft-cli/skill` to `~/.codex/skills/craft-cli` (create dir if missing).
- OpenCode / Cursor / other: place the skill where this host loads agent skills from. If you do not know the canonical path for this host, ask me.
After registration, read `skill/SKILL.md` once before you write any craft-* commands — it contains the precedence rules, exit codes, and the gotchas that the API does not document.
7. REPORT BACK
Tell me:
- which mode is active (hybrid vs api-only),
- where the binary landed,
- where the skill is registered,
- any step you skipped and why. Role and distribution
Personal tool, published as-is. I am not affiliated with Craft and do not plan to maintain package-manager distributions. If the Craft team wants to adopt or fork this into an official CLI, they are welcome to. The library half is in active use inside the Raycast Craft extension and inside several of my own agent workflows across the 1ar labs stack.