npx skills add ...
npx skills add julianobarbosa/claude-code-skills --skill obsidian
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.
npx skills add julianobarbosa/claude-code-skills --skill obsidian
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.
Native Obsidian supports obsidian:// protocol for automation:
| 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 |
| 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 |
The Local REST API plugin provides HTTP endpoints to interact with Obsidian programmatically.
https://127.0.0.1:27124Obsidian extends standard Markdown with special syntax:
references/uri-scheme.md - Complete URI scheme documentationreferences/plugin-development.md - Plugin development guidereferences/vault-structure.md - Vault and config structurereferences/markdown-extensions.md - Obsidian markdown syntaxreferences/api-reference.md - TypeScript API referencescripts/obsidian-vault.sh - Vault management utilitiesscripts/obsidian-api.py - Local REST API Python clientThis 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.[[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.[^1]) require a blank line before the definition — without the blank line, Obsidian renders them as plain text, no error.# Open a vault
obsidian://open?vault=MyVault
# Open a specific file
obsidian://open?vault=MyVault&file=Notes/MyNote
# Create a new note
obsidian://new?vault=MyVault&name=NewNote&content=Hello
# Search the vault
obsidian://search?vault=MyVault&query=keyword
# Open daily note
obsidian://daily?vault=MyVaultWhat 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 pluginmy-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{
"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
}import { Plugin, Notice, MarkdownView } from 'obsidian';
export default class MyPlugin extends Plugin {
async onload() {
console.log('Loading plugin');
// Register a command
this.addCommand({
id: 'my-command',
name: 'My Command',
callback: () => {
new Notice('Hello from my plugin!');
}
});
// Register editor command
this.addCommand({
id: 'my-editor-command',
name: 'Insert Text',
editorCallback: (editor, view: MarkdownView) => {
editor.replaceSelection('Inserted text');
}
});
// Register event listener
this.registerEvent(
this.app.workspace.on('file-open', (file) => {
if (file) {
console.log('Opened:', file.path);
}
})
);
}
onunload() {
console.log('Unloading plugin');
}
}// onload() - Called when plugin is enabled
async onload() {
// Initialize UI components
// Register event handlers
// Set up commands
// Load settings
}
// onunload() - Called when plugin is disabled
onunload() {
// Cleanup is mostly automatic
// Custom cleanup for external resources
}# Using API key header
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://127.0.0.1:27124/vault/# List all files
GET /vault/
# Get file content
GET /vault/{path-to-file}
# Create/Update file
PUT /vault/{path-to-file}
Content-Type: text/markdown
Body: File content here
# Delete file
DELETE /vault/{path-to-file}
# Search vault
POST /search/simple/
Content-Type: application/json
Body: {"query": "search term"}
# Execute command
POST /commands/{command-id}
# Get active file
GET /active/
# Open file in Obsidian
POST /open/{path-to-file}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 # Self-signed cert
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, "Content-Type": "text/markdown"},
data=content.encode('utf-8')
)
return response.status_code == 204
def search(self, query):
response = self.session.post(
f"{self.base_url}/search/simple/",
headers=self.headers,
json={"query": query}
)
return response.json()[[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![[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> [!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, citeThis is a paragraph. ^block-id
# Reference this block from another note:
[[Note#^block-id]]#tag
#nested/tag
#tag-with-dashes---
title: My Note
date: 2024-01-15
tags:
- tag1
- tag2
aliases:
- alternate name
cssclass: custom-class
---
# Note content starts here%%This is a comment that won't render%%
%%
Multi-line
comment
%%Inline: $E = mc^2$
Block:
$$
\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$