Obsidian Semantic Search MCP
This server enables read-only semantic retrieval for Obsidian vaults, allowing agents to search, read, and manage a local index without modifying notes.
Search: Perform hybrid, semantic, or keyword searches across your notes, with options to filter by folder, include archived notes, set result limits, and access sensitive paths if permitted.
Read notes: Retrieve full note content or specific line ranges by vault-relative path, with optional access to sensitive paths.
Index management: Build or update the semantic index incrementally or fully, target specific files, preview changes via dry-run, and check index status and safety settings.
Safety controls: Exclude sensitive or archived folders by default, respect custom exclusion lists, and unlock protected content only via a server-side environment variable.
Local-first: Uses Ollama embeddings and stores the index in SQLite, ensuring all data remains on your machine. The index updates automatically when needed (e.g., after file changes).
Read-only: Provides strictly read access; no modifications, edits, or deletions are possible. Works directly from the filesystem, with no Obsidian app required.
Provides read-only semantic search and retrieval over Obsidian vaults, enabling agents to find and read notes without modifying the vault.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Obsidian Semantic Search MCPfind the note on Redis Lua atomicity"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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:
local Obsidian vault -> read-only scanner -> local SQLite index -> MCP search/read toolsNo 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
Need | What this server does |
Find the note an agent should read | Hybrid semantic + keyword search over Markdown notes |
Keep the vault safe | Exposes search/read/index/status only; no write, patch, move, rename, or delete tools |
Stay local-first | Uses Ollama embeddings and stores the index on your machine |
Make results agent-friendly | Returns file-level matches with headings, snippets, and line ranges |
Avoid plugin state | Reads the vault directly from the filesystem; Obsidian does not need to be running |
Example result shape:
{
"path": "02_Projects/RealtimeAPI/05_Interview_QA.md",
"title": "Interview Q&A",
"score": 0.7431,
"matched_sections": [
{
"heading": "Level 4 > Redis Lua atomicity",
"lines": [266, 305],
"reason": "semantic=1, keyword=0.5565, metadata=0.6"
}
]
}Related MCP server: second-brain-mcp
Quick Start
Requirements:
Node.js
>= 24Ollama
An Obsidian vault
An MCP client such as Codex, Claude Desktop, Cursor, or another stdio MCP client
Install the embedding model:
ollama pull bge-m3
curl http://localhost:11434/api/tagsPrint setup guidance:
npx -y --package @dalecb/obsidian-semantic-mcp obsidian-semantic-mcp-setupCodex Setup
Add this to ~/.codex/config.toml:
[mcp_servers.obsidian_semantic]
command = "npx"
args = ["-y", "@dalecb/obsidian-semantic-mcp"]
[mcp_servers.obsidian_semantic.env]
OBSIDIAN_VAULT_ROOT = "/path/to/your/Obsidian Vault"
OBSIDIAN_SEMANTIC_MCP_HOME = "/Users/you/.obsidian-semantic-mcp"
OLLAMA_BASE_URL = "http://localhost:11434"
OBSIDIAN_EMBED_MODEL = "bge-m3"
OBSIDIAN_SEMANTIC_AUTO_INDEX = "true"Restart Codex, then run:
obsidian_semantic.index_status
obsidian_semantic.search_notes { "query": "Redis Lua atomicity", "limit": 5 }Claude Code Setup
Add the server at user scope so the personal vault path stays out of project .mcp.json files:
claude mcp add obsidian_semantic --scope user \
--env OBSIDIAN_VAULT_ROOT="/path/to/your/Obsidian Vault" \
--env OBSIDIAN_SEMANTIC_MCP_HOME="/Users/you/.obsidian-semantic-mcp" \
--env OLLAMA_BASE_URL="http://localhost:11434" \
--env OBSIDIAN_EMBED_MODEL="bge-m3" \
--env OBSIDIAN_SEMANTIC_AUTO_INDEX="true" \
-- npx -y @dalecb/obsidian-semantic-mcp
claude mcp get obsidian_semanticStart 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:
{
"mcpServers": {
"obsidian_semantic": {
"command": "npx",
"args": ["-y", "@dalecb/obsidian-semantic-mcp"],
"env": {
"OBSIDIAN_VAULT_ROOT": "/path/to/your/Obsidian Vault",
"OBSIDIAN_SEMANTIC_MCP_HOME": "/Users/you/.obsidian-semantic-mcp",
"OLLAMA_BASE_URL": "http://localhost:11434",
"OBSIDIAN_EMBED_MODEL": "bge-m3",
"OBSIDIAN_SEMANTIC_AUTO_INDEX": "true"
}
}
}
}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):
This project | Full-permission Obsidian MCP | GBrain | |
Access model | Read-only: search / read / index | Read + write + edit + delete | Read + write; compiles notes into its own model |
Touches your vault | Never | Yes | Yes — restructures content |
Obsidian must run | No — reads files directly | Yes — needs the REST API plugin | No |
Required local runtime | Node.js + Ollama | Obsidian + plugin | Standalone platform |
Embeddings & data | Local Ollama by default; remote URL is configurable | Local API; embeddings vary by setup | Built-in pipeline; optional sync |
Storage | One SQLite file you can delete and rebuild | Plugin-managed | Its own store / migration |
Best for | A small read-only retrieval boundary for agents | Full vault automation and editing | Building a compiled knowledge base across sources |
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.
{ "mode": "incremental" }Specific files:
{
"mode": "incremental",
"paths": ["02_Projects/My Note.md"]
}search_notes
Searches notes with hybrid semantic and keyword ranking.
{
"query": "live coding notes",
"limit": 8,
"mode": "hybrid"
}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.
{
"path": "02_Projects/My Note.md",
"start_line": 10,
"end_line": 40
}How It Works
index_vault
-> scan Markdown files under OBSIDIAN_VAULT_ROOT
-> block denied paths and symlink escapes
-> split notes by Markdown headings
-> create one summary chunk per file
-> embed chunks with Ollama bge-m3
-> store notes, chunks, FTS rows, and vectors in SQLite
search_notes
-> incrementally index on first search or first search after a Markdown change
-> embed the query with Ollama
-> score vector similarity
-> score SQLite FTS5 keyword matches
-> apply title/path/heading metadata boosts
-> regroup chunk matches into file-level resultsDefault storage:
~/.obsidian-semantic-mcp/
data/semantic.sqliteThe 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):
OBSIDIAN_SEMANTIC_SENSITIVE_PATHS = "08_PersonalInfo, 09_Finance"3. Your own excludes — always denied. Folders you never want indexed, searched, or read. No unlock flag:
OBSIDIAN_SEMANTIC_EXCLUDE = "03_Journal, Private, Clients/Acme"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:
OBSIDIAN_SEMANTIC_AUTO_INDEX = "false"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:
[
{ "query": "strong consistency at 1000 TPS", "expected_paths": ["03_Knowledge/QnA/Strong-Consistency-at-1000TPS.md"] }
]npm run evaluate -- ./queries.json 5The 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
npm test
npm run pack:checkBefore publishing:
npm pack --dry-runConfirm the package does not include data/, *.sqlite, or private vault files.
License
MIT
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityAmaintenanceEnables read-only access to Obsidian vaults with semantic search, tag filtering, and metadata queries. Provides secure, intelligent note retrieval and summarization for LLMs without modifying your vault.1912ISC
- Alicense-qualityCmaintenanceTurns an Obsidian vault into semantic memory for coding agents, providing read-only semantic search and a human-approved write workflow via MCP.5MIT
- Alicense-qualityDmaintenanceProvides semantic search and keyword search over Obsidian notes, along with direct note retrieval, allowing external AI agents to query and access the vault.18BSD Zero Clause
- Flicense-qualityDmaintenanceEnables semantic search over an Obsidian vault using ChromaDB, allowing users to search, read, and list notes via natural language.
Related MCP Connectors
Search and reason over your Obsidian-style Markdown vault, right from ChatGPT.
Search your Obsidian vault to quickly find notes by title or keyword, summarize related content, a…
Search your knowledge bases from any AI assistant using hybrid RAG.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/DalecB/obsidian-semantic-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server