Skip to main content
Glama
thedavidquan01

obsidian-mcp-fast

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.

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

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

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)

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.

-
license - not tested
-
quality - not tested
-
maintenance - not tested

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

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/thedavidquan01/obsidian-mcp-fast'

If you have feedback or need assistance with the MCP directory API, please join our Discord server