--- name: obsidian-curator description: Manage Obsidian vaults via LiveSync CouchDB — capture notes, AI-enrich and file them, manage tasks, audit and tidy vault structure. Use when working with Obsidian vaults through CouchDB/LiveSync (not local filesystem). Requires CouchDB with Obsidian LiveSync plugin. AI features (process, file) need an AI provider configured; capture, audit, tidy, and tasks work rule-based without any API key. metadata: openclaw: emoji: "📋" requires: bins: ["obsidian-curator"] install: - id: node kind: node package: obsidian-curator bins: ["obsidian-curator"] label: "Install obsidian-curator (npm)" --- # obsidian-curator Manage Obsidian vaults through the CouchDB database that powers [Obsidian LiveSync](https://github.com/vrtmrz/obsidian-livesync). Capture, process, file, audit, tidy, and manage tasks — all via CLI or Node.js API. **Prerequisites:** CouchDB with LiveSync configured, E2EE disabled. ## Security & Trust - **Open source:** [github.com/philmossman/obsidian-curator](https://github.com/philmossman/obsidian-curator) (MIT) - **npm provenance:** Published via GitHub Actions OIDC with [Sigstore attestation](https://www.npmjs.com/package/obsidian-curator) — cryptographically verifiable build provenance - **No lifecycle scripts:** No `preinstall`, `install`, or `postinstall` scripts — `npm install` only copies files - **Minimal dependencies:** Only `nano` (CouchDB client) and `date-fns` (date parsing) - **Local network only:** Connects to your CouchDB instance (user-configured host/port). No external telemetry, no phone-home, no data leaves your network - **Credentials:** Stored locally in `~/.obsidian-curator/config.json` — never transmitted except to your own CouchDB - **E2EE note:** LiveSync E2EE must be disabled because the tool reads/writes vault documents directly via CouchDB. This is a LiveSync architectural requirement, not a security compromise by this tool ## Setup Run the interactive wizard — it tests the CouchDB connection live: ```bash obsidian-curator init ``` Configures: CouchDB connection, vault structure preset (PARA/Zettelkasten/Johnny Decimal/Flat/Custom), AI provider (OpenAI/Anthropic/Ollama/None), task projects. Config location: `~/.obsidian-curator/config.json` ## Commands ### Capture (no AI needed) ```bash obsidian-curator capture "Quick thought about project X" obsidian-curator capture "Meeting notes from standup" --source meeting ``` ### Process inbox (AI required) Enrich inbox notes with tags, summary, and suggested folder: ```bash obsidian-curator process obsidian-curator process --limit 5 --dry-run obsidian-curator process --force # re-process already-processed notes ``` ### File notes (AI required) Route processed notes to canonical vault folders: ```bash obsidian-curator file obsidian-curator file --dry-run --min-confidence 0.8 ``` ### Audit (no AI needed) Check vault structure against configured canonical folders: ```bash obsidian-curator audit ``` ### Tidy (AI optional) Find duplicates, structure violations, dead notes. With AI, ambiguous cases are triaged automatically: ```bash obsidian-curator tidy --dry-run obsidian-curator tidy --checks dupes,stubs ``` ### Tasks (no AI needed) ```bash obsidian-curator tasks # list open tasks obsidian-curator tasks --project Work --priority high obsidian-curator task "call dentist next Tuesday" # create task (parses dates, priority, project) obsidian-curator done "dentist" # mark done by partial title match ``` ### Config ```bash obsidian-curator config show obsidian-curator config set ai.provider ollama obsidian-curator config set vault.host 192.168.1.100 ``` ## Programmatic API ```js const { VaultClient, Curator, createAIAdapter, loadConfig } = require('obsidian-curator'); const config = loadConfig(); const vault = new VaultClient(config.vault); await vault.ping(); const ai = createAIAdapter(config); const curator = new Curator({ vault, ai, config }); await curator.capture('Quick thought'); await curator.process({ limit: 5 }); await curator.file({ dryRun: true }); await curator.audit(); await curator.tidy({ checks: ['dupes', 'stubs'], dryRun: true }); const tasks = await curator.tasks({ status: 'open', project: 'Work' }); await curator.createTask('call Alice next Friday'); await curator.taskBrief(); // markdown summary ``` ## AI Providers | Provider | Cost | Privacy | Setup | |----------|------|---------|-------| | `none` | Free | Local | Default — rule-based features only | | `ollama` | Free | Local | `config set ai.provider ollama` + model name | | `openai` | Pay-per-use | Cloud | `config set ai.provider openai` + API key | | `anthropic` | Pay-per-use | Cloud | `config set ai.provider anthropic` + API key | | Custom/OpenRouter | Varies | Varies | Use `openai` provider with custom `baseUrl` | ## Vault Structure Presets - **PARA:** inbox → Projects / Areas / Resources / Archives - **Zettelkasten:** inbox → Slipbox / References / Projects / Archives - **Johnny Decimal:** inbox → numbered category folders (00-09, 10-19, ...) - **Flat:** inbox only, no enforced structure - **Custom:** define your own canonical folders