| name | obsidian |
| description | Guide for implementing Obsidian knowledge management - vault operations, plugin development, URI scheme automation, markdown extensions, and Local REST API integration. Use when working with Obsidian vaults, creating plugins, automating note workflows, querying notes via API, or implementing knowledge graph features. |
Obsidian
Overview
This skill provides comprehensive guidance for working with Obsidian,
a powerful knowledge management and note-taking application.
It covers vault structure, the Obsidian API for plugin development,
URI scheme automation, markdown extensions, and integration with
external tools via the Local REST API.
Quick Reference
Vault Structure
my-vault/
├── .obsidian/ # Configuration folder
│ ├── app.json # App settings
│ ├── appearance.json # Theme settings
│ ├── community-plugins.json # Installed plugins list
│ ├── core-plugins.json # Core plugin toggles
│ ├── hotkeys.json # Custom keybindings
│ ├── plugins/ # Plugin data folders
│ │ └── <plugin-id>/
│ │ ├── main.js # Compiled plugin code
│ │ ├── manifest.json
│ │ └── data.json # Plugin settings
│ └── workspace.json # Layout state
├── Notes/ # User notes (any structure)
├── Attachments/ # Images, PDFs, etc.
└── Templates/ # Template files
Obsidian URI Scheme
Native Obsidian supports obsidian:// protocol for automation:
obsidian://open?vault=MyVault
obsidian://open?vault=MyVault&file=Notes/MyNote
obsidian://new?vault=MyVault&name=NewNote&content=Hello
obsidian://search?vault=MyVault&query=keyword
obsidian://daily?vault=MyVault
URI Parameters
| Parameter | Description |
|---|
vault | Vault name (required) |
file | File path without .md extension |
path | Full file path including folders |
name | Note name for creation |
content | Content to insert |
query | Search query |
heading | Navigate to heading |
block | Navigate to block reference |
Workflow Decision Tree
What do you need to do?
├── Automate Obsidian from external tools?
│ ├── Simple open/create operations?
│ │ └── Use: Native obsidian:// URI scheme
│ ├── Complex automation (append, prepend, commands)?
│ │ └── Use: Advanced URI plugin
│ └── Full programmatic access?
│ └── Use: Local REST API plugin
├── Build a plugin for Obsidian?
│ └── See: Plugin Development section
├── Work with vault files directly?
│ └── Use: obsidian-cli or direct file operations
├── Extend markdown syntax?
│ └── See: Markdown Extensions section
└── Query notes and metadata?
└── Use: Local REST API or Dataview plugin
Plugin Development
Plugin Structure
my-plugin/
├── main.ts # Plugin entry point
├── manifest.json # Plugin metadata
├── package.json # npm dependencies
├── styles.css # Optional styles
├── tsconfig.json # TypeScript config
└── esbuild.config.mjs # Build config
manifest.json
{
"id": "my-plugin",
"name": "My Plugin",
"version": "1.0.0",
"minAppVersion": "1.0.0",
"description": "A sample plugin for Obsidian",
"author": "Your Name",
"authorUrl": "https://github.com/username",
"isDesktopOnly": false
}
Basic Plugin Template
import { Plugin, Notice, MarkdownView } from 'obsidian';
export default class MyPlugin extends Plugin {
async onload() {
console.log('Loading plugin');
this.addCommand({
id: 'my-command',
name: 'My Command',
callback: () => {
new Notice('Hello from my plugin!');
}
});
this.addCommand({
id: 'my-editor-command',
name: 'Insert Text',
editorCallback: (editor, view: MarkdownView) => {
editor.replaceSelection('Inserted text');
}
});
this.registerEvent(
this.app.workspace.(, {
(file) {
.(, file.);
}
})
);
}
() {
.();
}
}
Core API Classes
| Class | Purpose | Access |
|---|
App | Central application instance | this.app |
Vault | File system operations | this.app.vault |
Workspace | Pane and layout management | this.app.workspace |
MetadataCache | File metadata indexing | this.app.metadataCache |
FileManager | User-safe file operations | this.app.fileManager |
Plugin Lifecycle
async onload() {
}
onunload() {
}
Local REST API
The Local REST API plugin provides HTTP endpoints to interact with Obsidian programmatically.
Installation
- Install "Local REST API" from Community Plugins
- Enable the plugin
- Configure API key in settings
- Default endpoint:
https://127.0.0.1:27124
Authentication
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://127.0.0.1:27124/vault/
Common Endpoints
GET /vault/
GET /vault/{path-to-file}
PUT /vault/{path-to-file}
Content-Type: text/markdown
Body: File content here
DELETE /vault/{path-to-file}
POST /search/simple/
Content-Type: application/json
Body: {"query": "search term"}
POST /commands/{command-id}
GET /active/
POST /open/{path-to-file}
Python Example
import requests
class ObsidianAPI:
def __init__(self, api_key, base_url="https://127.0.0.1:27124"):
self.base_url = base_url
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
self.session = requests.Session()
self.session.verify = False
def list_files(self, path=""):
response = self.session.get(
f"{self.base_url}/vault/{path}",
headers=self.headers
)
return response.json()
def read_file(self, path):
response = self.session.get(
f"{self.base_url}/vault/{path}",
headers=self.headers
)
return response.text
def write_file(self, path, content):
response = self.session.put(
f"{self.base_url}/vault/{path}",
headers={**self.headers, : },
data=content.encode()
)
response.status_code ==
():
response = .session.post(
,
headers=.headers,
json={: query}
)
response.json()
Markdown Extensions
Obsidian extends standard Markdown with special syntax:
Internal Links (Wikilinks)
[[Note Name]] # Link to note
[[Note Name|Display Text]] # Link with alias
[[Note Name#Heading]] # Link to heading
[[Note Name#^block-id]] # Link to block
[[Note Name#^block-id|alias]] # Block link with alias
Embeds (Transclusion)
![[Note Name]] # Embed entire note
![[Note Name#Heading]] # Embed section
![[Note Name#^block-id]] # Embed block
![[image.png]] # Embed image
![[image.png|300]] # Embed with width
![[image.png|300x200]] # Embed with dimensions
![[audio.mp3]] # Embed audio
![[video.mp4]] # Embed video
![[document.pdf]] # Embed PDF
Callouts
> [!note] Title
> Content here
> [!warning] Caution
> Important warning message
> [!tip]+ Expandable (default open)
> Click to collapse
> [!info]- Collapsed (default closed)
> Click to expand
# Available types:
# note, abstract, summary, tldr, info, todo, tip, hint,
# important, success, check, done, question, help, faq,
# warning, caution, attention, failure, fail, missing,
# danger, error, bug, example, quote, cite
Block References
This is a paragraph. ^block-id
# Reference this block from another note:
[[Note#^block-id]]
Tags
#tag
#nested/tag
#tag-with-dashes
Frontmatter (YAML)
---
title: My Note
date: 2024-01-15
tags:
- tag1
- tag2
aliases:
- alternate name
cssclass: custom-class
---
# Note content starts here
Comments
%%This is a comment that won't render%%
%%
Multi-line
comment
%%
Math (LaTeX)
Inline: $E = mc^2$
Block:
$$
\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$
Mermaid Diagrams
```mermaid
graph TD
A[Start] --> B{Decision}
B -->|Yes| C[Action 1]
B -->|No| D[Action 2]
```
CLI Tools
obsidian-cli (Yakitrak)
go install github.com/Yakitrak/obsidian-cli@latest
obsidian-cli open "Note Name"
obsidian-cli search "query"
obsidian-cli create "New Note"
obsidian-cli daily
obsidian-cli list
obsidian-cli (Python)
pip install obsidian-cli
obs vault list
obs vault create <name>
obs note search <query>
obs settings export
Best Practices
- Use separate dev vault: Never develop plugins in your main vault
- Hot reload plugin: Install for faster development iteration
- Use registerEvent(): Ensures proper cleanup on unload
- Prefer UIDs over paths: File paths can change; use unique identifiers
- Handle async properly: Use await for vault operations
- Test with Obsidian sandbox: Use BRAT plugin for beta testing
- Follow manifest conventions: Keep id matching folder name
- Version carefully: Update versions.json for compatibility
Troubleshooting
Plugin Not Loading
Ctrl+Shift+I (or Cmd+Option+I on Mac)
jq . manifest.json
URI Not Working
obsidian://open?vault=test
REST API Connection Failed
Resources
References
references/uri-scheme.md - Complete URI scheme documentation
references/plugin-development.md - Plugin development guide
references/vault-structure.md - Vault and config structure
references/markdown-extensions.md - Obsidian markdown syntax
references/api-reference.md - TypeScript API reference
Scripts
scripts/obsidian-vault.sh - Vault management utilities
scripts/obsidian-api.py - Local REST API Python client
External Documentation
Absorbed sub-skill (post-consolidation)
This skill now subsumes the former obsidian-master skill (the "unified orchestration" umbrella). Its content is preserved as deep reference:
| Subject | Path |
|---|
| Original orchestration SKILL.md (multi-step vault workflows) | References/master.md |
| Master skill's reference docs | References/master-reference/ |
| Master skill's workflows | References/master-workflows/ |
| Master skill's tools | References/master-tools/ |
The former obsidian-second-brain skill has been renamed to obsidian-claude-integration to reflect what it actually is: integration patterns for Claude Code + Obsidian, not a generic "second brain" concept.
Narrow siblings still apply:
obsidian-markdown — syntax only (wikilinks, embeds, callouts, frontmatter, tags, LaTeX, Mermaid).
obsidian-bases — Bases (.base YAML, table views, filters, formulas) only.
obsidian-nvim — the obsidian.nvim Neovim plugin only.
obsidian-vault-management — CRUD on vault contents (notes, templates, Dataview).
obsidian-claude-integration — Claude Code ↔ Obsidian integration patterns.
Gotchas
- Wikilink
[[Note]] resolution picks the first alphabetical match in the vault when duplicates exist — silently. Two notes named "Index" in different folders create an invisible ambiguity.
obsidian:// URI scheme requires the vault to be open in the desktop app — headless contexts (CI, Claude Code without Obsidian running) silently no-op.
- Local REST API plugin must be enabled separately from the API key — default port 27124, but the plugin must be running for any HTTP request to land.
- Markdown footnotes (
[^1]) require a blank line before the definition — without the blank line, Obsidian renders them as plain text, no error.
- Vault path with spaces/special chars: most plugins handle it; some shell-integration plugins don't. Test scripted invocations explicitly.