Skip to main content
Glama
iamaries73

Project 5 MCP Server

by iamaries73
README.md
# Project 5 — First MCP Server

A **task kitchen** behind **MCP**, plus a Groq assistant that calls those tools through the protocol — not by importing the kitchen.

Project 4 imported `tasks.py`. Project 5 puts the same kind of functions in another layer: an MCP server. Any client (a test script, or Groq) can discover and call them.

```text
You
  → assistant.py          Groq loop + ALLOWED lock
       → Client(mcp)      MCP client (official SDK v2)
            → server.py   MCP server (MCPServer)
                 → kitchen.py
                      → data/tasks.json
```

Related repos:

- [project-1-first-agent](https://github.com/iamaries73/project-1-first-agent)
- [project-2-second-agent](https://github.com/iamaries73/project-2-second-agent)
- [project-3-research-team](https://github.com/iamaries73/project-3-research-team)
- [project-4-personal-assistant](https://github.com/iamaries73/project-4-personal-assistant)

---

## What you will learn

- What MCP is (a standard plug for tools)
- MCP **server** vs MCP **client**
- Why the cook (`kitchen.py`) and the plug (`server.py`) are separate files
- Official Python SDK **v2**: `MCPServer`, not the old `FastMCP` import
- Tool discovery: `list_tools()` then Groq schemas
- Permissions still live in Python (`ALLOWED`)

---

## What this is not

- Not Gmail / Calendar
- Not multiple agents (that is Project 6)
- Not OpenClaw
- Not Streamlit (optional later)

---

## MCP 2.x note

`pip install mcp` now installs **2.x**.

```text
Wrong (v1):  from mcp.server.fastmcp import FastMCP
Right (v2):  from mcp.server import MCPServer
```

`@mcp.tool()` is unchanged. Pin `mcp<2` only if you must run old tutorials.

---

## Requirements

- Python 3.12+
- Groq key in `.env` as `GROQ_API_KEY` (for `assistant.py` only)
- Packages: `mcp[cli]`, `openai`, `python-dotenv`

---

## Setup

```bash
cd ~/Desktop/projects/project-5-mcp-server
python3.12 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp ~/Desktop/projects/project-1-first-agent/.env .
```

`.env` is required only for the Groq assistant. `kitchen.py` and `client.py` do not need a key.

Never commit `.env` or `data/`.

---

## Project structure

```text
project-5-mcp-server/
├── kitchen.py       # cook — add / list / complete, writes JSON
├── server.py        # plug — MCPServer + @mcp.tool wrappers
├── client.py        # test waiter — no Groq
├── assistant.py     # talking waiter — Groq + MCP
├── requirements.txt
├── .gitignore
├── .env             # local only
└── data/            # local only
    └── tasks.json
```

---

## How to think about the files

| File | Room | Needs Groq? |
|---|---|---|
| `kitchen.py` | Cook | No |
| `server.py` | Plug / menu | No |
| `client.py` | Silent waiter | No |
| `assistant.py` | Talking waiter | Yes |

If the cook is broken, fix `kitchen.py`.  
If the menu is wrong, fix `server.py`.  
If Groq never calls a tool, fix the prompt / schemas.  
Do not debug all three at once.

---

## Run tests in order

### 1. Kitchen only

```bash
python kitchen.py
cat data/tasks.json
```

### 2. Silent client (starts the server in-process)

```bash
python client.py
```

You should see tool names and a new task in `data/tasks.json`.

Do **not** leave `python server.py` running in another window for these tests. `Client(mcp)` talks to the server object in the same process. `python server.py` alone waits on stdio; `Control+C` prints a `KeyboardInterrupt` — that is normal.

### 3. Groq assistant

```bash
python assistant.py
```

```text
Add a task to buy milk
List my tasks
Complete task 3
```

Look for:

```text
[loop] discovered tools: ['tool_add_task', 'tool_list_tasks', 'tool_complete_task']
[loop] round 1: tool_add_task(...)
[loop] result: ...
```

`INFO HTTP Request ... groq.com` lines are just API traffic.

---

## Environment

| Name | Required for | Purpose |
|---|---|---|
| `GROQ_API_KEY` | `assistant.py` | Model calls |

API base: `https://api.groq.com/openai/v1`  
Model: `openai/gpt-oss-20b`

---

## Security

- Key only in `.env`
- Tasks only under `data/`
- `.gitignore` lists `.env`, `.venv/`, `data/`
- `ALLOWED` in `assistant.py` is the lock. The model is not.
- This server is local and in-process. Do not expose it on the public internet in this slice.

---

## Troubleshooting

| Symptom | Cause | Fix |
|---|---|---|
| `No module named mcp.server.fastmcp` | SDK v2 rename | `from mcp.server import MCPServer` |
| `No module named openai` | New venv | `pip install openai python-dotenv` |
| Missing credentials | No `.env` in this folder | Copy `.env` from Project 1 |
| `python server.py` then a huge traceback after Ctrl+C | You stopped stdio | Expected `KeyboardInterrupt` |
| Model talks, no `[loop]` tool line | Tool not chosen | Stronger system prompt |
| `Permission denied` | Name not in `ALLOWED` | Add the exact MCP tool name |
| Kitchen works, assistant does not write JSON | Tool never called | Read `[loop]`, not the chat sentence |

---

## GitHub

Public repo name: `project-5-mcp-server`

Push code only. Never push `.env` or `data/tasks.json`.

---

## Next

Project 6: more than one agent sharing this (or another) MCP server.  
Do not add email here. The plug is the lesson.