Skip to the content.

MCP RAG from scratch

MCP RAG from scratch

English · 日本語

This is hands-on material for writing MCP and RAG yourself and understanding how they work.

If you have ever wanted to build your own MCP server — see what the Model Context Protocol actually sends on the wire, understand how JSON-RPC and tool calling fit together, or learn RAG by working through a small but real example — this course is for you. It covers ChromaDB vector search, sentence embeddings, and running a local LLM with Ollama, all on your own machine.

You may have used an MCP-capable tool, but what happens inside is not visible. In this project, you write both the client and the server yourself. We go as far as assembling the JSON-RPC messages by hand, one line at a time.

Everything stays local, and no API key is needed.


Documentation

# Page Contents
1 What you need and installing Docker Checking the resources you need, and installing Docker
2 Docker primer Containers, images, volumes, Compose. Skippable if you are used to it
3 Setting up a working environment The two containers, where the data lives, day-to-day operations, checking that it works
4 Running ChromaDB Reading and running the Step 1 code
5 Building the database and preparing a search function Building it on disk ahead of time, and preparing search()
6 Speaking MCP in raw JSON-RPC Step 2. Looking at the protocol one line at a time
7 Writing MCP with the SDK Step 3. Writing the server and the client in code
8 Setting up Ollama Downloading the model, and checking that it works on its own
9 The relationship between MCP and Ollama The structure of the whole. How the LLM chooses a tool
10 Completing RAG Step 4. Putting the LLM on, and the whole thing connects
11 Running the finished version interactively Running the interactive client in src/, and looking back over the whole

1 goes as far as installing Docker. 2 is a primer on Docker itself, and this project does not appear in it. You can skip it if you are used to Docker.

In 3 you set up the environment and confirm it as far as pytest passing.

4 and 5 are ChromaDB. They stop at the extent needed for reading MCP. Read through 5, and the search side is complete; MCP starts from Step 2.

6 and 7 are the heart of MCP. From 8 through 10 you put the LLM on, and in 11 you make it interactive.


The code you run

Alongside the chapters, we provide a single file that runs independently for each stage. As you read, run the corresponding Step.

Step File What it builds LLM
1 steps/01_chromadb.py ChromaDB — put documents in, and take out the ones close to a question Not needed
2 steps/02_mcp_raw.py MCP — call that search from another process, in raw JSON-RPC Not needed
3 steps/03_mcp_sdk.py MCP — write the same thing with the official SDK Not needed
4 steps/04_rag.py RAG — hand the retrieved documents to the LLM and have it write the answer Needed

How to run it

Running and testing happen in a Docker Ubuntu container.

docker compose up -d
docker compose exec app uv run python steps/01_chromadb.py

For setting up the environment, handling Ollama, and what to do when you run into trouble, see What you need and installing Docker. If you are unfamiliar with Docker itself, Docker primer comes first.


What is being searched

The 7 material files of the fictional cafe The Wandering Kettle, in data/documents/.

allergens.txt      faq.txt           hours_access.txt
menu_drinks.txt    menu_food.txt     staff_handbook.txt
story.txt

The menu, opening hours, FAQ, allergy information, notes for staff, and how the shop came about.

The reason it is a shop that does not exist is that if the LLM answers from knowledge it has already learned, you can no longer tell whether the search is working.

The data is in English, but you can look things up by asking in Japanese too. That is because we use a multilingual embedding model, and this in itself makes for an easy-to-grasp demonstration that “vector search is not keyword matching”.

docker compose exec app uv run python tools/query_chromadb.py
query> 犬を連れて行ってもいいですか?

--- Search results (1 items) ---
  [1] distance=0.2449  source=faq.txt
      CAN I STAY AND WORK?

The Wandering Kettle - Questions We Get Asked
...

Asked in Japanese, and the English faq.txt was retrieved. Since one file is one item, what comes back is the whole file. The part about dogs is inside it.

Swap out the .txt files in data/documents/, and it becomes a search tool for a different purpose as it is.


Tech stack

Category What is used
Language Python 3.11+
MCP The mcp official Python SDK v2
Vector DB ChromaDB
Embedding model intfloat/multilingual-e5-small
LLM Ollama (Step 4 only)
Package management uv
Runtime environment Docker (Ubuntu 24.04)

Tests

docker compose exec app uv run pytest

They all pass even without Ollama.