rag-mcp-server

rag-mcp-server

Exposes hybrid retrieval (dense embeddings + BM25 + RRF) and document operations (search, fetch, rerank) as MCP tools, using Qdrant and OpenAI embeddings for local or server mode.

Category
Visit Server

README

rag-mcp-server

MCP-сервер, оборачивающий production RAG pipeline (rag-eval-service) в стандартный протокол (Model Context Protocol) для агентов — гибридный поиск (dense-эмбеддинги + BM25 + RRF) становится инструментом, который может вызвать любой MCP-клиент: Claude Desktop, Claude Code или собственный агент.

Архитектура

Client (Claude Desktop / Claude Code / любой MCP-клиент)
    |
    v  MCP over stdio (JSON-RPC)
FastMCP server  (rag_mcp_server/server.py)
    |
    +--> search_documents(query, top_k)
    +--> get_document(doc_id)
    +--> rerank_results(query, doc_ids)
    |
    v
Hybrid retrieval  (rag_mcp_server/core/retrieval.py)
    |
    +---> Dense retriever  --- OpenAI text-embedding-3-small ---> Qdrant (cosine, 1536d)
    |                                                                 |
    +---> Sparse retriever -- BM25 (rank-bm25 / BM25Okapi) ----------+
    |                                                                 |
    |                                 +-------------------------------+
    |                                 v
    |                        Reciprocal Rank Fusion (k=60)
    |                                 |
    +---------------------------------v
                              Top-k документов --> клиент (LLM формирует ответ)

Qdrant по умолчанию работает в embedded-режиме (файл на диске, без отдельного процесса) — сервер self-contained и не требует внешней инфраструктуры для демо. При желании можно переключиться на полноценный Qdrant-сервер через docker-compose.yml (см. ниже).

Что это и зачем

Это MCP-обёртка, а не переизобретение retrieval-логики: сам гибридный поиск (dense + BM25 + RRF) портирован из rag-eval-service почти без изменений. Новое, что добавляет именно эта обёртка:

  • Протокол вместо HTTP API — инструменты видны любому MCP-клиенту (Claude Desktop, Claude Code) без написания кастомного HTTP-клиента и без необходимости держать сервис постоянно поднятым за REST.
  • Self-contained демо-режим — embedded Qdrant вместо докер-контейнера, чтобы git clone → работающий инструмент занимал минимум шагов.
  • doc_id/title-схема и агрегация результатов на уровне документа (а не чанка) — под нужды LLM-клиента, который вызывает search_documents → get_document, а не работает с сырыми чанками.
  • Docstring-контракты, написанные для LLM-потребителя инструмента (см. rag_mcp_server/server.py), а не для человека, читающего API-документацию.

Как запустить локально

Требования: Python 3.10+, ключ OpenAI API (для эмбеддингов).

git clone https://github.com/q6066697/rag-mcp-server.git
cd rag-mcp-server

python3 -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -r requirements.txt  # или: pip install -e ".[dev]"

cp .env.example .env
# впишите свой OPENAI_API_KEY в .env

Построить индекс (одноразово; читает data/, эмбеддит чанки через OpenAI и заливает их в embedded Qdrant):

python -m rag_mcp_server.core.indexing

(Опционально) реальный Qdrant вместо embedded-режима:

docker-compose up -d
# затем в .env: QDRANT_MODE=server

Запустить сервер (stdio-транспорт):

python -m rag_mcp_server.server

Проверить через MCP Inspector (встроенный инспектор из mcp[cli], открывает веб-UI для ручного вызова tools):

mcp dev rag_mcp_server/server.py

Тесты (не требуют живого Qdrant/OpenAI — векторный поиск и cross-encoder замоканы):

pytest

Как подключить в Claude Desktop / Claude Code

Добавьте в claude_desktop_config.json (Claude Desktop: Settings → Developer → Edit Config; Claude Code: .mcp.json в проекте или claude mcp add):

{
  "mcpServers": {
    "rag-mcp-server": {
      "command": "/absolute/path/to/rag-mcp-server/.venv/bin/python",
      "args": ["-m", "rag_mcp_server.server"],
      "cwd": "/absolute/path/to/rag-mcp-server",
      "env": {
        "OPENAI_API_KEY": "sk-..."
      }
    }
  }
}

После перезапуска клиента инструменты search_documents, get_document и rerank_results должны появиться в списке доступных tools.

Примеры вызова tools

search_documents

search_documents(query="что такое Reciprocal Rank Fusion", top_k=3)
[
  {
    "doc_id": "reciprocal-rank-fusion.md",
    "title": "Reciprocal Rank Fusion",
    "snippet": "RRF сливает несколько ранжированных списков без нормализации сырых score — документ на позиции r получает вклад 1/(k+r)…",
    "score": 0.0328
  },
  {
    "doc_id": "hybrid-search.md",
    "title": "Hybrid Search",
    "snippet": "Гибридный поиск комбинирует dense-эмбеддинги и BM25, чтобы ловить и семантическое сходство, и точные термины…",
    "score": 0.0301
  }
]

get_document

get_document(doc_id="reciprocal-rank-fusion.md")
"# Reciprocal Rank Fusion (RRF)\n\nRRF — метод слияния нескольких ранжированных списков результатов…"

rerank_results

rerank_results(
    query="как оценивать качество ретривера",
    doc_ids=["eval-retrieval-metrics.md", "reranking.md", "hybrid-search.md"]
)
[
  {
    "doc_id": "eval-retrieval-metrics.md",
    "title": "Evaluating Retrieval Quality",
    "snippet": "Метрики retrieval — hit@k, recall@k, MRR, nDCG@k — измеряют, находит ли поиск релевантные документы…",
    "score": 4.81
  },
  {
    "doc_id": "reranking.md",
    "title": "Reranking",
    "snippet": "Cross-encoder реранкинг переупорядочивает шортлист кандидатов, читая query и passage вместе…",
    "score": 1.02
  }
]

Структура репозитория

rag-mcp-server/
├── rag_mcp_server/
│   ├── server.py          # точка входа, FastMCP инстанс, регистрация tools
│   ├── core/
│   │   ├── retrieval.py   # портированная гибридная логика поиска (dense + BM25 + RRF + rerank)
│   │   └── indexing.py    # загрузка корпуса, чанкинг, индексация в Qdrant
│   └── config.py          # конфигурация из .env
├── data/                  # bootstrap-корпус (15 markdown-доков, копия из rag-eval-service)
├── tests/
│   └── test_server.py     # unit-тесты на MCP tools (мокают поиск)
├── docker-compose.yml     # опциональный Qdrant-сервер
├── pyproject.toml / requirements.txt
├── .env.example
└── LICENSE (MIT)

Источник retrieval-логики

Гибридный поиск (rag_mcp_server/core/retrieval.py, core/indexing.py) портирован из rag-eval-service — там же живёт eval-harness (NFCorpus/BEIR-бенчмарк, custom golden set, метрики hit@k/recall@k/MRR/nDCG), которого в этом репозитории намеренно нет: rag-mcp-server — это тонкая протокольная обёртка над уже провалидированным retrieval-пайплайном, а не его переоценка.

Известная проблема и её решение

При запуске через mcp dev изначально возникала ошибка AlreadyLocked от embedded Qdrant — Storage folder is already accessed by another instance of Qdrant client.

Причина: mcp dev импортирует модуль сервера дважды — сам инспектор (чтобы прочитать зависимости) и дочерний процесс uv run mcp run, который реально запускает сервер. Индексы (DenseIndex, SparseIndex, CrossEncoderReranker) изначально создавались на уровне модуля при импорте — второй импорт натыкался на файловый лок, оставленный первым.

Решение: инициализация индексов сделана ленивой — через геттер с кэшированием, вызываемый при первом обращении к tool, а не при импорте модуля. Это заодно и более правильная архитектура для MCP-сервера: сервер стартует мгновенно, тяжёлая инициализация (эмбеддинг-клиент, cross-encoder) откладывается до первого реального запроса.

Что бы добавил дальше

  • Docker для самого MCP-сервера — сейчас в контейнер оборачивается только Qdrant; для деплоя самого сервера нужен свой Dockerfile.
  • SSE/HTTP-транспорт — stdio предполагает локальный процесс на одной машине с клиентом; для удалённого доступа (несколько пользователей, облачный деплой) нужен SSE или Streamable HTTP транспорт из MCP SDK.
  • Авторизация — у stdio-транспорта её нет по конструкции (процесс доверенный, запущен локально); при переходе на сетевой транспорт понадобится API-ключ/OAuth на уровне сервера.
  • Инкрементальная индексация — сейчас core.indexing пересоздаёт коллекцию целиком; для растущего корпуса нужен upsert только изменившихся документов.
  • Реальный Qdrant по умолчанию в CI/проде — embedded-режим отлично подходит для демо и тестов, но для конкурентного доступа нескольких процессов нужен сервер.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured