obsidian-mcp-fast

obsidian-mcp-fast

Highly-performant MCP server for Obsidian vaults enabling sub-millisecond retrieval of notes without requiring Obsidian app, supporting Claude Desktop, Claude Code, Cursor, and other MCP clients.

Category
Visit Server

README

obsidian-mcp-fast

Highly-performant MCP server for Obsidian vaults. Sub-millisecond retrieval. No Obsidian app required. Works with Claude Desktop, Claude Code, Cursor, and anything else that speaks MCP.

License: MIT Python 3.10+ MCP

obsidian-mcp-fast is an MCP server that exposes your Obsidian vault to any compatible LLM client (Claude Desktop, Claude Code, Cursor, ChatGPT custom MCPs, etc.) for fast, structured retrieval. It reads your .md files directly from disk — Obsidian doesn't need to be running. Pre-computed indexes live in memory. A file watcher keeps them fresh as you edit.

If you've used MarkusPfundstein/mcp-obsidian and hit slow searches, timeouts on larger vaults, or just want retrieval that's actually engineered for speed, this is for you. Comparison below.


What it does

Three retrieval primitives, exposed as 4 MCP tools:

Tool What it does
wiki_query Primary tool. Runs 3-layer hybrid retrieval (frontmatter filter → atomic-claim keyword search → wikilink graph expansion). Returns top cited claims, graph-adjacent context, suggested pages to read.
wiki_read Fetch full content of a page by path or title (resolved via the graph).
wiki_stats Vault overview: counts by type, top hubs, recent edits, watcher state.
wiki_reindex Manually trigger reindex. Usually unnecessary — file watcher handles it.

The LLM does the synthesis from what these tools return. The server does the retrieval.


Why it's fast

Move Why it matters
Long-running process, RAM-resident indexes Server stays alive between queries. No JSON parsing per call, no file I/O for layer 1/2/3.
Direct file reads, no Obsidian REST API No HTTP round-trips, no localhost TLS handshake, no dependency on Obsidian being open.
File watcher → debounced reindex Edit a note → 500ms later the indexes update. Most queries hit a warm cache.
Indexer is pure Python stdlib Sub-second on 60–600 page vaults. No heavy NLP libraries to load.
Coarse tool API One wiki_query call replaces 5–10 file-by-file tool calls. Token cost is dominated by Claude inference, not tool plumbing.
Atomic-claim retrieval Returns specific cited facts, not whole pages. The LLM synthesis context stays small and precise.

Benchmarks (60 pages, 584 atomic claims, 373 wikilink edges)

Operation Latency
wiki_query end-to-end <1ms
wiki_read (single page) ~1ms
wiki_stats <1ms
Full reindex ~15ms
Server startup ~500ms (one-time)

These numbers should hold up to ~10K pages / ~50K claims with no architectural changes. Past that, swap brute-force claim search for vector ANN (roadmap).


Schema requirements (opinionated — read this)

This server is purpose-built for vaults that follow a specific schema. If your vault doesn't follow these conventions, retrieval will work but yield less than it could. See docs/schema.md for the full rationale.

Directory layout

your-vault/
├── Skills/         # Curated capability hubs (domain layer above types)
├── People/         # Real humans (founders, marketers, thinkers, etc.)
├── Brands/         # Companies and brand case studies
├── Frameworks/     # Actionable principles (have How To Apply + Anti-Patterns)
├── Concepts/       # Passive ideas, phenomena, definitions
├── References/     # Recurring resources (podcasts, dashboards, doc sites)
├── Sources/        # Immutable per-source notes (one per article/book/episode)
└── _System/
    └── index/      # Generated retrieval indexes (auto-managed)

Skills are first-class retrieval anchors. A Skill page is a curated hub that aggregates many Frameworks/Concepts/People/Brands under a single domain (e.g. "Offer Construction" pulls together Grand Slam Offer + Value Equation + Niche Down + …). When an agent gets a domain-shaped question, it queries wiki_query(type_filter=["skill"]) to find relevant hubs, then wiki_read("Offer Construction") to load the curated set in one call. This is faster and more coherent than searching individual frameworks one by one.

Page schema

Every entity page has YAML frontmatter:

---
type: framework         # one of: person | brand | framework | concept | reference | source
created: 2026-05-04
updated: 2026-05-04
tags: [meta-ads, dtc]   # for filtering
related: [Andromeda]    # explicit cross-refs (also queryable)
---

# Page Title

## Key Facts
- Atomic claim 1 stated as a fact ([[Source - Article 2026]])
- Atomic claim 2 ([[Source - Other 2025]])

## How To Apply        # required for Frameworks
1. Step
2. Step

## Examples
### [[Brand Name]]
- How it shows up here ([[Source - Article 2026]])

## Sources
- [[Source - Article 2026]]

Three disciplines drive the retrieval performance:

  1. Atomic claim-bullets — one bullet, one fact, one inline ([[Source - X]]) cite. The indexer treats each as an atomic retrievable unit.
  2. Wikilinks for entity references[[Page Name]] syntax everywhere. Builds the wikilink graph for free.
  3. Typed frontmattertype:, tags:, related: — enables structured filtering (Layer 1) before any keyword search.

If you'd like a complete reference architecture for this schema (templates, ingest pipeline, linter, etc.), see the-edge-wiki — the project this MCP was extracted from.


Installation

Prerequisites

  • macOS, Linux, or Windows (WSL)
  • Python 3.10+
  • uv (brew install uv on macOS, or see installation guide)

Install via uv tool (recommended)

uv tool install obsidian-mcp-fast

This installs the obsidian-mcp-fast and obsidian-mcp-fast-index commands globally, isolated in their own venv.

Install from source

git clone https://github.com/thedavidquan01/obsidian-mcp-fast
cd obsidian-mcp-fast
uv sync

Run via uv run obsidian-mcp-fast from the repo root.

Build the indexes once

Before first use, build the indexes:

OBSIDIAN_VAULT_PATH=/path/to/your/vault obsidian-mcp-fast-index
# Indexed 60 pages, 584 atomic claims, 373 wikilink edges in 27ms.

The MCP server will also build them automatically on first startup if missing.


Connect to a client

Claude Desktop (macOS)

Edit ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "obsidian": {
      "command": "obsidian-mcp-fast",
      "env": {
        "OBSIDIAN_VAULT_PATH": "/Users/you/Documents/your-vault"
      }
    }
  }
}

If obsidian-mcp-fast isn't found, use the absolute path (which obsidian-mcp-fast).

Restart Claude Desktop. The 4 tools should appear in the tool picker.

Claude Code (CLI)

Add to .mcp.json at your project root, or ~/.claude/mcp_settings.json for user-wide:

{
  "mcpServers": {
    "obsidian": {
      "command": "obsidian-mcp-fast",
      "env": {
        "OBSIDIAN_VAULT_PATH": "/Users/you/Documents/your-vault"
      }
    }
  }
}

Restart Claude Code (/clear or new session).

Cursor

Settings → MCP → Add MCP Server → use the same JSON shape.

Other clients

The server speaks standard MCP over stdio. Any client that supports stdio MCP works. See examples/ for additional config snippets.


Usage

Once connected, ask the LLM client wiki questions. The LLM will call wiki_query first, then optionally wiki_read on suggested pages, then synthesize:

"Use the obsidian tools. What does my vault say about earning a fresh Entity ID on Meta?"

"Use obsidian to find all DTC growth frameworks tagged for paid social, then summarize the common threads."

"Read [[Strategic Volume]] from my vault and explain how it relates to Andromeda."

"What does my vault know about pricing strategy? Cite sources."

For best results, mention the tool's connector name (whatever you set as the key in mcpServers) so Claude reliably routes to it.


Tool reference

wiki_query(query, keywords?, type_filter?, tag_filter?, related_to?, max_claims?, max_pages?)

3-layer hybrid retrieval. Returns:

{
  "query": "...",
  "keywords_used": [...],
  "filters_applied": { "type": [...], "tags": [...], "related_to": [...] },
  "candidates_after_layer1": 13,
  "top_claims": [
    { "page": "Concepts/Entity ID.md", "type": "concept", "line": 22, "text": "...", "sources": ["Source - X"], "wikilinks": ["Andromeda"] }
  ],
  "graph_context": {
    "Andromeda": { "type": "concept", "outbound": [...], "inbound": [...] }
  },
  "suggested_pages_to_read": ["Concepts/Entity ID.md", ...],
  "stats": { "total_pages": 60, "candidate_pool": 13, "claims_searched": 584, "latency_ms": 0.51 }
}

Parameters:

  • query (required) — natural-language question
  • keywords — explicit search terms (3–5 variants for best recall). Derived from query if omitted.
  • type_filter — restrict to types (e.g. ["framework", "concept"])
  • tag_filter — required tags (any-of match)
  • related_to — only pages whose related[] contains any of these titles
  • max_claims — top-K claims (default 15)
  • max_pages — suggested pages to read (default 8)

wiki_read(page)

Returns:

{
  "path": "Concepts/Entity ID.md",
  "title": "Entity ID",
  "type": "concept",
  "content": "---\ntype: concept\n...\n",
  "line_count": 55
}

Accepts either a page path or title.

wiki_stats()

Returns vault-wide stats: page counts by type, top hubs, recent edits, index file mtimes, watcher state.

wiki_reindex()

Force a rebuild. Returns counts + latency.


Configuration

Env var Default Purpose
OBSIDIAN_VAULT_PATH (required) Path to vault root
WIKI_ROOT (legacy alias) Same as OBSIDIAN_VAULT_PATH

Or pass --vault-path / --index-dir as CLI args.


Why not MarkusPfundstein/mcp-obsidian?

That server is a thin wrapper around Obsidian's Local REST API plugin running inside the Obsidian app. Comparison:

Concern MarkusPfundstein/mcp-obsidian obsidian-mcp-fast
Requires Obsidian to be running Yes (with REST API plugin enabled) No (reads files directly)
Per-tool-call overhead HTTP localhost round-trip + TLS handshake (~5–50ms) In-memory dict lookup (<1ms)
Search timeout Hardcoded 6s — fails on vaults >9K notes (#88) None — server holds state in RAM
Caching None — every call re-fetches via HTTP RAM-resident indexes, file watcher invalidates
Frontmatter-aware retrieval No Yes (Layer 1 filtering)
Atomic claim retrieval No (file-level only) Yes (one cited bullet = one retrievable unit)
Wikilink graph traversal No Yes (Layer 3 expansion)
Read-only by default No (read+write+delete tools exposed → "lethal trifecta", #121) Yes (writes intentionally not exposed)
Maintenance status Last commit June 2025; 87 open issues; #90 calls for new maintainers Active
UTF-8 handling on writes Broken (#135, #93, #73) N/A (read-only)
OBSIDIAN_HOST/PORT env vars Documented but ignored at runtime (#86, #111, #112) N/A (no HTTP layer)

If you need write access to your vault from an LLM, that server may still suit you. If you want fast, schema-aware retrieval, this one is built for that.


Telemetry

Every tool call appends a JSON line to <vault>/_System/index/queries.jsonl with tool, args, result summary, latency_ms. Inspect with jq:

# 5 slowest queries
jq -s 'sort_by(-.latency_ms) | .[0:5]' queries.jsonl

# Tool usage frequency
jq -r '.tool' queries.jsonl | sort | uniq -c | sort -rn

Telemetry is local-only. Nothing leaves your machine.


Troubleshooting

"Could not resolve vault root" — Set OBSIDIAN_VAULT_PATH env var, or run from inside a directory containing the expected dirs (People/, Brands/, Frameworks/, Concepts/, References/) or a CLAUDE.md.

"Indexes missing at startup" — The server tries to build them automatically. If that fails, run obsidian-mcp-fast-index manually first.

Watcher not picking up edits — On Linux, ensure inotify watch limit isn't exhausted: cat /proc/sys/fs/inotify/max_user_watches. Raise via sudo sysctl fs.inotify.max_user_watches=524288.

Tools not appearing in Claude Desktop — Check the MCP log: ~/Library/Logs/Claude/mcp*.log. Common cause is path resolution; use absolute paths in the config.

Want to verify it works without a clientOBSIDIAN_VAULT_PATH=/path/to/vault uv run python -c "from obsidian_mcp_fast import server; from pathlib import Path; server._startup(Path('/path/to/vault'), None); print(server.wiki_stats())"


Roadmap

  • Embeddings (Layer 2.5). Add when keyword + Claude reformulation demonstrably misses queries (likely past ~2,000 atomic claims). sentence-transformers/all-MiniLM-L6-v2 runs on CPU; numpy cosine sim under 50K claims; HNSW above.
  • Incremental reindex. Currently the watcher triggers a full reindex (sub-second, fine at this scale). At 1000+ pages, parse only the changed file.
  • HTTP/SSE transport. For Claude.ai web access. Will require the user to host the server somewhere reachable (Cloudflare Worker, fly.io, etc.).
  • Block-level retrieval. Obsidian's ^block-id references for sub-paragraph atomicity, alongside the current per-bullet claim model.
  • Generalized schema mode. A pluggable conventions layer for vaults that don't follow the opinionated schema.
  • PyPI release. Currently install via uv from GitHub; PyPI is the next packaging step.

Contributing

Issues and PRs welcome. The codebase is small (~600 LOC across 5 files):

src/obsidian_mcp_fast/
├── server.py       # MCP entry, tool registrations, in-memory state
├── retrieval.py    # 3-layer hybrid logic (pure functions)
├── watcher.py      # watchdog file events → debounced reindex
├── telemetry.py    # per-call latency log
└── indexer.py      # vault → 3 JSON indexes

For substantial changes, please open an issue first to discuss direction.


License

MIT

Acknowledgements

  • The MCP Python SDK.
  • The schema discipline (atomic claims, wikilink graph, typed frontmatter) is adapted from Andrej Karpathy's LLM Wiki pattern, refined for retrieval performance.
  • Originally extracted from the-edge-wiki.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured