rag-simplified
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@rag-simplifiedwhy is chunk size a trade-off? answer from my knowledge base"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
RAG, Simplified
Learn how Retrieval-Augmented Generation actually works — then run one.
An interactive, animated lab that takes RAG apart stage by stage, over a real index you can query. Every knob is live; the whole engine is a few hundred readable lines. No cloud, no API keys, runs entirely on your machine.
Features · Quickstart · How it works · Web UI · MCP for agents · Repo tour · Roadmap
What this is
Most RAG explainers show a diagram and a black box. This one shows the diagram, then lets you open the box: query a real index, toggle dense vs. keyword search, watch documents climb through fusion and reranking, and see the embedding space the retriever searches.
It is two things at once:
A course. Seven short, precise chapters covering chunking, embeddings, vector search, hybrid retrieval, fusion, reranking, and the failure modes.
A working product. A real hybrid RAG engine (dense + BM25 + RRF + a cross-encoder), a FastAPI server, an animated web UI, and an MCP server so agents can query it as a tool.
documents ──✂──▶ chunks ──🧮──▶ vectors
│
▼
[ index ] ← the offline half
▲
│
question ──🎯──▶ retrieve ─────────┘
│ dense + BM25 → RRF → rerank
▼
augment prompt ──▶ LLM ──▶ answer ← the online halfThe one rule this project teaches: the retrieval is the product. Everything else is plumbing around it.
Related MCP server: RAG Chatbot MCP Server
Features
Real hybrid retrieval — dense embeddings + BM25 keyword search, fused with Reciprocal Rank Fusion, then re-scored by a cross-encoder reranker.
Live playground — toggle each technique on/off and watch the ranking change.
Pipeline view — every query shows all four stages (dense / BM25 / fused / reranked) side by side, so you see fusion and reranking do their job.
Embedding-space map — the real 384-dim vectors projected to 2D with PCA; your query lands and its nearest neighbours light up.
Index any website — point it at a docs site and crawl it into the corpus.
Pluggable sources — bundled docs, a website crawler, and two Learn Anything adapters (a local export, and the mirrored
linsa-iomarkdown corpus); add your own in ~15 lines.MCP server — expose search/answer as tools to Claude, Cursor, Hermes, any MCP client.
Works with zero setup — no LLM? It still answers by returning the best passages. Add a local LLM and generation turns on automatically.
Quickstart
git clone https://github.com/Nilabh-code/rag-simplified
cd rag-simplified
python -m venv .venv && . .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
python -m engine.cli ingest # build the index
python -m engine.cli serve --port 8320 # open http://127.0.0.1:8320First run downloads two small models (an embedding model ~90 MB and a reranker ~90 MB). After that it is fully offline.
Prefer the terminal?
python -m engine.cli query "why is chunk size a trade-off?"
python -m engine.cli query "combine keyword and semantic search" --trace # show every stage
python -m engine.cli query "what is reranking?" --answer # retrieve + generateHow it works
The pipeline is a funnel. Cheap, high-recall stages first; an expensive, high-precision stage last.
# | Stage | File | What it does |
1 | Ingest |
| sources → documents → chunks → embeddings → index |
2 | Chunk |
| split text on paragraph boundaries, ~900-char windows with overlap |
3 | Embed |
| text → 384-dim vector where meaning is distance (L2-normalised) |
4 | Store |
|
|
5 | Retrieve |
| dense + BM25 → RRF fuse → cross-encoder rerank → diversify |
6 | Answer |
| paste the top chunks into the prompt; answer only from them |
7 | Visualise |
| PCA of the real vectors so you can see the space |
Why each technique exists:
Dense search matches meaning ("stale price" finds "outdated quote") but blurs exact tokens like
alg=none.BM25 nails exact tokens but cannot match synonyms.
RRF fuses the two ranked lists by rank, so two incomparable score scales can be combined fairly.
Reranking runs a cross-encoder over the shortlist — reading query and document together — so the genuinely best chunk lands at rank 1.
The web UI
python -m engine.cli serve then open http://127.0.0.1:8320. You get:
a playground with per-technique toggles and a top-k slider,
the pipeline view animating all four retrieval stages for your query,
the embedding-space map with your query and its nearest neighbours,
a corpus panel that lists what's indexed and lets you crawl a website,
and an answer panel showing the exact augmented prompt sent to the LLM.
Index learn-anything.xyz (the real corpus)
learn-anything.xyz is a JavaScript SPA behind Clerk
auth — every route returns the same empty shell, there is no public API and no
sitemap, so the site itself cannot be crawled. But the knowledge it is built from
is public markdown: the linsa-io GitHub org (where github.com/learn-anything
301-redirects) holds the curated-list repos (books, courses, websites, research
papers, …) and the archived Obsidian topic vault — thousands of interlinked
notes forming a genuine link graph.
scripts/fetch_learn_anything.py mirrors that graph: it seeds from the hub and the
vault, downloads each file's raw markdown, and follows every markdown link it
finds, recursing until the frontier is empty (explicit .md links and repo
readmes; pass --follow-repos to also chase every bare repo link).
export GITHUB_TOKEN=$(gh auth token) # lifts GitHub API rate limits
python scripts/fetch_learn_anything.py # -> data/corpus/learn-anything/
python -m engine.cli ingest # bundles it into the indexThe mirror lands as <repo>/<path>.md with _manifest.jsonl (file→URL map) and
_links.jsonl (the link-graph edge list). engine/sources/learn_anything_vault.py
reads it as the learn-anything-vault source, which the CLI, API and MCP server all
include automatically once a mirror exists.
Index any website
python -m engine.cli ingest --url https://en.wikipedia.org/wiki/Retrieval-augmented_generation --max-pages 25Or use the corpus panel in the web UI. The crawler is same-domain and capped; bundled docs stay in the index.
Use it from an agent (MCP)
The engine ships an MCP server, so any MCP-capable agent can search and answer over your knowledge base as tools.
python -m engine.mcp_server # stdio (for local clients)
python -m engine.mcp_server --http --port 8321 # HTTP for remote clientsRegister it (e.g. claude_desktop_config.json):
{
"mcpServers": {
"rag-simplified": {
"command": "python",
"args": ["-m", "engine.mcp_server"],
"cwd": "/absolute/path/to/rag-simplified"
}
}
}Tools exposed: rag_query, rag_answer, rag_stats, rag_corpus,
rag_add_website.
Repo tour — your learning path
Read the repo in this order; each file teaches one idea.
engine/
chunking.py text → chunks (why chunk? size, overlap)
embeddings.py chunks/questions → vectors (meaning as distance)
store.py save/load the index (the row-order contract)
retriever.py vectors → best chunks (dense + BM25 + RRF + rerank)
answer.py chunks → grounded answer (the "G" in RAG + prompt)
visualize.py 384-dim → 2D (PCA, so you can see it)
ingest.py the offline half, wired end to end
api.py HTTP server for the UI
cli.py ingest / query / serve / stats
sources/ where documents come from (pluggable)
scripts/
fetch_learn_anything.py mirror the learn-anything.xyz markdown link graph
web/ the animated, interactive front-end
data/corpus/ the bundled learning chapters (also a retrievable corpus)
mcp/ MCP setup notes
tests/ chunking units + an end-to-end ingest→query testThe data/corpus/*.md files are both the course and the corpus — the app
retrieves from the same chapters you read. Ask it "why is reranking useful?" and
the answer comes back from chapter 6.
Configuration
Everything tunable lives in config.json:
{
"embed_model": "sentence-transformers/all-MiniLM-L6-v2",
"rerank_model": "cross-encoder/ms-marco-MiniLM-L6-v2",
"chunk_size": 900,
"chunk_overlap": 120,
"top_k": 5,
"rerank": true
}Change chunk_size, re-run ingest, and watch retrieval move — chunk size is
the dial people most underestimate.
Roadmap
Swap brute-force search for an ANN index (HNSW / FAISS) at scale.
Evaluation harness: a golden set, Recall@k, MRR, answer faithfulness.
More sources: PDF, GitHub repos, Notion, an RSS watcher.
Async ingest with live progress in the UI.
More embedding/reranker models selectable from the UI.
Contributing
Issues and PRs welcome — especially new sources, more course chapters, and
evaluation tooling. See CONTRIBUTING.md.
License
MIT © 2026 Nilabh Yadav — see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
Persistent memory, hybrid search and a goal graph for AI agents, over stdio or remote HTTP.
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceLocal MCP server for indexing personal knowledge into SQLite with hybrid search, chunk-level citations, memory tools, and agent orchestration.4MIT
- FlicenseNot gradedqualityCmaintenanceExposes a local RAG document index as MCP tools (ask, search, rebuild_index, status) for MCP clients like Claude Desktop and Claude Code to query your documents over stdio.-
- AlicenseNot gradedqualityBmaintenanceEnables fully local retrieval over a personal document corpus via hybrid search, cross-encoder reranking, RAPTOR summaries, and knowledge graph queries, served to AI agents over MCP.MIT
- AlicenseNot gradedqualityBmaintenanceLocal RAG MCP server for documentation that indexes markdown repos (local paths or git URLs) and provides retrieval-only tools (ask_docs, list_docs, reindex) returning grounded passages and citations for the MCP host to synthesize answers.MIT