obsidian-semantic-search
Skill19 starsChanged 5 months agoMITView on GitHub
Search Obsidian vault notes by conceptual meaning, not just keywords. Builds a local embedding index over all vault notes (per-section chunking), then performs cosine similarity search at query time. Before any search, the agent MUST check the index state: Decision logic: The scripts locate the vault automatically via OBSIDIAN_VAULT env var or common paths (~/Documents/Obsidian, ~/Obsidian, ~/vault). If the vault is at a non-standard location, set it first: Returns JSON array of results, each with: - title — Note title…
- Reads credentials
In this repository14 other files it gives its agents.
- good-questionSkill
- knowledge-distillation-from-discussionSkill
- mao-semantic-searchSkill
- markdown-to-htmlSkill
- markitdown-convertSkill
- notion-to-markdownSkill
- obsidian-auto-classifierSkill
- obsidian-batch-yamlSkill
- paper-code-auditSkill
- paper-deep-readerSkill
- paper-finderSkill
- paper-quick-readSkill
- tech-doc-writingSkill
- weekly-report-generatorSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 2 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 3
Search Obsidian vault notes by conceptual meaning, not just keywords.
- Distinctive: line 28
Before any search, the agent MUST check the index state:
- Very specific: line 73
After getting results, use mcp__obsidian__read_note with the path field to read full content:
- Very specific: line 101
All settings via environment variables (loaded from .env):
- Very specific: line 116
Rebuild frequency: Run --force after major vault reorganization or when search quality degrades.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Obsidian Semantic Search
Search Obsidian vault notes by conceptual meaning, not just keywords. Builds a local embedding index over all vault notes (per-section chunking), then performs cosine similarity search at query time.
When to Use
- User asks a fuzzy/conceptual question about their own notes ("What papers discuss exploration in RL?")
- Keyword search (
mcp__obsidian__search_notes) returns too many or too few results - User wants to find notes related to a concept without knowing exact terminology
- As a pre-retrieval step before deep-reading or analyzing vault content
Architecture
Vault (.md files) ──build_index.py──> temp/obsidian/embeddings.json <──search.py── User Query
│
└── Shared with paper-deep-reader- Index: Flat JSON, one embedding per
.mdnote (full body text, frontmatter excluded), mtime-tracked incremental rebuild - Embeddings: Reuses
stable_jarvis.llm.embed()— same provider stack as paper-deep-reader (local / qwen / openai) - Search: Brute-force cosine similarity, O(n) over all notes
Workflow
Phase 0: Check Index Freshness (Always First)
Before any search, the agent MUST check the index state:
python skills/obsidian-semantic-search/scripts/build_index.py --statsDecision logic:
| State | Action |
| Index exists AND built today | Skip build, proceed to Phase 2 directly |
| Index exists AND built in last 3 days | Run build_index.py (incremental — only changed files) |
| Index exists AND older than 3 days | Run build_index.py --force (full rebuild) |
| Index does NOT exist | Run build_index.py --force (first build) |
Phase 1: Build/Update Index (If Needed)
# Incremental update (recommended when index exists but stale)
python skills/obsidian-semantic-search/scripts/build_index.py
# Full rebuild (first time, or after major vault changes)
python skills/obsidian-semantic-search/scripts/build_index.py --forceThe scripts locate the vault automatically via OBSIDIAN_VAULT env var or common paths (~/Documents/Obsidian, ~/Obsidian, ~/vault). If the vault is at a non-standard location, set it first:
export OBSIDIAN_VAULT="/path/to/vault"Phase 2: Semantic Search
python skills/obsidian-semantic-search/scripts/search.py "query text" --top-k 5Returns JSON array of results, each with:
title— Note title (from H1 or filename)path— Relative path in vault (use directly withmcp__obsidian__read_note)score— Cosine similarity (0–1, higher = more relevant)text_snippet— First 200 chars of the note bodyarxiv_id— From frontmatter, if present
Phase 3: Read Full Notes (via Obsidian MCP)
After getting results, use mcp__obsidian__read_note with the path field to read full content:
mcp__obsidian__read_note(path="30 Zettelkasten/RL/MAC.md")Phase 4: Present Results
Format search results for the user with:
- Note title as
[[wikilink]] - Relevance score
- Brief excerpt from
text_snippet
Commands
| Command | Purpose |
build_index.py | Incremental index rebuild (default) |
build_index.py --force | Full rebuild from scratch |
build_index.py --stats | Show index statistics |
build_index.py --clear | Remove index file |
search.py "query" | Semantic search (top 5) |
search.py "query" --top-k 10 | More results |
search.py "query" --min-score 0.4 | Filter low-relevance results |
search.py "query" --provider qwen | Use specific embedding provider |
Configuration
All settings via environment variables (loaded from .env):
| Variable | Default | Description |
OBSIDIAN_VAULT | Auto-detect | Path to Obsidian vault |
EMBEDDING_PROVIDER | local | local / qwen / openai |
EMBEDDING_MODEL | Provider-dependent | Model override |
EMBEDDING_API_KEY | From {PROVIDER}_API_KEY | API key for cloud embeddings |
The local provider uses sentence-transformers (paraphrase-multilingual-MiniLM-L12-v2) and requires no API key.
Index Management
- Incremental updates: Running
build_index.pywithout--forcecompares file mtimes and only re-embeds changed notes. Deleted notes are automatically removed from the index. - Shared index: The index at
temp/obsidian/embeddings.jsonis shared withpaper-deep-reader. Both skills read and benefit from the same index. - Rebuild frequency: Run
--forceafter major vault reorganization or when search quality degrades.
Integration Notes
- Results from
search.pyinclude the vault-relativepath— this is the exact argument to pass tomcp__obsidian__read_note - Combine with
mcp__obsidian__search_notesfor hybrid retrieval: semantic for recall, keyword for precision - Index is stored at
temp/obsidian/embeddings.json— shared withpaper-deep-readerskill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

