LabscoMCP early access ↗
flowing-abyssMCP SERVER

Obsidian Hybrid Search

Hybrid retrieval over an Obsidian vault — semantic, BM25, fuzzy titles, tags and backlinks — as four tools.

by flowing-abyss ↗Note-Taking & Personal Knowledge BasesCommunity

LABSCO SUMMARY

Retrieval quality is measured, and the numbers are published.

Most vault-search tools ask you to take their ranking on faith. This one publishes benchmarks with the method attached: on the Obsidian Help vault it reports nDCG@5 of 0.733 against 0.659 for the tool it compares itself with, and on a 22,419-note vault built from LongMemEval-S it reports nDCG@5 of 0.895 — with the result JSON and reproduction instructions in the repository. Retrieval on a personal vault is exactly the kind of thing that feels fine and quietly misses, so a checkable number is worth more here than a feature list.

What it is

One retrieval engine over an Obsidian vault, reachable three ways: a native Obsidian plugin, a CLI, and this MCP server. It fuses semantic embeddings with BM25 full-text, fuzzy title and alias matching, tags, folders, frontmatter, wikilinks and backlinks using RRF, so you can find a note by idea, phrase, title, metadata or relationship rather than by remembering your own wording.

What you get

  • search — text search in hybrid, semantic, fulltext or title mode, or similarity from a path; add related: true to walk the link graph; pass queries[] for multi-query fan-out merged by RRF, plus scope, tag, limit, threshold, depth, direction, snippet_length and rerank
  • read — fetch one or more notes by vault-relative path, returning full content with title, aliases, tags, links and backlinks; a path miss returns found: false and the three closest fuzzy suggestions instead of an error
  • reindex — reindex the vault or a single file
  • status — total notes, indexed count and last indexed time
  • Aliases from frontmatter are indexed and boosted, so a note can be found under any of its names
  • Incremental indexing that only reprocesses changed files and watches for edits as you write
  • Local embeddings by default via @huggingface/transformers — no API key, offline, 100+ languages — with an OpenAI-compatible API as the alternative for OpenRouter, Ollama or LM Studio
  • Optional cross-encoder reranking with bge-reranker-v2-m3, applied after the multi-query merge
  • OBSIDIAN_PREFIX to prefix every tool name, so several vaults can be connected at once without collisions
  • A shared HTTP mode — ohs serve, default 127.0.0.1:3939 — when several clients should use one long-lived index

Requirements

OBSIDIAN_VAULT_PATH pointing at the vault is the one required setting; everything else has a default. Run it through npx -y -p obsidian-hybrid-search@latest obsidian-hybrid-search-mcp — the package is obsidian-hybrid-search. The default local model downloads about 117 MB on first run and the optional reranker about 570 MB. OBSIDIAN_IGNORE_PATTERNS defaults to .obsidian/,templates/,*.canvas, .gitignore is respected unless you turn OBSIDIAN_RESPECT_GITIGNORE off, and OBSIDIAN_INCLUDE_PATTERNS puts back notes excluded only by that. Remote embeddings use OPENAI_API_KEY, OPENAI_BASE_URL and OPENAI_EMBEDDING_MODEL. HTTP mode is stateless and does not provide SSE streams or server-initiated notifications; bind beyond localhost and you must list every hostname clients will use.

Setup effort

One command — npm install -g obsidian-hybrid-search