Skip to main content
Glama
Mily-Lv
by Mily-Lv

RAG-MCP-SERVER

Ein steckbares, durchgängig beobachtbares modulares RAG-Retrieval-System. Es stellt Retrieval-Fähigkeiten in Form von MCP-Tools (Model Context Protocol) bereit und kann direkt von MCP-Clients wie Claude Desktop oder GitHub Copilot aufgerufen werden.

Das zentrale Designziel ist die Lösung von zwei konkreten Problemstellungen im RAG-Betrieb:

  1. Schwer nachvollziehbare Kette – Wenn das Retrieval-Ergebnis nicht stimmt: Liegt das Problem bei Recall, Fusion oder Rerank? Alle 10 Phasen der beiden Ketten (Index und Query) protokollieren je Phase Latenz, Kandidatenzahl, Score sowie Rangänderungen, sodass die Abläufe im Dashboard visualisiert und nachvollzogen werden können.

  2. Tuning nach Bauchgefühl – Verbessert ein anderer Embedding-Modell das Ergebnis wirklich? Gemeinsame Bewertung mit Hit Rate@K / MRR und Ragas Faithfulness / Context Precision, Regression anhand eines festen Testsatzes – Entscheidungen werden anhand von Metriken getroffen, nicht mangels fundierter Urteilskraft.


Inhaltsverzeichnis


Related MCP server: mcp-rag-assistant

Architektur-Überblick

                    ┌──────────────────────────────────────────┐
  文档 (PDF/DOCX/    │           Ingestion Pipeline             │
  MD/TXT)      ───▶ │  load → split → transform → embed →      │
                    │  upsert                                  │
                    └────────────────┬─────────────────────────┘
                                     │  SHA256 指纹 + SQLite 摄取历史
                                     │  (文档级增量索引 / 幂等)
                                     ▼
                    ┌──────────────────────────────────────────┐
                    │   ChromaDB (Dense)  +  BM25 (Sparse)     │
                    └────────────────┬─────────────────────────┘
                                     ▼
                    ┌──────────────────────────────────────────┐
  查询          ───▶│            Query Engine                  │
                    │  query_processing → dense ┐              │
                    │                            ├→ RRF fusion │
                    │                    sparse ┘      │       │
                    │                                  ▼       │
                    │                              rerank      │
                    │                    (失败回退至 RRF 顺序) │
                    └────────────────┬─────────────────────────┘
                                     ▼
             ┌───────────────┬───────────────┬──────────────────┐
             │  MCP Server   │  CLI Scripts  │  Dashboard       │
             │  (3 tools)    │  (5 scripts)  │  (Streamlit 6页) │
             └───────────────┴───────────────┴──────────────────┘

  贯穿全程:TraceContext(trace → stage)写入 logs/traces.jsonl

Steckbares Fundament

Jede Kernphase definiert ein einheitliches Base-Interface. Durch Factory + YAML-Konfiguration können Komponenten gewechselt werden – ohne Codeänderungen:

Schritt

Interface

Implementierte Provider

LLM

BaseLLM

openai / azure / deepseek / kimi / ollama

Vision-LLM

BaseVisionLLM

openai / azure / kimi

Embedding

BaseEmbedding

openai / azure / siliconflow / bge / ollama

Vektorspeicher

BaseVectorStore

chroma

Splitter

BaseSplitter

recursive

Reranker

BaseReranker

llm / cross_encoder (BGE)

Evaluator

BaseEvaluator

custom / ragas / composite

Loader

BaseLoader

pdf / docx / markdown / text

Jeder OpenAI-kompatible Endpoint kann über provider: "openai" + eine eigene base_url angebunden werden – ohne neuen Code zu schreiben.


Kernfunktionen

Hybrid-Retrieval: BM25-Sparse-Retrieval für exakte Übereinstimmungen von Eigennamen, Dense-Vektor-Retrieval für semantische Übereinstimmungen. Nach der zweigleisigen Recall-Phase folgt eine RRF-Fusion, gefolgt von präzisem Ranking durch den Reranker. Fällt die Rerank-Engine aus, wird autrace der RRF-Reihenfolge automatisch Fallback – ein einmaliger Timeout unterbricht nicht die Kette.

Inkrementelle Indexierung & Idempotenz: SHA256-Inhalts-Fingerabdruck + SQLite ingestion_history-Tabelle ermöglichen dokumentweite Ink-Nutzung. Doppelte Aufnahmen werden übersprungen, nur bei Änderungen wird neu aufgebaut. Erneutes Einlesen erzeugt keine Dirty Data.

Multimodalität: PyMuPDF extrahiert eingebettete Bilder aus PDFs und behält deren Originalposition. Vision-LLM erstellt Bildbeschreibungen, die in die Chunks eingefügt werden, sodass die reine Text-RAG-Kette für "Suche nach Text; finde das Bild" wiederverwendet wird. MCP liefert die Bilder als ImageContent.

MCP-Tools:

Tool

Einsatzzweck

query_knowledge_hub

Hybrid-Retrieval + Reranking, liefert referenzierte Ergebnisse (inkl. Bilder)

list_collections

Listet alle Sammlungen mit Dokument-/Chunk-Statistiken

get_document_summary

Liefert Zusammenfassung und Chunk-Übersicht eines Dokuments

Dashboard (Streamlit, sechs Seiten): Systemübersicht / Datenbrowser / Ingestion-Management / Ingestion-Tracing / Query-Tracing / Bewertungs-View.


Schnellstart

Voraussetzungen

Python ≥ 3.10.

Installation

git clone <your-repo-url>
cd RAG-MCP-SERVER

python -m venv .venv
# Windows
.venv\Scripts\activate
# Linux / macOS
source .venv/bin/activate

pip install -e ".[dev]"

Alle Abhängigkeiten sind nach oben versionbeschränkt. mcp ist auf <2.0 arretiert (2.x hat Felder wie CallToolResult.isError umbenannt), langchain-community auf <0.4 (0.4 entfernte chat_models.vertexai, was zu fehlgeschlagenen ragas-Importen hätte führen können).

Konfiguration

cp config/settings.yaml.example config/settings.yaml

Bearbeite config/settings.yaml und trage deine eigenen API Keys ein. Diese Datei wird von .gitignore ignoriert, also nicht committen.

Dokumente indexieren

python scripts/ingest.py --path ./your_docs --collection my_kb
python scripts/ingest.py --path ./your_docs --collection my_kb --force   # 强制重建
python scripts/ingest.py --path ./your_docs --dry-run                    # 只看会处理哪些文件

Abfragen

python scripts/query.py -q "你的问题" -c my_kb --top-k 5 --verbose

Mit --verbose werden die Zwischenergebnisse von dense / sparse / fusion / rereank ausgegeben.

Dashboard starten

python scripts/start_dashboard.py

Mit einem MCP-Client verbinden

Am Beispiel von Claude Desktop: In claude_desktop_config.json eintragen:

{
  "mcpServers": {
    "rag-mcp-server": {
      "command": "<绝对路径>/.venv/Scripts/python.exe",
      "args": ["<绝对路径>/main.py"]
    }
  }
}

Konfiguration

Wichtige Konfigurationsabschnitte (vollständige Kommentare in config/settings.yaml.example):

retrieval:
  dense_top_k: 20
  sparse_top_k: 20
  fusion_top_k: 10
  rrf_k: 60
  # 路由开关,用于 A/B 基线:只测 dense 则 enable_sparse: false,反之亦然
  enable_dense: true
  enable_sparse: true

rerank:
  enabled: true
  provider: "llm"           # 走已配置的 LLM,零额外依赖
  # provider: "cross_encoder"  # 本地 BGE cross-encoder,需 pip install sentence-transformers
  top_k: 5

evaluation:
  enabled: true
  provider: "composite"     # 同时跑检索指标与生成指标
  backends: ["custom", "ragas"]
  metrics: ["hit_rate", "mrr", "faithfulness", "context_precision"]

embedding.dimensions darf nach dem ersten Ingestion nicht mehr geändert werden – bestehende Chroma-Collections sind an die Vektor-Dimensionen gebunden.


Observability

Jeder angesetzte Ingestion und jede Abfrage erzeugen einen Trace-Datensatz, der in logs/traces.jsonl geschrieben wird. Die Struktur ist trace → stages[], und jede Stufe protokolliert elapsed_ms und die jeweiligen data der Stufe.

Kette

Stufen

Ingestion

loadsplittransformembedupsert

Query

query_processingdense_retrievalsparse_retrievalfusionrerank

Ranking-Änderungen nachvollziehen

Aus Benutzer wird lediglich aufgelistet, sobald jede Stufenstufe abgeschlossen ist. Damit ließe sich nicht beantworten, ob diese Stufe das Ranking tatsächlich verbessert hat und welcher Chunk davon gewonnen hatbe. Daher erfassen die Stufen fusion und rerank zusätzlich die Rangänderungen (src/core/query_engine/rank_tracking.py):

  • Konvention 1-basiert: rank_delta = rank_before - rank_after, positiv = aufgestiegen

  • rank_before von fusion ist der beste Rang des Chunks aus den beiden Kanälen. Das beantwortet die Frage, ob RRF es über das Einfach-Retrieval hinaus hebt. Zusätzlich werden dense_rank / sparse_rank geloggt, welche Kanal den Chunk zuerst gefunden hat

  • rank_before von pushierte ist die Position aus der zuvor fusionierten Liste – so sieht man genau, wen der Reranker nach oben oder unten gedreht hat

  • Neue Chunks, die erst beim Rerank endlich auftauchen, werden mit None markiert, ohne deren "Rangverbesserung" zu fingieren

  • Stufenbezogene Zusammenfassung: moved_up / moved_down / unchanged / new / max_gain / max_drop / dropped

Ein tatsächlicher Trace-Ausschnitt:

stage=fusion   elapsed=0.2ms
  rank_changes: {moved_up: 3, moved_down: 1, unchanged: 1, max_gain: 2, dropped: 18}
  rank=2  before=4  delta=+2   dense_rank=4  sparse_rank=4

stage=rerank   elapsed=12231ms
  rank_changes: {moved_up: 1, moved_down: 1, unchanged: 3, max_gain: 1}
  rank=1  before=2  delta=+1

Die Seite „Query-Tracing" im Dashboard rendert diese als Stufenwasser- bzw. Fallhöhen-View und Rangänderungstabelle zeige.


Evaluations-Framework

python scripts/evaluate.py --collection my_kb
python scripts/experiment.py --variants dense,sparse,hybrid,hybrid_rerank
  • Retrieval-Metriken (CustomEvaluator): Hit Rate@K, MRR – erfordern expected_chunk_ids als Ground-Truth im Testset

  • Generations-Metriken (RagasEvaluator): Faithfulness, Answer Relevancy, Context Precision

  • CompositeEvaluator läuft beide Arten parallel und merge die Ergebnisse. Jeder Backend filtert selbst die für ihn vorgesehenen Metriken aus der gemeinsame metrics-Liste; ein fehlerhafter Backend beeinträchtigt die anderen nicht

scripts/experiment.py erlaubt A/B-Vergleiche verschiedener Retrieval-Varianten und gibt Metriken sowie Latenz jeder Variante aus. So lässt sich klären, "ob der Rerank die zusätzlichen 12 Sekunden wert ist".


Tests

Schichtentezte Tests, insgesamt 1456 Fälle:

pytest tests/unit                      # 1298 passed, 1 skipped
pytest tests/integration -m "not llm"  #   94 passed, 10 skipped
pytest tests/e2e -m "not llm"          #   30 passed,  2 skipped

Mit -m "not llm" werden Tests ausgeschlossen, die echte LLM-API-Calls benötigen. Fehlt ein jeweiliges Provider-Zertifikat, werden die betreffenden Fälle übersprungen, mit Begründung, statt bestanden oder als Fehlschlag zu gelten.

Kritische Verzweigungen sind gezielt abgedeckt:

Schwerpunkt

Tests

RRF-Fusion

test_fusion_rrf.py

Reranker-Pfad-Fallback

test_reranker_fallback.py

Idempotente Daten-Integration

test_vector_upserter_idempotency.py

Rangänderungen-Tracking

test_rank_tracking.py

Segmentierer Index/Query-Konsistenz

test_sparse_encoder.py / test_query_processor.py

Chroma-Client-konkurrenz-Erstellung

test_chroma_client.py

Vektor-Store-Abstraktion

test_vector_store_contract.py


Projektstruktur

src/
├── core/
│   ├── query_engine/       # 混合检索:dense / sparse / RRF fusion / rerank
│   │   └── rank_tracking.py  # 排名变化计算(融合与重排共用)
│   ├── response/           # 响应组装、引用生成、多模态拼装
│   ├── trace/              # TraceContext:trace → stage
│   ├── tokenization.py     # BM25 分词器(索引端与查询端唯一实现)
│   └── settings.py         # YAML 配置加载与校验
├── ingestion/
│   ├── chunking/ embedding/ storage/ transform/
│   ├── pipeline.py         # 五阶段摄取流水线
│   └── document_manager.py # 文档删除(跨 Chroma / BM25 / 图片 / 摄取历史)
├── libs/                   # 可插拔底座:base_*.py + *_factory.py
│   ├── llm/ embedding/ loader/ reranker/ splitter/ vector_store/ evaluator/
├── mcp_server/             # MCP 协议与 3 个 Tool
└── observability/
    ├── dashboard/          # Streamlit 六页
    └── evaluation/         # ragas / composite / eval_runner

scripts/   ingest / query / evaluate / experiment / start_dashboard
config/    settings.yaml.example + prompts/
tests/     unit / integration / e2e

data/ (Chroma, BM25-Index, extrahierte Bilder, Ingestion-Historie) und logs/ (Traces) sind lokal im Betrieb erzeugte Artefakte, aber durch .gitignore von der Verteilung ausgeschlossen und werden bei der ersten Ausführung automatisch angelegt.


License

MIT

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides RAG-based knowledge retrieval and document management as MCP tools, supporting hybrid search, reranking, and retrieval process visualization.
  • A
    license
    Not graded
    quality
    C
    maintenance
    A pluggable, observable modular RAG framework that exposes query knowledge hub, list collections, and get document summary tools via MCP, enabling AI assistants to perform hybrid search and document retrieval with reranking.
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A modular RAG framework exposing knowledge retrieval tools via MCP, enabling AI assistants to perform hybrid search, reranking, and multimodal document queries with full observability and evaluation.
    MIT

View all related MCP servers

Related MCP Connectors

  • Search your knowledge bases from any AI assistant using hybrid RAG.

  • Multi-engine search for AI agents. Trust scoring, local corpus, MCP-native. Self-hostable, BYOK.

  • Agentic search over your Dewey document collections from any MCP-compatible client.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mily-Lv/RAG-MCP-SERVER'

If you have feedback or need assistance with the MCP directory API, please join our Discord server