From claude-superskills
Automates repetitive Obsidian vault tasks via CLI, shell commands, and scripts: batch-creates notes, bulk-updates frontmatter, runs maintenance, opens notes, navigates programmatically, integrates with external tools.
npx claudepluginhub ericgandrade/claude-superskills --plugin claude-superskillsThis skill uses the workspace's default tool permissions.
This skill automates Obsidian vault operations that are tedious to perform manually through the GUI. It bridges the gap between Obsidian's visual interface and the command line, scripting layer, and external tools.
Executes Obsidian CLI commands to read/write/append notes, search vaults, list/count files, manage tasks, move/rename notes, and find orphans/broken links.
Manages Obsidian vaults: search, create, edit, move Markdown notes; handle YAML frontmatter, wikilinks, backlinks, daily notes, Zettelkasten setup, and sync via obsidian-cli.
Manages Obsidian vaults using obsidian-cli: creates daily notes, moves/renames notes preserving [[wiki-links]], searches content, organizes notes with templates.
Share bugs, ideas, or general feedback.
This skill automates Obsidian vault operations that are tedious to perform manually through the GUI. It bridges the gap between Obsidian's visual interface and the command line, scripting layer, and external tools.
Automation tasks include: opening notes and performing actions (insert template, navigate, toggle pins), reading vault metadata without opening Obsidian, batch creating or modifying notes, integrating vault content with other applications, and running scheduled maintenance scripts.
The primary automation vector is the Obsidian CLI — a community-built command-line interface that communicates with Obsidian via its Local REST API plugin. Secondary automation paths include shell scripts operating on .md files directly, and native scripting with Obsidian's built-in Templater or DataviewJS plugins.
Invoke this skill when:
Do NOT use this skill when:
.md file directlyobsidian-frontmatter insteadobsidian-links insteadThe Obsidian Local REST API plugin exposes an HTTP API on localhost:27123 (default). The obsidian-cli npm package wraps this API with a command-line interface.
Installation:
# Install the Local REST API plugin in Obsidian (Community Plugins)
# Then install the CLI wrapper:
npm install -g obsidian-cli
# Or use via npx:
npx obsidian-cli --help
Configuration:
# Set the API key (found in Local REST API plugin settings)
export OBSIDIAN_API_KEY="your-key-here"
# Or pass per command:
obsidian-cli --api-key "your-key" <command>
Core commands:
# Open a note
obsidian-cli open "Daily Notes/2024-01-15"
# Get note content
obsidian-cli get "Projects/Project Alpha"
# Create or update a note
obsidian-cli put "Daily Notes/2024-01-15" --content "$(cat template.md)"
# Append to a note
obsidian-cli append "Daily Notes/2024-01-15" --content "- New task item"
# Search the vault
obsidian-cli search "query string"
# List notes in a folder
obsidian-cli list "Projects/"
# Delete a note
obsidian-cli delete "Archive/Old Note"
Many vault tasks do not require the CLI and can be done with standard shell tools on the .md files directly:
# Find all notes lacking frontmatter
grep -rL "^---" <vault-root>/*.md
# Count notes by tag
grep -rh "^ - " <vault-root>/**/*.md | sort | uniq -c | sort -rn | head 20
# Update a frontmatter field across all notes in a folder
find <vault-root>/Projects -name "*.md" -exec sed -i '' \
's/^status: planning$/status: active/' {} \;
# Create a note if it does not exist
NOTE="<vault-root>/Daily Notes/$(date +%Y-%m-%d).md"
[[ ! -f "$NOTE" ]] && cat daily-template.md > "$NOTE"
The Templater community plugin allows JavaScript execution inside note templates. Useful for:
Templater syntax:
<% tp.date.now("YYYY-MM-DD") %>
<% tp.file.title %>
<% await tp.system.prompt("Project name?") %>
Before scripting, determine what is available:
# Check if obsidian-cli is installed
which obsidian-cli 2>/dev/null || npx obsidian-cli --version 2>/dev/null
# Check if Obsidian is running (Local REST API must be active)
curl -s http://localhost:27123/vault/ -H "Authorization: Bearer $OBSIDIAN_API_KEY" | head -5
# Check Templater plugin (look for .js files in vault's scripts folder)
find <vault-root> -name "*.js" -path "*/scripts/*" 2>/dev/null | head 5
If neither the CLI nor the Local REST API is available, tell the user:
.md files).Classify the task into one of these categories:
| Category | Example tasks | Primary tool |
|---|---|---|
| Navigate | Open a note, navigate to a heading | obsidian-cli |
| Create | Batch-create notes from a list | file operations + CLI |
| Update | Bulk update frontmatter fields | shell sed / CLI |
| Search | Find notes by content or tag | CLI search / grep |
| Maintain | Archive old notes, generate MOC | shell script |
| Integrate | Sync with calendar, import from web | CLI + external tools |
For simple one-off tasks, output a single command. For multi-step automation, output a shell script with comments:
#!/usr/bin/env bash
# Purpose: Create daily notes for the next 7 days from a template
# Requirements: vault-root set, template.md exists
# Usage: ./create-daily-notes.sh /path/to/vault /path/to/template.md
VAULT="${1:?Usage: $0 <vault-root> <template>}"
TEMPLATE="${2:?Usage: $0 <vault-root> <template>}"
FOLDER="$VAULT/Daily Notes"
mkdir -p "$FOLDER"
for i in $(seq 0 6); do
DATE=$(date -v+${i}d +%Y-%m-%d 2>/dev/null || date -d "+${i} days" +%Y-%m-%d)
FILE="$FOLDER/$DATE.md"
if [[ ! -f "$FILE" ]]; then
sed "s/{{date}}/$DATE/g" "$TEMPLATE" > "$FILE"
echo "Created: $FILE"
else
echo "Exists: $FILE (skipped)"
fi
done
Key scripting principles:
#!/usr/bin/env bash shebang--dry-run mode where possible before applying changes$VAULT pathCreating notes with proper frontmatter:
When scripting note creation, always write a complete frontmatter block at the top of the file template. Pass it through sed or envsubst to inject dynamic values.
Batch frontmatter updates:
Use awk or python for reliable YAML frontmatter manipulation. Avoid sed for multi-line YAML edits — it's error-prone.
#!/usr/bin/env python3
"""Update the status field in all project notes."""
import os, re, sys
vault = sys.argv[1]
new_status = sys.argv[2]
for root, dirs, files in os.walk(vault):
for f in files:
if not f.endswith('.md'): continue
path = os.path.join(root, f)
with open(path, 'r') as fp:
content = fp.read()
if not content.startswith('---'): continue
updated = re.sub(r'^status: \w+', f'status: {new_status}', content, flags=re.MULTILINE)
if updated != content:
with open(path, 'w') as fp:
fp.write(updated)
print(f"Updated: {path}")
Vault maintenance — archive old notes:
#!/usr/bin/env bash
# Move notes not modified in 90+ days to Archive/
VAULT="${1:?}"
ARCHIVE="$VAULT/Archive"
mkdir -p "$ARCHIVE"
find "$VAULT" -name "*.md" -not -path "$ARCHIVE/*" -mtime +90 | while read -r f; do
echo "Archiving: $f"
mv "$f" "$ARCHIVE/$(basename "$f")"
done
Always offer a dry-run mode before making changes:
echo "Would create: $FILE" before actual operations--dry-run flag pattern: check [[ "$1" == "--dry-run" ]] before writes-f flag is explicitAt the end of any automation script, output a summary count:
Vault maintenance complete:
Notes created: 7
Notes updated: 23
Notes archived: 4
Errors: 0
Open today's daily note in Obsidian:
obsidian-cli open "Daily Notes/$(date +%Y-%m-%d)"
Create a new note from a template:
TITLE="Meeting with Alice - $(date +%Y-%m-%d)"
obsidian-cli put "Meetings/$TITLE" --content "$(cat meeting-template.md)"
obsidian-cli open "Meetings/$TITLE"
Append to the inbox note:
read -rp "Quick note: " QUICK_NOTE
obsidian-cli append "Inbox" --content "- $(date +%H:%M) — $QUICK_NOTE"
Find all notes without a status property:
grep -rL "^status:" <vault-root>/**/*.md
Generate an index of all project notes:
echo "# Project Index\n" > "$VAULT/Projects/Index.md"
find "$VAULT/Projects" -name "*.md" -not -name "Index.md" | sort | while read -r f; do
TITLE=$(basename "$f" .md)
echo "- [[$TITLE]]" >> "$VAULT/Projects/Index.md"
done
NEVER:
.md files inside a vault directoryALWAYS:
--dry-run pattern before applying irreversible changesExample 1: Open today's daily note
User: "Open today's daily note."
obsidian-cli open "Daily Notes/$(date +%Y-%m-%d)"
If the note does not exist, create it from a template first:
DATE=$(date +%Y-%m-%d)
NOTE="Daily Notes/$DATE"
# Create if missing
obsidian-cli list "$NOTE" 2>/dev/null || obsidian-cli put "$NOTE" --content "$(sed "s/{{date}}/$DATE/g" daily-template.md)"
obsidian-cli open "$NOTE"
Example 2: Batch-create meeting notes
User: "Create meeting notes for Alice, Bob, and Carol scheduled for today."
DATE=$(date +%Y-%m-%d)
for PERSON in "Alice" "Bob" "Carol"; do
TITLE="Meeting with $PERSON - $DATE"
obsidian-cli put "Meetings/$TITLE" \
--content "---
title: $TITLE
date: $DATE
attendees:
- \"[[$PERSON]]\"
tags:
- meeting
status: scheduled
---
## Agenda
## Notes
## Action Items
"
echo "Created: $TITLE"
done
Example 3: Vault search from CLI
User: "Find all notes that mention 'OKR' in my vault."
obsidian-cli search "OKR"
# Or with direct grep:
grep -rl "OKR" <vault-root> --include="*.md"
Example 4: Archive old inbox items
User: "Move all items in my Inbox folder older than 2 weeks to the Archive."
find "$VAULT/Inbox" -name "*.md" -mtime +14 | while read -r f; do
DEST="$VAULT/Archive/$(basename "$f")"
echo "Archiving: $f → $DEST"
# Add --execute flag to actually move:
# mv "$f" "$DEST"
done
echo "Run with --execute to apply changes."
Example 5: Nightly maintenance script
User: "Create a nightly script that: creates tomorrow's daily note, appends today's done tasks to a weekly review note."
Output: A full bash script with both operations, date calculations, template injection, and a summary log at the end.