| name | obsidian-cli |
| description | Interact with Obsidian via the official CLI (1.12+). Read/write files, reload plugins, query Bases, run JS eval, take screenshots, manage properties, and more. |
Obsidian CLI
Control Obsidian from the terminal. Requires Obsidian 1.12+ running with CLI enabled.
Setup
Binary path (WSL2):
OBSIDIAN="/mnt/c/Users/Cybersader/AppData/Local/Obsidian/Obsidian.com"
Use Obsidian.com (not .exe) — the .com file is a terminal redirector that gives proper stdin/stdout. Without it, Obsidian.exe (a GUI app) returns exit code 255 and many commands produce no output. The .com file requires Catalyst license and lives alongside Obsidian.exe in AppData/Local/Obsidian/.
Obsidian must be running. The first CLI command launches it if not.
WSL2 notes:
- Target vaults by name:
vault=tasknotes-dev-vault
- Screenshots save to Windows temp dir; copy to project with glob:
cp /mnt/c/Users/Cybersader/AppData/Local/Temp/obsidian-screenshot*.png test-results/
Targeting a Vault
$OBS command
$OBS vault=tasknotes-dev-vault command
$OBS vault="My Vault" search query="test"
Key Commands for Plugin Development
Plugin Management
$OBS vault=tasknotes-dev-vault plugins
$OBS vault=tasknotes-dev-vault plugin id=tasknotes
$OBS vault=tasknotes-dev-vault plugin:reload id=tasknotes
$OBS vault=tasknotes-dev-vault plugin:enable id=tasknotes
$OBS vault=tasknotes-dev-vault plugin:disable id=tasknotes
Execute JavaScript in Obsidian
$OBS vault=tasknotes-dev-vault eval "code=app.vault.getFiles().length"
$OBS vault=tasknotes-dev-vault eval "code=app.workspace.getActiveFile()?.path"
$OBS vault=tasknotes-dev-vault eval "code=JSON.stringify(app.plugins.plugins.tasknotes?.settings?.taskIdentificationMethod)"
Developer Tools
$OBS vault=tasknotes-dev-vault dev:screenshot path=screenshot.png
$OBS vault=tasknotes-dev-vault dev:console limit=10
$OBS vault=tasknotes-dev-vault dev:errors
$OBS vault=tasknotes-dev-vault dev:dom "selector=.tasknotes-settings" text
$OBS vault=tasknotes-dev-vault dev:css "selector=.tn-prop-row"
$OBS vault=tasknotes-dev-vault devtools
$OBS vault=tasknotes-dev-vault dev:mobile on
File Operations
$OBS vault=tasknotes-dev-vault read file=Recipe
$OBS vault=tasknotes-dev-vault read path="TaskNotes/Tasks/My Task.md"
$OBS vault=tasknotes-dev-vault create name="New Task" content="---\nstatus: open\n---" silent
$OBS vault=tasknotes-dev-vault append file=Recipe content="- [ ] New step"
$OBS vault=tasknotes-dev-vault files folder=TaskNotes/Tasks
$OBS vault=tasknotes-dev-vault file file=Recipe
Properties (Frontmatter)
$OBS vault=tasknotes-dev-vault properties all counts
$OBS vault=tasknotes-dev-vault property:read name=status file="My Task"
$OBS vault=tasknotes-dev-vault property:set name=status value=done file="My Task"
$OBS vault=tasknotes-dev-vault property:remove name=obsolete file="My Task"
Bases (Database Views)
$OBS vault=tasknotes-dev-vault bases
$OBS vault=tasknotes-dev-vault base:query file="All Tasks" format=json
$OBS vault=tasknotes-dev-vault base:query file="All Tasks" format=csv
$OBS vault=tasknotes-dev-vault base:query file="All Tasks" format=paths
$OBS vault=tasknotes-dev-vault base:views
Search
$OBS vault=tasknotes-dev-vault search query="meeting notes"
$OBS vault=tasknotes-dev-vault search query="TODO" matches
$OBS vault=tasknotes-dev-vault search:open query="bug fix"
Tasks (Markdown Checkboxes)
$OBS vault=tasknotes-dev-vault tasks todo
$OBS vault=tasknotes-dev-vault tasks daily
$OBS vault=tasknotes-dev-vault task ref="Recipe.md:8" toggle
Tags
$OBS vault=tasknotes-dev-vault tags all counts sort=count
Navigation
$OBS vault=tasknotes-dev-vault open file="My Task" newtab
$OBS vault=tasknotes-dev-vault daily
$OBS vault=tasknotes-dev-vault command id=app:open-settings
$OBS vault=tasknotes-dev-vault commands
Common Workflows
Build + Reload Plugin (no Hot Reload needed)
bun run build && $OBS vault=tasknotes-dev-vault plugin:reload id=tasknotes
Inspect Plugin State
$OBS vault=tasknotes-dev-vault plugin id=tasknotes
$OBS vault=tasknotes-dev-vault eval "code=JSON.stringify(app.plugins.plugins.tasknotes?.settings, null, 2)"
$OBS vault=tasknotes-dev-vault eval "code=app.vault.getMarkdownFiles().filter(f => f.path.startsWith('TaskNotes/')).length"
Debug UI Issues
$OBS vault=tasknotes-dev-vault dev:screenshot
$OBS vault=tasknotes-dev-vault dev:errors
$OBS vault=tasknotes-dev-vault dev:dom "selector=.modal-container" text
$OBS vault=tasknotes-dev-vault dev:css "selector=.tn-prop-row"
Query Base View Results
$OBS vault=tasknotes-dev-vault base:query file="All Tasks" format=json
$OBS vault=tasknotes-dev-vault base:query file="All Tasks" format=paths
Test Plugin UI via eval
Use eval to trigger plugin actions and inspect state without custom commands:
$OBS vault=tasknotes-dev-vault eval "code=app.commands.executeCommandById('tasknotes:bulk-task-creation')"
$OBS vault=tasknotes-dev-vault eval "code=document.querySelector('.tn-bulk-modal') ? 'open' : 'closed'"
$OBS vault=tasknotes-dev-vault eval "code=JSON.stringify(Object.keys(app.plugins.plugins.tasknotes), null, 2)"
$OBS vault=tasknotes-dev-vault eval "code=JSON.stringify(app.metadataCache.getCache('TaskNotes/Tasks/My Task.md')?.frontmatter, null, 2)"
$OBS vault=tasknotes-dev-vault eval "code=document.querySelectorAll('.tn-prop-row').length"
$OBS vault=tasknotes-dev-vault eval "code=document.querySelector('.tn-bulk-modal__custom-props-active')?.innerHTML?.substring(0,200) ?? 'not found'"
Build + Reload + Screenshot workflow
bun run build && $OBS vault=tasknotes-dev-vault plugin:reload id=tasknotes && sleep 1 && $OBS vault=tasknotes-dev-vault dev:screenshot
Parameter Syntax
- Parameters:
key=value (quote values with spaces: key="value with spaces")
- Flags: just the word (e.g.,
silent, verbose, total)
- Multiline: use
\n for newlines, \t for tabs
- Copy output: append
--copy to any command
- File targeting:
file=<name> (wikilink resolution) or path=<exact/path.md>
Troubleshooting & WSL2 Gotchas
Exit Code 1 with No Output
Many CLI commands silently return exit code 1 from WSL2. Common causes:
- Obsidian not running: The CLI requires a running Obsidian instance. If Obsidian is closed, commands fail silently.
- Vault name mismatch:
vault= must match the exact vault name in Obsidian's vault switcher (case-sensitive).
- Command not available: Some commands only work with specific Obsidian versions or features enabled.
Commands That Reliably Work from WSL2
These are confirmed working:
OBS="/mnt/c/Users/Cybersader/AppData/Local/Obsidian/Obsidian.com"
$OBS vault=tasknotes-dev-vault plugin id=tasknotes
$OBS vault=tasknotes-dev-vault eval "code=app.vault.getFiles().length"
$OBS vault=tasknotes-dev-vault read path="TaskNotes/Tasks/My Task.md"
$OBS vault=tasknotes-dev-vault files folder=TaskNotes/Tasks
$OBS vault=tasknotes-dev-vault commands
$OBS vault=tasknotes-dev-vault bases
$OBS vault=tasknotes-dev-vault dev:errors
$OBS vault=tasknotes-dev-vault dev:console limit=10
Commands That May Silently Fail
These sometimes return exit code 1 with no output:
$OBS vault=tasknotes-dev-vault plugin:reload id=tasknotes
$OBS vault=tasknotes-dev-vault base:query file="All Tasks" format=json
$OBS vault=tasknotes-dev-vault dev:screenshot
Quoting Issues in eval
The eval command is sensitive to quote nesting. WSL2 shell quoting adds another layer:
$OBS vault=tasknotes-dev-vault eval "code=app.vault.getFiles().length"
$OBS vault=tasknotes-dev-vault eval "code=JSON.stringify(app.plugins.plugins.tasknotes?.settings)"
$OBS vault=tasknotes-dev-vault eval "code=app.vault.getFiles().filter(f => f.path.includes('Tasks'))"
$OBS vault=tasknotes-dev-vault eval "code=app.vault.getFiles().filter(f => f.path.includes(\"Tasks\")).length"
Verifying plugin:reload Actually Worked
Since plugin:reload may silently fail, verify with eval:
$OBS vault=tasknotes-dev-vault plugin:reload id=tasknotes && \
$OBS vault=tasknotes-dev-vault eval "code=app.plugins.plugins.tasknotes ? 'loaded' : 'not loaded'"
Best Practices for Agents
- Prefer
eval over specialized commands — eval is the most reliable and versatile
- Don't retry on exit code 1 — if a command fails, try an alternative approach (e.g., eval)
- Don't waste context on repeated failures — if the CLI is unresponsive, fall back to manual testing
- Use
2>&1 to capture stderr — sometimes error messages go to stderr
- Set timeout — CLI commands can hang if Obsidian is unresponsive; use a 10-second timeout
Full Command Reference
See https://help.obsidian.md/cli for the complete docs.
Categories
| Category | Key Commands |
|---|
| General | help, version, reload, restart |
| Files | files, file, open, create, read, append, prepend, move, delete |
| Properties | properties, property:set, property:read, property:remove, aliases |
| Bases | bases, base:query, base:views, base:create |
| Search | search, search:open |
| Tags | tags, tag |
| Tasks | tasks, task |
| Links | backlinks, links, unresolved, orphans, deadends |
| Plugins | plugins, plugin, plugin:enable, plugin:disable, plugin:install, plugin:uninstall, plugin:reload |
| Daily | daily, daily:read, daily:append, daily:prepend |
| History | diff, history, history:read, history:restore |
| Workspace | workspace, tabs, tab:open, recents |
| Dev | devtools, dev:console, dev:errors, dev:screenshot, dev:dom, dev:css, dev:mobile, dev:debug, dev:cdp, eval |
| Themes | themes, theme, theme:set, theme:install, snippets, snippet:enable |
| Sync | sync, sync:status, sync:history |
| Publish | publish:site, publish:list, publish:status, publish:add |
| Templates | templates, template:read, template:insert |
| Vault | vault, vaults, vault:open |