Skip to main content
Glama
fjacquet

vault-rag-mcp

by fjacquet

vault-rag-mcp

CI

MCP server for semantic search in an Obsidian Second Brain vault, using a self-hosted Qdrant vector store and Google Gemini embeddings.

Architecture

Claude Code <-> vault-rag MCP server (stdio)
                 |-> Google Gemini gemini-embedding-001 (native 3072d)
                 |-> Qdrant `vault_chunks` collection (3072d, Cosine distance)

Part of a hybrid RAG architecture:

  • Indexation: n8n (remote) + Google Gemini API

  • Local queries: This MCP server + Google Gemini API

  • Web chat: n8n Vault Chat (AI Agent + Gemini native) or Chat Hub (HTTP pipeline)

  • Bulk index: Script using Gemini gemini-embedding-001

Same model (gemini-embedding-001, native 3072d) everywhere ensures vector compatibility. Vectors are stored at native 3072 dimensions (float32) with Cosine distance.

Asymmetric task types: RETRIEVAL_DOCUMENT for indexing, RETRIEVAL_QUERY for search.

Related MCP server: mcp-obsidian-local

Tools

Tool

Description

search_vault

Semantic search across the entire vault (query, limit, para_folder, note_type)

search_glossary

Search within glossary definitions (3_Resources/definitions/)

get_note

Retrieve full content of a note by file path

Prerequisites

  • Python >= 3.11

  • uv package manager

  • Google API key (for Gemini embeddings)

  • Qdrant instance with a vault_chunks collection (created automatically on first index)

Setup

# Clone and install
cd ~/Projects/vault-rag-mcp
uv sync

# Configure environment
cp .env.example .env
# Edit .env with your Google API key and Qdrant credentials

Environment variables

Variable

Description

Default

QDRANT_URL

Qdrant instance URL (HTTPS requires the :443 port; appended automatically if missing)

(required)

QDRANT_API_KEY

Qdrant API key

(required)

GOOGLE_API_KEY

Google AI API key

(required)

EMBEDDING_MODEL

Gemini embedding model

gemini-embedding-001

Usage

As MCP server (Claude Code)

Add to your project's .mcp.json:

{
  "mcpServers": {
    "vault-rag": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/vault-rag-mcp", "vault-rag-mcp"],
      "env": {
        "QDRANT_URL": "https://your-qdrant-instance.example.com",
        "QDRANT_API_KEY": "your-qdrant-api-key",
        "GOOGLE_API_KEY": "your-google-api-key",
        "EMBEDDING_MODEL": "gemini-embedding-001"
      }
    }
  }
}

Restart Claude Code to activate. Then use the tools directly in conversation.

Bulk indexation

Script to index an entire Obsidian vault via Google Gemini:

uv run python scripts/bulk_index.py /path/to/vault [--force]

Options:

  • --force : Re-index all files, ignoring file_hash cache

The script:

  1. Walks the vault, skips .obsidian/, templates/, .trash/, files > 500 KB

  2. Parses YAML frontmatter (type, tags, PARA folder)

  3. Chunks by H2 sections, splits oversized chunks (> 2000 chars)

  4. Embeds via Google Gemini in batches of 50 (task_type=RETRIEVAL_DOCUMENT)

  5. Upserts to Qdrant with a SHA256 file_hash payload for incremental re-runs

After initial bulk indexation, incremental updates are handled by n8n via Gemini API.

Project structure

vault-rag-mcp/
├── pyproject.toml              # uv + hatch build config
├── .env.example                # Environment template
├── src/
│   └── vault_rag_mcp/
│       ├── __init__.py
│       ├── server.py           # MCP server (FastMCP, stdio) — 3 tools
│       ├── embeddings.py       # Google Gemini embedding client (native 3072d)
│       └── qdrant_store.py     # Qdrant client + collection operations
├── scripts/
│   └── bulk_index.py           # Bulk indexation via Google Gemini
└── n8n-workflows/              # n8n workflow definitions
    ├── vault-rag-github-indexation.json
    └── vault-rag-chat-hub.json

Qdrant collection

Collection vault_chunks — vectors at 3072 dimensions, Cosine distance. Each point carries:

  • content — chunk text

  • file_path — relative path from vault root

  • chunk_index — position within file

  • para_folder — PARA folder (1_Projects, 2_Areas, etc.)

  • note_type — frontmatter type (memo, glossary, howto, etc.)

  • file_hash — SHA256 for change detection

  • metadata — tags, type, para_folder

Point IDs are deterministic UUID5 values derived from file_path::chunk_index.

Payload indexes: file_path (keyword), para_folder (keyword), note_type (keyword), chunk_index (integer).

Tech stack

  • MCP SDK: mcp[cli] with FastMCP (stdio transport)

  • Embeddings: Google Gemini gemini-embedding-001 via the google-genai SDK (native 3072d, multilingual, 2048 token/text)

  • Vector DB: Qdrant (self-hosted) — vault_chunks collection, 3072d Cosine distance

  • Build: uv + hatch

Available Tools

3 tools
get_noteA

Retrieve the full content of a specific note by its file path.

Args: file_path: Path relative to vault root (e.g. '3_Resources/definitions/p/powerflex.md')

ParametersJSON Schema
NameRequiredDescriptionDefault
file_pathYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. It states retrieval of content, implying read-only. Missing details on error behavior if file doesn't exist, but for a simple read operation, this is acceptable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences: first states purpose, second explains the single parameter. No filler, front-loaded with the main action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values are covered. The description addresses the core functionality and parameter. Minor omission is handling of invalid paths, but overall complete for the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, but description explains file_path as 'Path relative to vault root' with an example, adding meaning beyond the bare type declaration.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves full content of a specific note by file path. It distinguishes itself from sibling tools like search_glossary and search_vault by focusing on retrieval of a known note.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is implied: use when you have a file path. No explicit guidance on when not to use or alternatives, but the sibling tools are different enough that the purpose alone suggests appropriate usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_glossaryB

Search the glossary (1878 term definitions in 3_Resources/definitions/).

Args: query: Term or concept to look up (works in French and English) limit: Maximum number of results (default 5)

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It mentions the resource location and bilingual functionality but does not disclose behavioral traits like idempotency, side effects, or access requirements. A search tool is likely read-only, but this is not explicitly stated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise, front-loading the purpose in one sentence, then briefly documenting parameters. Every sentence adds value with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (2 params, output schema present), the description provides essential context: purpose, resource location, language support, and parameters. It could mention return type or read-only nature, but is largely complete for a search tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, requiring the description to add meaning. It effectively explains both parameters: 'query' as a term/concept in French/English, and 'limit' as max results with default 5. This compensates for the lack of schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches a glossary with 1878 term definitions, using a specific verb and resource. It does not explicitly distinguish from sibling tools like search_vault, but the context implies a focused glossary search, making it sufficiently clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives (e.g., search_vault) or when not to use it. The description only states what it does, leaving usage decisions to the agent without explicit context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_vaultA

Search the vault semantically. Returns the most relevant notes.

Args: query: Natural language search query (works in French and English) limit: Maximum number of results (default 10) para_folder: Filter by PARA folder (1_Projects, 2_Areas, 3_Resources, 4_Archives) note_type: Filter by note type (memo, glossary, howto, meeting-note, etc.)

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
note_typeNo
para_folderNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. Describes semantic search and language support (French/English) but does not disclose read-only nature, auth needs, rate limits, or error behavior. Adequate but could be more transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

First sentence clearly states purpose, followed by bullet-point parameter details. No redundancy, though the examples in parameter descriptions add length. Efficient overall.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema exists, so return values are covered. Description explains all four parameters and their filtering roles. Lacks mention of edge cases or errors, but is sufficient for a search tool with moderate complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description adds critical meaning: explains 'query' as natural language, 'limit' includes default, 'para_folder' lists possible values, 'note_type' gives examples. This goes far beyond the schema titles and types.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the action ('Search the vault semantically') and outcome ('Returns the most relevant notes'). It distinguishes from siblings 'get_note' and 'search_glossary' by specifying semantic search over the vault vs. specific note retrieval or glossary search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies usage for natural language queries, but does not explicitly state when to use this tool over siblings or when not to use it. No alternatives or exclusions are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observedget_note
    • First observedsearch_glossary
    • First observedsearch_vault

TDQS

A3.9/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: retrieving a specific note by path, searching the glossary, and performing semantic search across the vault. No overlap in functionality.

Naming Consistency5/5

All tool names follow the consistent verb_noun pattern with snake_case: 'get_note', 'search_glossary', 'search_vault'. No deviations.

Tool Count4/5

With 3 tools, the set is on the lower end but appropriate for a read-only RAG server. It covers the essential retrieval operations without being too sparse.

Completeness4/5

The tool set covers all core retrieval needs (exact note lookup, glossary search, semantic vault search). Minor gaps exist, such as listing available folders or note types, but filters in search_vault mitigate this.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers