StudyBuddy
README.md
# MCP in 45 Minutes — A Classroom Walkthrough
You've already given the theory. This is the "now let's see it" session.
Two files, ~90 lines of Python total, nothing exotic.
## Setup (5 min, do this before class starts)
```bash
pip install "mcp[cli]==1.29.0"
```
That's the only dependency. Both files run with plain `python3`.
## The three files
| File | Role | What it plays the part of |
|---|---|---|
| `study_buddy_server.py` | MCP **server** | The "tool box" — e.g. a school's database, a weather API, a calculator |
| `simple_client.py` | MCP **client** (scripted) | The "app" that wants to use those tools — calls are hardcoded so you can read the protocol steps in order |
| `interactive_client.py` | MCP **client** (REPL) | Same idea, but it asks *you* which tool to call and for its arguments, live in the terminal |
### About `interactive_client.py`
Run it with:
```bash
python3 interactive_client.py
```
It connects to the server, calls `list_tools()`, and prints whatever tools
come back as a numbered menu — nothing is hardcoded, so if a student adds a
new tool to `study_buddy_server.py`, it just shows up next time this runs.
Pick a number, and for each argument the tool needs it prompts you for a
value (reading the *schema* FastMCP built from the function's type hints —
this is a nice moment to point out that the schema is not hand-written).
Type `q` to quit.
This is the best one to leave running on a projector: it's the closest
students will get to "talking to the server" without wiring up a real LLM,
and it makes the discovery step (menu built live from `list_tools()`)
visually obvious in a way the scripted client doesn't.
## Suggested flow in class
### 1. Read the server first, run nothing yet (10 min)
Open `study_buddy_server.py` on the projector. Walk through it top to bottom:
- `mcp = FastMCP("StudyBuddy")` — creating the server and naming it.
- `@mcp.tool()` — point out this is the *entire* difference between "a Python
function" and "a function an AI can discover and call." Nothing else changes.
- The **docstring** under each function (`"""Roll a dice..."""`) is not just a
comment — the client/model reads this text to decide *when* to use the tool.
This is worth emphasizing: MCP tool descriptions are part of the protocol,
not decoration.
- `mcp.run()` at the bottom — starts the server listening for a connection.
Ask students: "If I wanted to add a tool that looks up tomorrow's weather,
what three things would I need to write?" (a function, a docstring, the
decorator) — this checks they got the pattern.
### 2. Run the server alone (2 min)
```bash
python3 study_buddy_server.py
```
It will appear to hang / do nothing. That's the point — a server on its own
is inert. It's just sitting there waiting for something to talk to it over
stdin/stdout. Ctrl+C to stop.
### 3. Read and run the client (15 min)
Open `simple_client.py`. This is the file that shows the *protocol steps*
explicitly, because normally an AI app hides them from you:
1. **Launch** — `stdio_client(server_params)` starts the server as a
subprocess and opens a pipe to it.
2. **Handshake** — `session.initialize()`. Client and server introduce
themselves and agree on what they support.
3. **Discover** — `session.list_tools()`. The client asks "what can you do?"
and gets back the tool names + docstrings + expected inputs.
4. **Call** — `session.call_tool("roll_dice", {"sides": 20})`. The client
asks the server to actually run one specific tool with specific
arguments, and gets a result back.
Run it:
```bash
python3 simple_client.py
```
Point out: **no AI model was involved anywhere in this script.** We (the
humans) hardcoded which tool to call. That's deliberate — it isolates "what
MCP does" from "what an LLM adds on top," which is normally where the
confusion is. The LLM's job in a real app is just step 4: deciding *which*
tool to call and *what arguments* to pass, based on the tool descriptions
from step 3 and the user's message.
### 4. Live-code a new tool together (10 min)
Add a fourth tool to `study_buddy_server.py` as a class, e.g.:
```python
@mcp.tool()
def word_of_the_day() -> str:
"""Return a random vocabulary word with its definition."""
words = {
"ephemeral": "lasting for a very short time",
"resilient": "able to recover quickly from difficulty",
"lucid": "clear and easy to understand",
}
word, definition = random.choice(list(words.items()))
return f"{word}: {definition}"
```
Then add one line to `simple_client.py` to call it, and re-run. This is the
moment that usually makes it click: adding a capability took one decorator
and zero protocol code.
### 5. Bonus, if time allows: connect it to Claude Desktop
If any students have Claude Desktop installed, show them that the *same*
`study_buddy_server.py` file can be registered in Claude Desktop's config
(`claude_desktop_config.json`) instead of `simple_client.py`, and then Claude
itself — not a hardcoded script — decides when to roll a dice or quiz them,
based on what they type in chat. This is the "aha": the server code never
changes, only who's driving the client side.
## Key takeaway to write on the board
> MCP doesn't make the AI smarter. It gives the AI a standard way to discover
> and call tools it doesn't know about in advance — so anyone can plug new
> capabilities into any AI app without custom integration code.This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues