---
name: obsidian
description: "Complete mastery of Obsidian: filesystem vault operations, CLI automation, URI schemes, plugin ecosystem (Dataview, Templater, QuickAdd, etc.), iCloud sync, API integration, and advanced workflows."
version: 3.0.0
author: Hermes Agent
license: MIT
platforms: [linux, macos, windows]
metadata:
  hermes:
    tags: [Obsidian, Note-Taking, Markdown, Vault, CLI, Automation, PKM, iCloud, Sync, Templates, Dataview, Templater]
    related_skills: [5etools-query, ttrpg-campaign-vault, ttrpg-vault-organization]
---

# Obsidian Vault - Complete Reference

This skill covers every facet of working with Obsidian programmatically: direct filesystem manipulation, the official CLI, URI schemes, iCloud sync, and the plugin ecosystem.

## Quick Navigation

| You want to... | See section |
|---|---|
| Read, write, or search notes on disk | [Vault Path & File Tools](#vault-path--file-tools) |
| Automate via terminal (100+ commands) | [Obsidian CLI](#obsidian-cli) |
| Trigger Obsidian from other apps/scripts | [URI Scheme](#uri-scheme) |
| Access iCloud-backed vaults from Linux | [iCloud Sync](#icloud-sync) |
| Build/query with Dataview, Templater, etc. | [Plugin Ecosystem](#plugin-ecosystem) |
| Deep TypeScript API for plugins | [Developer API](#developer-api) |
| Common automation recipes | [Workflows & Patterns](#workflows--patterns) |
| Full action index (everything possible) | `references/automation-actions-index.md` |
| All CLI commands listed | `references/cli-command-reference.md` |
| All URI actions listed | `references/uri-actions.md` |
| Key plugins and what they automate | `references/plugin-ecosystem.md` |

---

## Vault Path & File Tools

### Resolving the vault path

Always resolve the vault path before calling file tools.

**Environment variable**: `OBSIDIAN_VAULT_PATH` (check `~/.hermes/.env` or `~/.env`).

**Fallbacks**:
- `~/Documents/Obsidian Vault`
- `~/obsidian-vault/`
- `~/Obsidian/` (macOS common)

**Important**: File tools do not expand shell variables. Never pass `$OBSIDIAN_VAULT_PATH` to `read_file`, `write_file`, `patch`, or `search_files`. Resolve it first.

### File operations

| Task | Tool | Pattern |
|---|---|---|
| Read a note | `read_file` | `read_file(path="/abs/path/to/note.md")` |
| List all notes | `search_files` | `search_files(target="files", pattern="*.md", path="/abs/vault/path")` |
| Search note contents | `search_files` | `search_files(target="content", pattern="regex", path="/abs/vault/path", file_glob="*.md")` |
| Create a note | `write_file` | `write_file(path="/abs/path/new.md", content="...")` |
| Append content | `patch` | Anchored replace: `patch(path="...", old_string="## Footer\n", new_string="## Footer\n\nNew line.")` |
| Edit inline | `patch` | `patch(path="...", old_string="...", new_string="...")` |
| Bulk rename | terminal | `find . -name "*.md" -exec rename ...` or Python script |

### Wikilinks & markdown syntax

```markdown
[[Note Name]]                    # Link to another note
[[Note Name|Display Text]]       # Link with custom display
[[Note Name#Heading]]            # Link to heading
[[Note Name#^block-id]]          # Link to block
![[Embedded Note]]                # Embed another note
#tag                             # Inline tag
#tag/subtag                      # Nested tag
```

### YAML frontmatter (Properties)

Obsidian v1.4+ uses a Properties UI on top of YAML frontmatter. Types supported:
- `text`, `number`, `date`, `datetime`
- `checkbox` (boolean)
- `list`, `tags` (arrays)
- `links` (wiki-link arrays)

```yaml
---
title: My Note
date: 2026-07-14
tags: [project, active]
status: draft
---
```

> Frontmatter is cached by Obsidian's `metadataCache` and accessible via Dataview queries and the API.

---

## Obsidian CLI

The official CLI ships in Obsidian v1.12.4+ (February 2026). It requires the Obsidian desktop app to be running.

### Activation
1. Settings -> General -> Enable "Command line interface"
2. Follow the prompt to register `obsidian` in PATH
3. Restart terminal

### Command categories

| Category | Examples |
|---|---|
| **Notes** | `obsidian create`, `obsidian read`, `obsidian edit`, `obsidian move`, `obsidian delete`, `obsidian rename` |
| **Daily** | `obsidian daily`, `obsidian daily:append`, `obsidian daily:prepend` |
| **Search** | `obsidian search query="..."`, `obsidian search:files`, `obsidian search:content` |
| **Tags** | `obsidian tags`, `obsidian tags counts`, `obsidian tag add`, `obsidian tag remove` |
| **Properties** | `obsidian properties:set`, `obsidian properties:get`, `obsidian properties:list` |
| **Tasks** | `obsidian tasks`, `obsidian tasks daily`, `obsidian task add`, `obsidian task toggle` |
| **Graph** | `obsidian graph`, `obsidian graph analyze`, `obsidian backlinks` |
| **Templates** | `obsidian template apply`, `obsidian template list` |
| **Diff** | `obsidian diff file=Note from=1 to=3` |
| **Developer** | `obsidian dev:reload`, `obsidian dev:inspect`, `obsidian dev:screenshot` |

### Key CLI workflows

**Create from template**:
```bash
obsidian create name="Meeting Notes" template="Meeting" folder="Meetings/"
```

**Append to daily note**:
```bash
obsidian daily:append content="- [ ] Review PRs"
```

**Search and pipe**:
```bash
obsidian search query="project:alpha" --json | jq '.[].path'
```

**Batch tag**:
```bash
obsidian tag add --files "*.md" tag="archive"
```

> For the complete command list, see `references/cli-command-reference.md`.

---

## URI Scheme

The `obsidian://` protocol enables cross-app triggering. Works on all platforms.

### Available actions

| Action | Purpose | Example |
|---|---|---|
| `open` | Open vault or file | `obsidian://open?vault=My%20Vault&file=Note` |
| `new` | Create or append to note | `obsidian://new?vault=MyVault&name=Idea&content=Hello` |
| `daily` | Open/create daily note | `obsidian://daily?vault=MyVault` |
| `unique` | Create unique note (Zettelkasten) | `obsidian://unique?vault=MyVault` |
| `search` | Open search | `obsidian://search?vault=MyVault&query=meeting` |
| `choose-vault` | Open vault manager | `obsidian://choose-vault` |

### Parameters for `open`
- `vault` - vault name or ID
- `file` - file path (relative to vault root)
- `path` - absolute file path

### Parameters for `new`
- `vault` - vault name
- `name` - note name (creates if missing, appends if exists)
- `content` - content to insert
- `append` - append instead of overwrite (true/false)
- `overwrite` - overwrite existing (true/false)

> **Encoding**: Always URI-encode values. Space = `%20`, `/` = `%2F`, `&` = `%26`.

### Cross-platform invocation

**Linux (xdg-open)**:
```bash
xdg-open "obsidian://open?vault=MyVault&file=My%20Note"
```

**macOS**:
```bash
open "obsidian://open?vault=MyVault&file=My%20Note"
```

**From Python**:
```python
import urllib.parse
vault = "My Vault"
file = "My Note"
url = f"obsidian://open?vault={urllib.parse.quote(vault)}&file={urllib.parse.quote(file)}"
```

> For the complete URI reference, see `references/uri-actions.md`.

---

## iCloud Sync

### Problem
Obsidian vault lives in iCloud Drive and is not present locally on headless Linux.

### Options

**Option 1: pyicloud (automated)**
- Install: `pip3 install pyicloud`
- Requires actual Apple ID password (NOT app-specific password)
- Triggers 2FA/MFA on Apple devices
- Session cached in `~/.pyicloud/`
- See `references/icloud-vault-access.md` for full recipe

**Option 2: Manual transfer (recommended)**
- Zip vault from Mac/iPhone, transfer via SFTP/SCP/Nextcloud
- Work locally, user syncs back manually
- Avoids credential exposure

**Option 3: Alternative sync**
- Syncthing, Nextcloud, Dropbox, git

### Pitfalls
1. App-specific passwords are rejected by pyicloud (401 Unauthorized)
2. `.env` lines may have `***` placeholder prefix -- strip before use
3. Never inline `.env` parsing in shell one-liners (quotes/spaces break it)
4. New iCloud directories may lag in `get_children()` -- cache directory nodes
5. Upload requires `.name` attribute -- use `NamedBytesIO`
6. Overwriting files throws 412 -- delete old file first, then upload

> See `scripts/icloud-vault-sync.py` for bidirectional sync automation.
> See `scripts/icloud-vault-lister.py` for listing vault contents.

---

## Plugin Ecosystem

Obsidian's power comes from its plugin ecosystem. Here are the automation-heavy ones:

### Dataview (query language for vaults)
- Query notes like a database
- Tables, lists, tasks, calendars
- Access frontmatter, tags, links, dates
- Can execute inline JavaScript

```dataview
TABLE status, date
FROM #project
WHERE status = "active"
SORT date DESC
```

### Templater (dynamic templates)
- Insert variables, dates, random values
- Execute JavaScript and system commands
- Trigger on file creation (folder templates)
- System commands: `<% tp.system.prompt() %>`

```markdown
---
created: <% tp.date.now() %>
tags: [<% tp.system.suggester("Tag", ["work", "personal"]) %>]
---
# <% tp.file.title %>
```

### QuickAdd (capture & macros)
- Capture ideas to specific notes
- Macro workflows (multi-step automation)
- Choice types: capture, template, macro, multi
- Can trigger from command palette or hotkeys

### Tasks (task management)
- Recurring tasks, due dates, start dates
- Query tasks across vault
- Integration with Dataview
- Custom status symbols

### Periodic Notes
- Daily, weekly, monthly, quarterly, yearly notes
- Template integration
- Automatic date-based naming

### Kanban
- Markdown-backed kanban boards
- Drag-and-drop
- Date properties, tags
- Template cards

### Obsidian Git
- Version control for vault
- Auto-commit on interval
- Push/pull from remote
- Diff viewing

### Advanced Tables
- Spreadsheet-like table editing
- Formula support
- CSV import/export

### Local REST API
- Exposes Obsidian as a REST API
- CRUD notes, search, open files
- API key authentication
- MCP integration for AI agents
- Endpoint examples:
  - `GET /vault/` - list files
  - `GET /vault/<file>` - read note
  - `POST /vault/<file>` - create/update
  - `POST /active/` - open in UI

> For full plugin details, see `references/plugin-ecosystem.md`.

---

## Developer API

For building plugins or advanced automation:

### Core objects

| Object | Access | Purpose |
|---|---|---|
| `app.vault` | `this.app.vault` | File system operations |
| `app.fileManager` | `this.app.fileManager` | File creation, renaming |
| `app.metadataCache` | `this.app.metadataCache` | Cached frontmatter/links/tags |
| `app.workspace` | `this.app.workspace` | Panes, leaves, tabs |
| `app.plugins` | `this.app.plugins` | Plugin management |

### Vault API methods

```typescript
// File listing
vault.getMarkdownFiles()     // All .md files
vault.getFiles()             // All files (including attachments)
vault.getAbstractFileByPath(path)

// Reading
vault.read(file: TFile)                    // Fresh read from disk
vault.cachedRead(file: TFile)              // Cached read (faster)

// Writing
vault.create(path, content)                // Create new file
vault.createFolder(path)                   // Create folder
vault.modify(file, content)                // Overwrite file
vault.process(file, (data) => newData)     // Read-modify-write (atomic)
vault.append(file, content)                // Append to file
vault.adapter.append(file, content)        // Low-level append

// Deletion
vault.delete(file)                         // Permanent delete
vault.trash(file, system: boolean)         // Move to trash

// Metadata
vault.getAllLoadedFiles()
vault.getName()
```

### MetadataCache

```typescript
const cache = app.metadataCache.getFileCache(file)
// Returns:
// {
//   frontmatter: { title: "...", tags: [...] },
//   tags: [{ tag: "#tag", position: ... }],
//   headings: [{ heading: "H1", level: 1, position: ... }],
//   links: [{ link: "Target", displayText: "...", original: "..." }],
//   embeds: [{ link: "File", displayText: "..." }],
//   blocks: [{ id: "block-id", ... }],
//   sections: [...]
// }
```

### Events

```typescript
// Listen for file changes
this.registerEvent(app.vault.on('create', (file) => { ... }))
this.registerEvent(app.vault.on('modify', (file) => { ... }))
this.registerEvent(app.vault.on('delete', (file) => { ... }))
this.registerEvent(app.vault.on('rename', (file, oldPath) => { ... }))

// Metadata changes
this.registerEvent(app.metadataCache.on('changed', (file, data, cache) => { ... }))
```

### Commands

```typescript
// Add a command to the palette
this.addCommand({
  id: 'my-command',
  name: 'Do Something',
  callback: () => { ... }
})
```

> For deep API coverage, see `references/vault-api-deep-dive.md`.

---

## Workflows & Patterns

### Workflow 1: Daily Note Auto-Generation
```
1. Periodic Notes creates daily note from template
2. Templater inserts date, weather, morning priorities
3. QuickAdd captures fleeting thoughts throughout day
4. Tasks plugin tracks todos with due dates
5. End of day: Dataview summarizes completed tasks
```

### Workflow 2: Project Dashboard
```
1. Create project note with frontmatter: status, deadline, tags
2. Dataview query aggregates all project notes in a dashboard
3. Kanban board tracks project stages
4. QuickAdd adds new tasks to correct project file
5. Git commits daily for version history
```

### Workflow 3: Literature Review / Zettelkasten
```
1. Read paper, create atomic note per concept
2. Templater auto-assigns Zettel ID (timestamp)
3. Link related concepts with [[wikilinks]]
4. Dataview builds index of all papers by topic
5. Graph view shows knowledge connections
```

### Workflow 4: Meeting Notes Pipeline
```
1. QuickAdd trigger: "New Meeting"
2. Prompts for attendees, topic
3. Creates note from template in Meetings/ folder
4. Inserts date and attendee list
5. After meeting: tag action items, Tasks picks them up
```

### Workflow 5: TTRPG Campaign Management
```
1. Vault-local scaffold.py queries 5e.tools API
2. Generates templated markdown in correct folders
3. Updates _Index.md navigation files
4. HTML/JS tools complement markdown for session use
5. iCloud sync pushes to user's devices
```

### Automation via cron (Hermes)

```bash
# Daily: generate daily note via CLI
hermes cronjob create --schedule "0 6 * * *" --command "obsidian daily"

# Weekly: commit vault to git
hermes cronjob create --schedule "0 22 * * 0" --command "cd ~/vault && git add -A && git commit -m 'weekly backup' && git push"

# Hourly: sync iCloud vault
hermes cronjob create --schedule "0 * * * *" --command "cd ~/scripts && APPLE_EMAIL=... APPLE_PASSWORD=... python3 icloud-vault-sync.py"
```

---

## Canvas

Obsidian Canvas is a visual workspace:
- **Text nodes**: Markdown-rendered text
- **File nodes**: Links to vault files (auto-sync when file changes)
- **Group nodes**: Containers for organization
- **Edges**: Connections between nodes (appear in Graph View)
- **URL nodes**: External links

Canvas files are JSON (`.canvas`). Can be generated programmatically.

---

## Graph View

The graph view visualizes note relationships:
- Nodes = notes
- Edges = wikilinks between notes
- Filter by tags, folders, links
- Local graph (one note + neighbors)
- Global graph (entire vault)

Programmatically: `app.metadataCache.resolvedLinks` gives the link graph.

---

## Vault-local Scripts

Vaults can include custom `scripts/` folders for scaffolding and sync:
- **Scaffolding**: Query external APIs, generate templated notes
- **Sync**: Push/pull from cloud storage
- **Validation**: Check for broken links, orphaned notes
- **Reports**: Generate indexes, statistics, summaries

Before creating new automation, check if the vault already provides these.

---

## Related Skills

- `5etools-query` -- Query self-hosted 5e.tools data for D&D content
- `ttrpg-campaign-vault` -- Campaign vault patterns and conventions
- `ttrpg-vault-organization` -- Consolidate and reorganize sprawling vaults
- `obsidian` (this skill) -- General vault operations and automation

## Reference Files

- `references/automation-actions-index.md` -- Complete index of every possible Obsidian action
- `references/cli-command-reference.md` -- All CLI commands with examples
- `references/uri-actions.md` -- All URI scheme actions and parameters
- `references/plugin-ecosystem.md` -- Key plugins and automation capabilities
- `references/vault-api-deep-dive.md` -- Deep TypeScript API coverage
- `references/workflows-and-patterns.md` -- Advanced automation recipes
- `references/icloud-vault-access.md` -- iCloud access via pyicloud
- `references/ttrpg-campaign-vault.md` -- TTRPG-specific vault patterns
- `references/icloud-sync.md` -- iCloud sync options and pitfalls

## Scripts

- `scripts/icloud-vault-sync.py` -- Bidirectional iCloud sync
- `scripts/icloud-vault-lister.py` -- List iCloud vault contents
