rag-mcp-server
This server exposes a RAG hybrid retrieval pipeline as MCP tools, letting any MCP client search a markdown knowledge base and refine results.
search_documents(query, top_k) — hybrid dense+BM25 search with Reciprocal Rank Fusion; returns ranked docs with doc_id, title, snippet, and score.
get_document(doc_id) — fetch the full markdown text of a document by its ID; unknown IDs return a helpful list of available IDs.
rerank_results(query, doc_ids) — reorder a shortlist of candidate documents using a cross-encoder for more precise relevance ranking.
It runs as a self-contained local MCP server over stdio (embedded Qdrant by default), so it can be plugged into Claude Desktop, Claude Code, or any MCP-compatible agent.
Supports building/updating the index from local markdown files via
python -m rag_mcp_server.core.indexing, and can optionally use a real Qdrant server via docker-compose.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@rag-mcp-server search the docs for what is reciprocal rank fusion"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
rag-mcp-server
An MCP server that wraps the production RAG pipeline (rag-eval-service) into the standard Model Context Protocol for agents — hybrid search (dense embeddings + BM25 + RRF) becomes a tool that any MCP client can call: Claude Desktop, Claude Code, or your own agent.
Architecture
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 by default runs in embedded mode (a file on disk, no separate process) — the server is self-contained and requires no external infrastructure for a demo. If desired, you can switch to a full Qdrant server via docker-compose.yml (see below).
Related MCP server: RAG MCP Server
What this is and why
This is an MCP wrapper, not a reinvention of the retrieval logic: the hybrid search (dense + BM25 + RRF) is ported from rag-eval-service almost unchanged. What this wrapper adds:
Protocol instead of HTTP API — the tools are visible to any MCP client (Claude Desktop, Claude Code) without writing a custom HTTP client and without the need to keep the service always up behind REST.
Self-contained demo mode — embedded Qdrant instead of a Docker container, so then
git clone→ working tool takes the minimum number of steps.doc_id/title schema and document-level result aggregation (rather than chunk-level) — for the needs of an LLM client that calls
search_documents→get_documentinstead of working with raw chunks.Docstring contracts written for the LLM consumer of the tool (see
rag_mcp_server/server.py), not for a human reading the API documentation.
How to run locally
Requirements: Python 3.10+ and an OpenAI API key (for embeddings).
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 в .envBuild the index (one-time; reads data/, embeds chunks through OpenAI and loads them into embedded Qdrant):
python -m rag_mcp_server.core.indexing(Optional) real Qdrant instead of embedded mode:
docker-compose up -d
# затем в .env: QDRANT_MODE=serverStart the server (stdio transport):
python -m rag_mcp_server.serverCheck via MCP Inspector (the built-in inspector from mcp[cli]; opens a web UI for calling tools manually):
mcp dev rag_mcp_server/server.pyTests (require no live Qdrant/OpenAI — vector search and cross-encoder are mocked):
pytestHow to connect in Claude Desktop / Claude Code
Add it to claude_desktop_config.json (Claude Desktop: Settings → Developer → Edit Config; Claude Code: .mcp.json in the project or 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-..."
}
}
}
}After restarting the client, the search_documents, get_document, and rerank_results tools should appear in the list of available tools.
Examples of calling the 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
}
]Repository structure
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)Source of the retrieval logic
The hybrid search (rag_mcp_server/core/retrieval.py, core/indexing.py) is ported from rag-eval-service — the eval harness also lives there (NFCorpus/BEIR benchmark, a custom golden set, and hit@k/recall@k/MRR/nDCG metrics), which is intentionally missing from this repository: rag-mcp-server is a thin protocol wrapper around an already validated retrieval pipeline, not a re-evaluation of it.
What would be added next
Docker for the MCP server itself — right now only Qdrant is wrapped in a container; deploying the server itself requires its own Dockerfile.
SSE/HTTP transport — stdio assumes a local process on the same machine as the client; for remote access (multiple users, cloud deployment), SSE or Streamable HTTP transport from the MCP SDK is needed.
Authorization — stdio has none by design (a trusted process run locally); moving to a network transport will require an API key / OAuth at the server level.
Incremental indexing —
core.indexingcurrently recreates the whole collection; for a growing corpus, you need to upsert only changed documents.Real Qdrant by default in CI/production — embedded mode is fine for demos and tests, but concurrency multiple processes require a running server.
Available Tools
3 toolsget_documentA
Возвращает полный текст документа из корпуса по его doc_id.
Используй этот инструмент после search_documents(), когда сниппета недостаточно и нужен полный текст найденного документа — например, чтобы процитировать точную формулировку или прочитать раздел, который не попал в сниппет.
Args: doc_id: Идентификатор документа, как он возвращается в поле "doc_id" у search_documents() (совпадает с именем файла в корпусе, например "hybrid-search.md").
Returns: Полный текст документа (markdown). Если doc_id не найден в корпусе, вместо ошибки возвращается строка со списком доступных doc_id, чтобы клиент мог сразу повторить вызов с корректным значением.
Inputs: doc_id (required). Returns: result
rerank_resultsA
Переранжирует переданный список документов-кандидатов относительно query с помощью cross-encoder модели, которая читает пару (query, документ) вместе — точнее, чем независимое векторное сходство, но дороже по compute, поэтому применяется к уже отфильтрованному шортлисту, а не ко всему корпусу.
Используй этот инструмент, когда уже есть список кандидатов (например, из search_documents() или собранный вручную из нескольких запросов) и нужно уточнить их порядок релевантности перед тем, как процитировать top-N пользователю. Для поиска по всему корпусу используй search_documents() — этот инструмент только переупорядочивает уже известные doc_id и не находит новые документы.
Args: query: Запрос, относительно которого переранжируются документы. doc_ids: Список doc_id кандидатов (см. search_documents/ get_document). Неизвестные doc_id молча пропускаются.
Returns: Список [{"doc_id": str, "title": str, "snippet": str, "score": float}, ...], отсортированный по убыванию cross-encoder score. score здесь — необязательно вероятность и несравним по шкале со score из search_documents() (RRF-скор).
Inputs: query (required), doc_ids (required). Returns: result
search_documentsA
Гибридный поиск (dense-эмбеддинги + BM25, слитые через Reciprocal Rank Fusion) по проиндексированному корпусу markdown-документов о RAG, поиске и LLM-инфраструктуре.
Используй этот инструмент, когда нужно найти релевантные документы или факты по теме или вопросу пользователя, прежде чем отвечать — вместо того, чтобы полагаться на собственные знания. Одинаково хорошо работает и для семантических запросов на естественном языке ("как оценивать качество ретривера"), и для точных терминов/аббревиатур ("RRF", "BM25"), поскольку сочетает векторный и лексический поиск.
Args: query: Запрос на естественном языке или ключевые слова. top_k: Сколько документов вернуть (по умолчанию 5, максимум 20).
Returns: Список словарей, отсортированный по убыванию релевантности — [{"doc_id": str, "title": str, "snippet": str, "score": float}, ...]. doc_id — идентификатор документа, который нужно передать в get_document(), чтобы получить его полный текст, или в rerank_results(), чтобы уточнить порядок кандидатов.
Inputs: query (required), top_k. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 3 tools
Tools have clear boundaries: search_documents retrieves candidates, get_document fetches full text by ID, rerank_results reorders given IDs. No overlap in purpose, and each description explicitly states when to use it.
All tool names follow a consistent verb_noun pattern (search_documents, get_document, rerank_results) in snake_case. Naming convention is uniform and predictable.
Three tools is well-scoped for a focused retrieval server: search, fetch full content, and re-rank. Each tool serves a distinct step in the pipeline without redundancy, fitting the typical 3-15 range.
The tool surface covers the full read-only retrieval workflow: hybrid search with snippets, full document access, and optional cross-encoder re-ranking. No missing operations are needed for the stated purpose.
Maintenance
Related MCP Connectors
Cloud or self-hosted knowledge for AI agents: hybrid search, reranking, GraphRAG, scoped MCP tools.
Ingest, manage, and retrieve documents for RAG-powered AI applications
Turn a GitHub repo or docs site into agent-ready context: pack it or search it, over MCP.
Your personal library, readable by AI agents: durable snapshots, hybrid search, 46 MCP tools.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceEnables any MCP-compatible AI assistant to search, filter, and retrieve information from a local document collection using a hybrid search pipeline with vector, BM25, reranking, and LLM enrichment.4-
- FlicenseNot gradedqualityDmaintenanceIndexes PDF documents into Qdrant and exposes semantic search as MCP tools, enabling RAG-based interactions with your documents.-
- FlicenseNot gradedqualityCmaintenanceProvides RAG-based knowledge retrieval and document management as MCP tools, supporting hybrid search, reranking, and retrieval process visualization.-
- FlicenseNot gradedqualityCmaintenanceEnables agent tools like Claude Code and GitHub Copilot to perform knowledge retrieval using hybrid search (BM25 + dense) with reranking, via MCP protocol.-