
Obsidian Semantic Search
io.github.DalecBPublished by GitHub account DalecBv0.2.1Updated Oct 24, 2026
Read-only semantic search MCP server for Obsidian vaults using local Ollama embeddings.
Overview
Read-only MCP server that lets an assistant semantically search and read notes in a local Obsidian vault using local Ollama embeddings.
- What you can do
- Search notes with hybrid semantic, keyword or vector ranking and get file-level matches with headings, snippets and line ranges, plus an option to include sensitive folders when unlocked. Read a note or a line range by vault-relative path. Build or update the external SQLite index, incrementally or for specific files, and check index metadata and active safety settings.
- When to use it
- Use it when an agent should find and read the right note in an Obsidian vault without any ability to write, edit, move or delete notes, and when you want embeddings and the index to stay on your machine. It suits retrieval questions such as which note explains a decision or where a topic was written up.
- Requirements
- Runs locally over stdio via npx, needing Node.js 24 or newer, a running Ollama instance with an embedding model pulled (default bge-m3), and an MCP client. Requires the OBSIDIAN_VAULT_ROOT environment variable set to the vault's absolute path; optional variables cover the index home directory, Ollama base URL, embedding model, excludes and sensitive paths.
Installation
In SourceWeft
- Open Obsidian Semantic Search in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
Obsidian Semantic Search MCP
Read-only semantic retrieval for agents that need to find the right Obsidian note without write access.
[npm] [MCP Registry] [License] [Node.js]
한국어 · Quick Start · Why This Exists · How It Works
Your Obsidian vault is useful only if your agent can find the right note.
Keyword search misses context. Full write-capable Obsidian MCP servers expose more power than a retrieval agent needs. Obsidian plugins are great inside Obsidian, but they are not always the right boundary for Codex, Claude Desktop, Cursor, or any other MCP client.
This project is the narrow version:
No note writes. No cloud embeddings by default. No Obsidian plugin runtime. No sync service.
Status:
0.3.1early preview. The server is usable today, but ranking behavior and tool schemas may change before1.0.
What You Get
Example result shape:
Quick Start
Requirements:
- Node.js
>= 24 - Ollama
- An Obsidian vault
- An MCP client such as Codex, Claude Desktop, Cursor, or another stdio MCP client
Install the embedding model:
Print setup guidance:
Codex Setup
Add this to ~/.codex/config.toml:
Restart Codex, then run:
Claude Code Setup
Add the server at user scope so the personal vault path stays out of project .mcp.json files:
Start a new Claude Code session and run /mcp to confirm the server is connected. On native Windows, use -- cmd /c npx -y @dalecb/obsidian-semantic-mcp after the environment flags.
See Anthropic's Claude Code MCP documentation for scope and command details.
Claude Desktop / JSON MCP Client Setup
In Claude Desktop, open Settings → Developer → Edit Config. This opens ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows. Merge the following server into mcpServers:
Fully quit and restart Claude Desktop. Cursor and other JSON-style stdio MCP clients can use the same mcpServers entry. On Windows, if npx is not found, use "command": "cmd" and prepend "/c", "npx" to args.
See the official local MCP server guide for Claude Desktop configuration and logs.
Why This Exists
This isn't aiming to be the most powerful Obsidian automation server. It aims to be the safest retrieval tool you can hand an agent.
Here's how it stacks up against the two tools it usually comes down to — a full-permission Obsidian MCP server (Local REST API based) and GBrain (a broader knowledge-compilation platform):
That trade is on purpose: give up writing, editing, and running inside Obsidian, and you get fewer moving parts and a smaller blast radius in return.
Use this if your agent should answer:
- "Which note explains this project decision?"
- "Find the file where I wrote about idempotency payload mismatch."
- "Show me the career notes related to this interview topic."
- "Search my vault, but do not mutate it."
Do not use this if you want an Obsidian UI plugin, automatic note generation, or write-capable vault automation.
Tools
index_status
Returns index metadata and safety settings.
index_vault
Builds or updates the external SQLite index.
Specific files:
search_notes
Searches notes with hybrid semantic and keyword ranking.
Modes:
hybrid: semantic vector + SQLite FTS5 + metadata boostssemantic: vector-first searchkeyword: FTS5 keyword search without embedding the query
read_note
Reads a note or line range by vault-relative path.
How It Works
Default storage:
The vault remains the source of truth. The SQLite database is a derived index and can be deleted/rebuilt.
Safety Model
The server reads your vault and never writes to it. Three layers decide what an agent can see.
1. Always denied (system / tooling). Never indexed, no override:
.obsidian/,.smart-env/,.claude/,.codex-*/- any hidden folder (name starts with
.) node_modules,cache,logs
2. Sensitive — denied by default, unlockable. Stays blocked even when a tool call passes include_sensitive: true, unless the server is started with OBSIDIAN_SEMANTIC_ALLOW_SENSITIVE=true. Defaults to 08_PersonalInfo/. Override the list with OBSIDIAN_SEMANTIC_SENSITIVE_PATHS (comma- or newline-separated folders):
3. Your own excludes — always denied. Folders you never want indexed, searched, or read. No unlock flag:
Which one do you want?
- "Don't index this at all" →
OBSIDIAN_SEMANTIC_EXCLUDE - "Keep it locked, but I can unlock it with a flag when I need to" →
OBSIDIAN_SEMANTIC_SENSITIVE_PATHS+OBSIDIAN_SEMANTIC_ALLOW_SENSITIVE
Additional guards:
- All paths are resolved through
realpath. - Path traversal and URL-encoded traversal are blocked.
- Symlinks that escape the vault root or point to a denied in-vault path are blocked.
search_notesandread_noteenforce the current exclusion settings on every call. With automatic indexing enabled, the next search also removes excluded stale rows from the index. Confirm the active lists withindex_status.
The local index stores snippets and embedding vectors. Treat it as a derived copy of your vault. See PRIVACY.md.
Indexing Strategy
The default is action-driven, not timer-based:
- The first
search_notesafter server start. - The first
search_notesafter a Markdown create, update, delete, or rename event. - The first
search_notesafter the embedding model or index format changes; this triggers a full rebuild. - An explicit
index_vaultcall.
The filesystem watcher only marks the index dirty. Indexing runs once, immediately before the next search, and concurrent searches share that work. If recursive watching is unavailable, the server falls back to an incremental scan before every search.
Disable automatic indexing with:
Then call index_vault { "mode": "incremental" } yourself. The legacy OBSIDIAN_SEMANTIC_STARTUP_INDEX=true remains supported, but is not the default because it does work even when no search follows.
Search Quality Evaluation
Create a JSON file containing queries and expected paths to compare keyword, semantic, and hybrid modes under the same conditions:
The command reports Recall@K and MRR. Avoid adding ranking complexity or embedding cost unless hybrid search measurably beats the keyword baseline.
Refresh the index with search_notes or index_vault before evaluating.
Development
Before publishing:
Confirm the package does not include data/, *.sqlite, or private vault files.
License
MIT
Source: README.md at commit 0e01b3a
Tools
0Version history
1- v0.2.1LatestSep 16, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts
