Skip to main content

MCP server for semantic search and file management over Obsidian vaults using Qdrant and local embeddings

Project description

obsidian-qdrant-search

Obsidian Qdrant Search

Version PyPI Python License Qdrant MCP Obsidian

MCP server for semantic search and file management over an Obsidian vault. Uses Qdrant as vector store and FastEmbed for local embeddings. Provides a complete set of tools for AI agents to read, write, search, and manage vault content โ€” no external Obsidian plugins required.


Table of Contents

Section Description
? Why? The problem this solves
โœจ Features Full feature list
โšก Quick Start Installation and setup
๐Ÿค– Agent Skills Skill and agent for Claude Code
๐Ÿ”ง MCP Tools All 23 tools โ€” Search, Read, Write, Discover, Graph, Batch, Maintenance
๐Ÿ’ป CLI Commands Command-line interface
๐Ÿ—๏ธ Architecture How it works under the hood
๐Ÿ“ Project Structure File layout

Why?

Standard text search in Obsidian (and MCP tools like mcp-obsidian) is keyword-based โ€” it only finds exact matches. This means:

  • Searching for "API logs" won't find a section titled "Execution tracking endpoints"
  • Searching for "how does authentication work" returns nothing unless those exact words appear
  • Typos, synonyms, and rephrased concepts are invisible to keyword search

obsidian-qdrant-search uses vector embeddings to understand the meaning of your query and match it against the meaning of your documentation. It finds relevant results even when the wording is completely different.

Additionally, it provides full CRUD file operations directly on the vault filesystem, so AI agents can read, create, update, and manage notes without relying on external Obsidian community plugins like Local Rest API.

Features

  • Semantic search โ€” find docs by meaning, not just keywords
  • Full file management โ€” read, create, update, append, patch, and delete vault files
  • Targeted patching โ€” modify specific sections by heading or frontmatter field
  • Text search โ€” case-insensitive keyword search across all markdown files
  • Markdown-aware chunking โ€” tables and code blocks are never split mid-block
  • Frontmatter filters โ€” narrow results by project, document type, or tags
  • Context expansion โ€” fetch adjacent chunks around a search result
  • Wikilink graph โ€” navigate backlinks, outgoing links, find broken links and orphan files
  • Vault map โ€” visualize directory structure with file counts
  • Frontmatter schema discovery โ€” see all fields, types, and usage across the vault
  • Tag discovery โ€” list all tags (frontmatter + inline) with occurrence counts
  • Recent changes โ€” track recently modified files
  • Batch operations โ€” update frontmatter or rename tags across multiple files at once
  • Incremental indexing โ€” only re-embeds changed files
  • Auto-reindex on write โ€” modified files are automatically re-indexed (best-effort)
  • Auto-start Qdrant โ€” Docker container is managed automatically
  • Local embeddings โ€” no API keys needed, runs entirely on your machine
  • Path security โ€” all file operations are validated to prevent access outside the vault

Prerequisites

  • Python 3.11+
  • Docker (for Qdrant)
  • uv (recommended) or pip

Quick start

1. MCP Configuration

Add to your .mcp.json (project root or Claude Code settings):

{
  "mcpServers": {
    "obsidian-qdrant-search": {
      "command": "uvx",
      "args": ["obsidian-qdrant-search"],
      "env": {
        "VAULT_PATH": "/absolute/path/to/your/vault"
      }
    }
  }
}

Qdrant is started automatically via Docker when needed. If a qdrant container already exists, it will be reused.

2. Initial indexing

VAULT_PATH=/path/to/your/vault uvx --from obsidian-qdrant-search vault-index --full

Agent Skills

This repo includes Claude Code skills and agents in .claude/. Copy the .claude/ directory into your project to make them available. Claude will automatically discover and use them based on context.

/vault-search โ€” Skill (.claude/skills/vault-search/)

Guides the agent through semantic search, text search, file reading, and knowledge graph navigation. Claude can invoke it automatically or you can use it as a slash command:

/vault-search how does authentication work

doc-manager โ€” Agent (.claude/agents/)

An autonomous documentation agent that creates, updates, organizes, and maintains vault documentation. Includes templates, conventions, health check workflows, and restructuring procedures. Claude dispatches it as a subagent when documentation tasks are needed.

/doc-manager document the new authentication module in projects/core
/doc-manager run a vault health check
/doc-manager create an ADR for switching to PostgreSQL

Environment variables

Variable Default Description
VAULT_PATH Current working directory Path to the Obsidian vault directory
QDRANT_URL http://localhost:6333 Qdrant server URL
COLLECTION_NAME vault_docs Qdrant collection name

MCP Tools

Search

search_vault

Semantic search over the vault documentation.

Parameter Type Default Description
query string required Natural language search query
project string null Filter by project name (e.g. "core")
doc_type string null Filter by document type (e.g. "api-contract", "service-layer")
tag string null Filter by frontmatter tag (e.g. "kubernetes", "database")
top_k int 5 Number of results to return

simple_search

Case-insensitive text search across all markdown files.

Parameter Type Default Description
query string required Text to search for
context_length int 100 Characters of context around each match

get_chunk_context

Expand context around a search result by fetching adjacent chunks.

Parameter Type Default Description
file_path string required The file_path from a search result
chunk_index int required The chunk_index from a search result
window int 1 Number of chunks before/after to include

Read

get_file_contents

Read the raw content of a vault file.

Parameter Type Default Description
filepath string required Path relative to vault root

get_file_metadata

Get frontmatter metadata, tags, and file stats (size, dates).

Parameter Type Default Description
filepath string required Path relative to vault root

list_files_in_dir

List files and subdirectories in a vault directory (non-recursive).

Parameter Type Default Description
dirpath string "" Relative directory path (empty for root)

list_files_in_vault

List all top-level files and directories in the vault root.

Write

create_or_update_file

Create a new file or overwrite an existing one. Parent directories are created automatically.

Parameter Type Default Description
filepath string required Path relative to vault root
content string required Full file content

append_content

Append content to a file (creates the file if it doesn't exist).

Parameter Type Default Description
filepath string required Path relative to vault root
content string required Content to append

patch_content

Targeted modification of a specific section by heading or frontmatter field.

Parameter Type Default Description
filepath string required Path relative to vault root
operation string required "append", "prepend", or "replace"
target_type string required "heading" or "frontmatter"
target string required Heading text (e.g. "Setup" or "Setup/Installation") or frontmatter field name
content string required Content to insert or replace with

delete_file

Delete a file from the vault.

Parameter Type Default Description
filepath string required Path relative to vault root
confirm bool false Must be true to actually delete (safety guard)

Discover

list_projects

Lists all indexed projects with file and chunk counts.

list_tags

Lists all tags (frontmatter + inline #tag) with occurrence counts across the vault.

get_recent_changes

Returns recently modified markdown files sorted by modification date.

Parameter Type Default Description
days int 14 Only include files modified within this many days
limit int 10 Maximum number of results

get_vault_map

Get the vault's directory structure as a tree with file counts.

Parameter Type Default Description
max_depth int 3 Maximum directory depth to show

get_frontmatter_schema

Discover all frontmatter fields used across the vault with types, frequency, and examples.

Graph

get_backlinks

Find all files that contain wikilinks pointing to the given file.

Parameter Type Default Description
filepath string required Relative path to the target file

get_outgoing_links

List all files that the given file links to via wikilinks.

Parameter Type Default Description
filepath string required Relative path to the source file

find_broken_links

Find all wikilinks in the vault that point to non-existent files.

find_orphan_files

Find files that have no incoming wikilinks from other files.

Batch

batch_update_frontmatter

Update a frontmatter field across multiple files matching a filter.

Parameter Type Default Description
filter_type string required "project", "tag", or "glob"
filter_value string required Filter value (project name, tag, or glob pattern)
field string required Frontmatter field to update
value string required Value to set/append/remove (YAML parsed)
operation string "set" "set", "append", or "remove"
confirm bool false Set to true to apply (default returns preview)

batch_rename_tag

Rename a tag across all vault files (both frontmatter and inline #tags).

Parameter Type Default Description
old_tag string required Tag to rename (without #)
new_tag string required New tag name (without #)
confirm bool false Set to true to apply (default returns preview)

Maintenance

reindex_vault

Re-indexes the vault into Qdrant. After upgrading to v0.3.0, run with full=true to index wikilink data.

Parameter Type Default Description
full bool false If true, drops and recreates the collection

CLI Commands

Command Description
obsidian-qdrant-search Start the MCP server (stdio transport)
vault-index Run indexing from the command line
vault-index --full Full reindex (drops existing data)

Architecture

Obsidian vault (.md files)
    |
    v
indexer โ”€โ”€ chunk by H2/H3 sections โ”€โ”€> Qdrant (vector DB)
    |         preserves tables              |
    |         preserves code blocks         |
    v                                       v
fastembed (BAAI/bge-small-en-v1.5)    server (MCP stdio)
    local embeddings, 384 dim            search / CRUD / reindex

Chunking strategy: Documents are split by ## headings, then ### if needed. Tables and fenced code blocks are never split mid-block. Large sections fall back to a block-aware sliding window with overlap.

Incremental indexing: Files are tracked by SHA-256 hash. Only changed files are re-embedded on reindex_vault(). Deleted files are automatically cleaned up.

Auto-reindex on write: When files are created, updated, or deleted via MCP tools, the search index is automatically updated for the affected file. This is best-effort โ€” if Qdrant is unavailable, the write still succeeds.

Project structure

obsidian-qdrant-search/
โ”œโ”€โ”€ pyproject.toml
โ”œโ”€โ”€ docker-compose.yml
โ”œโ”€โ”€ CHANGELOG.md
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ .claude/
โ”‚   โ”œโ”€โ”€ skills/
โ”‚   โ”‚   โ””โ”€โ”€ vault-search/SKILL.md   # /vault-search slash command
โ”‚   โ””โ”€โ”€ agents/
โ”‚       โ””โ”€โ”€ doc-manager.md           # documentation manager agent
โ”œโ”€โ”€ tests/
โ”‚   โ”œโ”€โ”€ test_path_utils.py
โ”‚   โ”œโ”€โ”€ test_vault_ops.py
โ”‚   โ””โ”€โ”€ test_indexer.py
โ””โ”€โ”€ src/
    โ””โ”€โ”€ vault_search/
        โ”œโ”€โ”€ __init__.py
        โ”œโ”€โ”€ __main__.py      # python -m vault_search
        โ”œโ”€โ”€ cli.py            # vault-index CLI
        โ”œโ”€โ”€ config.py         # env-based configuration
        โ”œโ”€โ”€ path_utils.py     # path security & validation
        โ”œโ”€โ”€ vault_ops.py      # CRUD & batch file operations
        โ”œโ”€โ”€ qdrant.py         # auto-start Qdrant Docker container
        โ”œโ”€โ”€ indexer.py         # markdown parsing, chunking, wikilinks, embedding
        โ””โ”€โ”€ server.py         # MCP server + 23 tools

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

obsidian_qdrant_search-0.3.0.tar.gz (863.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

obsidian_qdrant_search-0.3.0-py3-none-any.whl (29.2 kB view details)

Uploaded Python 3

File details

Details for the file obsidian_qdrant_search-0.3.0.tar.gz.

File metadata

  • Download URL: obsidian_qdrant_search-0.3.0.tar.gz
  • Upload date:
  • Size: 863.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"25.10","id":"questing","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for obsidian_qdrant_search-0.3.0.tar.gz
Algorithm Hash digest
SHA256 1f35857ed49dfe5427a7c57a72626b6939f6d01f2cede65cac99da808e373878
MD5 9b1bfe72cc08c9ac2e2ec2887de1dd20
BLAKE2b-256 7cd7737829c4685f58013229c908050bc38710c5732638fea88b55b0b09600e2

See more details on using hashes here.

File details

Details for the file obsidian_qdrant_search-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: obsidian_qdrant_search-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 29.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"25.10","id":"questing","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for obsidian_qdrant_search-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ad17ccf92cd59e8c179c0b81dc1c8c8bfa19daf92c6a1b093900a9f1e93a1f3b
MD5 dfb47c344def0f8428736f27e4aac4f7
BLAKE2b-256 c6828874be2b57d100cfaf772c5a51bfa6d2e004ad4f51942b87aad4a5e035c3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page