Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9d3554feff | |||
| 69c42bfb92 | |||
| cdb3bd2209 | |||
| 6f5ed7c70e | |||
| 7d20d45a71 | |||
| ec070a1371 | |||
| 1ab03980b9 | |||
| d7d115781e | |||
| a882e74591 | |||
| de356e8396 | |||
| c7b35b314d | |||
| b116ad4abf | |||
| 536320574b | |||
| a5a0d10d35 | |||
| 986ff986d2 | |||
| 4e43a03f8c | |||
| 22c5c8af83 | |||
| e30c0eb9cc | |||
| 131c1654ee | |||
| 931a3a9517 | |||
| e5c8b8e223 | |||
| 507ef7149b | |||
| 462a38b164 | |||
| 89e6296c94 | |||
| 68d6ec9ce3 | |||
| 5981bcfe98 | |||
| 4dc24c4295 | |||
| 36c739f609 | |||
| 3f9a593fa7 | |||
| 321330ac3f | |||
| 47d3d78f66 | |||
| 2fc0cd7c7d | |||
| 55abf71ab0 | |||
| 2c78b1e658 |
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
||||||
|
"name": "obsidian-cli-skill",
|
||||||
|
"description": "Obsidian CLI skill for Claude Code — interact with Obsidian vaults from the terminal",
|
||||||
|
"owner": {
|
||||||
|
"name": "pablo-mano"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "obsidian-cli",
|
||||||
|
"description": "Interact with Obsidian vaults using the official Obsidian CLI (v1.12+). Read, create, append, search, and manage notes, daily notes, properties, tags, tasks, bookmarks, templates, themes, sync, plugins, and links — all from the terminal.",
|
||||||
|
"author": {
|
||||||
|
"name": "pablo-mano"
|
||||||
|
},
|
||||||
|
"source": "./plugins/obsidian-cli",
|
||||||
|
"category": "productivity",
|
||||||
|
"homepage": "https://github.com/pablo-mano/Obsidian-CLI-skill"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "obsidian-cli",
|
||||||
|
"description": "Interact with Obsidian vaults using the official Obsidian CLI (v1.12+). Read, create, append, search, and manage notes, daily notes, properties, tags, tasks, bookmarks, templates, themes, sync, plugins, and links — all from the terminal.",
|
||||||
|
"version": "1.3.0",
|
||||||
|
"author": {
|
||||||
|
"name": "pablo-mano"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/pablo-mano/Obsidian-CLI-skill",
|
||||||
|
"repository": "https://github.com/pablo-mano/Obsidian-CLI-skill"
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
name: Claude Code Review
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, ready_for_review, reopened]
|
||||||
|
# Optional: Only run on specific file changes
|
||||||
|
# paths:
|
||||||
|
# - "src/**/*.ts"
|
||||||
|
# - "src/**/*.tsx"
|
||||||
|
# - "src/**/*.js"
|
||||||
|
# - "src/**/*.jsx"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
claude-review:
|
||||||
|
# Optional: Filter by PR author
|
||||||
|
# if: |
|
||||||
|
# github.event.pull_request.user.login == 'external-contributor' ||
|
||||||
|
# github.event.pull_request.user.login == 'new-developer' ||
|
||||||
|
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: read
|
||||||
|
issues: read
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- name: Run Claude Code Review
|
||||||
|
id: claude-review
|
||||||
|
uses: anthropics/claude-code-action@v1
|
||||||
|
with:
|
||||||
|
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||||
|
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
|
||||||
|
plugins: 'code-review@claude-code-plugins'
|
||||||
|
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
|
||||||
|
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
||||||
|
# or https://code.claude.com/docs/en/cli-reference for available options
|
||||||
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
name: Claude Code
|
||||||
|
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
pull_request_review_comment:
|
||||||
|
types: [created]
|
||||||
|
issues:
|
||||||
|
types: [opened, assigned]
|
||||||
|
pull_request_review:
|
||||||
|
types: [submitted]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
claude:
|
||||||
|
if: |
|
||||||
|
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||||
|
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||||
|
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
||||||
|
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: read
|
||||||
|
issues: read
|
||||||
|
id-token: write
|
||||||
|
actions: read # Required for Claude to read CI results on PRs
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- name: Run Claude Code
|
||||||
|
id: claude
|
||||||
|
uses: anthropics/claude-code-action@v1
|
||||||
|
with:
|
||||||
|
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||||
|
|
||||||
|
# This is an optional setting that allows Claude to read CI results on PRs
|
||||||
|
additional_permissions: |
|
||||||
|
actions: read
|
||||||
|
|
||||||
|
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
|
||||||
|
# prompt: 'Update the pull request description to include a summary of changes.'
|
||||||
|
|
||||||
|
# Optional: Add claude_args to customize behavior and configuration
|
||||||
|
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
||||||
|
# or https://code.claude.com/docs/en/cli-reference for available options
|
||||||
|
# claude_args: '--allowed-tools Bash(gh pr:*)'
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
test-results/
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
A skill for AI coding agents that enables full control of [Obsidian](https://obsidian.md) vaults from the terminal using the official **Obsidian CLI** (v1.12+).
|
A skill for AI coding agents that enables full control of [Obsidian](https://obsidian.md) vaults from the terminal using the official **Obsidian CLI** (v1.12+).
|
||||||
|
|
||||||
|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
@@ -31,6 +32,20 @@ Covers **100+ commands** across all major areas:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Invoking the Skill
|
||||||
|
|
||||||
|
The skill activates automatically when your request clearly involves Obsidian vault operations. For casual phrasing, you may need to invoke it explicitly:
|
||||||
|
|
||||||
|
| Method | Example |
|
||||||
|
|---|---|
|
||||||
|
| **Natural language** (usually works) | *"add this to my daily note: …"*, *"search my vault for X"* |
|
||||||
|
| **Explicit prefix** (always works) | `$obsidian-cli append to today's daily note: "…"` |
|
||||||
|
| **Strict mode** (always active) | Enable in Claude Code settings so the skill is always loaded |
|
||||||
|
|
||||||
|
If Claude tries to answer a vault request without executing any commands, just say `use obsidian-cli` and it will retry with the skill active.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
> Obsidian v1.12 is available to **all users** — no Early Access build or Catalyst license required.
|
> Obsidian v1.12 is available to **all users** — no Early Access build or Catalyst license required.
|
||||||
@@ -53,53 +68,164 @@ Covers **100+ commands** across all major areas:
|
|||||||
|
|
||||||
### Claude Code — Plugin (native)
|
### Claude Code — Plugin (native)
|
||||||
|
|
||||||
Install directly from GitHub using the Claude Code plugin system:
|
**Option A — Marketplace install (recommended):**
|
||||||
|
|
||||||
1. Open Claude Code and run:
|
|
||||||
```
|
```
|
||||||
/plugin marketplace add https://github.com/pablo-mano/Obsidian-CLI-skill
|
/plugin marketplace add https://github.com/pablo-mano/Obsidian-CLI-skill
|
||||||
|
/plugin install obsidian-cli
|
||||||
```
|
```
|
||||||
2. Install the `obsidian-cli` skill from the plugin list.
|
|
||||||
3. Done — the skill auto-triggers when you ask Claude to interact with Obsidian, automate vault operations, manage daily notes, search your vault, etc.
|
|
||||||
|
|
||||||
**Alternative — manual install:**
|
Done — see [Invoking the Skill](#invoking-the-skill) above for how to activate it.
|
||||||
1. Download `obsidian-cli-skill-v1.0.0.zip` from the [Releases](https://github.com/pablo-mano/Obsidian-CLI-skill/releases) page.
|
|
||||||
2. Open Claude Code → Skills plugin settings → Import → select the `.zip`.
|
|
||||||
|
|
||||||
> The `plugin.json` manifest at the repo root makes this repository directly compatible with Claude Code's plugin system.
|
**Option B — Direct plugin load:**
|
||||||
|
|
||||||
|
1. Clone this repository:
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/pablo-mano/Obsidian-CLI-skill
|
||||||
|
```
|
||||||
|
2. Load the plugin with the `--plugin-dir` flag:
|
||||||
|
```bash
|
||||||
|
claude --plugin-dir ./Obsidian-CLI-skill
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option C — Persistent via `settings.json`:**
|
||||||
|
|
||||||
|
Add to your project's `.claude/settings.json`:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"plugins": {
|
||||||
|
"obsidian-cli": {
|
||||||
|
"source": { "source": "github", "repo": "pablo-mano/Obsidian-CLI-skill" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> The `.claude-plugin/marketplace.json` manifest makes this repository compatible with Claude Code's marketplace system.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Cursor
|
### Cursor
|
||||||
|
|
||||||
Cursor loads context via [Rules](https://docs.cursor.com/context/rules-for-ai). Add the skill as a project-level or global rule:
|
Cursor has a native skills system (launched Feb 2026) that is directly compatible with the `SKILL.md` format — no rules file needed.
|
||||||
|
|
||||||
1. Create the file `.cursor/rules/obsidian-cli.mdc` in your project root (or in `~/.cursor/rules/` for global scope).
|
In a terminal:
|
||||||
2. Paste the body of `SKILL.md` (everything after the `---` frontmatter block) into the file.
|
|
||||||
3. Optionally append the contents of `references/command-reference.md` for the full command reference.
|
|
||||||
|
|
||||||
Cursor will now apply Obsidian CLI knowledge when you work on related tasks.
|
```bash
|
||||||
|
git clone --depth 1 https://github.com/pablo-mano/Obsidian-CLI-skill /tmp/Obsidian-CLI-skill
|
||||||
|
mkdir -p ~/.cursor/skills
|
||||||
|
cp -r /tmp/Obsidian-CLI-skill/skills/obsidian-cli ~/.cursor/skills/obsidian-cli
|
||||||
|
rm -rf /tmp/Obsidian-CLI-skill
|
||||||
|
```
|
||||||
|
|
||||||
|
Cursor picks it up automatically — no restart needed.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Windsurf
|
### Cortex Code
|
||||||
|
|
||||||
Windsurf uses [Rules](https://docs.windsurf.com/windsurf/memories-and-rules) stored in `.windsurf/rules/`:
|
**Option A — Remote install (recommended)**
|
||||||
|
|
||||||
1. Create `.windsurf/rules/obsidian-cli.md` in your project.
|
In a Cortex Code session, run:
|
||||||
2. Paste the body of `SKILL.md` (below the frontmatter) into the file.
|
|
||||||
3. Optionally include the command reference from `references/command-reference.md`.
|
```
|
||||||
|
/skill add https://github.com/pablo-mano/Obsidian-CLI-skill.git
|
||||||
|
```
|
||||||
|
|
||||||
|
Cortex Code clones the repo and caches the skill. Use `/skill sync obsidian-cli` to pull
|
||||||
|
updates later.
|
||||||
|
|
||||||
|
**Option B — Project-local install**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p .cortex/skills/obsidian-cli
|
||||||
|
curl -sSL https://raw.githubusercontent.com/pablo-mano/Obsidian-CLI-skill/main/skills/obsidian-cli/SKILL.md \
|
||||||
|
-o .cortex/skills/obsidian-cli/SKILL.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Or clone the repo and copy:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/pablo-mano/Obsidian-CLI-skill.git /tmp/obsidian-cli-skill
|
||||||
|
cp -r /tmp/obsidian-cli-skill/skills/obsidian-cli .cortex/skills/
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option C — User-level install**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ~/.snowflake/cortex/skills/obsidian-cli
|
||||||
|
cp skills/obsidian-cli/SKILL.md ~/.snowflake/cortex/skills/obsidian-cli/
|
||||||
|
```
|
||||||
|
|
||||||
|
**Verify**
|
||||||
|
|
||||||
|
```
|
||||||
|
/skill list
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see `obsidian-cli` in the output.
|
||||||
|
|
||||||
|
**Invoke**
|
||||||
|
|
||||||
|
Prefix requests with `$obsidian-cli` or just describe what you want — Cortex Code activates
|
||||||
|
the skill automatically when the context matches:
|
||||||
|
|
||||||
|
```
|
||||||
|
$obsidian-cli append to today's daily note: "Reviewed Snowflake PR #42"
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### GitHub Copilot (VS Code)
|
### GitHub Copilot (VS Code)
|
||||||
|
|
||||||
Copilot supports [custom instructions](https://docs.github.com/en/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot) via a repository-level file:
|
Copilot supports [custom instructions](https://docs.github.com/en/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot) via repository files:
|
||||||
|
|
||||||
|
**Option A — Repository-wide (recommended):**
|
||||||
1. Create `.github/copilot-instructions.md` in your repo.
|
1. Create `.github/copilot-instructions.md` in your repo.
|
||||||
2. Paste the body of `SKILL.md` into the file.
|
2. Paste the body of `SKILL.md` into the file.
|
||||||
|
|
||||||
For workspace-level instructions in VS Code, add the content to your VS Code settings under `"github.copilot.chat.codeGeneration.instructions"`.
|
**Option B — Path-scoped:**
|
||||||
|
1. Create `.github/instructions/obsidian-cli.instructions.md`
|
||||||
|
2. Add frontmatter `applyTo: "**/*"` then paste the `SKILL.md` body.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Windsurf
|
||||||
|
|
||||||
|
Windsurf uses a Rules system (`.windsurf/rules/`). Rules have a 12,000 character limit per file, so split the skill across two files:
|
||||||
|
|
||||||
|
1. Create `.windsurf/rules/obsidian-cli.md` — paste the body of `SKILL.md` (everything after the `---` frontmatter).
|
||||||
|
2. Create `.windsurf/rules/obsidian-cli-reference.md` — paste the contents of `skills/obsidian-cli/references/command-reference.md`.
|
||||||
|
|
||||||
|
Set the activation mode to **Always On** or **Model Decision** in each file's frontmatter to control when the rules apply.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Nanoclaw
|
||||||
|
|
||||||
|
Nanoclaw loads skills from `.claude/skills/` using the same `SKILL.md` format — directly compatible.
|
||||||
|
|
||||||
|
1. Clone or download this repo
|
||||||
|
2. Copy the skill folder into your Nanoclaw project:
|
||||||
|
```bash
|
||||||
|
cp -r Obsidian-CLI-skill /path/to/nanoclaw/.claude/skills/obsidian-cli
|
||||||
|
```
|
||||||
|
3. The skill is available as a slash command (`/obsidian-cli`) or auto-triggers when you ask the agent to interact with Obsidian.
|
||||||
|
|
||||||
|
> This is a knowledge skill — it adds Obsidian CLI awareness to the agent without modifying Nanoclaw's codebase.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Openclaw
|
||||||
|
|
||||||
|
Openclaw loads skills from the `skills/` directory at the project root using the `SKILL.md` format — directly compatible.
|
||||||
|
|
||||||
|
1. Clone or download this repo
|
||||||
|
2. Copy the skill folder into Openclaw's skills directory:
|
||||||
|
```bash
|
||||||
|
cp -r Obsidian-CLI-skill /path/to/openclaw/skills/obsidian-cli
|
||||||
|
```
|
||||||
|
3. Restart the Openclaw agent — skills are discovered automatically.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -109,9 +235,9 @@ For workspace-level instructions in VS Code, add the content to your VS Code set
|
|||||||
|
|
||||||
1. Open the agent's system prompt / custom instructions settings.
|
1. Open the agent's system prompt / custom instructions settings.
|
||||||
2. Paste the contents of `SKILL.md` (with or without the YAML frontmatter — most agents accept either).
|
2. Paste the contents of `SKILL.md` (with or without the YAML frontmatter — most agents accept either).
|
||||||
3. Optionally include `references/command-reference.md` for the complete command reference.
|
3. Optionally include `skills/obsidian-cli/references/command-reference.md` for the complete command reference.
|
||||||
|
|
||||||
This works with Aider, Continue.dev, LM Studio, Open Interpreter, or any chat interface with a system prompt field.
|
This works with any chat interface or coding agent that has a system prompt or custom instructions field.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -152,7 +278,7 @@ obsidian daily:append content="- Started [[projects/new-feature|New Feature]]"
|
|||||||
|
|
||||||
## Full Command Reference
|
## Full Command Reference
|
||||||
|
|
||||||
See [`references/command-reference.md`](references/command-reference.md) for the complete reference covering all commands, parameters, flags, output formatting, multi-vault usage, and headless Linux setup.
|
See [`skills/obsidian-cli/references/command-reference.md`](skills/obsidian-cli/references/command-reference.md) for the complete reference covering all commands, parameters, flags, output formatting, multi-vault usage, and headless Linux setup.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,221 +0,0 @@
|
|||||||
---
|
|
||||||
name: obsidian-cli
|
|
||||||
description: >
|
|
||||||
Interact with Obsidian vaults using the official Obsidian CLI (v1.12+).
|
|
||||||
Read, create, append, search, and manage notes, daily notes, properties, tags,
|
|
||||||
tasks, bookmarks, templates, themes, sync, plugins, and links — all from the terminal.
|
|
||||||
Use this skill whenever the user mentions Obsidian CLI, wants to automate Obsidian
|
|
||||||
vault operations, manage notes programmatically, script daily note workflows,
|
|
||||||
query vault metadata, or integrate Obsidian with AI agents or automation pipelines.
|
|
||||||
Also trigger when the user asks about controlling Obsidian from the command line,
|
|
||||||
building scripts around their knowledge base, or running headless Obsidian setups.
|
|
||||||
Even if the user just says "add something to my daily note" or "search my vault"
|
|
||||||
in a CLI/scripting context, this skill applies.
|
|
||||||
---
|
|
||||||
|
|
||||||
# Obsidian CLI
|
|
||||||
|
|
||||||
The official Obsidian CLI (released in v1.12, February 2026) lets you control every aspect of Obsidian from the terminal. It communicates with a running Obsidian desktop instance via IPC.
|
|
||||||
|
|
||||||
> For the full command reference with all subcommands, flags and examples, read
|
|
||||||
> `references/command-reference.md` in this skill folder.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
| Requirement | Details |
|
|
||||||
|---|---|
|
|
||||||
| Obsidian Desktop | **v1.12.0+** |
|
|
||||||
| CLI enabled | Settings → Command line interface → Toggle ON |
|
|
||||||
| Obsidian running | The desktop app **must be running** for CLI to work (IPC) |
|
|
||||||
|
|
||||||
### Platform Notes
|
|
||||||
|
|
||||||
- **macOS / Linux**: The `obsidian` binary is registered in PATH automatically when you enable CLI in settings.
|
|
||||||
- **Windows**: Requires an `Obsidian.com` redirector file placed alongside `Obsidian.exe`. **Must run with normal user privileges** — admin terminals produce silent failures.
|
|
||||||
- **Headless Linux**: Use the `.deb` package (not snap). Run under `xvfb`. Prefix commands with `DISPLAY=:5` (or your xvfb display number). Ensure `PrivateTmp=false` if running as a service.
|
|
||||||
|
|
||||||
## Syntax
|
|
||||||
|
|
||||||
All parameters use **`key=value`** syntax. Quote values containing spaces.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian <command> [subcommand] [key=value ...] [flags]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Multi-Vault
|
|
||||||
|
|
||||||
Target a specific vault by making it the **first argument**:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian "My Vault" daily:read
|
|
||||||
obsidian "Work Notes" search query="meeting"
|
|
||||||
```
|
|
||||||
|
|
||||||
If omitted, the CLI targets the most recently active vault.
|
|
||||||
|
|
||||||
## Command Overview
|
|
||||||
|
|
||||||
The CLI provides **100+ commands** across these groups:
|
|
||||||
|
|
||||||
| Group | Key Commands | Purpose |
|
|
||||||
|---|---|---|
|
|
||||||
| **files** | `read`, `create`, `append`, `prepend`, `move`, `delete`, `files`, `folders`, `file` | Note CRUD and file discovery |
|
|
||||||
| **daily** | `daily`, `daily:read`, `daily:append`, `daily:prepend` | Daily note operations |
|
|
||||||
| **search** | `search` | Full-text vault search with scoping and JSON output |
|
|
||||||
| **properties** | `properties`, `property:read`, `property:set`, `property:remove`, `aliases` | Frontmatter/metadata management |
|
|
||||||
| **tags** | `tags`, `tag` | Tag listing, counts, and filtering |
|
|
||||||
| **tasks** | `tasks`, `task` | Task querying, filtering, and toggling |
|
|
||||||
| **links** | `backlinks`, `links`, `unresolved`, `orphans`, `deadends` | Graph and link analysis |
|
|
||||||
| **bookmarks** | `bookmarks` | Bookmark management |
|
|
||||||
| **templates** | `templates`, `template:read`, `template:insert` | Template listing, rendering, insertion |
|
|
||||||
| **plugins** | `plugins`, `plugin:enable`, `plugin:disable`, `plugin:install`, `plugin:reload` | Plugin management |
|
|
||||||
| **sync** | `sync`, `sync:status`, `sync:history`, `sync:read`, `sync:restore`, `sync:deleted` | Obsidian Sync operations |
|
|
||||||
| **themes** | `themes` | Theme management |
|
|
||||||
| **dev** | `dev:screenshot`, `eval`, `dev:console`, `dev:errors` | Developer/debugging tools |
|
|
||||||
| **vault** | `vault`, `vaults`, `version` | Vault info and metadata |
|
|
||||||
| **other** | `outline`, `wordcount`, `recents`, `reload` | Utility commands |
|
|
||||||
|
|
||||||
## Quick Reference — Most Common Commands
|
|
||||||
|
|
||||||
### Reading & Writing Notes
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian read path="folder/note.md"
|
|
||||||
obsidian create path="folder/note" content="# New Note"
|
|
||||||
obsidian create path="folder/note" template="meeting-notes"
|
|
||||||
obsidian append path="folder/note.md" content="New paragraph"
|
|
||||||
obsidian prepend path="folder/note.md" content="Top content"
|
|
||||||
obsidian move path="old/note.md" name="new-name"
|
|
||||||
obsidian delete path="folder/note.md"
|
|
||||||
obsidian delete path="folder/note.md" permanent
|
|
||||||
```
|
|
||||||
|
|
||||||
### Daily Notes
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian daily # Open today's daily note
|
|
||||||
obsidian daily:read # Print content of today's note
|
|
||||||
obsidian daily:append content="- [ ] New task"
|
|
||||||
obsidian daily:prepend content="## Morning Notes"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Search
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian search query="project alpha"
|
|
||||||
obsidian search query="TODO" path="projects" limit=10
|
|
||||||
obsidian search query="meeting" format=json
|
|
||||||
obsidian search query="urgent" matches case
|
|
||||||
```
|
|
||||||
|
|
||||||
### Properties & Tags
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian properties path="note.md"
|
|
||||||
obsidian property:set path="note.md" name="status" value="active"
|
|
||||||
obsidian property:read path="note.md" name="status"
|
|
||||||
obsidian property:remove path="note.md" name="draft"
|
|
||||||
obsidian tags counts sort=count
|
|
||||||
obsidian tag name="project/alpha"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Tasks
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian tasks # All incomplete tasks
|
|
||||||
obsidian tasks all # All tasks (done + todo)
|
|
||||||
obsidian tasks done # Completed only
|
|
||||||
obsidian tasks daily # Tasks in today's daily note
|
|
||||||
obsidian task path="note.md" line=12 toggle
|
|
||||||
```
|
|
||||||
|
|
||||||
### Developer & Automation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian eval code="app.vault.getFiles().length"
|
|
||||||
obsidian dev:screenshot path="screenshot.png"
|
|
||||||
obsidian dev:console limit=20
|
|
||||||
obsidian dev:errors
|
|
||||||
```
|
|
||||||
|
|
||||||
## TUI Mode
|
|
||||||
|
|
||||||
Running `obsidian` with no arguments launches an interactive TUI (Terminal User Interface):
|
|
||||||
|
|
||||||
| Key | Action |
|
|
||||||
|---|---|
|
|
||||||
| `↑↓` | Navigate files |
|
|
||||||
| `Enter` | Open file |
|
|
||||||
| `/` | Search |
|
|
||||||
| `n` | Create new file |
|
|
||||||
| `d` | Delete file |
|
|
||||||
| `r` | Rename file |
|
|
||||||
| `q` | Quit |
|
|
||||||
|
|
||||||
## Common Agent Patterns
|
|
||||||
|
|
||||||
### Daily Journal Automation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Append a timestamped entry
|
|
||||||
obsidian daily:append content="## $(date '+%H:%M') — Status Update
|
|
||||||
- Completed: feature branch merge
|
|
||||||
- Next: code review for PR #42
|
|
||||||
- Blocked: waiting on API credentials"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Create Note from Template with Metadata
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian create path="projects/new-feature" template="project-template"
|
|
||||||
obsidian property:set path="projects/new-feature.md" name="status" value="planning"
|
|
||||||
obsidian property:set path="projects/new-feature.md" name="created" value="$(date -I)"
|
|
||||||
obsidian daily:append content="- Started [[projects/new-feature|New Feature]]"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Vault Analytics Script
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian files total # Total file count
|
|
||||||
obsidian tags counts sort=count # Most used tags
|
|
||||||
obsidian tasks # Open tasks across vault
|
|
||||||
obsidian orphans # Notes needing integration
|
|
||||||
obsidian unresolved # Broken links to fix
|
|
||||||
```
|
|
||||||
|
|
||||||
### Search and Extract for AI Processing
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian search query="meeting notes" format=json | jq '.[] | .path'
|
|
||||||
obsidian read path="meetings/standup.md" | grep "Action item"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sync Management
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian sync:status # Check sync health
|
|
||||||
obsidian sync:history path="important.md" # Version history
|
|
||||||
obsidian sync:restore path="important.md" version=3 # Rollback
|
|
||||||
```
|
|
||||||
|
|
||||||
## Tips
|
|
||||||
|
|
||||||
1. **Paths are vault-relative** — use `folder/note.md`, not absolute filesystem paths.
|
|
||||||
2. **`create` paths omit `.md`** — the extension is added automatically.
|
|
||||||
3. **`move` requires full target path** including `.md` extension.
|
|
||||||
4. **Pipe-friendly** — plain text output works with `grep`, `awk`, `sed`, `jq`.
|
|
||||||
5. **JSON output** — use `format=json` on search and file commands for machine parsing.
|
|
||||||
6. **Stderr noise** — GPU/Electron warnings on headless are harmless; filter with `2>/dev/null`.
|
|
||||||
7. **`daily:prepend`** inserts content after frontmatter, not at byte 0.
|
|
||||||
8. **Use `eval`** to run arbitrary JavaScript against the Obsidian API (`app.*`).
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
| Problem | Cause | Fix |
|
|
||||||
|---|---|---|
|
|
||||||
| Empty output / hangs | Obsidian not running, or admin terminal (Windows) | Start Obsidian; use normal-privilege terminal |
|
|
||||||
| Command not found | CLI not registered in PATH | Re-enable CLI in Settings; restart terminal |
|
|
||||||
| Unicode errors | Fixed in v1.12.2+ | Update Obsidian |
|
|
||||||
| Wrong vault targeted | Multi-vault ambiguity | Pass vault name as first arg |
|
|
||||||
| IPC socket not found (Linux) | `PrivateTmp=true` in systemd | Set `PrivateTmp=false` |
|
|
||||||
| Snap confinement issues | Snap restricts IPC | Use `.deb` package instead |
|
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Eval Set Review - obsidian-cli v2</title>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@500;600&family=Lora:wght@400;500&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
|
body { font-family: 'Lora', Georgia, serif; background: #faf9f5; padding: 2rem; color: #141413; }
|
||||||
|
h1 { font-family: 'Poppins', sans-serif; margin-bottom: 0.5rem; font-size: 1.5rem; }
|
||||||
|
.description { color: #b0aea5; margin-bottom: 1.5rem; font-style: italic; max-width: 900px; }
|
||||||
|
.controls { margin-bottom: 1rem; display: flex; gap: 0.5rem; }
|
||||||
|
.btn { font-family: 'Poppins', sans-serif; padding: 0.5rem 1rem; border: none; border-radius: 6px; cursor: pointer; font-size: 0.875rem; font-weight: 500; }
|
||||||
|
.btn-add { background: #6a9bcc; color: white; }
|
||||||
|
.btn-add:hover { background: #5889b8; }
|
||||||
|
.btn-export { background: #d97757; color: white; }
|
||||||
|
.btn-export:hover { background: #c4613f; }
|
||||||
|
table { width: 100%; max-width: 1100px; border-collapse: collapse; background: white; border-radius: 6px; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
|
||||||
|
th { font-family: 'Poppins', sans-serif; background: #141413; color: #faf9f5; padding: 0.75rem 1rem; text-align: left; font-size: 0.875rem; }
|
||||||
|
td { padding: 0.75rem 1rem; border-bottom: 1px solid #e8e6dc; vertical-align: top; }
|
||||||
|
tr:nth-child(even) td { background: #faf9f5; }
|
||||||
|
tr:hover td { background: #f3f1ea; }
|
||||||
|
.section-header td { background: #e8e6dc; font-family: 'Poppins', sans-serif; font-weight: 500; font-size: 0.8rem; color: #141413; text-transform: uppercase; letter-spacing: 0.05em; }
|
||||||
|
.query-input { width: 100%; padding: 0.4rem; border: 1px solid #e8e6dc; border-radius: 4px; font-size: 0.875rem; font-family: 'Lora', Georgia, serif; resize: vertical; min-height: 60px; }
|
||||||
|
.query-input:focus { outline: none; border-color: #d97757; box-shadow: 0 0 0 2px rgba(217,119,87,0.15); }
|
||||||
|
.toggle { position: relative; display: inline-block; width: 44px; height: 24px; }
|
||||||
|
.toggle input { opacity: 0; width: 0; height: 0; }
|
||||||
|
.toggle .slider { position: absolute; inset: 0; background: #b0aea5; border-radius: 24px; cursor: pointer; transition: 0.2s; }
|
||||||
|
.toggle .slider::before { content: ""; position: absolute; width: 18px; height: 18px; left: 3px; bottom: 3px; background: white; border-radius: 50%; transition: 0.2s; }
|
||||||
|
.toggle input:checked + .slider { background: #d97757; }
|
||||||
|
.toggle input:checked + .slider::before { transform: translateX(20px); }
|
||||||
|
.btn-delete { background: #c44; color: white; padding: 0.3rem 0.6rem; border: none; border-radius: 4px; cursor: pointer; font-size: 0.75rem; font-family: 'Poppins', sans-serif; }
|
||||||
|
.btn-delete:hover { background: #a33; }
|
||||||
|
.summary { margin-top: 1rem; color: #b0aea5; font-size: 0.875rem; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Eval Set Review: <span id="skill-name">obsidian-cli</span></h1>
|
||||||
|
<p class="description">Current description: <span id="skill-desc">Use this skill whenever the user wants Claude to interact with their Obsidian vault — reading notes, creating or appending content, searching, managing tasks, tags, properties, daily notes, bookmarks, templates, sync, plugins, or links. The underlying mechanism is the official Obsidian CLI (v1.12+), but trigger even when the user doesn't mention the CLI — phrases like "add this to my daily note", "search my vault", "create a note from template", or "what tasks do I have open?" all apply. Also trigger for explicit CLI usage: running obsidian subcommands from a shell, scripting or automating vault operations, scheduling via cron, debugging IPC/headless Linux setups, or building programmatic wrappers. Skip only for pure GUI questions (Obsidian settings navigation, theme/plugin installation via UI) or iCloud sync configuration that has nothing to do with vault content.</span></p>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<button class="btn btn-add" onclick="addRow()">+ Add Query</button>
|
||||||
|
<button class="btn btn-export" onclick="exportEvalSet()">Export Eval Set</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width:65%">Query</th>
|
||||||
|
<th style="width:18%">Should Trigger</th>
|
||||||
|
<th style="width:10%">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="eval-body"></tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p class="summary" id="summary"></p>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const EVAL_DATA = [
|
||||||
|
{
|
||||||
|
"query": "add this to my daily note: 'reviewed the Q1 roadmap with sarah, she wants the mockups by friday'",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "search my vault for everything i've written about the Henderson project, i need to prep for a call",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "what open tasks do i have in obsidian? just the incomplete ones",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "create a new note from my meeting-notes template and call it 'Standup 2026-03-04'",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "append '- [ ] follow up with the design team about the nav bar' to my projects/mobile-redesign.md",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "how many notes are in my vault right now? also which ones have no links pointing to them?",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "read me today's daily note",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "set the status property on projects/q2-launch.md to 'in-review'",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "i want to write a script that pulls all notes tagged #meeting from the past week and summarizes them",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "move everything in my Inbox/ folder to Archive/2026/ and update the daily note with a log entry",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "how do i change the accent color in obsidian? i want something more muted than the default purple",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "i can't figure out how to enable community plugins in obsidian — the toggle is greyed out in safe mode",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "does obsidian have a built-in kanban view or do i need a plugin for that?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "my icloud sync for obsidian keeps conflicting with files on my ipad — how do i resolve this without losing data?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "how do i set up the obsidian git plugin to auto-commit my vault every hour?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "i use notion for my notes but i'm thinking of switching to obsidian — what's the best way to export from notion and import into obsidian?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "in the dataview plugin, how do i write a query that shows all notes with a due-date property before today?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "i want to customize the obsidian theme with css — how do i target the sidebar background color specifically?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "what's the keyboard shortcut to open the command palette in obsidian on mac?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "i'm writing a python script to parse markdown files from my notes folder and extract all the headings into a CSV — what's the best library for this?",
|
||||||
|
"should_trigger": false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
let evalItems = [...EVAL_DATA];
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
const tbody = document.getElementById('eval-body');
|
||||||
|
tbody.innerHTML = '';
|
||||||
|
const sorted = evalItems
|
||||||
|
.map((item, origIdx) => ({ ...item, origIdx }))
|
||||||
|
.sort((a, b) => (b.should_trigger ? 1 : 0) - (a.should_trigger ? 1 : 0));
|
||||||
|
let lastGroup = null;
|
||||||
|
sorted.forEach(item => {
|
||||||
|
const group = item.should_trigger ? 'trigger' : 'no-trigger';
|
||||||
|
if (group !== lastGroup) {
|
||||||
|
const headerRow = document.createElement('tr');
|
||||||
|
headerRow.className = 'section-header';
|
||||||
|
headerRow.innerHTML = `<td colspan="3">${item.should_trigger ? 'Should Trigger' : 'Should NOT Trigger'}</td>`;
|
||||||
|
tbody.appendChild(headerRow);
|
||||||
|
lastGroup = group;
|
||||||
|
}
|
||||||
|
const idx = item.origIdx;
|
||||||
|
const tr = document.createElement('tr');
|
||||||
|
tr.innerHTML = `
|
||||||
|
<td><textarea class="query-input" onchange="updateQuery(${idx}, this.value)">${escapeHtml(item.query)}</textarea></td>
|
||||||
|
<td>
|
||||||
|
<label class="toggle">
|
||||||
|
<input type="checkbox" ${item.should_trigger ? 'checked' : ''} onchange="updateTrigger(${idx}, this.checked)">
|
||||||
|
<span class="slider"></span>
|
||||||
|
</label>
|
||||||
|
<span style="margin-left:8px;font-size:0.8rem;color:#b0aea5">${item.should_trigger ? 'Yes' : 'No'}</span>
|
||||||
|
</td>
|
||||||
|
<td><button class="btn-delete" onclick="deleteRow(${idx})">Delete</button></td>
|
||||||
|
`;
|
||||||
|
tbody.appendChild(tr);
|
||||||
|
});
|
||||||
|
updateSummary();
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeHtml(text) {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.textContent = text;
|
||||||
|
return div.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateQuery(idx, value) { evalItems[idx].query = value; updateSummary(); }
|
||||||
|
function updateTrigger(idx, value) { evalItems[idx].should_trigger = value; render(); }
|
||||||
|
function deleteRow(idx) { evalItems.splice(idx, 1); render(); }
|
||||||
|
function addRow() {
|
||||||
|
evalItems.push({ query: '', should_trigger: true });
|
||||||
|
render();
|
||||||
|
const inputs = document.querySelectorAll('.query-input');
|
||||||
|
inputs[inputs.length - 1].focus();
|
||||||
|
}
|
||||||
|
function updateSummary() {
|
||||||
|
const trigger = evalItems.filter(i => i.should_trigger).length;
|
||||||
|
const noTrigger = evalItems.filter(i => !i.should_trigger).length;
|
||||||
|
document.getElementById('summary').textContent =
|
||||||
|
`${evalItems.length} queries total: ${trigger} should trigger, ${noTrigger} should not trigger`;
|
||||||
|
}
|
||||||
|
function exportEvalSet() {
|
||||||
|
const valid = evalItems.filter(i => i.query.trim() !== '');
|
||||||
|
const data = valid.map(i => ({ query: i.query.trim(), should_trigger: i.should_trigger }));
|
||||||
|
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'eval_set.json';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}
|
||||||
|
render();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"query": "add this to my daily note: 'reviewed the Q1 roadmap with sarah, she wants the mockups by friday'",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "search my vault for everything i've written about the Henderson project, i need to prep for a call",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "what open tasks do i have in obsidian? just the incomplete ones",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "create a new note from my meeting-notes template and call it 'Standup 2026-03-04'",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "append '- [ ] follow up with the design team about the nav bar' to my projects/mobile-redesign.md",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "how many notes are in my vault right now? also which ones have no links pointing to them?",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "read me today's daily note",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "set the status property on projects/q2-launch.md to 'in-review'",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "i want to write a script that pulls all notes tagged #meeting from the past week and summarizes them",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "move everything in my Inbox/ folder to Archive/2026/ and update the daily note with a log entry",
|
||||||
|
"should_trigger": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "how do i change the accent color in obsidian? i want something more muted than the default purple",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "i can't figure out how to enable community plugins in obsidian — the toggle is greyed out in safe mode",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "does obsidian have a built-in kanban view or do i need a plugin for that?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "my icloud sync for obsidian keeps conflicting with files on my ipad — how do i resolve this without losing data?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "how do i set up the obsidian git plugin to auto-commit my vault every hour?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "i use notion for my notes but i'm thinking of switching to obsidian — what's the best way to export from notion and import into obsidian?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "in the dataview plugin, how do i write a query that shows all notes with a due-date property before today?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "i want to customize the obsidian theme with css — how do i target the sidebar background color specifically?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "what's the keyboard shortcut to open the command palette in obsidian on mac?",
|
||||||
|
"should_trigger": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query": "i'm writing a python script to parse markdown files from my notes folder and extract all the headings into a CSV — what's the best library for this?",
|
||||||
|
"should_trigger": false
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "obsidian-cli",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "Interact with Obsidian vaults using the official Obsidian CLI (v1.12+). Read, create, search, and manage notes, daily notes, properties, tags, tasks, bookmarks, templates, sync, plugins, and links — all from the terminal.",
|
|
||||||
"author": "pablo-mano",
|
|
||||||
"repository": "https://github.com/pablo-mano/Obsidian-CLI-skill",
|
|
||||||
"skills": ["."]
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "obsidian-cli",
|
||||||
|
"description": "Interact with Obsidian vaults using the official Obsidian CLI (v1.12+). Read, create, append, search, and manage notes, daily notes, properties, tags, tasks, bookmarks, templates, themes, sync, plugins, and links — all from the terminal.",
|
||||||
|
"version": "1.3.0",
|
||||||
|
"author": {
|
||||||
|
"name": "pablo-mano"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/pablo-mano/Obsidian-CLI-skill",
|
||||||
|
"repository": "https://github.com/pablo-mano/Obsidian-CLI-skill"
|
||||||
|
}
|
||||||
@@ -0,0 +1,261 @@
|
|||||||
|
---
|
||||||
|
name: obsidian-cli
|
||||||
|
description: >
|
||||||
|
Use this skill whenever the user wants Claude to directly interact with their
|
||||||
|
Obsidian vault — reading a note or daily note, writing or appending content,
|
||||||
|
searching vault contents, counting or listing notes, managing tasks, moving or
|
||||||
|
renaming files, finding orphaned notes or broken links. Without this skill, Claude
|
||||||
|
has no way to access vault data or execute vault operations. Treat any request that
|
||||||
|
implies "go into my vault and do X" as a trigger — the user is asking Claude to act,
|
||||||
|
not to explain. Also trigger for vault automation, CLI scripting, or cron-based
|
||||||
|
workflows involving Obsidian. Skip for pure conceptual questions: how Obsidian's GUI
|
||||||
|
works, navigating settings menus, theme or plugin installation via the UI, or general
|
||||||
|
Dataview query syntax — anything where the user needs an explanation rather than
|
||||||
|
Claude performing a vault operation.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Obsidian CLI
|
||||||
|
|
||||||
|
The official Obsidian CLI (released in v1.12, February 2026) lets you control every aspect of Obsidian from the terminal. It communicates with a running Obsidian desktop instance via IPC.
|
||||||
|
|
||||||
|
> Read `references/command-reference.md` when you need specific flags, output formats, or
|
||||||
|
> subcommands for any command group. It covers all 130+ commands with full parameter tables
|
||||||
|
> and has a table of contents at the top.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
| Requirement | Details |
|
||||||
|
|---|---|
|
||||||
|
| Obsidian Desktop | **v1.12.0+** |
|
||||||
|
| CLI enabled | Settings → Command line interface → Toggle ON |
|
||||||
|
| Obsidian running | The desktop app **must be running** for CLI to work (IPC) |
|
||||||
|
|
||||||
|
### Platform Notes
|
||||||
|
|
||||||
|
- **macOS / Linux**: The `obsidian` binary is registered in PATH automatically when you enable CLI in settings.
|
||||||
|
- **Windows**: Requires an `Obsidian.com` redirector file placed alongside `Obsidian.exe`. **Must run with normal user privileges** — admin terminals produce silent failures.
|
||||||
|
- If colon subcommands (`property:set`, `daily:append`, etc.) with parameters return exit 127, verify that `Obsidian.com` exists alongside `Obsidian.exe`. Users who installed before v1.12 and updated in-app may be missing this file — download the latest installer from [obsidian.md/download](https://obsidian.md/download) to fix.
|
||||||
|
- **Git Bash / MSYS2 users**: Bash does not follow Windows' `.com`-before-`.exe` priority, so `obsidian` resolves to `Obsidian.exe` (GUI mode) instead of `Obsidian.com` (CLI). Create a wrapper script — see Troubleshooting.
|
||||||
|
- **Headless Linux**: Use the `.deb` package (not snap). Run under `xvfb`. Prefix commands with `DISPLAY=:5` (or your xvfb display number). Ensure `PrivateTmp=false` if running as a service.
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
All parameters use **`key=value`** syntax. Quote values containing spaces.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian <command> [subcommand] [key=value ...] [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Vault
|
||||||
|
|
||||||
|
Target a specific vault by making it the **first argument**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian "My Vault" daily:read
|
||||||
|
obsidian "Work Notes" search query="meeting"
|
||||||
|
```
|
||||||
|
|
||||||
|
If omitted, the CLI targets the most recently active vault.
|
||||||
|
|
||||||
|
## Command Overview
|
||||||
|
|
||||||
|
The CLI provides **130+ commands** across these groups:
|
||||||
|
|
||||||
|
| Group | Key Commands | Purpose |
|
||||||
|
|---|---|---|
|
||||||
|
| **files** | `read`, `create`, `append`, `prepend`, `move`, `rename`, `delete`, `files`, `folders`, `file`, `random` | Note CRUD and file discovery |
|
||||||
|
| **daily** | `daily`, `daily:read`, `daily:append`, `daily:prepend`, `daily:path` | Daily note operations |
|
||||||
|
| **search** | `search`, `search:context` | Full-text search; `search:context` returns matching lines |
|
||||||
|
| **properties** | `properties`, `property:read`, `property:set`, `property:remove`, `aliases` | Frontmatter/metadata management |
|
||||||
|
| **tags** | `tags`, `tag` | Tag listing, counts, and filtering |
|
||||||
|
| **tasks** | `tasks`, `task` | Task querying, filtering, and toggling |
|
||||||
|
| **links** | `backlinks`, `links`, `unresolved`, `orphans`, `deadends` | Graph and link analysis |
|
||||||
|
| **bookmarks** | `bookmarks`, `bookmark` | List and add bookmarks |
|
||||||
|
| **templates** | `templates`, `template:read`, `template:insert` | Template listing, rendering, insertion |
|
||||||
|
| **plugins** | `plugins`, `plugin`, `plugin:enable`, `plugin:disable`, `plugin:install`, `plugin:uninstall`, `plugins:restrict` | Plugin management |
|
||||||
|
| **sync** | `sync`, `sync:status`, `sync:history`, `sync:read`, `sync:restore`, `sync:deleted` | Obsidian Sync operations |
|
||||||
|
| **themes** | `themes`, `theme`, `theme:set`, `theme:install`, `theme:uninstall` | Theme management |
|
||||||
|
| **snippets** | `snippets`, `snippets:enabled`, `snippet:enable`, `snippet:disable` | CSS snippet management |
|
||||||
|
| **commands** | `commands`, `command`, `hotkeys`, `hotkey` | Execute Obsidian commands by ID; inspect hotkeys |
|
||||||
|
| **bases** | `bases`, `base:query`, `base:views`, `base:create` | Obsidian Bases (v1.12+ database feature) |
|
||||||
|
| **history** | `history`, `history:list`, `history:read`, `history:restore` | File version recovery (File Recovery plugin) |
|
||||||
|
| **workspace** | `workspace`, `tabs`, `tab:open` | Workspace layout and tab management |
|
||||||
|
| **diff** | `diff` | Compare local vs sync file versions |
|
||||||
|
| **dev** | `eval`, `dev:screenshot`, `dev:debug`, `dev:console`, `dev:errors`, `dev:css`, `dev:dom`, `devtools` | Developer/debugging tools |
|
||||||
|
| **vault** | `vault`, `vaults`, `version`, `reload`, `restart` | Vault info and app control |
|
||||||
|
| **other** | `outline`, `wordcount`, `recents` | Utility commands |
|
||||||
|
|
||||||
|
## Quick Reference — Most Common Commands
|
||||||
|
|
||||||
|
### Reading & Writing Notes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian read path="folder/note.md"
|
||||||
|
obsidian create path="folder/note" content="# New Note"
|
||||||
|
obsidian create path="folder/note" template="meeting-notes"
|
||||||
|
obsidian append path="folder/note.md" content="New paragraph"
|
||||||
|
obsidian prepend path="folder/note.md" content="Top content"
|
||||||
|
obsidian move path="old/note.md" to="new/note.md"
|
||||||
|
obsidian delete path="folder/note.md"
|
||||||
|
obsidian delete path="folder/note.md" permanent
|
||||||
|
```
|
||||||
|
|
||||||
|
### Daily Notes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian daily # Open today's daily note
|
||||||
|
obsidian daily:read # Print content of today's note
|
||||||
|
obsidian daily:append content="- [ ] New task"
|
||||||
|
obsidian daily:prepend content="## Morning Notes"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Search
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian search query="project alpha"
|
||||||
|
obsidian search query="TODO" path="projects" limit=10
|
||||||
|
obsidian search query="meeting" format=json # Returns JSON array of file paths
|
||||||
|
obsidian search query="urgent" case
|
||||||
|
```
|
||||||
|
|
||||||
|
### Properties & Tags
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian properties path="note.md"
|
||||||
|
obsidian property:set path="note.md" name="status" value="active"
|
||||||
|
obsidian property:read path="note.md" name="status"
|
||||||
|
obsidian property:remove path="note.md" name="draft"
|
||||||
|
obsidian tags counts sort=count
|
||||||
|
obsidian tag name="project/alpha"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tasks
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian tasks # All tasks (done + todo) — same as tasks all in v1.12
|
||||||
|
obsidian tasks all # All tasks (done + todo)
|
||||||
|
obsidian tasks done # Completed only
|
||||||
|
obsidian tasks daily # Tasks in today's daily note
|
||||||
|
obsidian task path="note.md" line=12 toggle
|
||||||
|
obsidian tasks | grep "\[ \]" # Workaround: filter to incomplete only
|
||||||
|
```
|
||||||
|
|
||||||
|
### Developer & Automation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian eval code="app.vault.getFiles().length"
|
||||||
|
obsidian dev:screenshot path="folder/screenshot.png" # Path must be vault-relative
|
||||||
|
obsidian dev:debug on # Required before dev:console
|
||||||
|
obsidian dev:console limit=20
|
||||||
|
obsidian dev:errors
|
||||||
|
```
|
||||||
|
|
||||||
|
## TUI Mode
|
||||||
|
|
||||||
|
Running `obsidian` with no arguments launches an interactive TUI (Terminal User Interface):
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|---|---|
|
||||||
|
| `↑↓` | Navigate files |
|
||||||
|
| `Enter` | Open file |
|
||||||
|
| `/` | Search |
|
||||||
|
| `n` | Create new file |
|
||||||
|
| `d` | Delete file |
|
||||||
|
| `r` | Rename file |
|
||||||
|
| `q` | Quit |
|
||||||
|
|
||||||
|
## Common Agent Patterns
|
||||||
|
|
||||||
|
### Daily Journal Automation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Append a timestamped entry
|
||||||
|
obsidian daily:append content="## $(date '+%H:%M') — Status Update
|
||||||
|
- Completed: feature branch merge
|
||||||
|
- Next: code review for PR #42
|
||||||
|
- Blocked: waiting on API credentials"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create Note from Template with Metadata
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian create path="projects/new-feature" template="project-template"
|
||||||
|
obsidian property:set path="projects/new-feature.md" name="status" value="planning"
|
||||||
|
obsidian property:set path="projects/new-feature.md" name="created" value="$(date -I)"
|
||||||
|
obsidian daily:append content="- Started [[projects/new-feature|New Feature]]"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vault Analytics Script
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian files total # Total file count
|
||||||
|
obsidian tags counts sort=count # Most used tags
|
||||||
|
obsidian tasks | grep "\[ \]" # Incomplete tasks across vault
|
||||||
|
obsidian orphans # Notes needing integration
|
||||||
|
obsidian unresolved # Broken links to fix
|
||||||
|
```
|
||||||
|
|
||||||
|
### Search and Extract for AI Processing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian search query="meeting notes" format=json | jq '.[]'
|
||||||
|
obsidian read path="meetings/standup.md" | grep "Action item"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sync Management
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian sync:status # Check sync health
|
||||||
|
obsidian sync:history path="important.md" # Version history
|
||||||
|
obsidian sync:restore path="important.md" version=3 # Rollback
|
||||||
|
```
|
||||||
|
|
||||||
|
### Execute Obsidian Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Find a command ID, then execute it
|
||||||
|
obsidian commands | grep "graph"
|
||||||
|
obsidian command id="graph:open"
|
||||||
|
|
||||||
|
# Open settings, trigger a plugin action
|
||||||
|
obsidian command id="app:open-settings"
|
||||||
|
obsidian command id="dataview:dataview-force-refresh-views"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
1. **Paths are vault-relative** — use `folder/note.md`, not absolute filesystem paths.
|
||||||
|
2. **`create` paths omit `.md`** — the extension is added automatically.
|
||||||
|
3. **`move` requires full target path** including `.md` extension.
|
||||||
|
4. **Pipe-friendly** — plain text output works with `grep`, `awk`, `sed`, `jq`.
|
||||||
|
5. **JSON output** — use `format=json` on `search` for a JSON array of file paths. The `files` command does not support JSON output.
|
||||||
|
6. **Stderr noise** — GPU/Electron warnings on headless are harmless; filter with `2>/dev/null`.
|
||||||
|
7. **`daily:prepend`** inserts content after frontmatter, not at byte 0.
|
||||||
|
8. **Use `eval`** to run arbitrary JavaScript against the Obsidian API (`app.*`).
|
||||||
|
9. **`template:insert`** inserts into the currently active file in the Obsidian UI — it does not accept a `path=` parameter. If no file is open, it returns `Error: No active editor. Open a file first.` To create a file from a template via CLI, use `obsidian create path="..." template="..."` instead.
|
||||||
|
10. **`property:set` stores list values as strings** — `value="tag1, tag2"` writes a literal comma-separated string, not a YAML array. For proper array fields, edit the note's frontmatter directly (e.g. via `read` → modify → `create --force`) or use `eval` to call the Obsidian API.
|
||||||
|
11. **`eval` requires single-line JavaScript** — multiline JS passed inline fails with a token error. Write the script to a temp file instead:
|
||||||
|
```bash
|
||||||
|
cat > /tmp/obs.js << 'JS'
|
||||||
|
var files = app.vault.getMarkdownFiles();
|
||||||
|
files.length;
|
||||||
|
JS
|
||||||
|
obsidian eval code="$(cat /tmp/obs.js)"
|
||||||
|
```
|
||||||
|
12. **Multi-vault targeting may not work in all environments** — `obsidian "My Vault" command` can return `Error: Command "My Vault" not found` on some setups. If this happens, omit the vault name (CLI targets the most recently active vault) and switch vaults manually in the Obsidian UI.
|
||||||
|
13. **When colon subcommands are unavailable** (e.g., missing `Obsidian.com` on Windows), prefer non-colon alternatives: use `properties` instead of `property:read`, or `obsidian daily:path` + `obsidian append path="..."` instead of `daily:append`. Most read-only and file operations work without colon subcommands.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
| Problem | Cause | Fix |
|
||||||
|
|---|---|---|
|
||||||
|
| Empty output / hangs | Obsidian not running, or admin terminal (Windows) | Start Obsidian; use normal-privilege terminal |
|
||||||
|
| Command not found | CLI not registered in PATH | Re-enable CLI in Settings; restart terminal |
|
||||||
|
| Unicode errors | Fixed in v1.12.2+ | Update Obsidian |
|
||||||
|
| Wrong vault targeted | Multi-vault ambiguity | Pass vault name as first arg |
|
||||||
|
| IPC socket not found (Linux) | `PrivateTmp=true` in systemd | Set `PrivateTmp=false` |
|
||||||
|
| Snap confinement issues | Snap restricts IPC | Use `.deb` package instead |
|
||||||
|
| Multi-vault `"Name" command` fails | Vault name matching issue | Omit vault name; target most recent vault |
|
||||||
|
| `property:set` list value is a string | CLI stores value as-is | Edit frontmatter directly or use `eval` |
|
||||||
|
| Colon+params exit 127 (Windows, `Obsidian.com` missing) | Outdated installer — in-app update skips `.com` file | Reinstall from [obsidian.md/download](https://obsidian.md/download) |
|
||||||
|
| Colon+params exit 127 (Git Bash / MSYS2) | Bash resolves `obsidian` to `.exe` (GUI), not `.com` (CLI) | Create `~/bin/obsidian` wrapper: `#!/bin/bash`<br>`/c/Users/<you>/AppData/Local/Obsidian/Obsidian.com "$@"` and add `export PATH="$HOME/bin:$PATH"` to `~/.bashrc` |
|
||||||
@@ -0,0 +1,651 @@
|
|||||||
|
# Obsidian CLI — Full Command Reference
|
||||||
|
|
||||||
|
Complete reference for all official Obsidian CLI commands (v1.12+).
|
||||||
|
|
||||||
|
**Syntax**: `obsidian [vault] <command> [subcommand] [key=value ...] [flags]`
|
||||||
|
|
||||||
|
All parameters use `key=value` syntax. Quote values containing spaces: `content="hello world"`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
1. [Files](#files)
|
||||||
|
2. [Daily Notes](#daily-notes)
|
||||||
|
3. [Search](#search)
|
||||||
|
4. [Properties](#properties)
|
||||||
|
5. [Tags](#tags)
|
||||||
|
6. [Tasks](#tasks)
|
||||||
|
7. [Links](#links)
|
||||||
|
8. [Bookmarks](#bookmarks)
|
||||||
|
9. [Templates](#templates)
|
||||||
|
10. [Plugins](#plugins)
|
||||||
|
11. [Sync](#sync)
|
||||||
|
12. [Themes](#themes)
|
||||||
|
13. [CSS Snippets](#css-snippets)
|
||||||
|
14. [Commands & Hotkeys](#commands--hotkeys)
|
||||||
|
15. [Obsidian Bases](#obsidian-bases)
|
||||||
|
16. [History](#history)
|
||||||
|
17. [Workspace & Tabs](#workspace--tabs)
|
||||||
|
18. [Diff](#diff)
|
||||||
|
19. [Developer](#developer)
|
||||||
|
20. [Vault & System](#vault--system)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
File operations: read, write, create, move, delete, list.
|
||||||
|
|
||||||
|
### Reading Notes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian read path="folder/note.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
Prints raw markdown content of a note to stdout. Path is vault-relative.
|
||||||
|
|
||||||
|
### Creating Notes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian create path="folder/note" content="# Title\n\nBody text"
|
||||||
|
obsidian create path="folder/note" template="template-name"
|
||||||
|
```
|
||||||
|
|
||||||
|
- Path should **not** include `.md` — it is appended automatically.
|
||||||
|
- Use `template=` to create from a template file.
|
||||||
|
- Use `content=` to set initial content directly.
|
||||||
|
|
||||||
|
### Appending & Prepending
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian append path="folder/note.md" content="Appended text"
|
||||||
|
obsidian prepend path="folder/note.md" content="Prepended text"
|
||||||
|
```
|
||||||
|
|
||||||
|
- `append` adds content at the end of the file.
|
||||||
|
- `prepend` adds content after the frontmatter (not at byte 0).
|
||||||
|
|
||||||
|
### Moving & Renaming
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian move path="old/path/note.md" to="new/path/note.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
- `to=` is the full vault-relative target path including the `.md` extension.
|
||||||
|
- Can be used to move, rename, or both in a single command.
|
||||||
|
|
||||||
|
### Deleting
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian delete path="folder/note.md" # Moves to trash
|
||||||
|
obsidian delete path="folder/note.md" permanent # Permanent deletion
|
||||||
|
```
|
||||||
|
|
||||||
|
### File Discovery
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian files # List all files in vault
|
||||||
|
obsidian files ext=md # Filter by extension
|
||||||
|
obsidian files folder="subfolder" # Files in specific folder
|
||||||
|
obsidian files total # Just the file count
|
||||||
|
obsidian folders # List all folders
|
||||||
|
obsidian file path="folder/note.md" # File info (size, created, modified dates)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Random Notes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian random # Open a random note in Obsidian
|
||||||
|
obsidian random:read # Print content of a random note to stdout
|
||||||
|
```
|
||||||
|
|
||||||
|
### Renaming
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian rename path="folder/note.md" name="new-name"
|
||||||
|
```
|
||||||
|
|
||||||
|
- `name=` is the new filename only (no path, no `.md` extension).
|
||||||
|
- Use `move` when you also want to change the folder.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Daily Notes
|
||||||
|
|
||||||
|
Operations on the daily note (requires Daily Notes core plugin enabled).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian daily # Open today's daily note in Obsidian
|
||||||
|
obsidian daily:read # Print today's daily note content to stdout
|
||||||
|
obsidian daily:append content="text" # Append content to today's note
|
||||||
|
obsidian daily:prepend content="text" # Prepend content (after frontmatter)
|
||||||
|
obsidian daily:path # Print vault-relative path of today's note
|
||||||
|
```
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
- `daily:prepend` inserts content after the frontmatter block, not at the very beginning.
|
||||||
|
- If today's note doesn't exist, `daily` will create it (using the configured template if set).
|
||||||
|
- Daily note format/folder are configured in Obsidian's Daily Notes plugin settings.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Search
|
||||||
|
|
||||||
|
Full-text search across the vault.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian search query="search text"
|
||||||
|
obsidian search query="text" path="folder" # Scope to folder
|
||||||
|
obsidian search query="text" limit=10 # Limit results
|
||||||
|
obsidian search query="text" format=json # JSON output (array of file paths)
|
||||||
|
obsidian search query="text" matches # Accepted but returns file paths only
|
||||||
|
obsidian search query="text" case # Case-sensitive search
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `query=` — Search term (required)
|
||||||
|
- `path=` — Restrict search to a folder
|
||||||
|
- `limit=` — Maximum number of results
|
||||||
|
- `format=json` — Returns a JSON array of matching file paths: `["folder/note.md", ...]`
|
||||||
|
- `matches` — Flag accepted by the CLI but does not return match context/snippets in v1.12
|
||||||
|
- `case` — Enable case-sensitive matching
|
||||||
|
|
||||||
|
### Search with Context
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian search:context query="search text"
|
||||||
|
obsidian search:context query="text" path="folder" limit=10
|
||||||
|
obsidian search:context query="text" case
|
||||||
|
obsidian search:context query="text" format=json
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns matching lines with surrounding context (not just file paths). Useful when you need to see the actual content that matched rather than just file paths.
|
||||||
|
|
||||||
|
### Open Search View
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian search:open query="search text"
|
||||||
|
```
|
||||||
|
|
||||||
|
Opens the Obsidian search panel in the UI with the given query.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
Manage frontmatter (YAML metadata) on notes.
|
||||||
|
|
||||||
|
### Read All Properties
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian properties path="note.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Read Single Property
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian property:read path="note.md" name="status"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set Property
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian property:set path="note.md" name="status" value="active"
|
||||||
|
obsidian property:set path="note.md" name="tags" value="[project, alpha]"
|
||||||
|
obsidian property:set path="note.md" name="date" value="2026-02-27"
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** `property:set` always stores `value=` as a string. Passing `value="[project, alpha]"` writes
|
||||||
|
> the literal string `[project, alpha]`, not a YAML array. For true array-typed properties (e.g. `tags`),
|
||||||
|
> edit the note's frontmatter directly or use `eval` with the Obsidian API.
|
||||||
|
|
||||||
|
### Remove Property
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian property:remove path="note.md" name="draft"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Aliases
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian aliases path="note.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
Lists all aliases defined in the note's frontmatter.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tags
|
||||||
|
|
||||||
|
Tag discovery and filtering.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian tags # List all tags in the vault
|
||||||
|
obsidian tags counts # Tags with usage counts
|
||||||
|
obsidian tags counts sort=count # Sorted by frequency (most used first)
|
||||||
|
obsidian tags path="note.md" # Tags in a specific file
|
||||||
|
obsidian tag name="project/alpha" # List notes with a specific tag
|
||||||
|
```
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
- Nested tags are supported (e.g., `project/alpha`).
|
||||||
|
- Tags from both frontmatter and inline `#tag` syntax are included.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
Query and manage checkbox tasks across the vault.
|
||||||
|
|
||||||
|
### Querying Tasks
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian tasks # All tasks (same as tasks all in v1.12)
|
||||||
|
obsidian tasks all # All tasks (complete + incomplete)
|
||||||
|
obsidian tasks done # Only completed tasks
|
||||||
|
obsidian tasks path="note.md" # Tasks in a specific file
|
||||||
|
obsidian tasks daily # Tasks in today's daily note
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** In v1.12, `tasks` with no arguments returns all tasks (complete + incomplete), identical to `tasks all`. Filtering to incomplete-only is not currently supported without post-processing (e.g. pipe to `grep "\[ \]"`).
|
||||||
|
|
||||||
|
### Toggling Task Status
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian task path="note.md" line=12 toggle
|
||||||
|
```
|
||||||
|
|
||||||
|
Toggles the checkbox on the specified line number between `- [ ]` and `- [x]`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
Graph analysis and link management.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian backlinks path="note.md" # Notes linking TO this note
|
||||||
|
obsidian backlinks path="note.md" counts # With link counts per file
|
||||||
|
obsidian links path="note.md" # Outgoing links FROM this note
|
||||||
|
obsidian unresolved # All unresolved [[wikilinks]]
|
||||||
|
obsidian orphans # Notes with no incoming or outgoing links
|
||||||
|
obsidian deadends # Notes with no outgoing links
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bookmarks
|
||||||
|
|
||||||
|
Manage Obsidian bookmarks (requires Bookmarks core plugin).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian bookmarks # List all bookmarks
|
||||||
|
obsidian bookmark file="folder/note.md" # Bookmark a note
|
||||||
|
obsidian bookmark file="folder/note.md" subpath="#Heading" # Bookmark a heading
|
||||||
|
obsidian bookmark folder="projects" # Bookmark a folder
|
||||||
|
obsidian bookmark search="query text" title="My Search" # Bookmark a search
|
||||||
|
obsidian bookmark url="https://example.com" title="Link" # Bookmark a URL
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Templates
|
||||||
|
|
||||||
|
Work with note templates (requires Templates or Templater plugin).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian templates # List available templates
|
||||||
|
obsidian template:read name="weekly-review" # Read template content
|
||||||
|
obsidian template:read name="weekly-review" resolve title="My Note" # Render with variables
|
||||||
|
obsidian template:insert name="weekly-review" # Insert template into the active Obsidian UI file
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `name=` — Template name (without path prefix or extension)
|
||||||
|
- `resolve` — Process template variables (`{{date}}`, `{{title}}`, etc.)
|
||||||
|
- Title and other variables can be passed as `key=value` for template rendering.
|
||||||
|
|
||||||
|
> **Note:** `template:insert` inserts into whichever file is currently active in the Obsidian UI — it does not accept a `path=` parameter. If no file is open, it returns `Error: No active editor. Open a file first.` To create a new file from a template, use `obsidian create path="..." template="..."` instead.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plugins
|
||||||
|
|
||||||
|
Manage community and core plugins.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian plugins # List all plugins (core + community)
|
||||||
|
obsidian plugins:enabled # Only enabled plugins
|
||||||
|
obsidian plugins versions # Plugins with version numbers (community only)
|
||||||
|
obsidian plugins:restrict # Show restricted mode status
|
||||||
|
obsidian plugins:restrict on # Enable restricted mode (disables community plugins)
|
||||||
|
obsidian plugins:restrict off # Disable restricted mode
|
||||||
|
obsidian plugin id="dataview" # Get info about a specific plugin
|
||||||
|
obsidian plugin:enable id="canvas" # Enable a plugin
|
||||||
|
obsidian plugin:disable id="canvas" # Disable a plugin
|
||||||
|
obsidian plugin:install id="dataview" # Install from community plugins
|
||||||
|
obsidian plugin:uninstall id="dataview" # Uninstall a community plugin
|
||||||
|
obsidian plugin:reload id="my-plugin" # Reload a plugin (useful for dev)
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** `plugins versions` only shows version numbers for community plugins. Core (built-in) plugins share Obsidian's version and display blank version fields.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sync
|
||||||
|
|
||||||
|
Manage Obsidian Sync (requires active Sync subscription).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian sync # Show sync status summary
|
||||||
|
obsidian sync on # Resume syncing
|
||||||
|
obsidian sync off # Pause syncing
|
||||||
|
obsidian sync:status # Detailed sync status
|
||||||
|
obsidian sync:history path="note.md" # Version history for a file
|
||||||
|
obsidian sync:read path="note.md" version=3 # Read a specific version
|
||||||
|
obsidian sync:restore path="note.md" version=3 # Restore a previous version
|
||||||
|
obsidian sync:deleted # List files deleted via sync
|
||||||
|
obsidian sync:open # Open the Sync history view in the UI
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Themes
|
||||||
|
|
||||||
|
Manage appearance themes.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian themes # List installed themes
|
||||||
|
obsidian themes versions # List installed themes with version numbers
|
||||||
|
obsidian theme # Show the currently active theme
|
||||||
|
obsidian theme name="Minimal" # Get details about a specific theme
|
||||||
|
obsidian theme:set name="Minimal" # Switch to a theme
|
||||||
|
obsidian theme:set name="" # Switch back to default theme
|
||||||
|
obsidian theme:install name="Minimal" # Install a community theme
|
||||||
|
obsidian theme:install name="Minimal" enable # Install and activate immediately
|
||||||
|
obsidian theme:uninstall name="Minimal" # Uninstall a theme
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CSS Snippets
|
||||||
|
|
||||||
|
Manage custom CSS snippet files (snippets live in `.obsidian/snippets/`).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian snippets # List all installed CSS snippets
|
||||||
|
obsidian snippets:enabled # List only enabled snippets
|
||||||
|
obsidian snippet:enable name="my-style" # Enable a snippet
|
||||||
|
obsidian snippet:disable name="my-style" # Disable a snippet
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Commands & Hotkeys
|
||||||
|
|
||||||
|
Execute any Obsidian command by its ID, and inspect hotkey bindings.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian commands # List all available command IDs
|
||||||
|
obsidian command id="app:reload" # Execute a command by ID
|
||||||
|
obsidian command id="editor:toggle-bold" # Example: toggle bold in active editor
|
||||||
|
obsidian hotkeys # List all hotkeys (tab-separated: id \t keybinding)
|
||||||
|
obsidian hotkey id="app:open-settings" # Get hotkey for a specific command
|
||||||
|
obsidian hotkey id="app:open-settings" verbose # Show if custom or default
|
||||||
|
```
|
||||||
|
|
||||||
|
**Typical workflow — find and run a command:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian commands | grep "canvas" # Find canvas-related command IDs
|
||||||
|
obsidian command id="canvas:new-file" # Execute the matched command
|
||||||
|
```
|
||||||
|
|
||||||
|
**Getting plugin command IDs:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian commands | grep "dataview" # List all Dataview plugin commands
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Obsidian Bases
|
||||||
|
|
||||||
|
Obsidian Bases (v1.12+) is a built-in database feature. Base files (`.base`) store structured data and support multiple views.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian bases # List all .base files in vault
|
||||||
|
obsidian base:query file="tasks" format=json # Query default view of a base
|
||||||
|
obsidian base:query file="tasks" view="Kanban" # Query a specific view
|
||||||
|
obsidian base:query path="folder/tasks.base" format=csv # Query by path
|
||||||
|
obsidian base:views file="tasks" # List all views in a base file
|
||||||
|
obsidian base:create file="tasks" title="Buy milk" # Add an item to a base
|
||||||
|
```
|
||||||
|
|
||||||
|
**Supported output formats for `base:query`:** `json` (default), `csv`, `tsv`, `md`, `paths`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## History
|
||||||
|
|
||||||
|
File version history (built-in to Obsidian, separate from Sync). Requires the File Recovery core plugin.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian history:list # List all files that have history
|
||||||
|
obsidian history path="folder/note.md" # List versions of a specific file
|
||||||
|
obsidian history:read path="folder/note.md" # Read the latest saved version
|
||||||
|
obsidian history:read path="folder/note.md" version=3 # Read a specific version
|
||||||
|
obsidian history:restore path="folder/note.md" version=3 # Restore a version
|
||||||
|
obsidian history:open path="folder/note.md" # Open file recovery UI for a file
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** History is distinct from [Sync version history](#sync). History uses Obsidian's built-in File Recovery snapshots; Sync history uses Obsidian Sync cloud versions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Workspace & Tabs
|
||||||
|
|
||||||
|
Inspect and manage the Obsidian workspace layout and open tabs.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian workspace # Show the full workspace tree
|
||||||
|
obsidian tabs # List all open tabs (flat list)
|
||||||
|
obsidian tab:open file="folder/note.md" # Open a file in a new tab
|
||||||
|
obsidian tab:open view="graph" # Open a view type in a new tab
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Diff
|
||||||
|
|
||||||
|
Compare local and sync versions of a file.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian diff path="folder/note.md" # List available versions (local + sync)
|
||||||
|
obsidian diff path="folder/note.md" from=1 to=2 # Diff two specific versions
|
||||||
|
obsidian diff path="folder/note.md" filter=local # Show only local versions
|
||||||
|
obsidian diff path="folder/note.md" filter=sync # Show only sync versions
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Developer
|
||||||
|
|
||||||
|
Debugging and development tools.
|
||||||
|
|
||||||
|
### Screenshots
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian dev:screenshot path="folder/screenshot.png"
|
||||||
|
```
|
||||||
|
|
||||||
|
Takes a screenshot of the Obsidian window and saves it. **Path must be vault-relative** — absolute filesystem paths are silently ignored.
|
||||||
|
|
||||||
|
### JavaScript Evaluation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian eval code="app.vault.getFiles().length"
|
||||||
|
obsidian eval code="app.vault.getMarkdownFiles().map(f => f.path).join('\n')"
|
||||||
|
```
|
||||||
|
|
||||||
|
Executes arbitrary JavaScript in the Obsidian app context. Has access to the full Obsidian API (`app`, `app.vault`, `app.workspace`, `app.metadataCache`, etc.).
|
||||||
|
|
||||||
|
> **Multiline scripts:** Passing multiline JavaScript inline fails with "Invalid or unexpected token".
|
||||||
|
> Write the code to a temp file and use command substitution instead:
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> cat > /tmp/obs.js << 'JS'
|
||||||
|
> var files = app.vault.getMarkdownFiles();
|
||||||
|
> files.map(f => f.path).join('\n');
|
||||||
|
> JS
|
||||||
|
> obsidian eval code="$(cat /tmp/obs.js)"
|
||||||
|
> ```
|
||||||
|
|
||||||
|
### Console & Errors
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian dev:debug on # Start capturing console output (required before dev:console)
|
||||||
|
obsidian dev:debug off # Stop capturing console output
|
||||||
|
obsidian dev:console limit=20 # Recent console output (requires dev:debug on first)
|
||||||
|
obsidian dev:errors # Recent error messages
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** `dev:console` will return an error unless `dev:debug on` has been run first in the current session.
|
||||||
|
|
||||||
|
### DOM Inspection
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian dev:dom selector=".view-content" # Get outerHTML of first match
|
||||||
|
obsidian dev:dom selector=".view-content" all # Get all matches
|
||||||
|
obsidian dev:dom selector=".view-content" text # Get text content
|
||||||
|
obsidian dev:dom selector=".view-content" total # Count matching elements
|
||||||
|
obsidian dev:dom selector=".view-content" attr=class # Get an attribute value
|
||||||
|
obsidian dev:dom selector=".view-content" css=color # Get a CSS property value
|
||||||
|
```
|
||||||
|
|
||||||
|
### CSS Inspection
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian dev:css selector=".view-content" # Inspect CSS with source locations
|
||||||
|
obsidian dev:css selector=".view-content" prop=color # Filter by CSS property name
|
||||||
|
```
|
||||||
|
|
||||||
|
### Chrome DevTools Protocol
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian devtools # Toggle Electron DevTools panel
|
||||||
|
obsidian dev:cdp method="Runtime.evaluate" params='{"expression":"1+1"}' # Run a CDP command
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mobile Emulation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian dev:mobile on # Enable mobile emulation
|
||||||
|
obsidian dev:mobile off # Disable mobile emulation
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vault & System
|
||||||
|
|
||||||
|
### Vault Information
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian vault # Current vault: name, path, file/folder counts
|
||||||
|
obsidian vaults # List all known vaults
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other Utilities
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian version # Obsidian version info
|
||||||
|
obsidian outline path="note.md" # Heading structure of a note
|
||||||
|
obsidian wordcount path="note.md" # Word and character count
|
||||||
|
obsidian recents # Recently opened files
|
||||||
|
obsidian reload # Reload the vault (re-index)
|
||||||
|
obsidian restart # Restart the Obsidian app
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Formatting & Piping
|
||||||
|
|
||||||
|
The CLI outputs plain text by default, ideal for piping into Unix tools.
|
||||||
|
|
||||||
|
### Supported `format=` values
|
||||||
|
|
||||||
|
| Format | Description | Best for |
|
||||||
|
|---|---|---|
|
||||||
|
| `text` | Plain text (default) | Piping to grep/awk/sed |
|
||||||
|
| `json` | JSON array or object | Processing with jq, AI agents |
|
||||||
|
| `csv` | Comma-separated values | Spreadsheet import |
|
||||||
|
| `tsv` | Tab-separated values | Shell parsing with cut/awk |
|
||||||
|
| `yaml` | YAML output | Config-style processing |
|
||||||
|
| `md` | Markdown table | Embedding results in notes |
|
||||||
|
| `paths` | One path per line | Batch file operations |
|
||||||
|
| `tree` | Tree view | Visual hierarchy |
|
||||||
|
|
||||||
|
Not all formats are supported by every command. Use `text` or `json` when in doubt.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Count notes in a folder
|
||||||
|
obsidian files folder="projects" | wc -l
|
||||||
|
|
||||||
|
# Find notes with a specific tag, then read them
|
||||||
|
obsidian tag name="urgent" | while read -r note; do
|
||||||
|
echo "=== $note ==="
|
||||||
|
obsidian read path="$note"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Export search results as JSON and process with jq
|
||||||
|
# format=json returns an array of file path strings: ["folder/note.md", ...]
|
||||||
|
obsidian search query="meeting" format=json | jq '.[]'
|
||||||
|
|
||||||
|
# Query a base as CSV
|
||||||
|
obsidian base:query file="tasks" format=csv
|
||||||
|
|
||||||
|
# Filter console errors (requires dev:debug on first)
|
||||||
|
obsidian dev:debug on
|
||||||
|
obsidian dev:console limit=50 | grep -i error
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Multi-Vault Usage
|
||||||
|
|
||||||
|
When working with multiple vaults, pass the vault name as the **first argument** (before the command):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian "Personal" daily:read
|
||||||
|
obsidian "Work" search query="standup"
|
||||||
|
obsidian "Archive" files total
|
||||||
|
```
|
||||||
|
|
||||||
|
If the vault name contains spaces, quote it. The vault name must match what's shown in `obsidian vaults`.
|
||||||
|
|
||||||
|
> **Compatibility note:** On some environments, `obsidian "My Vault" command` returns
|
||||||
|
> `Error: Command "My Vault" not found`. If this occurs, omit the vault name — the CLI will target
|
||||||
|
> the most recently active vault. Switch vaults in the Obsidian UI before running CLI commands
|
||||||
|
> when targeting a specific vault.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Headless / Server Setup (Linux)
|
||||||
|
|
||||||
|
For running Obsidian CLI on a headless Linux server (useful for AI agent integration):
|
||||||
|
|
||||||
|
1. Install the `.deb` package (not snap — snap confinement breaks IPC)
|
||||||
|
2. Install and start `xvfb`: `Xvfb :5 -screen 0 1920x1080x24 &`
|
||||||
|
3. Start Obsidian under xvfb: `DISPLAY=:5 obsidian &`
|
||||||
|
4. Run CLI commands: `DISPLAY=:5 obsidian daily:read`
|
||||||
|
|
||||||
|
**Systemd note**: If running as a service, ensure `PrivateTmp=false` so the IPC socket is accessible.
|
||||||
|
|
||||||
|
**Stderr filtering**: Headless environments produce harmless GPU warnings. Filter with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
DISPLAY=:5 obsidian search query="test" 2>/dev/null
|
||||||
|
```
|
||||||
@@ -1,409 +0,0 @@
|
|||||||
# Obsidian CLI — Full Command Reference
|
|
||||||
|
|
||||||
Complete reference for all official Obsidian CLI commands (v1.12+).
|
|
||||||
|
|
||||||
**Syntax**: `obsidian [vault] <command> [subcommand] [key=value ...] [flags]`
|
|
||||||
|
|
||||||
All parameters use `key=value` syntax. Quote values containing spaces: `content="hello world"`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Table of Contents
|
|
||||||
|
|
||||||
1. [Files](#files)
|
|
||||||
2. [Daily Notes](#daily-notes)
|
|
||||||
3. [Search](#search)
|
|
||||||
4. [Properties](#properties)
|
|
||||||
5. [Tags](#tags)
|
|
||||||
6. [Tasks](#tasks)
|
|
||||||
7. [Links](#links)
|
|
||||||
8. [Bookmarks](#bookmarks)
|
|
||||||
9. [Templates](#templates)
|
|
||||||
10. [Plugins](#plugins)
|
|
||||||
11. [Sync](#sync)
|
|
||||||
12. [Themes](#themes)
|
|
||||||
13. [Developer](#developer)
|
|
||||||
14. [Vault & System](#vault--system)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Files
|
|
||||||
|
|
||||||
File operations: read, write, create, move, delete, list.
|
|
||||||
|
|
||||||
### Reading Notes
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian read path="folder/note.md"
|
|
||||||
```
|
|
||||||
|
|
||||||
Prints raw markdown content of a note to stdout. Path is vault-relative.
|
|
||||||
|
|
||||||
### Creating Notes
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian create path="folder/note" content="# Title\n\nBody text"
|
|
||||||
obsidian create path="folder/note" template="template-name"
|
|
||||||
```
|
|
||||||
|
|
||||||
- Path should **not** include `.md` — it is appended automatically.
|
|
||||||
- Use `template=` to create from a template file.
|
|
||||||
- Use `content=` to set initial content directly.
|
|
||||||
|
|
||||||
### Appending & Prepending
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian append path="folder/note.md" content="Appended text"
|
|
||||||
obsidian prepend path="folder/note.md" content="Prepended text"
|
|
||||||
```
|
|
||||||
|
|
||||||
- `append` adds content at the end of the file.
|
|
||||||
- `prepend` adds content after the frontmatter (not at byte 0).
|
|
||||||
|
|
||||||
### Moving & Renaming
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian move path="old/path/note.md" name="new-name"
|
|
||||||
```
|
|
||||||
|
|
||||||
- `name=` is the new filename (moves/renames).
|
|
||||||
- The target path must include the `.md` extension when specifying a full path.
|
|
||||||
|
|
||||||
### Deleting
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian delete path="folder/note.md" # Moves to trash
|
|
||||||
obsidian delete path="folder/note.md" permanent # Permanent deletion
|
|
||||||
```
|
|
||||||
|
|
||||||
### File Discovery
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian files # List all files in vault
|
|
||||||
obsidian files ext=md # Filter by extension
|
|
||||||
obsidian files folder="subfolder" # Files in specific folder
|
|
||||||
obsidian files total # Just the file count
|
|
||||||
obsidian files format=json # JSON output
|
|
||||||
obsidian folders # List all folders
|
|
||||||
obsidian file path="folder/note.md" # File info (size, created, modified dates)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Daily Notes
|
|
||||||
|
|
||||||
Operations on the daily note (requires Daily Notes core plugin enabled).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian daily # Open today's daily note in Obsidian
|
|
||||||
obsidian daily:read # Print today's daily note content to stdout
|
|
||||||
obsidian daily:append content="text" # Append content to today's note
|
|
||||||
obsidian daily:prepend content="text" # Prepend content (after frontmatter)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Notes:**
|
|
||||||
- `daily:prepend` inserts content after the frontmatter block, not at the very beginning.
|
|
||||||
- If today's note doesn't exist, `daily` will create it (using the configured template if set).
|
|
||||||
- Daily note format/folder are configured in Obsidian's Daily Notes plugin settings.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Search
|
|
||||||
|
|
||||||
Full-text search across the vault.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian search query="search text"
|
|
||||||
obsidian search query="text" path="folder" # Scope to folder
|
|
||||||
obsidian search query="text" limit=10 # Limit results
|
|
||||||
obsidian search query="text" format=json # JSON output
|
|
||||||
obsidian search query="text" matches # Include match context/snippets
|
|
||||||
obsidian search query="text" case # Case-sensitive search
|
|
||||||
```
|
|
||||||
|
|
||||||
**Parameters:**
|
|
||||||
- `query=` — Search term (required)
|
|
||||||
- `path=` — Restrict search to a folder
|
|
||||||
- `limit=` — Maximum number of results
|
|
||||||
- `format=json` — Machine-readable JSON output
|
|
||||||
- `matches` — Show matching line context
|
|
||||||
- `case` — Enable case-sensitive matching
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Manage frontmatter (YAML metadata) on notes.
|
|
||||||
|
|
||||||
### Read All Properties
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian properties path="note.md"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Read Single Property
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian property:read path="note.md" name="status"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Set Property
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian property:set path="note.md" name="status" value="active"
|
|
||||||
obsidian property:set path="note.md" name="tags" value="[project, alpha]"
|
|
||||||
obsidian property:set path="note.md" name="date" value="2026-02-27"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Remove Property
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian property:remove path="note.md" name="draft"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Aliases
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian aliases path="note.md"
|
|
||||||
```
|
|
||||||
|
|
||||||
Lists all aliases defined in the note's frontmatter.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Tags
|
|
||||||
|
|
||||||
Tag discovery and filtering.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian tags # List all tags in the vault
|
|
||||||
obsidian tags counts # Tags with usage counts
|
|
||||||
obsidian tags counts sort=count # Sorted by frequency (most used first)
|
|
||||||
obsidian tags path="note.md" # Tags in a specific file
|
|
||||||
obsidian tag name="project/alpha" # List notes with a specific tag
|
|
||||||
```
|
|
||||||
|
|
||||||
**Notes:**
|
|
||||||
- Nested tags are supported (e.g., `project/alpha`).
|
|
||||||
- Tags from both frontmatter and inline `#tag` syntax are included.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Tasks
|
|
||||||
|
|
||||||
Query and manage checkbox tasks across the vault.
|
|
||||||
|
|
||||||
### Querying Tasks
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian tasks # All incomplete tasks
|
|
||||||
obsidian tasks all # All tasks (complete + incomplete)
|
|
||||||
obsidian tasks done # Only completed tasks
|
|
||||||
obsidian tasks path="note.md" # Tasks in a specific file
|
|
||||||
obsidian tasks daily # Tasks in today's daily note
|
|
||||||
```
|
|
||||||
|
|
||||||
### Toggling Task Status
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian task path="note.md" line=12 toggle
|
|
||||||
```
|
|
||||||
|
|
||||||
Toggles the checkbox on the specified line number between `- [ ]` and `- [x]`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Links
|
|
||||||
|
|
||||||
Graph analysis and link management.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian backlinks path="note.md" # Notes linking TO this note
|
|
||||||
obsidian backlinks path="note.md" counts # With link counts per file
|
|
||||||
obsidian links path="note.md" # Outgoing links FROM this note
|
|
||||||
obsidian unresolved # All unresolved [[wikilinks]]
|
|
||||||
obsidian orphans # Notes with no incoming or outgoing links
|
|
||||||
obsidian deadends # Notes with no outgoing links
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Bookmarks
|
|
||||||
|
|
||||||
Manage Obsidian bookmarks (requires Bookmarks core plugin).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian bookmarks # List all bookmarks
|
|
||||||
```
|
|
||||||
|
|
||||||
Bookmarks commands let you view and manage bookmarked notes, searches, and groups. Use `obsidian bookmarks --help` for all available subcommands.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Templates
|
|
||||||
|
|
||||||
Work with note templates (requires Templates or Templater plugin).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian templates # List available templates
|
|
||||||
obsidian template:read name="weekly-review" # Read template content
|
|
||||||
obsidian template:read name="weekly-review" resolve title="My Note" # Render with variables
|
|
||||||
obsidian template:insert name="weekly-review" # Insert template into active file
|
|
||||||
```
|
|
||||||
|
|
||||||
**Parameters:**
|
|
||||||
- `name=` — Template name (without path prefix or extension)
|
|
||||||
- `resolve` — Process template variables
|
|
||||||
- Title and other variables can be passed as `key=value` for template rendering.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Plugins
|
|
||||||
|
|
||||||
Manage community and core plugins.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian plugins # List all installed plugins
|
|
||||||
obsidian plugins:enabled # Only enabled plugins
|
|
||||||
obsidian plugins versions # Plugins with version numbers
|
|
||||||
obsidian plugin:enable id="canvas" # Enable a plugin
|
|
||||||
obsidian plugin:disable id="canvas" # Disable a plugin
|
|
||||||
obsidian plugin:install id="dataview" # Install from community plugins
|
|
||||||
obsidian plugin:reload id="my-plugin" # Reload a plugin (useful for dev)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Sync
|
|
||||||
|
|
||||||
Manage Obsidian Sync (requires active Sync subscription).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian sync # Show sync status summary
|
|
||||||
obsidian sync on # Resume syncing
|
|
||||||
obsidian sync off # Pause syncing
|
|
||||||
obsidian sync:status # Detailed sync status
|
|
||||||
obsidian sync:history path="note.md" # Version history for a file
|
|
||||||
obsidian sync:read path="note.md" version=3 # Read a specific version
|
|
||||||
obsidian sync:restore path="note.md" version=3 # Restore a previous version
|
|
||||||
obsidian sync:deleted # List files deleted via sync
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Themes
|
|
||||||
|
|
||||||
Manage appearance themes.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian themes # List available/installed themes
|
|
||||||
```
|
|
||||||
|
|
||||||
Use `obsidian themes --help` for additional subcommands related to theme management (install, switch, etc.).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Developer
|
|
||||||
|
|
||||||
Debugging and development tools.
|
|
||||||
|
|
||||||
### Screenshots
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian dev:screenshot path="screenshot.png"
|
|
||||||
```
|
|
||||||
|
|
||||||
Takes a screenshot of the Obsidian window and saves it.
|
|
||||||
|
|
||||||
### JavaScript Evaluation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian eval code="app.vault.getFiles().length"
|
|
||||||
obsidian eval code="app.vault.getMarkdownFiles().map(f => f.path).join('\n')"
|
|
||||||
```
|
|
||||||
|
|
||||||
Executes arbitrary JavaScript in the Obsidian app context. Has access to the full Obsidian API (`app`, `app.vault`, `app.workspace`, `app.metadataCache`, etc.).
|
|
||||||
|
|
||||||
### Console & Errors
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian dev:console limit=20 # Recent console output
|
|
||||||
obsidian dev:errors # Recent error messages
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Vault & System
|
|
||||||
|
|
||||||
### Vault Information
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian vault # Current vault: name, path, file/folder counts
|
|
||||||
obsidian vaults # List all known vaults
|
|
||||||
```
|
|
||||||
|
|
||||||
### Other Utilities
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian version # Obsidian version info
|
|
||||||
obsidian outline path="note.md" # Heading structure of a note
|
|
||||||
obsidian wordcount path="note.md" # Word and character count
|
|
||||||
obsidian recents # Recently opened files
|
|
||||||
obsidian reload # Reload the vault (re-index)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Output Formatting & Piping
|
|
||||||
|
|
||||||
The CLI outputs plain text by default, ideal for piping into Unix tools:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Count notes in a folder
|
|
||||||
obsidian files folder="projects" | wc -l
|
|
||||||
|
|
||||||
# Find notes with a specific tag, then read them
|
|
||||||
obsidian tag name="urgent" | while read -r note; do
|
|
||||||
echo "=== $note ==="
|
|
||||||
obsidian read path="$note"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Export search results as JSON and process with jq
|
|
||||||
obsidian search query="meeting" format=json | jq '.[].path'
|
|
||||||
|
|
||||||
# Filter console errors
|
|
||||||
obsidian dev:console limit=50 | grep -i error
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Multi-Vault Usage
|
|
||||||
|
|
||||||
When working with multiple vaults, pass the vault name as the **first argument** (before the command):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
obsidian "Personal" daily:read
|
|
||||||
obsidian "Work" search query="standup"
|
|
||||||
obsidian "Archive" files total
|
|
||||||
```
|
|
||||||
|
|
||||||
If the vault name contains spaces, quote it. The vault name must match what's shown in `obsidian vaults`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Headless / Server Setup (Linux)
|
|
||||||
|
|
||||||
For running Obsidian CLI on a headless Linux server (useful for AI agent integration):
|
|
||||||
|
|
||||||
1. Install the `.deb` package (not snap — snap confinement breaks IPC)
|
|
||||||
2. Install and start `xvfb`: `Xvfb :5 -screen 0 1920x1080x24 &`
|
|
||||||
3. Start Obsidian under xvfb: `DISPLAY=:5 obsidian &`
|
|
||||||
4. Run CLI commands: `DISPLAY=:5 obsidian daily:read`
|
|
||||||
|
|
||||||
**Systemd note**: If running as a service, ensure `PrivateTmp=false` so the IPC socket is accessible.
|
|
||||||
|
|
||||||
**Stderr filtering**: Headless environments produce harmless GPU warnings. Filter with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
DISPLAY=:5 obsidian search query="test" 2>/dev/null
|
|
||||||
```
|
|
||||||
@@ -0,0 +1,261 @@
|
|||||||
|
---
|
||||||
|
name: obsidian-cli
|
||||||
|
description: >
|
||||||
|
Use this skill whenever the user wants Claude to directly interact with their
|
||||||
|
Obsidian vault — reading a note or daily note, writing or appending content,
|
||||||
|
searching vault contents, counting or listing notes, managing tasks, moving or
|
||||||
|
renaming files, finding orphaned notes or broken links. Without this skill, Claude
|
||||||
|
has no way to access vault data or execute vault operations. Treat any request that
|
||||||
|
implies "go into my vault and do X" as a trigger — the user is asking Claude to act,
|
||||||
|
not to explain. Also trigger for vault automation, CLI scripting, or cron-based
|
||||||
|
workflows involving Obsidian. Skip for pure conceptual questions: how Obsidian's GUI
|
||||||
|
works, navigating settings menus, theme or plugin installation via the UI, or general
|
||||||
|
Dataview query syntax — anything where the user needs an explanation rather than
|
||||||
|
Claude performing a vault operation.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Obsidian CLI
|
||||||
|
|
||||||
|
The official Obsidian CLI (released in v1.12, February 2026) lets you control every aspect of Obsidian from the terminal. It communicates with a running Obsidian desktop instance via IPC.
|
||||||
|
|
||||||
|
> Read `references/command-reference.md` when you need specific flags, output formats, or
|
||||||
|
> subcommands for any command group. It covers all 130+ commands with full parameter tables
|
||||||
|
> and has a table of contents at the top.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
| Requirement | Details |
|
||||||
|
|---|---|
|
||||||
|
| Obsidian Desktop | **v1.12.0+** |
|
||||||
|
| CLI enabled | Settings → Command line interface → Toggle ON |
|
||||||
|
| Obsidian running | The desktop app **must be running** for CLI to work (IPC) |
|
||||||
|
|
||||||
|
### Platform Notes
|
||||||
|
|
||||||
|
- **macOS / Linux**: The `obsidian` binary is registered in PATH automatically when you enable CLI in settings.
|
||||||
|
- **Windows**: Requires an `Obsidian.com` redirector file placed alongside `Obsidian.exe`. **Must run with normal user privileges** — admin terminals produce silent failures.
|
||||||
|
- If colon subcommands (`property:set`, `daily:append`, etc.) with parameters return exit 127, verify that `Obsidian.com` exists alongside `Obsidian.exe`. Users who installed before v1.12 and updated in-app may be missing this file — download the latest installer from [obsidian.md/download](https://obsidian.md/download) to fix.
|
||||||
|
- **Git Bash / MSYS2 users**: Bash does not follow Windows' `.com`-before-`.exe` priority, so `obsidian` resolves to `Obsidian.exe` (GUI mode) instead of `Obsidian.com` (CLI). Create a wrapper script — see Troubleshooting.
|
||||||
|
- **Headless Linux**: Use the `.deb` package (not snap). Run under `xvfb`. Prefix commands with `DISPLAY=:5` (or your xvfb display number). Ensure `PrivateTmp=false` if running as a service.
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
All parameters use **`key=value`** syntax. Quote values containing spaces.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian <command> [subcommand] [key=value ...] [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Vault
|
||||||
|
|
||||||
|
Target a specific vault by making it the **first argument**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian "My Vault" daily:read
|
||||||
|
obsidian "Work Notes" search query="meeting"
|
||||||
|
```
|
||||||
|
|
||||||
|
If omitted, the CLI targets the most recently active vault.
|
||||||
|
|
||||||
|
## Command Overview
|
||||||
|
|
||||||
|
The CLI provides **130+ commands** across these groups:
|
||||||
|
|
||||||
|
| Group | Key Commands | Purpose |
|
||||||
|
|---|---|---|
|
||||||
|
| **files** | `read`, `create`, `append`, `prepend`, `move`, `rename`, `delete`, `files`, `folders`, `file`, `random` | Note CRUD and file discovery |
|
||||||
|
| **daily** | `daily`, `daily:read`, `daily:append`, `daily:prepend`, `daily:path` | Daily note operations |
|
||||||
|
| **search** | `search`, `search:context` | Full-text search; `search:context` returns matching lines |
|
||||||
|
| **properties** | `properties`, `property:read`, `property:set`, `property:remove`, `aliases` | Frontmatter/metadata management |
|
||||||
|
| **tags** | `tags`, `tag` | Tag listing, counts, and filtering |
|
||||||
|
| **tasks** | `tasks`, `task` | Task querying, filtering, and toggling |
|
||||||
|
| **links** | `backlinks`, `links`, `unresolved`, `orphans`, `deadends` | Graph and link analysis |
|
||||||
|
| **bookmarks** | `bookmarks`, `bookmark` | List and add bookmarks |
|
||||||
|
| **templates** | `templates`, `template:read`, `template:insert` | Template listing, rendering, insertion |
|
||||||
|
| **plugins** | `plugins`, `plugin`, `plugin:enable`, `plugin:disable`, `plugin:install`, `plugin:uninstall`, `plugins:restrict` | Plugin management |
|
||||||
|
| **sync** | `sync`, `sync:status`, `sync:history`, `sync:read`, `sync:restore`, `sync:deleted` | Obsidian Sync operations |
|
||||||
|
| **themes** | `themes`, `theme`, `theme:set`, `theme:install`, `theme:uninstall` | Theme management |
|
||||||
|
| **snippets** | `snippets`, `snippets:enabled`, `snippet:enable`, `snippet:disable` | CSS snippet management |
|
||||||
|
| **commands** | `commands`, `command`, `hotkeys`, `hotkey` | Execute Obsidian commands by ID; inspect hotkeys |
|
||||||
|
| **bases** | `bases`, `base:query`, `base:views`, `base:create` | Obsidian Bases (v1.12+ database feature) |
|
||||||
|
| **history** | `history`, `history:list`, `history:read`, `history:restore` | File version recovery (File Recovery plugin) |
|
||||||
|
| **workspace** | `workspace`, `tabs`, `tab:open` | Workspace layout and tab management |
|
||||||
|
| **diff** | `diff` | Compare local vs sync file versions |
|
||||||
|
| **dev** | `eval`, `dev:screenshot`, `dev:debug`, `dev:console`, `dev:errors`, `dev:css`, `dev:dom`, `devtools` | Developer/debugging tools |
|
||||||
|
| **vault** | `vault`, `vaults`, `version`, `reload`, `restart` | Vault info and app control |
|
||||||
|
| **other** | `outline`, `wordcount`, `recents` | Utility commands |
|
||||||
|
|
||||||
|
## Quick Reference — Most Common Commands
|
||||||
|
|
||||||
|
### Reading & Writing Notes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian read path="folder/note.md"
|
||||||
|
obsidian create path="folder/note" content="# New Note"
|
||||||
|
obsidian create path="folder/note" template="meeting-notes"
|
||||||
|
obsidian append path="folder/note.md" content="New paragraph"
|
||||||
|
obsidian prepend path="folder/note.md" content="Top content"
|
||||||
|
obsidian move path="old/note.md" to="new/note.md"
|
||||||
|
obsidian delete path="folder/note.md"
|
||||||
|
obsidian delete path="folder/note.md" permanent
|
||||||
|
```
|
||||||
|
|
||||||
|
### Daily Notes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian daily # Open today's daily note
|
||||||
|
obsidian daily:read # Print content of today's note
|
||||||
|
obsidian daily:append content="- [ ] New task"
|
||||||
|
obsidian daily:prepend content="## Morning Notes"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Search
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian search query="project alpha"
|
||||||
|
obsidian search query="TODO" path="projects" limit=10
|
||||||
|
obsidian search query="meeting" format=json # Returns JSON array of file paths
|
||||||
|
obsidian search query="urgent" case
|
||||||
|
```
|
||||||
|
|
||||||
|
### Properties & Tags
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian properties path="note.md"
|
||||||
|
obsidian property:set path="note.md" name="status" value="active"
|
||||||
|
obsidian property:read path="note.md" name="status"
|
||||||
|
obsidian property:remove path="note.md" name="draft"
|
||||||
|
obsidian tags counts sort=count
|
||||||
|
obsidian tag name="project/alpha"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tasks
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian tasks # All tasks (done + todo) — same as tasks all in v1.12
|
||||||
|
obsidian tasks all # All tasks (done + todo)
|
||||||
|
obsidian tasks done # Completed only
|
||||||
|
obsidian tasks daily # Tasks in today's daily note
|
||||||
|
obsidian task path="note.md" line=12 toggle
|
||||||
|
obsidian tasks | grep "\[ \]" # Workaround: filter to incomplete only
|
||||||
|
```
|
||||||
|
|
||||||
|
### Developer & Automation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian eval code="app.vault.getFiles().length"
|
||||||
|
obsidian dev:screenshot path="folder/screenshot.png" # Path must be vault-relative
|
||||||
|
obsidian dev:debug on # Required before dev:console
|
||||||
|
obsidian dev:console limit=20
|
||||||
|
obsidian dev:errors
|
||||||
|
```
|
||||||
|
|
||||||
|
## TUI Mode
|
||||||
|
|
||||||
|
Running `obsidian` with no arguments launches an interactive TUI (Terminal User Interface):
|
||||||
|
|
||||||
|
| Key | Action |
|
||||||
|
|---|---|
|
||||||
|
| `↑↓` | Navigate files |
|
||||||
|
| `Enter` | Open file |
|
||||||
|
| `/` | Search |
|
||||||
|
| `n` | Create new file |
|
||||||
|
| `d` | Delete file |
|
||||||
|
| `r` | Rename file |
|
||||||
|
| `q` | Quit |
|
||||||
|
|
||||||
|
## Common Agent Patterns
|
||||||
|
|
||||||
|
### Daily Journal Automation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Append a timestamped entry
|
||||||
|
obsidian daily:append content="## $(date '+%H:%M') — Status Update
|
||||||
|
- Completed: feature branch merge
|
||||||
|
- Next: code review for PR #42
|
||||||
|
- Blocked: waiting on API credentials"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create Note from Template with Metadata
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian create path="projects/new-feature" template="project-template"
|
||||||
|
obsidian property:set path="projects/new-feature.md" name="status" value="planning"
|
||||||
|
obsidian property:set path="projects/new-feature.md" name="created" value="$(date -I)"
|
||||||
|
obsidian daily:append content="- Started [[projects/new-feature|New Feature]]"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vault Analytics Script
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian files total # Total file count
|
||||||
|
obsidian tags counts sort=count # Most used tags
|
||||||
|
obsidian tasks | grep "\[ \]" # Incomplete tasks across vault
|
||||||
|
obsidian orphans # Notes needing integration
|
||||||
|
obsidian unresolved # Broken links to fix
|
||||||
|
```
|
||||||
|
|
||||||
|
### Search and Extract for AI Processing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian search query="meeting notes" format=json | jq '.[]'
|
||||||
|
obsidian read path="meetings/standup.md" | grep "Action item"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sync Management
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian sync:status # Check sync health
|
||||||
|
obsidian sync:history path="important.md" # Version history
|
||||||
|
obsidian sync:restore path="important.md" version=3 # Rollback
|
||||||
|
```
|
||||||
|
|
||||||
|
### Execute Obsidian Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Find a command ID, then execute it
|
||||||
|
obsidian commands | grep "graph"
|
||||||
|
obsidian command id="graph:open"
|
||||||
|
|
||||||
|
# Open settings, trigger a plugin action
|
||||||
|
obsidian command id="app:open-settings"
|
||||||
|
obsidian command id="dataview:dataview-force-refresh-views"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
1. **Paths are vault-relative** — use `folder/note.md`, not absolute filesystem paths.
|
||||||
|
2. **`create` paths omit `.md`** — the extension is added automatically.
|
||||||
|
3. **`move` requires full target path** including `.md` extension.
|
||||||
|
4. **Pipe-friendly** — plain text output works with `grep`, `awk`, `sed`, `jq`.
|
||||||
|
5. **JSON output** — use `format=json` on `search` for a JSON array of file paths. The `files` command does not support JSON output.
|
||||||
|
6. **Stderr noise** — GPU/Electron warnings on headless are harmless; filter with `2>/dev/null`.
|
||||||
|
7. **`daily:prepend`** inserts content after frontmatter, not at byte 0.
|
||||||
|
8. **Use `eval`** to run arbitrary JavaScript against the Obsidian API (`app.*`).
|
||||||
|
9. **`template:insert`** inserts into the currently active file in the Obsidian UI — it does not accept a `path=` parameter. If no file is open, it returns `Error: No active editor. Open a file first.` To create a file from a template via CLI, use `obsidian create path="..." template="..."` instead.
|
||||||
|
10. **`property:set` stores list values as strings** — `value="tag1, tag2"` writes a literal comma-separated string, not a YAML array. For proper array fields, edit the note's frontmatter directly (e.g. via `read` → modify → `create --force`) or use `eval` to call the Obsidian API.
|
||||||
|
11. **`eval` requires single-line JavaScript** — multiline JS passed inline fails with a token error. Write the script to a temp file instead:
|
||||||
|
```bash
|
||||||
|
cat > /tmp/obs.js << 'JS'
|
||||||
|
var files = app.vault.getMarkdownFiles();
|
||||||
|
files.length;
|
||||||
|
JS
|
||||||
|
obsidian eval code="$(cat /tmp/obs.js)"
|
||||||
|
```
|
||||||
|
12. **Multi-vault targeting may not work in all environments** — `obsidian "My Vault" command` can return `Error: Command "My Vault" not found` on some setups. If this happens, omit the vault name (CLI targets the most recently active vault) and switch vaults manually in the Obsidian UI.
|
||||||
|
13. **When colon subcommands are unavailable** (e.g., missing `Obsidian.com` on Windows), prefer non-colon alternatives: use `properties` instead of `property:read`, or `obsidian daily:path` + `obsidian append path="..."` instead of `daily:append`. Most read-only and file operations work without colon subcommands.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
| Problem | Cause | Fix |
|
||||||
|
|---|---|---|
|
||||||
|
| Empty output / hangs | Obsidian not running, or admin terminal (Windows) | Start Obsidian; use normal-privilege terminal |
|
||||||
|
| Command not found | CLI not registered in PATH | Re-enable CLI in Settings; restart terminal |
|
||||||
|
| Unicode errors | Fixed in v1.12.2+ | Update Obsidian |
|
||||||
|
| Wrong vault targeted | Multi-vault ambiguity | Pass vault name as first arg |
|
||||||
|
| IPC socket not found (Linux) | `PrivateTmp=true` in systemd | Set `PrivateTmp=false` |
|
||||||
|
| Snap confinement issues | Snap restricts IPC | Use `.deb` package instead |
|
||||||
|
| Multi-vault `"Name" command` fails | Vault name matching issue | Omit vault name; target most recent vault |
|
||||||
|
| `property:set` list value is a string | CLI stores value as-is | Edit frontmatter directly or use `eval` |
|
||||||
|
| Colon+params exit 127 (Windows, `Obsidian.com` missing) | Outdated installer — in-app update skips `.com` file | Reinstall from [obsidian.md/download](https://obsidian.md/download) |
|
||||||
|
| Colon+params exit 127 (Git Bash / MSYS2) | Bash resolves `obsidian` to `.exe` (GUI), not `.com` (CLI) | Create `~/bin/obsidian` wrapper: `#!/bin/bash`<br>`/c/Users/<you>/AppData/Local/Obsidian/Obsidian.com "$@"` and add `export PATH="$HOME/bin:$PATH"` to `~/.bashrc` |
|
||||||
@@ -0,0 +1,651 @@
|
|||||||
|
# Obsidian CLI — Full Command Reference
|
||||||
|
|
||||||
|
Complete reference for all official Obsidian CLI commands (v1.12+).
|
||||||
|
|
||||||
|
**Syntax**: `obsidian [vault] <command> [subcommand] [key=value ...] [flags]`
|
||||||
|
|
||||||
|
All parameters use `key=value` syntax. Quote values containing spaces: `content="hello world"`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
1. [Files](#files)
|
||||||
|
2. [Daily Notes](#daily-notes)
|
||||||
|
3. [Search](#search)
|
||||||
|
4. [Properties](#properties)
|
||||||
|
5. [Tags](#tags)
|
||||||
|
6. [Tasks](#tasks)
|
||||||
|
7. [Links](#links)
|
||||||
|
8. [Bookmarks](#bookmarks)
|
||||||
|
9. [Templates](#templates)
|
||||||
|
10. [Plugins](#plugins)
|
||||||
|
11. [Sync](#sync)
|
||||||
|
12. [Themes](#themes)
|
||||||
|
13. [CSS Snippets](#css-snippets)
|
||||||
|
14. [Commands & Hotkeys](#commands--hotkeys)
|
||||||
|
15. [Obsidian Bases](#obsidian-bases)
|
||||||
|
16. [History](#history)
|
||||||
|
17. [Workspace & Tabs](#workspace--tabs)
|
||||||
|
18. [Diff](#diff)
|
||||||
|
19. [Developer](#developer)
|
||||||
|
20. [Vault & System](#vault--system)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
File operations: read, write, create, move, delete, list.
|
||||||
|
|
||||||
|
### Reading Notes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian read path="folder/note.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
Prints raw markdown content of a note to stdout. Path is vault-relative.
|
||||||
|
|
||||||
|
### Creating Notes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian create path="folder/note" content="# Title\n\nBody text"
|
||||||
|
obsidian create path="folder/note" template="template-name"
|
||||||
|
```
|
||||||
|
|
||||||
|
- Path should **not** include `.md` — it is appended automatically.
|
||||||
|
- Use `template=` to create from a template file.
|
||||||
|
- Use `content=` to set initial content directly.
|
||||||
|
|
||||||
|
### Appending & Prepending
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian append path="folder/note.md" content="Appended text"
|
||||||
|
obsidian prepend path="folder/note.md" content="Prepended text"
|
||||||
|
```
|
||||||
|
|
||||||
|
- `append` adds content at the end of the file.
|
||||||
|
- `prepend` adds content after the frontmatter (not at byte 0).
|
||||||
|
|
||||||
|
### Moving & Renaming
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian move path="old/path/note.md" to="new/path/note.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
- `to=` is the full vault-relative target path including the `.md` extension.
|
||||||
|
- Can be used to move, rename, or both in a single command.
|
||||||
|
|
||||||
|
### Deleting
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian delete path="folder/note.md" # Moves to trash
|
||||||
|
obsidian delete path="folder/note.md" permanent # Permanent deletion
|
||||||
|
```
|
||||||
|
|
||||||
|
### File Discovery
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian files # List all files in vault
|
||||||
|
obsidian files ext=md # Filter by extension
|
||||||
|
obsidian files folder="subfolder" # Files in specific folder
|
||||||
|
obsidian files total # Just the file count
|
||||||
|
obsidian folders # List all folders
|
||||||
|
obsidian file path="folder/note.md" # File info (size, created, modified dates)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Random Notes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian random # Open a random note in Obsidian
|
||||||
|
obsidian random:read # Print content of a random note to stdout
|
||||||
|
```
|
||||||
|
|
||||||
|
### Renaming
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian rename path="folder/note.md" name="new-name"
|
||||||
|
```
|
||||||
|
|
||||||
|
- `name=` is the new filename only (no path, no `.md` extension).
|
||||||
|
- Use `move` when you also want to change the folder.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Daily Notes
|
||||||
|
|
||||||
|
Operations on the daily note (requires Daily Notes core plugin enabled).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian daily # Open today's daily note in Obsidian
|
||||||
|
obsidian daily:read # Print today's daily note content to stdout
|
||||||
|
obsidian daily:append content="text" # Append content to today's note
|
||||||
|
obsidian daily:prepend content="text" # Prepend content (after frontmatter)
|
||||||
|
obsidian daily:path # Print vault-relative path of today's note
|
||||||
|
```
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
- `daily:prepend` inserts content after the frontmatter block, not at the very beginning.
|
||||||
|
- If today's note doesn't exist, `daily` will create it (using the configured template if set).
|
||||||
|
- Daily note format/folder are configured in Obsidian's Daily Notes plugin settings.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Search
|
||||||
|
|
||||||
|
Full-text search across the vault.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian search query="search text"
|
||||||
|
obsidian search query="text" path="folder" # Scope to folder
|
||||||
|
obsidian search query="text" limit=10 # Limit results
|
||||||
|
obsidian search query="text" format=json # JSON output (array of file paths)
|
||||||
|
obsidian search query="text" matches # Accepted but returns file paths only
|
||||||
|
obsidian search query="text" case # Case-sensitive search
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `query=` — Search term (required)
|
||||||
|
- `path=` — Restrict search to a folder
|
||||||
|
- `limit=` — Maximum number of results
|
||||||
|
- `format=json` — Returns a JSON array of matching file paths: `["folder/note.md", ...]`
|
||||||
|
- `matches` — Flag accepted by the CLI but does not return match context/snippets in v1.12
|
||||||
|
- `case` — Enable case-sensitive matching
|
||||||
|
|
||||||
|
### Search with Context
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian search:context query="search text"
|
||||||
|
obsidian search:context query="text" path="folder" limit=10
|
||||||
|
obsidian search:context query="text" case
|
||||||
|
obsidian search:context query="text" format=json
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns matching lines with surrounding context (not just file paths). Useful when you need to see the actual content that matched rather than just file paths.
|
||||||
|
|
||||||
|
### Open Search View
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian search:open query="search text"
|
||||||
|
```
|
||||||
|
|
||||||
|
Opens the Obsidian search panel in the UI with the given query.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
Manage frontmatter (YAML metadata) on notes.
|
||||||
|
|
||||||
|
### Read All Properties
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian properties path="note.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Read Single Property
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian property:read path="note.md" name="status"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set Property
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian property:set path="note.md" name="status" value="active"
|
||||||
|
obsidian property:set path="note.md" name="tags" value="[project, alpha]"
|
||||||
|
obsidian property:set path="note.md" name="date" value="2026-02-27"
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** `property:set` always stores `value=` as a string. Passing `value="[project, alpha]"` writes
|
||||||
|
> the literal string `[project, alpha]`, not a YAML array. For true array-typed properties (e.g. `tags`),
|
||||||
|
> edit the note's frontmatter directly or use `eval` with the Obsidian API.
|
||||||
|
|
||||||
|
### Remove Property
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian property:remove path="note.md" name="draft"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Aliases
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian aliases path="note.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
Lists all aliases defined in the note's frontmatter.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tags
|
||||||
|
|
||||||
|
Tag discovery and filtering.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian tags # List all tags in the vault
|
||||||
|
obsidian tags counts # Tags with usage counts
|
||||||
|
obsidian tags counts sort=count # Sorted by frequency (most used first)
|
||||||
|
obsidian tags path="note.md" # Tags in a specific file
|
||||||
|
obsidian tag name="project/alpha" # List notes with a specific tag
|
||||||
|
```
|
||||||
|
|
||||||
|
**Notes:**
|
||||||
|
- Nested tags are supported (e.g., `project/alpha`).
|
||||||
|
- Tags from both frontmatter and inline `#tag` syntax are included.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
|
||||||
|
Query and manage checkbox tasks across the vault.
|
||||||
|
|
||||||
|
### Querying Tasks
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian tasks # All tasks (same as tasks all in v1.12)
|
||||||
|
obsidian tasks all # All tasks (complete + incomplete)
|
||||||
|
obsidian tasks done # Only completed tasks
|
||||||
|
obsidian tasks path="note.md" # Tasks in a specific file
|
||||||
|
obsidian tasks daily # Tasks in today's daily note
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** In v1.12, `tasks` with no arguments returns all tasks (complete + incomplete), identical to `tasks all`. Filtering to incomplete-only is not currently supported without post-processing (e.g. pipe to `grep "\[ \]"`).
|
||||||
|
|
||||||
|
### Toggling Task Status
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian task path="note.md" line=12 toggle
|
||||||
|
```
|
||||||
|
|
||||||
|
Toggles the checkbox on the specified line number between `- [ ]` and `- [x]`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
Graph analysis and link management.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian backlinks path="note.md" # Notes linking TO this note
|
||||||
|
obsidian backlinks path="note.md" counts # With link counts per file
|
||||||
|
obsidian links path="note.md" # Outgoing links FROM this note
|
||||||
|
obsidian unresolved # All unresolved [[wikilinks]]
|
||||||
|
obsidian orphans # Notes with no incoming or outgoing links
|
||||||
|
obsidian deadends # Notes with no outgoing links
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bookmarks
|
||||||
|
|
||||||
|
Manage Obsidian bookmarks (requires Bookmarks core plugin).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian bookmarks # List all bookmarks
|
||||||
|
obsidian bookmark file="folder/note.md" # Bookmark a note
|
||||||
|
obsidian bookmark file="folder/note.md" subpath="#Heading" # Bookmark a heading
|
||||||
|
obsidian bookmark folder="projects" # Bookmark a folder
|
||||||
|
obsidian bookmark search="query text" title="My Search" # Bookmark a search
|
||||||
|
obsidian bookmark url="https://example.com" title="Link" # Bookmark a URL
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Templates
|
||||||
|
|
||||||
|
Work with note templates (requires Templates or Templater plugin).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian templates # List available templates
|
||||||
|
obsidian template:read name="weekly-review" # Read template content
|
||||||
|
obsidian template:read name="weekly-review" resolve title="My Note" # Render with variables
|
||||||
|
obsidian template:insert name="weekly-review" # Insert template into the active Obsidian UI file
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `name=` — Template name (without path prefix or extension)
|
||||||
|
- `resolve` — Process template variables (`{{date}}`, `{{title}}`, etc.)
|
||||||
|
- Title and other variables can be passed as `key=value` for template rendering.
|
||||||
|
|
||||||
|
> **Note:** `template:insert` inserts into whichever file is currently active in the Obsidian UI — it does not accept a `path=` parameter. If no file is open, it returns `Error: No active editor. Open a file first.` To create a new file from a template, use `obsidian create path="..." template="..."` instead.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plugins
|
||||||
|
|
||||||
|
Manage community and core plugins.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian plugins # List all plugins (core + community)
|
||||||
|
obsidian plugins:enabled # Only enabled plugins
|
||||||
|
obsidian plugins versions # Plugins with version numbers (community only)
|
||||||
|
obsidian plugins:restrict # Show restricted mode status
|
||||||
|
obsidian plugins:restrict on # Enable restricted mode (disables community plugins)
|
||||||
|
obsidian plugins:restrict off # Disable restricted mode
|
||||||
|
obsidian plugin id="dataview" # Get info about a specific plugin
|
||||||
|
obsidian plugin:enable id="canvas" # Enable a plugin
|
||||||
|
obsidian plugin:disable id="canvas" # Disable a plugin
|
||||||
|
obsidian plugin:install id="dataview" # Install from community plugins
|
||||||
|
obsidian plugin:uninstall id="dataview" # Uninstall a community plugin
|
||||||
|
obsidian plugin:reload id="my-plugin" # Reload a plugin (useful for dev)
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** `plugins versions` only shows version numbers for community plugins. Core (built-in) plugins share Obsidian's version and display blank version fields.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sync
|
||||||
|
|
||||||
|
Manage Obsidian Sync (requires active Sync subscription).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian sync # Show sync status summary
|
||||||
|
obsidian sync on # Resume syncing
|
||||||
|
obsidian sync off # Pause syncing
|
||||||
|
obsidian sync:status # Detailed sync status
|
||||||
|
obsidian sync:history path="note.md" # Version history for a file
|
||||||
|
obsidian sync:read path="note.md" version=3 # Read a specific version
|
||||||
|
obsidian sync:restore path="note.md" version=3 # Restore a previous version
|
||||||
|
obsidian sync:deleted # List files deleted via sync
|
||||||
|
obsidian sync:open # Open the Sync history view in the UI
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Themes
|
||||||
|
|
||||||
|
Manage appearance themes.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian themes # List installed themes
|
||||||
|
obsidian themes versions # List installed themes with version numbers
|
||||||
|
obsidian theme # Show the currently active theme
|
||||||
|
obsidian theme name="Minimal" # Get details about a specific theme
|
||||||
|
obsidian theme:set name="Minimal" # Switch to a theme
|
||||||
|
obsidian theme:set name="" # Switch back to default theme
|
||||||
|
obsidian theme:install name="Minimal" # Install a community theme
|
||||||
|
obsidian theme:install name="Minimal" enable # Install and activate immediately
|
||||||
|
obsidian theme:uninstall name="Minimal" # Uninstall a theme
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CSS Snippets
|
||||||
|
|
||||||
|
Manage custom CSS snippet files (snippets live in `.obsidian/snippets/`).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian snippets # List all installed CSS snippets
|
||||||
|
obsidian snippets:enabled # List only enabled snippets
|
||||||
|
obsidian snippet:enable name="my-style" # Enable a snippet
|
||||||
|
obsidian snippet:disable name="my-style" # Disable a snippet
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Commands & Hotkeys
|
||||||
|
|
||||||
|
Execute any Obsidian command by its ID, and inspect hotkey bindings.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian commands # List all available command IDs
|
||||||
|
obsidian command id="app:reload" # Execute a command by ID
|
||||||
|
obsidian command id="editor:toggle-bold" # Example: toggle bold in active editor
|
||||||
|
obsidian hotkeys # List all hotkeys (tab-separated: id \t keybinding)
|
||||||
|
obsidian hotkey id="app:open-settings" # Get hotkey for a specific command
|
||||||
|
obsidian hotkey id="app:open-settings" verbose # Show if custom or default
|
||||||
|
```
|
||||||
|
|
||||||
|
**Typical workflow — find and run a command:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian commands | grep "canvas" # Find canvas-related command IDs
|
||||||
|
obsidian command id="canvas:new-file" # Execute the matched command
|
||||||
|
```
|
||||||
|
|
||||||
|
**Getting plugin command IDs:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian commands | grep "dataview" # List all Dataview plugin commands
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Obsidian Bases
|
||||||
|
|
||||||
|
Obsidian Bases (v1.12+) is a built-in database feature. Base files (`.base`) store structured data and support multiple views.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian bases # List all .base files in vault
|
||||||
|
obsidian base:query file="tasks" format=json # Query default view of a base
|
||||||
|
obsidian base:query file="tasks" view="Kanban" # Query a specific view
|
||||||
|
obsidian base:query path="folder/tasks.base" format=csv # Query by path
|
||||||
|
obsidian base:views file="tasks" # List all views in a base file
|
||||||
|
obsidian base:create file="tasks" title="Buy milk" # Add an item to a base
|
||||||
|
```
|
||||||
|
|
||||||
|
**Supported output formats for `base:query`:** `json` (default), `csv`, `tsv`, `md`, `paths`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## History
|
||||||
|
|
||||||
|
File version history (built-in to Obsidian, separate from Sync). Requires the File Recovery core plugin.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian history:list # List all files that have history
|
||||||
|
obsidian history path="folder/note.md" # List versions of a specific file
|
||||||
|
obsidian history:read path="folder/note.md" # Read the latest saved version
|
||||||
|
obsidian history:read path="folder/note.md" version=3 # Read a specific version
|
||||||
|
obsidian history:restore path="folder/note.md" version=3 # Restore a version
|
||||||
|
obsidian history:open path="folder/note.md" # Open file recovery UI for a file
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** History is distinct from [Sync version history](#sync). History uses Obsidian's built-in File Recovery snapshots; Sync history uses Obsidian Sync cloud versions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Workspace & Tabs
|
||||||
|
|
||||||
|
Inspect and manage the Obsidian workspace layout and open tabs.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian workspace # Show the full workspace tree
|
||||||
|
obsidian tabs # List all open tabs (flat list)
|
||||||
|
obsidian tab:open file="folder/note.md" # Open a file in a new tab
|
||||||
|
obsidian tab:open view="graph" # Open a view type in a new tab
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Diff
|
||||||
|
|
||||||
|
Compare local and sync versions of a file.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian diff path="folder/note.md" # List available versions (local + sync)
|
||||||
|
obsidian diff path="folder/note.md" from=1 to=2 # Diff two specific versions
|
||||||
|
obsidian diff path="folder/note.md" filter=local # Show only local versions
|
||||||
|
obsidian diff path="folder/note.md" filter=sync # Show only sync versions
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Developer
|
||||||
|
|
||||||
|
Debugging and development tools.
|
||||||
|
|
||||||
|
### Screenshots
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian dev:screenshot path="folder/screenshot.png"
|
||||||
|
```
|
||||||
|
|
||||||
|
Takes a screenshot of the Obsidian window and saves it. **Path must be vault-relative** — absolute filesystem paths are silently ignored.
|
||||||
|
|
||||||
|
### JavaScript Evaluation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian eval code="app.vault.getFiles().length"
|
||||||
|
obsidian eval code="app.vault.getMarkdownFiles().map(f => f.path).join('\n')"
|
||||||
|
```
|
||||||
|
|
||||||
|
Executes arbitrary JavaScript in the Obsidian app context. Has access to the full Obsidian API (`app`, `app.vault`, `app.workspace`, `app.metadataCache`, etc.).
|
||||||
|
|
||||||
|
> **Multiline scripts:** Passing multiline JavaScript inline fails with "Invalid or unexpected token".
|
||||||
|
> Write the code to a temp file and use command substitution instead:
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> cat > /tmp/obs.js << 'JS'
|
||||||
|
> var files = app.vault.getMarkdownFiles();
|
||||||
|
> files.map(f => f.path).join('\n');
|
||||||
|
> JS
|
||||||
|
> obsidian eval code="$(cat /tmp/obs.js)"
|
||||||
|
> ```
|
||||||
|
|
||||||
|
### Console & Errors
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian dev:debug on # Start capturing console output (required before dev:console)
|
||||||
|
obsidian dev:debug off # Stop capturing console output
|
||||||
|
obsidian dev:console limit=20 # Recent console output (requires dev:debug on first)
|
||||||
|
obsidian dev:errors # Recent error messages
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** `dev:console` will return an error unless `dev:debug on` has been run first in the current session.
|
||||||
|
|
||||||
|
### DOM Inspection
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian dev:dom selector=".view-content" # Get outerHTML of first match
|
||||||
|
obsidian dev:dom selector=".view-content" all # Get all matches
|
||||||
|
obsidian dev:dom selector=".view-content" text # Get text content
|
||||||
|
obsidian dev:dom selector=".view-content" total # Count matching elements
|
||||||
|
obsidian dev:dom selector=".view-content" attr=class # Get an attribute value
|
||||||
|
obsidian dev:dom selector=".view-content" css=color # Get a CSS property value
|
||||||
|
```
|
||||||
|
|
||||||
|
### CSS Inspection
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian dev:css selector=".view-content" # Inspect CSS with source locations
|
||||||
|
obsidian dev:css selector=".view-content" prop=color # Filter by CSS property name
|
||||||
|
```
|
||||||
|
|
||||||
|
### Chrome DevTools Protocol
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian devtools # Toggle Electron DevTools panel
|
||||||
|
obsidian dev:cdp method="Runtime.evaluate" params='{"expression":"1+1"}' # Run a CDP command
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mobile Emulation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian dev:mobile on # Enable mobile emulation
|
||||||
|
obsidian dev:mobile off # Disable mobile emulation
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vault & System
|
||||||
|
|
||||||
|
### Vault Information
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian vault # Current vault: name, path, file/folder counts
|
||||||
|
obsidian vaults # List all known vaults
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other Utilities
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian version # Obsidian version info
|
||||||
|
obsidian outline path="note.md" # Heading structure of a note
|
||||||
|
obsidian wordcount path="note.md" # Word and character count
|
||||||
|
obsidian recents # Recently opened files
|
||||||
|
obsidian reload # Reload the vault (re-index)
|
||||||
|
obsidian restart # Restart the Obsidian app
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Formatting & Piping
|
||||||
|
|
||||||
|
The CLI outputs plain text by default, ideal for piping into Unix tools.
|
||||||
|
|
||||||
|
### Supported `format=` values
|
||||||
|
|
||||||
|
| Format | Description | Best for |
|
||||||
|
|---|---|---|
|
||||||
|
| `text` | Plain text (default) | Piping to grep/awk/sed |
|
||||||
|
| `json` | JSON array or object | Processing with jq, AI agents |
|
||||||
|
| `csv` | Comma-separated values | Spreadsheet import |
|
||||||
|
| `tsv` | Tab-separated values | Shell parsing with cut/awk |
|
||||||
|
| `yaml` | YAML output | Config-style processing |
|
||||||
|
| `md` | Markdown table | Embedding results in notes |
|
||||||
|
| `paths` | One path per line | Batch file operations |
|
||||||
|
| `tree` | Tree view | Visual hierarchy |
|
||||||
|
|
||||||
|
Not all formats are supported by every command. Use `text` or `json` when in doubt.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Count notes in a folder
|
||||||
|
obsidian files folder="projects" | wc -l
|
||||||
|
|
||||||
|
# Find notes with a specific tag, then read them
|
||||||
|
obsidian tag name="urgent" | while read -r note; do
|
||||||
|
echo "=== $note ==="
|
||||||
|
obsidian read path="$note"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Export search results as JSON and process with jq
|
||||||
|
# format=json returns an array of file path strings: ["folder/note.md", ...]
|
||||||
|
obsidian search query="meeting" format=json | jq '.[]'
|
||||||
|
|
||||||
|
# Query a base as CSV
|
||||||
|
obsidian base:query file="tasks" format=csv
|
||||||
|
|
||||||
|
# Filter console errors (requires dev:debug on first)
|
||||||
|
obsidian dev:debug on
|
||||||
|
obsidian dev:console limit=50 | grep -i error
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Multi-Vault Usage
|
||||||
|
|
||||||
|
When working with multiple vaults, pass the vault name as the **first argument** (before the command):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
obsidian "Personal" daily:read
|
||||||
|
obsidian "Work" search query="standup"
|
||||||
|
obsidian "Archive" files total
|
||||||
|
```
|
||||||
|
|
||||||
|
If the vault name contains spaces, quote it. The vault name must match what's shown in `obsidian vaults`.
|
||||||
|
|
||||||
|
> **Compatibility note:** On some environments, `obsidian "My Vault" command` returns
|
||||||
|
> `Error: Command "My Vault" not found`. If this occurs, omit the vault name — the CLI will target
|
||||||
|
> the most recently active vault. Switch vaults in the Obsidian UI before running CLI commands
|
||||||
|
> when targeting a specific vault.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Headless / Server Setup (Linux)
|
||||||
|
|
||||||
|
For running Obsidian CLI on a headless Linux server (useful for AI agent integration):
|
||||||
|
|
||||||
|
1. Install the `.deb` package (not snap — snap confinement breaks IPC)
|
||||||
|
2. Install and start `xvfb`: `Xvfb :5 -screen 0 1920x1080x24 &`
|
||||||
|
3. Start Obsidian under xvfb: `DISPLAY=:5 obsidian &`
|
||||||
|
4. Run CLI commands: `DISPLAY=:5 obsidian daily:read`
|
||||||
|
|
||||||
|
**Systemd note**: If running as a service, ensure `PrivateTmp=false` so the IPC socket is accessible.
|
||||||
|
|
||||||
|
**Stderr filtering**: Headless environments produce harmless GPU warnings. Filter with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
DISPLAY=:5 obsidian search query="test" 2>/dev/null
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user