Skip to main content
Glama
README.md
# rag-starter — chat with your documents (RAG), with citations

[![rag-starter MCP server](https://glama.ai/mcp/servers/cstamigo-droid/rag-starter/badges/score.svg)](https://glama.ai/mcp/servers/cstamigo-droid/rag-starter)

[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) [![Python](https://img.shields.io/badge/Python-3.10%2B-3776AB.svg?logo=python&logoColor=white)](https://www.python.org) [![MCP](https://img.shields.io/badge/Model_Context_Protocol-server-7C3AED.svg)](https://modelcontextprotocol.io)

A production-ready starter that turns a folder of documents into a **cited Q&A
service**. Drop in your PDFs / Markdown / text, ask questions, get answers grounded
in the source — every claim traceable to the exact passage it came from.

Exposed two ways from one codebase:
- **MCP server** — plug it into Claude Desktop / Claude Code / any MCP host and chat with your docs.
- **HTTP API** (FastAPI) — call it from any app.

> Built once, reskinned per client. Swap the `data/` folder, tweak `config.py`, ship.

## Why it's different
- **Keyless by default.** Embeddings run locally (ONNX MiniLM) — no API key, no per-query cost, runs offline. Demo it anywhere in seconds.
- **Citations, not hallucinations.** Retrieval returns ranked passages tagged `[source#chunk]` / `[file.pdf p3]`. A missing answer returns *"Not found in the documents"* — never a fabricated one.
- **Answer synthesis is optional.** With an `ANTHROPIC_API_KEY` it writes a cited answer for you; without one it returns passages for the host LLM to answer. Either way the RAG works.
- **Idempotent ingestion.** Re-ingesting a file updates it in place (no duplicates).

## Quickstart

```bash
pip install -r requirements.txt          # or: pip install -e .
PYTHONUTF8=1 python tests/test_smoke.py   # proves retrieval works on the sample docs
```

### As an HTTP API
```bash
rag-starter-api            # uvicorn on 127.0.0.1:8000
# then:
curl -X POST localhost:8000/ingest  -H "content-type: application/json" -d '{"path":"./data"}'
curl -X POST localhost:8000/search  -H "content-type: application/json" -d '{"query":"refund policy"}'
curl -X POST localhost:8000/answer  -H "content-type: application/json" -d '{"query":"how long is the refund window?"}'
```

### As an MCP server (Claude Desktop)
Add to `claude_desktop_config.json` → `mcpServers`:
```json
{
  "rag-starter": {
    "command": "python",
    "args": ["-m", "rag_starter"],
    "cwd": "C:/path/to/rag-starter"
  }
}
```
Restart Claude Desktop, then: *"Ingest the folder ./data"*, then *"What's the refund policy?"*

## Tools / endpoints
| MCP tool | HTTP | Purpose |
|----------|------|---------|
| `rag_ingest(path)` | `POST /ingest` | Index a file or folder (txt/md/pdf). |
| `rag_search(query, k)` | `POST /search` | Top-k cited passages (keyless). |
| `rag_answer(query, k)` | `POST /answer` | Cited answer (with key) or passages (without). |
| — | `GET /health` | Liveness + indexed-chunk count + embedding backend. |

## Configuration
Everything is in `config.py` (or env / `.env` — see `.env.example`): chunk size & overlap,
top-k, embedding backend (`default` local vs `openai`), and the answer model. A client
reskin is usually just: replace `data/`, set `RAG_COLLECTION`, re-ingest.

## Architecture
```
documents ──ingest.py──> chunks(+citations) ──store.py──> Chroma (local, persistent)
                                                              │
question ─────────────────retrieve.py──> top-k cited passages┤
                                                              ├─> rag_search  (host LLM answers)
                                                  answer.py ──┴─> rag_answer  (server synthesizes, optional)
```
Reuses the mcp-factory contract (`Result`, `formatting`, `cache`) so it composes with the
rest of the catalog.

## License
MIT.

TDQS

A3.7/5.0

Scored across 3 tools

Disambiguation4/5

The three tools map to distinct lifecycle stages (index, retrieve, synthesize), but rag_search and rag_answer overlap: both take a query and can return ranked passages, since rag_answer falls back to passages without an API key. The descriptions do clarify the difference, so confusion is limited.

Naming Consistency5/5

All tools use a consistent rag_ prefix followed by a clear verb (ingest, search, answer) in uniform snake_case. The pattern is predictable and immediately readable.

Tool Count4/5

Three tools is a tight, well-scoped set for a RAG starter, each earning its place. It is at the lower end but appropriately minimal for the stated purpose.

Completeness3/5

The core ingest-search-answer flow is covered, but there is no way to remove, delete, or list indexed documents, and no re-index/update operation. These gaps around document lifecycle management could force agents to work around stale content.

Maintenance

ActivityMaintained
ResponsivenessNo issues