Labsco
MCP SERVER

Obsidian Hybrid Search

by flowing-abyss

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

Note-Taking & Personal Knowledge Bases
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 indexed and boosted, so a note 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