Skip to main content
Glama
zhtong-star

Modular RAG MCP Server

by zhtong-star

Modular RAG MCP Server

一个可插拔、可观测的模块化 RAG(检索增强生成)服务框架。通过 MCP(Model Context Protocol)标准协议对外暴露工具接口,让 Claude、Copilot 等 AI 助手直接调用私有知识库;配套 Streamlit 管理面板与自动化评估体系,实现从文档摄取到在线检索的完整闭环。


📖 目录


Related MCP server: Modular RAG MCP Server

🏗️ 项目简介

本项目把 RAG 的核心环节——混合检索(Hybrid Search + RRF)多模态视觉处理(Image Captioning)RAG 评估(Ragas + Custom)——与当下热门的应用协议 MCP(Model Context Protocol) 串联为一个完整、可运行的工程系统。

设计定位

  1. 全链路可插拔:LLM / Embedding / Reranker / Splitter / VectorStore / Evaluator 每个能力维度都定义了抽象接口 + 工厂模式,通过 config/settings.yaml 一键切换后端,零代码修改即可适配不同 Provider 与部署环境。

  2. 白盒化可观测:Ingestion 与 Query 两条链路的每一个中间状态(耗时、输入输出、错误)都被 TraceContext 记录到 logs/traces.jsonl,并通过 6 页面 Streamlit Dashboard 可视化呈现,慢查询诊断不再靠猜。

  3. 标准协议接入:遵循 MCP 协议(stdio + JSON-RPC 2.0),可直接对接 Claude Desktop、GitHub Copilot、Cursor 等任意 MCP Client,一次开发、多处调用。

  4. 数据驱动的质量闭环:集成 Custom(Hit Rate / MRR)与 Ragas(Faithfulness 等)双评估体系,配合 Golden Test Set 回归基线,让检索质量的每次调优都有数据可依。

一段话讲清楚它做什么

丢进一篇 PDF → 系统将其解析、分块、LLM 精炼、生成图片描述、向量化编码、写入多路存储 → 一个可检索的知识库就绪。之后任何 MCP Client 都能用自然语言查询它,系统做 jieba 分词 + Dense/Sparse 并行混合检索 + RRF 融合排序 + 可选重排,最终返回带引用来源的 Markdown 结构化答案,必要时还能附带检索到的图片。


✨ 核心能力

模块

能力

说明

Ingestion Pipeline

PDF → Markdown → Chunk → Transform → Embedding → Upsert

6 阶段全链路数据摄取,SHA256 幂等去重,支持多模态图片描述

Hybrid Search

Dense(向量)+ Sparse(BM25)+ RRF 融合 + 可选 Rerank

两段式检索架构:粗排召回 + 精排重排

MCP Server

标准 MCP 协议暴露 Tools

query_knowledge_hub / list_collections / get_document_summary

Multimodal

Image-to-Text 策略

Vision LLM 自动为文档图片生成描述并缝合进 Chunk,"搜文字出图"

Observability

全链路白盒化追踪

双链路(摄取/查询)独立打点,JSON Lines 持久化

Dashboard

Streamlit 6 页面管理平台

总览 / 数据浏览 / 摄取管理 / 摄取追踪 / 查询追踪 / 评估面板

Evaluation

Custom + Ragas 双评估体系

Golden Test Set 回归测试,拒绝"凭感觉"调优

可插拔架构

6 大抽象接口 + 工厂模式

LLM ×4 / Embedding ×3 / Reranker ×2 / Splitter / VectorStore / Evaluator


🏛️ 系统架构

总体设计

系统由离线摄取在线查询两大链路构成,共享同一套存储层:

┌─────────────────────────────────────────────────────────────────────────┐
│                        Modular RAG MCP Server                           │
│                                                                          │
│  ┌──────────────────────────────┐    ┌──────────────────────────────┐   │
│  │  离线 Ingestion 链路(摄取)    │    │  在线 Query 链路(查询)       │   │
│  │                              │    │                              │   │
│  │  ① 文件完整性检查 (SHA256)     │    │  ① MCP 工具调用 (stdio)       │   │
│  │  ② PDF 解析 (MarkItDown)      │    │  ② 查询预处理 (jieba 分词)    │   │
│  │  ③ 递归分块 (chunk=1000)      │    │  ③ 并行混合检索 (Dense+Sparse)│   │
│  │  ④ 变换管线 (Refine+Enrich+   │    │  ④ RRF 融合排序 (k=60)        │   │
│  │     Caption)                  │    │  ⑤ 可选 Rerank               │   │
│  │  ⑤ 向量编码 (Dense+Sparse)    │    │  ⑥ 响应构建 (Markdown+引用+   │   │
│  │  ⑥ 多路存储 (3 个后端)         │    │     图片)                     │   │
│  └──────────────────────────────┘    └──────────────────────────────┘   │
│                                                                          │
│  ┌──────────────────────────────────────────────────────────────────┐   │
│  │  存储层:ChromaDB(稠密向量)+ BM25 Index(稀疏索引)               │   │
│  │          + ImageStorage(图片索引)+ SQLite(摄取历史/幂等)         │   │
│  └──────────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────┘

五层分层架构

代码按依赖方向分为五层,层间通过抽象基类解耦,上层依赖下层接口而非具体实现:

   ┌──────────────────────────────────────────────────────────┐
   │   AI 助手(Claude / Copilot / Cursor 等 MCP Client)        │
   └──────────────────────────┬───────────────────────────────┘
                              │ MCP Protocol (stdio JSON-RPC 2.0)
   ┌──────────────────────────▼───────────────────────────────┐
   │  src/mcp_server/    【协议服务层】                          │
   │  server.py → protocol_handler.py → tools/(3 个 Tool)     │
   └──────────────────────────┬───────────────────────────────┘
                              │ 调用
   ┌────────────┬─────────────▼─────────────┬─────────────────┐
   │            │                           │                 │
   │ src/       │ src/core/query_engine/    │ src/            │
   │ ingestion/ │ 【检索引擎层】             │ observability/  │
   │ 【业务管道】│ HybridSearch → RRF →      │ 【可观测性层】   │
   │ Pipeline   │ Rerank → Response         │ Dashboard +     │
   │ 6 阶段     │                           │ Evaluation      │
   └────────────┴─────────────┬─────────────┴─────────────────┘
                              │ 依赖抽象
   ┌──────────────────────────▼───────────────────────────────┐
   │  src/libs/   【可插拔库层】                                 │
   │  LLM | Embedding | Loader | Splitter | VectorStore        │
   │  | Reranker | Evaluator(Base 类 + Factory 模式)           │
   └──────────────────────────┬───────────────────────────────┘
                              │ 读写
   ┌──────────────────────────▼───────────────────────────────┐
   │  src/core/    【基础设施层】                                │
   │  settings.py | types.py | trace/(配置 + 数据类型 + 追踪)  │
   └──────────────────────────────────────────────────────────┘

层级依赖规则:上层可调用下层,下层绝不引用上层;src/libs/ 是纯抽象层,不依赖任何业务层;src/core/ 只含纯数据与配置,零业务逻辑。

链路一:离线摄取(Ingestion Pipeline)

IngestionPipeline::run() 将一篇 PDF 逐步转换为可检索的向量与索引,共 6 个阶段:

阶段

组件

作用

① 完整性检查

SQLiteIntegrityChecker

计算 SHA256 哈希,查询历史记录,已处理文件自动跳过(幂等)

② 文档加载

PdfLoader

MarkItDown 转 Markdown + PyMuPDF 提取图片,插入 [IMAGE: id] 占位符

③ 文档分块

DocumentChunker + RecursiveSplitter

chunk_size=1000 / overlap=200,生成确定性 Chunk ID,继承源数据

④ 变换管线

ChunkRefiner + MetadataEnricher + ImageCaptioner

LLM 精炼去噪、生成 title/summary/tags、为图片生成描述;LLM 失败自动降级为规则模式

⑤ 向量编码

BatchProcessorDenseEncoder + SparseEncoder

Dense:Embedding API(2560 维);Sparse:jieba 分词 + BM25 词频统计(本地零成本)

⑥ 多路存储

VectorUpserter + BM25Indexer + ImageStorage

分别写入 ChromaDB、JSON 倒排索引、SQLite 图片索引;三路并行独立,一路失败不影响其他

幂等性设计:SHA256 文件级去重 + Chunk ID 确定性生成({doc_id}_{index:04d}_{content_hash[:8]}),同一文件重复提交自动跳过,--force 可强制重处理。

链路二:在线查询(Query Pipeline)

MCP Client 发出 JSON-RPC 请求,经 ProtocolHandler 分发到对应 Tool,核心链路如下:

MCP Client (stdio)
  └─ tools/call: query_knowledge_hub
      └─ QueryProcessor      → jieba 分词 + 停用词过滤 + 过滤语法解析
      └─ HybridSearch        → DenseRetriever + SparseRetriever 并行(ThreadPool)
      └─ RRFFusion (k=60)    → Σ 1/(k + rank_i),排名级融合,无需分数归一化
      └─ Reranker(可选)     → Cross-Encoder / LLM 精排,失败保持原序
      └─ ResponseBuilder     → Markdown 内容 + [1][2] 引用标记 + 多模态图片
      └─ TraceCollector      → 写入 logs/traces.jsonl
      └─ MCP Response        → TextContent + 可选 ImageContent

并行与降级:Dense 与 Sparse 通过 ThreadPoolExecutor 并行执行,总耗时取二者最大值;任一路失败,另一路结果直接作为最终结果,两路皆失败才报错——单点故障不阻断整体查询。

可观测性与评估

  • TraceContext:每个阶段独立计时,记录 {name, elapsed_ms, details},最终持久化为 logs/traces.jsonl(每行一条合法 JSON,可按类型/时间/集合过滤)。

  • Streamlit Dashboard(6 页面):系统总览 / 数据浏览 / 摄取管理 / 摄取追踪(阶段瀑布图)/ 查询追踪(Dense vs Sparse 对比)/ 评估面板。

  • 评估体系CustomEvaluator(Hit Rate、MRR 等确定性指标)+ RagasEvaluator(Faithfulness、Answer Relevancy、Context Precision 等 LLM-as-Judge 语义指标),由 CompositeEvaluator 并行组合、EvalRunner 基于 Golden Test Set 批量运行。


💡 技术亮点

🔌 全链路可插拔架构:LLM / Embedding / Reranker / Splitter / VectorStore / Evaluator 均定义抽象基类 + 工厂模式,通过 settings.yaml 一键切换 Provider(LLM ×4、Embedding ×3、Reranker ×2),替换组件不修改任何上游代码。

🔍 混合检索 + RRF 融合:BM25 稀疏检索解决专有名词精确匹配,Dense Embedding 解决同义词语义匹配,两者互补;RRF 基于排名而非原始分数融合(RRF_score = Σ 1/(k+rank)),免去跨路分数归一化,输出完全确定性。

🖼️ 多模态图像处理:采用 Image-to-Text 策略,Vision LLM(Qwen3-VL)自动为文档图片生成描述并缝合进 Chunk,复用纯文本 RAG 链路即可实现"搜文字出图";图片以 base64 编码随 MCP 响应返回。

📡 MCP 生态集成:遵循 MCP 标准协议(stdio + JSON-RPC 2.0),stdout 专用于协议消息、所有日志重定向 stderr;阻塞 I/O 用 asyncio.to_thread() 放入线程池;主线程预加载 chromadb/onnxruntime 规避 import 死锁。可直接对接任意 MCP Client,零前端开发。

🧪 三层测试体系:Unit(无外部依赖,Mock-First)/ Integration(跨模块协作,LLM 相关用 marker 可选运行)/ E2E(全链路端到端),覆盖独立模块逻辑、模块间交互与完整链路。

⛓️ 幂等与优雅降级:SHA256 文件级去重 + 确定性 Chunk ID 保证重复摄取不产生脏数据;LLM 失败回退规则、Dense/Sparse 互备、Rerank 失败保序,任何单点故障都不中断主链路。

📊 数据驱动迭代:Golden Test Set 回归基线 + 双评估体系,让检索调优(如调整 RRF k、chunk_size)有量化指标可循。


🛠️ MCP 工具

工具名

描述

输入参数

query_knowledge_hub

知识库混合检索(核心工具)

query(必填)、top_k(默认 5)、collection(可选)

list_collections

列出所有集合及统计信息

include_stats(默认 true)

get_document_summary

按文档 ID 获取标题/摘要/标签

doc_id(必填)、collection(可选)


🧰 技术栈

┌───────────────────────────────────────────────────────────────┐
│  交互层:Streamlit(Dashboard)· MCP Protocol(JSON-RPC over  │
│          stdio)· Python 3.10+ · asyncio                       │
├───────────────────────────────────────────────────────────────┤
│  RAG 核心:                                                   │
│    检索     Dense: Qwen3-Embedding-4B(2560 维)              │
│             Sparse: 自实现 BM25(jieba 分词)                  │
│    融合     RRF(k=60,排名级融合)                             │
│    重排     Cross-Encoder / LLM Rerank(可插拔)               │
│    生成/变换 DeepSeek-V3.2 等(OpenAI 兼容)                    │
├───────────────────────────────────────────────────────────────┤
│  存储层:ChromaDB(向量)· BM25 JSON Index(稀疏)·            │
│          SQLite(图片索引 / 摄取历史)· 文件系统                │
├───────────────────────────────────────────────────────────────┤
│  可观测性:TraceContext · JSON Lines · Ragas · CustomEvaluator│
│             · pytest(三层测试)· Golden Test Set              │
└───────────────────────────────────────────────────────────────┘

关键依赖mcp(官方 SDK)、chromadblangchain-text-splittersmarkitdown[pdf] + PyMuPDFjiebaopenai(兼容 SiliconFlow / Azure / DeepSeek)、ollamaragasstreamlitsentence-transformers(可选重排)。

支持的 Provider:LLM ×4(OpenAI 兼容 / Azure / DeepSeek / Ollama)、Embedding ×3、Rerank ×2(LLM / Cross-Encoder)、Vision LLM(Qwen3-VL 等)。


📂 项目结构

MODULAR-RAG-MCP-SERVER/
├── config/
│   ├── settings.yaml              # 全局配置中心(LLM/Embedding/检索/摄取…)
│   └── prompts/                   # 各阶段 Prompt 模板(精炼/元数据/图片描述/重排)
├── documents/                     # 待摄取原始文档
├── data/db/                       # 运行时数据(chroma/ bm25/ 图片索引/ 摄取历史)
├── logs/traces.jsonl              # 全链路追踪 JSON Lines
├── scripts/                       # CLI 入口(ingest/query/evaluate/start_dashboard/探测脚本)
├── src/
│   ├── core/                      # 【基础设施层】settings、types、query_engine、response、trace
│   ├── ingestion/                 # 【业务管道层】pipeline、chunking、embedding、storage、transform
│   ├── libs/                      # 【可插拔库层】llm、embedding、loader、splitter、vector_store、reranker、evaluator
│   ├── mcp_server/                # 【协议服务层】server、protocol_handler、tools/
│   └── observability/             # 【可观测性层】logger、dashboard(6 页)、evaluation
├── tests/                         # unit / integration / e2e / fixtures(Golden Test Set)
├── DEV_SPEC.md                    # 开发规格文档
├── main.py                        # 项目主入口(注册为 mcp-server CLI)
└── pyproject.toml                 # 项目元数据与依赖

🛠️ 我是怎么做的:Harness 工程方法

这个项目的构建遵循 Harness 工程思路——不是"让一个模型一次写完所有代码",而是 Initializer + Coding Loop 的最小闭环:

先拆解 → 再循环执行 → 靠外部状态保持连续性 → 靠确定性验证保证质量

核心哲学是五个字:拆、循环、记、验、守

1. 拆:Initializer 把需求拆成可验证的 Feature

不直接写代码,先把需求整理成后续 Agent 可反复执行的任务蓝图(AppSpec.md),再由 Initializer 把大任务拆成一组细粒度、可执行、可验证的 Feature,产出 feature_list.json 状态文件。

本项目被拆成 24 个独立 Feature(F-001 → F-024),每个 Feature 明确四件事:

{
  "id": "F-005",
  "name": "VectorStore 抽象层",
  "description": "BaseVectorStore 抽象类 + VectorStoreFactory + ChromaStore 实现",
  "files": ["src/libs/vector_store/*.py"],
  "depends_on": ["F-001", "F-002"],
  "verification": "python -m pytest tests/unit/test_vector_store.py -v",
  "acceptance": "ChromaStore 可 upsert/query/delete/get_by_ids,cosine 排序正确"
}

F-001(核心数据类型)到 F-024(端到端集成测试),依赖关系清晰、按拓扑序执行:先打通 F-001 types / F-002 settings / F-007 integrity 等无依赖地基,再到 F-013 pipeline 编排、F-017 hybrid search、F-020 MCP Server,最后是 F-021~F-024 工具与端到端验收。

2. 循环:Coding Loop 每轮只做一件事

每轮启动一个全新的 Coding Agent,只完成一个明确的小任务,靠外部状态接力:

┌──────────────────────────────────────────────────────────┐
│                   Coding Loop 单轮协议                     │
│                                                          │
│  ① 启动全新 Agent(无历史上下文)                           │
│  ② Agent 读取 3 个外部文件:                              │
│     - feature_list.json → 知道当前该做哪个 Feature        │
│     - progress.md      → 知道前面完成了什么、踩了什么坑     │
│     - 目标代码文件      → 了解当前代码状态                  │
│  ③ Agent 完成一个 Feature                                 │
│  ④ 确定性验证 Gate(不是 Agent 自评):                    │
│     - pytest 必须 PASS                                    │
│     - mypy/pyright 类型检查必须 PASS                       │
│     - ruff lint 必须 PASS                                 │
│  ⑤ 验证通过后,由系统(非 Agent)更新状态:                 │
│     - feature_list.json: status → completed               │
│     - progress.md: 追加交接记录                            │
│     - git commit: 提交代码 + 验证结果                      │
│  ⑥ Agent 立即退出,下一轮由新 Agent 接力                   │
└──────────────────────────────────────────────────────────┘

3. 记:外部状态是系统的核心记忆

不把连续性寄托在模型上下文里,每个 Agent 启动时从三份持久化信息快速接手:

外部状态

作用

feature_list.json

所有 Feature 的定义、依赖、状态、验证命令;状态由验证结果决定,不由 Agent 自评,永远反映真实进度

progress.md

每轮完成后的交接记录(做了什么、结果如何、踩了什么坑),是新 Agent 的 onboarding 材料

Git Log

每个 Feature 一个 commit,feat(F-xxx): description 命名,git log --oneline 就是天然的任务完成清单

4. 验:确定性验证 Gate

每个 Feature 都有明确的验证命令和预期输出,pytest pass ≠ 代码完成,pytest pass = 代码至少通过了预定义的确定性检查。通过才更新状态、提交、进入下一轮;失败则记录失败原因,由下一轮新 Agent 接手修复——质量不由"AI 说做好了就是做好了"决定。

5. 守:Human-in-the-Loop 关键节点

高度自动化但并非无人值守,在以下节点设计人工确认断点

断点时机

触发条件

本项目实例

高风险依赖选择

Feature 涉及关键依赖引入

PDF Loader 选择 MarkItDown vs pdfminer

架构决策点

跨多个 Feature 的接口设计

LLM / Embedding 抽象基类签名

失败重试 > 2 次

同一 Feature 连续失败

Pipeline 编排器集成反复失败时人工介入

关键界面变更

修改已有公共 API

VectorStore 接口变更影响所有 consumer

集成验证前

最后几个 Feature 完成

端到端验收通过后再正式发布

为什么这么做

传统方式让一个 Agent 一次做完所有事,产出的代码无法验证、无法复现、无法交接。而 Initializer + Coding Loop 最小闭环让每个 Feature 都有明确的输入文件、输出文件、验证命令和依赖关系,把"靠 AI 记忆"变成"靠外部状态 + 确定性验证",把一个复杂项目稳扎稳打地交付出来。


🚀 快速开始

# 1. 克隆并进入项目
git clone <repo-url>
cd MODULAR-RAG-MCP-SERVER

# 2. 安装依赖(Python 3.10+)
pip install -e ".[dev]"

# 3. 配置 API Key:从模板复制(config/settings.yaml 已被 git 忽略,请勿提交真实密钥)
cp config/settings.yaml.example config/settings.yaml
#   然后编辑 config/settings.yaml,填写 LLM / Embedding 的 API Key 与 base_url

# 4. 摄取文档:将 PDF 放入 documents/,执行
python scripts/ingest.py --path documents/ --collection knowledge_hub

# 5. 查询验证
python scripts/query.py --query "你的问题" --collection knowledge_hub

# 6. 启动 Dashboard
python scripts/start_dashboard.py

# 7. 启动 MCP Server(供 Claude / Copilot 等 Client 调用)
mcp-server

配置 Provider 切换、新文档格式扩展等,只需修改 settings.yaml 或基于 src/libs/ 的抽象接口新增实现——可插拔架构让这些改动不影响任何上游代码。


📚 配套文档

文档

内容

DEV_SPEC.md

开发规格文档:项目概述、核心特点、技术选型、测试方案、系统架构、排期与可扩展性

A
license - permissive license
-
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
    -
    quality
    C
    maintenance
    A pluggable, observable modular RAG service framework that exposes tool interfaces via the MCP protocol, enabling AI assistants like Copilot and Claude to directly query knowledge bases.
  • A
    license
    -
    quality
    F
    maintenance
    A pluggable, observable modular RAG framework exposing tools via MCP protocol for AI assistants like Copilot/Claude to query knowledge bases, list collections, and retrieve document summaries.
    1,070
    MIT
  • A
    license
    -
    quality
    C
    maintenance
    A pluggable, observable modular RAG service framework that exposes tool interfaces via the MCP protocol, enabling AI assistants like Copilot and Claude to directly invoke knowledge retrieval and reasoning capabilities.
    MIT
  • A
    license
    -
    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

View all related MCP servers

Related MCP Connectors

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

  • Persistent memory and knowledge graphs for AI agents. Hybrid search, context checkpoints, and more.

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

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/zhtong-star/MODULAR-RAG-MCP-SERVER'

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