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.
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-режим отлично подходит для демо и тестов, но для конкурентного доступа нескольких процессов нужен сервер.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。