Skip to main content
Glama
Sujith29k

MCP RAG Server

by Sujith29k
README.md
# MCP RAG

MCP server that owns the full RAG pipeline, plus a small web client for uploading PDFs and asking questions.

## Layout

```
src/mcp_rag/
  server/     MCP tools: ingest, index, search, ask
  client/     FastAPI UI: upload files, ask questions
data/docs/    PDF corpus (owned by the MCP server)
data/faiss_index/   cached embeddings
```

```
PDFs uploaded in the client
        │
        ▼
MCP server (:8001/mcp)
  ingest → chunk → embed → FAISS
  retrieve → generate (OpenAI / LangGraph)
        │  Streamable HTTP
        ▼
Web client (:8000)
  upload / delete / ask
```

## Requirements

- Python **3.10+** (3.12 recommended)
- [uv](https://docs.astral.sh/uv/)
- An OpenAI API key

## Setup

```bash
uv sync
copy .env.example .env   # or: cp .env.example .env
```

Put your OpenAI key in `.env`. Optional sample PDFs:

```bash
uv run python scripts/make_sample_pdfs.py
```

## Run

Terminal 1 — MCP server (RAG):

```bash
uv run python -m mcp_rag.server
```

Terminal 2 — web client:

```bash
uv run python -m mcp_rag.client
```

Open [http://127.0.0.1:8000](http://127.0.0.1:8000). Upload PDFs, then ask questions.

On Windows you can also use `scripts\run_server.bat` and `scripts\run_client.bat`.

## MCP tools

| Tool | Purpose |
| --- | --- |
| `ingest_document` | Add a PDF (base64) and rebuild the index |
| `delete_document` | Remove a PDF and rebuild the index |
| `ensure_index` | Build or reuse the FAISS index |
| `search_documents` | Semantic search over chunks |
| `ask_question` | Retrieve + generate a grounded answer |
| `list_documents` | List PDFs in the corpus |
| `index_status` | Index readiness and chunk count |

## Client API

| Method | Path | Purpose |
| --- | --- | --- |
| `GET` | `/api/health` | Client + MCP status |
| `GET` | `/api/documents` | List PDFs |
| `POST` | `/api/upload` | Multipart PDF upload |
| `DELETE` | `/api/documents/{name}` | Remove a PDF |
| `POST` | `/api/reindex?force=true` | Rebuild FAISS index |
| `POST` | `/api/ask` | `{"question":"..."}` → answer + sources |