Driving the vault from the CLI

The official Obsidian CLI is the primary interface to this vault. It ships with the desktop app and is on PATH at /Applications/Obsidian.app/Contents/MacOS/obsidian.

Run obsidian help for the full command list, or obsidian help <command> for one command. Do not guess flags — check first.

Three rules that prevent damage

  1. Obsidian must be running. If it is not, the first command starts it.
  2. Always target this vault. The CLI defaults to the most recently focused vault, and several are registered on this machine — including a work vault. Either run from inside digital-garden/, or pass vault="digital-garden" as the first parameter. A command aimed at the wrong vault is the most likely way to do real damage here.
  3. Sync is live. The vault syncs through Obsidian Sync, so writes propagate to other devices, and the author may be editing the same file right now. Prefer obsidian property:set over rewriting a whole file, and do not batch-rewrite many notes without asking.

Two output quirks

Every call prints Your Obsidian installer is out of date when the app runtime has self-updated past the installer version. Filter that line out of anything shown to the user. Installing the current installer from https://obsidian.md/download removes it.

A command sometimes returns nothing, then works on the next call. Observed on search, help, commands and version when the app is cold or busy.

Empty output is not a result. Re-run before concluding the vault has no match. A wrong “nothing found” is how a duplicate note gets created.

obsidian read on a missing file prints Error: File "..." not found. and still exits 0. Never trust the exit code — check the output text, or test with test -f first.

Commands that matter here

obsidian read path="Notes/Boolean blindness.md"
obsidian search:context query="Hamming" path="Notes"
obsidian create path="Inbox/My idea.md" template="Seedling 🌱"
obsidian append path="Inbox/My idea.md" content="line one\nline two"
obsidian property:set name="growth" value="Budding" path="Notes/X.md"
obsidian backlinks file="Boolean blindness"
obsidian unresolved counts
obsidian tags counts sort=count

create ... template= resolves {{title}}, {{date}} and {{time}} correctly and uses the filename as {{title}}. Prefer it over hand-writing frontmatter — see the created_at rule in conventions.md.

Use \n for newlines inside a content= value, and quote any value with spaces.

property:set ... type=checkbox writes a real unquoted YAML boolean, which is the only form that hides a note. Verified 2026-08-18.

Periodic notes: never write the file

The author creates daily and weekly notes by clicking a date in the Calendar plugin, which delegates to periodic-notes. That path applies the right template and the right filename. Reproduce it through the plugin:

obsidian command id="periodic-notes:open-daily-note"
obsidian command id="periodic-notes:open-weekly-note"
obsidian command id="periodic-notes:open-monthly-note"

These create the note from its template when it does not exist. Then edit the file on disk. Never use obsidian create or a file write for a periodic note — that loses the template, the aliases, and the filename conformance.

The daily-notes trap, and its fix

The CLI’s daily:* commands read the core daily-notes plugin, not periodic-notes. Core daily-notes had never been configured here, so it fell back to the default new-file location:

obsidian daily:path  →  Inbox/2026-08-18.md      ← wrong

Every daily command would have written into Inbox/. Fixed on 2026-08-18 by writing .obsidian/daily-notes.json to match periodic-notes exactly:

{ "folder": "Journal", "format": "YYYY/MM/YYYY-MM-DD", "template": "Templates/Daily" }
obsidian daily:path  →  Journal/2026/08/2026-08-18.md

Both plugins now agree, so daily, daily:path, daily:read, daily:append and tasks daily all resolve correctly. Do not change that file.

There is no core equivalent for weekly notes. Compute the weekly path with the ISO week-year — %G/%V, never %Y/%U, which break in early January:

WEEK="Journal/$(date +%G)/$(date +%G)-week-$(date +%V).md"

Escape hatch

obsidian eval code="..." runs JavaScript in the app context — useful for things the CLI does not expose, such as reading a plugin’s live settings:

obsidian eval code="JSON.stringify(app.plugins.plugins['periodic-notes'].settings.weekly)"

It can also mutate the vault, so it is deliberately not in the project permission allowlist and will prompt.