Skip to main content
Glama
README.md
# mcp-poc

A small [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that
exposes the retrieval step of the sibling [rag-poc](https://github.com/RenoLu/rag-from-scratch)
project as an MCP tool — "RAG over MCP."

MCP is a standard way to give an LLM client (Claude Code, Claude Desktop, …) access
to tools that live outside the model. Here the pattern is deliberate: the server
does **retrieval only** — it embeds your query, finds the most similar chunks in
rag-poc's local vector store, and hands them back. The **client's model does the
generation**, reading those chunks and writing a grounded, cited answer. The server
never calls a chat model.

## The tool

| Tool | Signature | What it does |
|------|-----------|--------------|
| `rag_search` | `(query: str, k: int = 4) -> list[dict]` | Embeds `query` with the same local Ollama model that built the store, cosine-ranks the stored chunks, and returns the top `k` as `{source, score, text}` (most similar first). |

The model calling it is expected to answer from the returned chunks and cite each
`source`, or say it doesn't know if they don't contain the answer.

## How it connects to rag-poc

This repo doesn't reimplement RAG — it imports rag-poc's `rag` package. The server
puts the rag-poc folder on `sys.path` and reuses its vector store, query embedder,
and input-sanitising hook. By default it expects rag-poc as a **sibling folder**
(`../rag-poc`); point elsewhere with the `RAG_POC_PATH` environment variable. The
store is read from `RAG_POC_PATH/store.npz`.

## Prerequisites

- **Ollama** running at `localhost:11434` with the `nomic-embed-text` model pulled
  (`ollama pull nomic-embed-text`). The query must be embedded by the *same* model
  that embedded the documents.
- **rag-poc ingested** so its store exists — in the rag-poc folder: `python main.py ingest`.

## Setup

```powershell
cd "C:\Coding Space\mcp-poc"
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
```

## Test it — two ways

**1. MCP Inspector (no Claude needed):**

```powershell
mcp dev server.py
```

Open the printed URL, pick `rag_search`, enter a query (e.g. *"What is retrieval-augmented generation?"*),
and inspect the returned chunks with their similarity scores.

**2. From Claude Code.** Register the server so `rag_search` appears in your session:

```powershell
claude mcp add mcp-poc -- "C:\Coding Space\mcp-poc\.venv\Scripts\python.exe" "C:\Coding Space\mcp-poc\server.py"
```

If rag-poc is **not** a sibling of this repo, pass its location when registering:

```powershell
claude mcp add mcp-poc --env RAG_POC_PATH="C:\path\to\rag-poc" -- "C:\Coding Space\mcp-poc\.venv\Scripts\python.exe" "C:\Coding Space\mcp-poc\server.py"
```

Then `/mcp` lists connected servers, and you can ask a question about your indexed
docs — Claude will call `rag_search`, pull the relevant chunks, and answer from them.
Remove it with `claude mcp remove mcp-poc`.

## Next steps

- Add a `rag_answer` tool that runs rag-poc's full local pipeline (Ollama generation)
  to compare "the client model generates" vs "the local model generates."
- Expose the indexed documents as MCP **resources**, or add a **prompt** template for
  a standard "answer with citations" instruction.