Skip to main content
Glama
nongtiensonpro

Document RAG MCP

README.md
# Document RAG MCP

**Hệ Thống Document Intelligence & Hybrid Retrieval Toàn Diện Cho AI Agent**

> Một server [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) chuẩn mực, kết hợp sức mạnh của **Trích xuất đa định dạng** + **Xác thực cấu trúc tự động** + **Kho dữ liệu quan hệ DuckDB (Read-Only SQL)** + **Tìm kiếm lai Vector Dense/Sparse (Qdrant) với BGE-M3 Cross-Encoder Reranker**.

---

## 📑 Mục Lục

- [1. Tổng Quan Kiến Trúc](#1-tổng-quan-kiến-trúc)
- [2. Tính Năng Nổi Bật](#2-tính-năng-nổi-bật)
- [3. Cài Đặt & Khởi Động Nhanh](#3-cài-đặt--khởi-động-nhanh)
- [4. Danh Sách & Chi Tiết 12 Công Cụ MCP](#4-danh-sách--chi-tiết-12-công-cụ-mcp)
- [5. Hướng Dẫn Tích Hợp Chi Tiết Vào Hermes Agent](#5-hướng-dẫn-tích-hợp-chi-tiết-vào-hermes-agent)
  - [Cách A: Sử dụng Native Hermes Plugin (Khuyến nghị cho CLI & Desktop)](#cách-a-sử-dụng-native-hermes-plugin-khuyến-nghị-cho-cli--desktop)
  - [Cách B: Khai báo MCP Server trong config.yaml](#cách-b-khai-báo-mcp-server-trong-configyaml)
  - [Quản lý trực quan trên giao diện Hermes Desktop](#quản-lý-trực-quan-trên-giao-diện-hermes-desktop)
- [6. Cấu Hình Cho Các Client MCP Khác (Claude Desktop, Cursor, ...)](#6-cấu-hình-cho-các-client-mcp-khác)
- [7. Kịch Bản & Quy Trình Sử Dụng Mẫu (Workflow Thực Tế)](#7-kịch-bản--quy-trình-sử-dụng-mẫu)
- [8. Xử Lý Sự Cố & Câu Hỏi Thường Gặp (Troubleshooting)](#8-xử-lý-sự-cố--câu-hỏi-thường-gặp)
- [9. Cấu Trúc Thư Mục Dự Án](#9-cấu-trúc-thư-mục-dự-án)
- [10. Kiểm Thử](#10-kiểm-thử)

---

## 1. Tổng Quan Kiến Trúc

Hệ thống hoạt động theo pipeline 4 tầng độc lập và song song:

```text
Tài liệu đầu vào (PDF, DOCX, XLSX, CSV, PPTX, HTML, Markdown, TXT, XML)
                                  │
                    ┌─────────────┴─────────────┐
                    ▼                           ▼
          Tầng 1: TRÍCH XUẤT            (Mỗi định dạng có
          (Format-Specific Extractors)   Extractor chuyên biệt)
                    │
                    ▼
          Tầng 2: MÔ HÌNH TÀI LIỆU CHUẨN
          DocumentModel { sections[], tables[], metadata }
                    │
       ┌────────────┼────────────────┐
       ▼            ▼                ▼
  Tầng 3a:     Tầng 3b:        Tầng 3c:
  XÁC THỰC     LƯU TRỮ BẢNG   CHIA ĐOẠN
  (Validation)  (DuckDB)       (Chunking)
       │                             │
       ▼                             ▼
  Báo cáo lỗi              Tầng 4: TÌM KIẾM NGỮ NGHĨA
  & cảnh báo               Qdrant Vector Store
                            - Dense + BM25 Sparse (RRF)
                            - Multilingual Cross-Encoder Reranker
```

- **Nguyên lý thiết kế**: Dữ liệu sau khi trích xuất được chuẩn hóa thành `DocumentModel` duy nhất. Dữ liệu bảng lập tức được nạp vào cơ sở dữ liệu quan hệ **DuckDB** để phục vụ các câu hỏi thống kê/tính toán chính xác $100\%$, đồng thời chia đoạn thông minh nạp vào **Qdrant** để phục vụ tìm kiếm ngữ nghĩa mờ.

---

## 2. Tính Năng Nổi Bật

### 📄 1. Trích Xuất Chuyên Biệt Theo Định Dạng
- **Spreadsheet (`.xlsx`, `.xls`)**: Đọc trực tiếp qua `openpyxl`, tự động nhận diện header thống kê nhiều tầng, lan truyền ô gộp (merged cells), bảo toàn giá trị công thức tính toán.
- **Dữ liệu phân tách (`.csv`)**: Tự động nhận diện dấu phân cách (`csv.Sniffer`), thử nhiều bảng mã (`utf-8`, `utf-8-sig`, `latin-1`, `cp1252`).
- **Tài liệu Word (`.docx`)**: Tái hiện cây cấu trúc Heading 1 $\rightarrow$ Heading 2 $\rightarrow$ nội dung, trích xuất bảng nhúng.
- **Tài liệu PDF (`.pdf`)**: Tích hợp OCR bố cục trang, trích xuất cấu trúc bảng thông minh qua Docling.
- **Trình chiếu (`.pptx`)**: Trích xuất tiêu đề slide, bullet points, ghi chú thuyết trình (speaker notes) và bảng biểu.
- **Văn bản có cấu trúc (`.md`, `.txt`, `.html`, `.xml`)**: Phân tích cú pháp tiêu đề và trích xuất bảng HTML/XML.

### 🛡️ 2. Công Cụ Xác Thực Dữ Liệu Tự Động (Validation Engine)
- **Tự động không cần cấu hình**:
  - Đối chiếu số lượng thực tế của từng sheet với số liệu khai báo trong sheet Tổng Hợp/Summary.
  - Tự động dò tìm cột số thứ tự (STT, ID) và phát hiện khoảng trống (gaps) hoặc số trùng lặp.
  - Phát hiện bản ghi trùng lặp khóa chính xuyên suốt các sheet con (Cross-sheet duplicate keys).
  - Phân tích thống kê phát hiện lỗi copy-paste nhầm tên sheet/danh mục.
- **Khai báo qua Rule JSON (`rules/*.json`)**: Hỗ trợ thiết lập ràng buộc `required`, `required_any` (nhóm cột ứng viên), `unique`, `sequence` theo từng mẫu tài liệu.

### 📊 3. Lưu Trữ & Phân Tích Quan Hệ (DuckDB Read-Only)
- Mỗi bảng biểu trích xuất được tạo thành một bảng riêng biệt trong file `tables.duckdb`.
- **An toàn tuyệt đối**: Lớp bảo vệ `_validate_readonly_sql` chỉ cho phép các câu lệnh đọc (`SELECT`, `WITH`, `DESCRIBE`, `EXPLAIN`, `SHOW`), ngăn chặn mọi hành vi thay đổi/xóa dữ liệu (`DROP`, `DELETE`, `INSERT`, multi-statement injection `;`).
- Cung cấp API `aggregate` để AI Agent tổng hợp dữ liệu dễ dàng mà không cần sinh câu lệnh SQL phức tạp.

### 🎯 4. Tìm Kiếm Lai & Xếp Hạng Lại (Hybrid Search & Reranking)
- **Tìm kiếm lai**: Kết hợp Dense Vector + Sparse BM25 thông qua thuật toán Reciprocal Rank Fusion (RRF).
- **Reranker Đa Ngôn Ngữ**: Sử dụng `BAAI/bge-reranker-v2-m3` xếp hạng lại top kết quả với độ chính xác vượt trội.
- **Trích dẫn có căn cứ**: Mỗi đoạn văn bản trả về đều kèm mã trích dẫn `[S1]`, `[S2]` chỉ rõ tên file, tên sheet, khoảng dòng hoặc đường dẫn mục lục.

---

## 3. Cài Đặt & Khởi Động Nhanh

### Yêu Cầu Hệ Thống
- Python: `3.11` – `3.13`
- Công cụ quản lý: [`uv`](https://docs.astral.sh/uv/) (khuyến nghị)
- Cơ sở dữ liệu Vector: Qdrant (Docker hoặc Local Embedded)

### Các Bước Cài Đặt

```bash
# 1. Clone mã nguồn dự án
git clone https://github.com/nongtiensonpro/document-rag-mcp.git
cd document-rag-mcp

# 2. Tạo file cấu hình môi trường
cp .env.example .env

# 3. Đồng bộ và cài đặt toàn bộ thư viện phụ thuộc
uv sync

# 4. (Tùy chọn) Khởi chạy Qdrant qua Docker nếu dùng Docker mode
docker compose up -d qdrant
```

---

## 4. Danh Sách & Chi Tiết 14 Công Cụ MCP

Server đăng ký sẵn 14 công cụ chuyên biệt:

| STT | Tên Tool | Nhóm | Mô tả chi tiết |
|:---:|---|---|---|
| 1 | `index_document` | Nạp dữ liệu | Trích xuất, xác thực cấu trúc, lưu bảng vào DuckDB và nhúng vector một file. Hỗ trợ `force=True` (ép nạp lại) và `async_index=True` (chạy ngầm). |
| 2 | `index_directory` | Nạp dữ liệu | Quét nạp hàng loạt cả thư mục, hỗ trợ đệ quy, lọc đuôi file, báo cáo diff chi tiết (mới, sửa đổi, giữ nguyên, lỗi). |
| 3 | `search_documents` | Tìm kiếm | Tìm kiếm lai kết hợp Dense + BM25, rerank BGE-M3, hỗ trợ lọc theo metadata (sheet, file, ...) và trả về trích dẫn. |
| 4 | `query_tables` | SQL DuckDB | Chạy các câu truy vấn SQL phân tích chỉ đọc (`SELECT`, `WITH`, `JOIN`, `GROUP BY`) trên các bảng dữ liệu hoặc View hợp nhất (`v_{doc_id}`). Hỗ trợ cột `_sheet_row` để biết chính xác số dòng Excel. |
| 5 | `aggregate` | SQL DuckDB | API tổng hợp nhanh: đếm (`count`), tính tổng (`sum`), trung bình (`avg`), `min`, `max` theo nhóm cột. |
| 6 | `list_tables` | SQL DuckDB | Liệt kê danh sách toàn bộ các bảng và Unified View trong DuckDB kèm tên cột, kiểu dữ liệu, số dòng và file nguồn. |
| 7 | `find_duplicates` | SQL / Dedupe | Tự động tìm kiếm các bản ghi trùng lặp mã, tài khoản, STK, CCCD, ID xuyên suốt các sheet trong một tài liệu hoặc toàn bộ cơ sở dữ liệu. |
| 8 | `reconcile_summary` | Đối chiếu | Đối chiếu tự động số lượng khai báo trong sheet Tổng Hợp so với các sheet dữ liệu con, phát hiện các sheet bị bỏ sót (`missing_from_summary`) và sai lệch tổng cộng. |
| 9 | `list_documents` | Kiểm tra | Liệt kê toàn bộ tài liệu đã nạp kèm mã băm SHA-256, số chunk vector, số bảng và thời gian nạp. |
| 10 | `get_document` | Kiểm tra | Lấy toàn bộ nội dung chunk, các bảng và thông tin metadata chi tiết của một tài liệu theo `document_id`. |
| 11 | `get_index_status` | Hệ thống | Kiểm tra số lượng vector, số bảng DuckDB, dung lượng và danh sách các thư mục gốc được phép nạp. |
| 12 | `health` | Hệ thống | Kiểm tra kết nối tới Qdrant Vector Store và DuckDB backend. |
| 13 | `get_config` | Hệ thống | Xem cấu hình đang hoạt động của server (các khóa bảo mật tự động được ẩn). |
| 14 | `get_job_status` | Tác vụ ngầm | Kiểm tra trạng thái, tiến độ phần trăm và kết quả của tác vụ index bất đồng bộ theo `job_id`. |

---

## 5. Hướng Dẫn Tích Hợp Chi Tiết Vào Hermes Agent

Dự án hỗ trợ 2 phương thức tích hợp vào **Hermes Agent**:

```
                  ┌─────────────────────────────────────┐
                  │          HERMES AGENT CORE          │
                  └──────────────────┬──────────────────┘
                                     │
           ┌─────────────────────────┴─────────────────────────┐
           ▼                                                   ▼
┌─────────────────────────────┐                     ┌─────────────────────────────┐
│  Cách A: Native User Plugin │                     │    Cách B: Std MCP Server   │
│   (~/.hermes/plugins/...)   │                     │      (config.yaml stdio)    │
│  - hermes plugins enable    │                     │  - Tự động spawn subprocess │
│  - Quản lý qua Desktop GUI  │                     │  - Chuẩn kết nối stdio JSON │
└─────────────────────────────┘                     └─────────────────────────────┘
```

---

### Cách A: Sử dụng Native Hermes Plugin (Khuyến nghị cho CLI & Desktop)

Plugin đã được cài đặt sẵn tại `C:\Users\<user>\AppData\Local\hermes\plugins\document-rag\` (hoặc lưu trong thư mục `plugins/document-rag` của dự án).

#### 1. Kiểm tra & Bật Plugin qua Hermes CLI
```bash
# Xem danh sách plugin (document-rag sẽ xuất hiện trong danh sách)
hermes plugins list

# Bật plugin document-rag
hermes plugins enable document-rag

# Kiểm tra tính toàn vẹn (Diagnostics & Validation)
hermes plugins doctor document-rag
```
*Kết quả `hermes plugins doctor` chuẩn:*
```text
Plugin Doctor: ...\plugins\document-rag
  manifest: document-rag 0.3.0 (standalone)
  OK: runtime discovery, manifest parsing, import, and registration passed
  registrations: 14 tool(s), 0 hook(s)
```

#### 2. Tắt Plugin khi không sử dụng
```bash
hermes plugins disable document-rag
```

---

### Cách B: Khai báo MCP Server trong config.yaml

Nếu bạn muốn cấu hình trực tiếp như một MCP Server độc lập trong file cấu hình của Hermes Agent (`%LOCALAPPDATA%\hermes\config.yaml`):

```yaml
mcp_servers:
  document_rag:
    command: "uv"
    args:
      - "run"
      - "--project"
      - "D:/document-rag-mcp"       # ← Thay bằng đường dẫn tuyệt đối thư mục dự án của bạn
      - "document-rag-mcp"
    env:
      RAG_DOCUMENT_ROOT: "D:/document-rag-mcp/documents"
      QDRANT_URL: "http://localhost:6333"
      DUCKDB_PATH: "D:/document-rag-mcp/data/tables.duckdb"
      RAG_RULES_DIR: "D:/document-rag-mcp/rules"
      RAG_RERANKER_MODEL: "BAAI/bge-reranker-v2-m3"
      DENSE_MODEL: "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
      SPARSE_MODEL: "Qdrant/bm25"
      HYBRID_PREFETCH_LIMIT: "24"
      DEFAULT_LIMIT: "6"
      MAX_LIMIT: "20"
      RAG_LOG_LEVEL: "INFO"
      DOCLING_DO_OCR: "true"
      DOCLING_DO_TABLE_STRUCTURE: "true"
    enabled: true
    timeout: 300
    connect_timeout: 120
    supports_parallel_tool_calls: false
    tools:
      include:
        - index_document
        - index_directory
        - search_documents
        - query_tables
        - aggregate
        - list_tables
        - find_duplicates
        - reconcile_summary
        - list_documents
        - get_document
        - get_index_status
        - health
        - get_config
        - get_job_status
      resources: false
      prompts: false
```

---

### Quản lý trực quan trên giao diện Hermes Desktop

1. Mở ứng dụng **Hermes Desktop**.
2. Điều hướng vào menu **Settings** $\rightarrow$ **Plugins** hoặc **MCP Servers**.
3. Bạn sẽ thấy plugin **`document-rag`** hiển thị với phiên bản `0.3.0` cùng đầy đủ danh sách 14 công cụ.
4. Bạn có thể bật/tắt bằng nút gạt (Toggle switch) trực quan.

---

## 6. Cấu Hình Cho Các Client MCP Khác

### Claude Desktop (`claude_desktop_config.json`)
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "document-rag": {
      "command": "uv",
      "args": [
        "run",
        "--project",
        "D:/document-rag-mcp",
        "document-rag-mcp"
      ],
      "env": {
        "RAG_DOCUMENT_ROOT": "D:/document-rag-mcp/documents",
        "DUCKDB_PATH": "D:/document-rag-mcp/data/tables.duckdb",
        "QDRANT_URL": "http://localhost:6333"
      }
    }
  }
}
```

### Chuẩn Portable Agent Plugins v1 (`agent-plugins.org`)
Dự án đã tích hợp sẵn:
- [`plugin.json`](file:///D:/document-rag-mcp/plugin.json): Khai báo metadata chuẩn quốc tế.
- [`mcp.json`](file:///D:/document-rag-mcp/mcp.json): Khai báo khởi chạy tự động với placeholder `${PLUGIN_ROOT}`.

---

## 7. Kịch Bản & Quy Trình Sử Dụng Mẫu

Dưới đây là ví dụ các câu lệnh thực tế mà AI Agent sẽ thực thi khi làm việc với tài liệu của bạn:

### Kịch bản 1: Nạp & Xác thực một tài liệu mới
**Yêu cầu người dùng**: *"Hãy nạp file báo cáo tài chính quý 3 `reports/q3_finance.xlsx` và kiểm tra xem có lỗi dữ liệu nào không."*

**AI Agent gọi tool**:
```json
index_document({
  "path": "reports/q3_finance.xlsx"
})
```
**Kết quả trả về**:
- `tables_stored: 4` (đã lưu 4 sheet vào DuckDB)
- `chunks_indexed: 18` (đã nhúng 18 đoạn vào Qdrant)
- `validation.status`: `"ok"` (hoặc danh sách cảnh báo nếu phát hiện thiếu dòng, trùng lặp STT).

---

### Kịch bản 2: Hỏi đáp ngữ nghĩa & tìm kiếm có căn cứ
**Yêu cầu người dùng**: *"Chính sách bảo hành và điều khoản thanh toán trong hợp đồng mẫu quy định như thế nào?"*

**AI Agent gọi tool**:
```json
search_documents({
  "query": "chính sách bảo hành và điều khoản thanh toán",
  "limit": 5
})
```
**Kết quả**: Trả về các đoạn trích dẫn kèm điểm tương đồng (reranker score) và căn cứ chính xác `[S1] hop_dong_mau.docx, Điều 5: Thanh toán, dòng 45-60`.

---

### Kịch bản 3: Thống kê & Tính toán số liệu chính xác 100%
**Yêu cầu người dùng**: *"Tổng doanh thu của khu vực Miền Bắc trong bảng dữ liệu là bao nhiêu?"*

**AI Agent gọi tool**:
```json
// Bước 1: Liệt kê các bảng để lấy tên bảng và tên cột
list_tables()

// Bước 2: Chạy câu lệnh SQL chính xác
query_tables({
  "sql": "SELECT SUM(doanh_thu) AS tong_doanh_thu FROM t_a1b2c3d4_0 WHERE khu_vuc = 'Miền Bắc'"
})
```

---

### Kịch bản 4: Nạp thư mục lớn ở chế độ chạy ngầm (Async Background Job)
**Yêu cầu người dùng**: *"Hãy nạp toàn bộ tài liệu trong thư mục `archive/2025/`."*

**AI Agent gọi tool**:
```json
// Bắt đầu tác vụ chạy ngầm
index_directory({
  "dir": "archive/2025",
  "async_index": true
})
// Trả về: { "job_id": "job_987654", "status": "running" }

// Kiểm tra tiến độ
get_job_status({
  "job_id": "job_987654"
})
// Trả về: { "status": "completed", "progress": { "processed": 45, "total": 45 } }
```

---

## 8. Xử Lý Sự Cố & Câu Hỏi Thường Gặp

### ❓ 1. Lỗi: Đường dẫn file nằm ngoài phạm vi (`RAG_DOCUMENT_ROOT`)
- **Nguyên nhân**: Bạn truyền đường dẫn tuyệt đối ở ổ đĩa khác hoặc ngoài thư mục `RAG_DOCUMENT_ROOT`.
- **Khắc phục**: Sao chép file vào thư mục `documents/` (hoặc thư mục đã khai báo trong `RAG_DOCUMENT_ROOT`) và truyền đường dẫn tương đối (ví dụ: `index_document(path="subfolder/file.xlsx")`).

### ❓ 2. Qdrant không kết nối được (`Connection refused`)
- **Khắc phục**: 
  - Nếu dùng Docker: Đảm bảo container đang chạy bằng lệnh `docker compose up -d qdrant`.
  - Nếu dùng local mode không cần Docker: Cấu hình `QDRANT_LOCAL_PATH=./data/qdrant` trong file `.env`.

### ❓ 3. Muốn ép nạp lại file khi nội dung không đổi
- **Khắc phục**: Mặc định hệ thống so sánh SHA-256 để bỏ qua file không đổi nhằm tối ưu tốc độ. Để nạp đè lại, chỉ cần thêm tham số `"force": true` khi gọi `index_document` hoặc `index_directory`.

---

## 9. Cấu Trúc Thư Mục Dự Án

```text
document-rag-mcp/
├── src/document_rag_mcp/
│   ├── server.py              # Entrypoint MCP server (khai báo 12 công cụ)
│   ├── rag.py                 # Pipeline điều phối chính (Extract → Validate → Store → Vector)
│   ├── config.py              # Đọc và resolve cấu hình độc lập CWD
│   ├── models.py              # Cấu trúc DocumentModel, Section, Table
│   ├── errors.py              # Định nghĩa mã lỗi chuẩn hóa
│   ├── utils.py               # Tiện ích tính hash, đường dẫn, text processing
│   ├── extractors/            # Tầng trích xuất đa định dạng
│   │   ├── base.py            #   Lớp trừu tượng BaseExtractor
│   │   ├── xlsx_extractor.py  #   Trích xuất Excel (.xlsx, .xls)
│   │   ├── csv_extractor.py   #   Trích xuất CSV (auto delimiter)
│   │   ├── docx_extractor.py  #   Trích xuất Word (.docx)
│   │   ├── pdf_extractor.py   #   Trích xuất PDF (Docling)
│   │   ├── pptx_extractor.py  #   Trích xuất PowerPoint (.pptx)
│   │   └── text_extractor.py  #   Trích xuất Markdown, TXT, HTML, XML
│   ├── validation/            # Tầng xác thực cấu trúc & dữ liệu
│   │   ├── engine.py          #   ValidationEngine & khử trùng lặp cảnh báo
│   │   ├── schema.py          #   ValidationRule, ValidationIssue schema
│   │   └── structural_rules.py#   Các quy tắc tự động (STT, summary, duplicate key)
│   ├── stores/                # Tầng lưu trữ
│   │   ├── table_store.py     #   DuckDB TableStore (bảo vệ SQL Read-Only)
│   │   └── vector_store.py    #   Qdrant Vector Store wrapper
│   ├── chunkers/              # Tầng chia nhỏ văn bản & bảng biểu
│   │   ├── table_chunker.py   #   Chia bảng (giữ header, row overlap)
│   │   └── text_chunker.py    #   Chia văn bản theo cấu trúc Heading
│   └── jobs/                  # Tầng quản lý tác vụ bất đồng bộ
│       ├── manager.py         #   JobManager (Thread pool)
│       └── worker.py          #   Hàm thực thi indexing worker
├── plugins/                   # Thư mục plugin đóng gói
│   └── document-rag/          #   Native Hermes Plugin (plugin.yaml, __init__.py)
├── rules/                     # Thư mục quy tắc kiểm tra JSON
│   └── _example.json          #   Mẫu khai báo quy tắc
├── documents/                 # Thư mục chứa tài liệu nạp mặc định
├── data/                      # Lưu trữ dữ liệu DuckDB & Qdrant local
├── tests/                     # Bộ kiểm thử tự động
│   ├── run_tests.py           #   Test runner thực thi
│   ├── test_models.py         #   Kiểm thử DocumentModel
│   ├── test_validation.py     #   Kiểm thử các quy tắc validation
│   ├── test_table_store.py    #   Kiểm thử DuckDB CRUD & SQL Read-Only
│   ├── test_chunkers.py       #   Kiểm thử chia đoạn bảng/văn bản
│   └── test_extractors.py     #   Kiểm thử các extractor
├── plugin.json                # Manifest chuẩn Portable Agent Plugins v1
├── mcp.json                   # Cấu hình MCP chuẩn Portable Agent Plugins v1
├── hermes.config.yaml.example # File cấu hình mẫu cho Hermes Agent
└── pyproject.toml             # Cấu hình gói và dependencies
```

---

## 10. Kiểm Thử

Để chạy toàn bộ bộ kiểm thử tự động (23 bài kiểm thử unit tests):

```bash
uv run python tests/run_tests.py
```

**Kết quả kiểm thử chuẩn:**
```text
============================================================
 Running Document RAG MCP Test Suite
============================================================

[test_models]
  [PASS] test_document_model_summary
  [PASS] test_section_hierarchy
  [PASS] test_table_operations

[test_validation]
  [PASS] test_cross_sheet_duplicate_keys
  [PASS] test_data_sheet_with_tong_prefix_not_misclassified_as_summary
  [PASS] test_duplicate_keys
  [PASS] test_filename_vs_content
  [PASS] test_required_any
  [PASS] test_required_not_empty
  [PASS] test_row_count_vs_declared_subsheet_and_grand_total
  [PASS] test_sequence_continuity_duplicate
  [PASS] test_sequence_continuity_gap
  [PASS] test_validation_engine_deduplication
  [PASS] test_validation_engine_with_rules

[test_table_store]
  [PASS] test_settings_path_resolution_independent_of_cwd
  [PASS] test_table_store_crud_and_query
  [PASS] test_table_store_strictly_read_only_queries

[test_chunkers]
  [PASS] test_table_chunker_header_once_and_overlap
  [PASS] test_text_chunker_sections

[test_extractors]
  [PASS] test_csv_extractor
  [PASS] test_markdown_extractor
  [PASS] test_xlsx_extractor_headerless_summary_sheet
  [PASS] test_xlsx_extractor_merged_title_banner

============================================================
 Tests: 23/23 passed (0 failed) in 0.83s
============================================================
```

---

## 📄 Giấy Phép

Dự án được phát hành theo giấy phép [MIT License](LICENSE).

TDQS

A3.7/5.0

Scored across 12 tools

Disambiguation4/5

Most tools target distinct resources or actions, but query_tables and aggregate overlap for table analytics, and get_index_status substantially overlaps with health. Descriptions help clarify intent, but an agent could occasionally select the wrong one.

Naming Consistency4/5

Tool names mostly follow a verb_noun snake_case pattern like list_tables, index_document, and get_config. The main inconsistency is the bare noun 'health' instead of something like 'get_health', and the mix of query/search/aggregate verbs is acceptable but slightly varied.

Tool Count5/5

Twelve tools is well-scoped for a document RAG server covering indexing, retrieval, table querying, and operational status. Each tool serves a credible purpose without feeling bloated or thin.

Completeness4/5

Core workflows are covered: indexing, directory indexing, search, document retrieval, table listing/querying, and status checks. The main gap is the lack of a delete/remove tool for indexed documents or tables, though force re-indexing mitigates updates.

Maintenance

ActivityMaintained
ResponsivenessNo issues