Benchmarked against
the whole field.
Every number on this page comes from an open-source harness run on committed vaults of 1,000, 5,000, and 10,000 notes — public-domain content, 20 runs per query. Nothing here is a marketing estimate — the vaults ship in the repo, so clone it and reproduce each figure exactly.
The only Obsidian MCP server
with published numbers.
As far as we know, no other Obsidian MCP server publishes benchmarks at all. Measured against 7 other popular servers — 8 servers total — across 1,000 / 5,000 / 10,000-note vaults — public-domain content, fully reproducible, 20 runs each. The harness and the vaults are open source; clone the repo and verify every figure.
One broad search via a REST-proxy server (mcp-obsidian) returns 97.8 million tokens at 10,000 notes — about 489× larger than Claude's entire ~200K-token context window. The result can't even be sent. Seekstone returns the same search in ~570 tokens.
Latency is nice. Payload is the point.
REST-proxy servers return full note content for every search hit — tens of megabytes the model has to read. Seekstone returns short ranked excerpts. Same query, up to ~47,000× less to send at 10,000 notes (the plugin's HTTP API alone is ~31,000×; proxy envelopes push it higher).
| Metric | Seekstone | REST API plugin |
|---|---|---|
| Search payload (mean, 10k vault) | ~2 KB | 62.6 MB |
| Worst-case payload (broad query) | ~2 KB | 245.4 MB |
| Context tokens (broad query) | ~570 | 65.8 million |
| Warm keyword search (10k vault) | 5.2 ms mean (1.0–15.4 across queries) | ~575 ms mean |
| Obsidian app required | No | Yes |
| Local REST API plugin required | No | Yes |
| Network calls | Zero | HTTP to localhost |
| Search matching | Fuzzy + prefix · optional local semantic | Exact / plugin-dependent |
| Frontmatter write safety | Byte-identical | Varies |
This table measures the Local REST API plugin's HTTP API directly — the lower bound for any server built on it. MCP servers that proxy the plugin add JSON-RPC encoding on top: the same broad query via mcp-obsidian averaged 370.9 MB / 97.8 million tokens per call.
The rest of the field spans ~430–2,667 ms warm search latency at 10,000 notes in the chart above (one exception: obsidian-mcp-rs at 35 ms); Seekstone's in-process index serves the same queries in single-digit milliseconds — and the gap only widens as the vault grows.
Watch what happens as your vault grows.
A real vault only gets bigger — and that's where the architectures diverge. Seekstone holds a warm in-process index, so it stays flat on both payload and latency, while REST-proxy and full-scan servers climb with every note.
Holds a warm full-text index and returns ranked excerpts. Flat on both payload and latency — a few KB and a few ms at any vault size.
Spawn a process and scan the disk per query. Latency climbs with the vault — the fastest (obsidian-mcp-rs, Rust) is still ~7× slower than Seekstone at 10,000 notes; the rest run ~430–900 ms at 10k notes.
SQLite index behind a governance pipeline. Search runs ~2.7 s warm at 10,000 notes, and its read envelope returns each note's content twice.
Forward to Obsidian's HTTP API, which returns full note content for every hit — tens of megabytes per search, growing with the vault.
Search payload — bytes per query lower is better
| Server | 1k notes | 5k notes | 10k notes |
|---|---|---|---|
| Seekstone | 1.6 KB | 1.8 KB | 2.0 KB |
| mcpvault | 1.7 KB | 1.9 KB | 2.2 KB |
| obsidian-mcp-rs | 5.4 KB | 5.8 KB | 6.2 KB |
| obsidian-tc | 4.6 KB | 6.8 KB | 7.2 KB |
| obsidian-mcp-server | 55 KB | 47 KB | 47 KB |
| obsidian-mcp-pro | 25 KB | 84 KB | 114 KB |
| obsidian-mcp | 18 KB | 105 KB | 201 KB |
| mcp-obsidian | 9.8 MB | 45 MB | 95 MB |
Warm search latency — milliseconds lower is better
| Server | 1k notes | 5k notes | 10k notes |
|---|---|---|---|
| Seekstone | 1.0 ms | 2.7 ms | 5.2 ms |
| obsidian-mcp-rs | 5.8 ms | 18 ms | 35 ms |
| obsidian-mcp-pro | 46 ms | 213 ms | 430 ms |
| obsidian-mcp-server | 82 ms | 356 ms | 732 ms |
| obsidian-mcp | 82 ms | 405 ms | 811 ms |
| mcpvault | 89 ms | 436 ms | 897 ms |
| mcp-obsidian | 164 ms | 740 ms | 1,550 ms |
| obsidian-tc | 263 ms | 1,253 ms | 2,667 ms |
At 10,000 notes that's a ~47,000× payload difference, and Seekstone is 110–300× faster than the REST proxies — both gaps widening with scale. Seekstone is the only server that stays flat on both axes.
Run it yourself.
The harness lives in the Seekstone repo. It runs each query set against every adapter and reports cold (run 1) and warm (runs 2–N) distributions separately — a cheap warm number can't hide a brutal cold start.
- VaultsCommitted 1,000 / 5,000 / 10,000-note vaults generated from the public-domain 1911 Encyclopædia Britannica — the same size distribution as a real PKM vault, and byte-for-byte reproducible.
- Runs20 per query; warm latency reported as the mean of per-query medians (run 1 excluded as cold).
- PayloadBytes measured on the actual MCP tool response, not an idealized excerpt.
- FieldCompared against mcpvault, obsidian-mcp-pro, obsidian-mcp, obsidian-mcp-rs, obsidian-tc, obsidian-mcp-server, and mcp-obsidian.
Semantic search, measured the same way.
Opt-in meaning-based search through a small local embedding model — fully in-process, offline at runtime, no API key, no native modules — with a MaxSim rerank on top since 0.17.0. Evaluated on the same committed 10,000-note vault with a 150-query golden set and a locked-away held-out split.
Numbers from the committed retrieval-quality baseline —
a single synthetic vault and our own golden query set.
Reproducible: npm run harness -- retrieval --shipped.
And benchmarked against the field — losses included.
Same golden set, same vault, same run, competitor semantic search measured head-to-head. We pre-registered a gate to claim the top spot, missed it, and published the miss with the same prominence a win would have gotten — and the fixture-v2 re-baseline shown here moved the numbers in both directions.
| Semantic search | hit@5 (150q) | held-out | Latency (p50) | Payload/query | Cold index | Needs |
|---|---|---|---|---|---|---|
| Seekstone quality mode (opt-in 32M + MaxSim) | 86.7% | 86.7% | 55 ms | ~2 KB | 25 s | Nothing — in-process, offline |
| Seekstone default (8M + MaxSim) | 83.3% | 86.7% | 26 ms | ~2 KB | 28 s | Nothing — in-process, offline |
| obsidian-tc semantic | 88.7% | 90.0% | 169 ms | 15.6 KB | 30 min | Ollama server + native modules + Node ≥ 24 |
| obsidian-tc GraphRAG | 93.3% | 95.0% | 2.9 s (p95 4.2 s) | 16.0 KB | (same) | (same) |
| obsidian-mcp-pro | Failed — could not index the 10k-note vault (crashed after ~17 min of embedding) | Ollama or OpenAI | ||||
The honest read, both directions: obsidian-tc's plain semantic mode edges Seekstone's best shipped mode on the held-out split (90.0% vs 86.7%) — at 169 ms per query against our 55 ms, a 30 minute Ollama index against our 25 s, and a second server you install, run, and keep a 137M-parameter model loaded in. Its GraphRAG mode is the most accurate we benchmarked (95.0% held-out), at seconds per query (2.9 s median, 4.2 s p95 — 50–110× ours) and ~8× the payload. Seekstone is the only benchmarked server whose semantic search needs nothing but Seekstone. We pre-registered a gate to call ourselves #1 on fixture v1 and missed it; no new gate ran on the fixture-v2 re-baseline shown here, and the same clauses recompute to the same miss. Verdict and read-out, clause by clause, are committed: GATE-V2-SHA-316.md · COMPETITORS-SHA-322.md · retrieval-eval-competitors.md. Every number on this page comes from the same committed benchmarks.json the README is checked against.
Where Seekstone isn't the answer.
No tool wins every axis. Here's where the trade-offs land — so you can decide with eyes open.
It keeps an index in memory.
Seekstone builds a small in-process search index (a few MB for a typical vault). If you run many MCP servers at once, that's real RAM the REST plugin offloads to the already-running Obsidian process.
The first query is the slow one.
Cold start pays for the index build before the millisecond latencies above: a few seconds on a typical vault, tens of seconds on our 10,000-note benchmark vault. Enabling semantic search adds a background embedding pass on top (~28 s at 10k — cached per-vault, so restarts reload it instantly).
Semantic search is opt-in, not default.
Keyword search (fuzzy + prefix) is the default. Since 0.15.0, semantic and hybrid modes search by meaning through a small local embedding model: run npx -y seekstone fetch-model once (~30 MB, checksum-verified) and set SEEKSTONE_SEMANTIC=1. The costs, plainly: the one-time download, a background embedding pass at startup, and a per-vault vector cache under ~/.cache/seekstone. After that nothing ever leaves your machine — and if you never opt in, none of it exists.