Build
The capstone project
Your server works, on your machine, because you've been running it from inside this project folder with your own uv environment. Today's job is to check that claim: could a stranger clone this repo and get it running without asking you a single question?
The MCP inspector: debugging without claude desktop in the loop
Up to now you've tested every change by restarting Claude Desktop and asking it a question — slow, and it conflates "is my tool broken" with "did Claude decide to call it." The MCP Inspector removes the model from that loop entirely.
mcp dev server.py
mcp dev (from the mcp[cli] extra you installed in Lesson 2) launches a web UI where you can call any tool directly with explicit arguments, see the raw response, and inspect your resources and prompts -- all without Claude Desktop, without wondering whether a bad result is your tool's fault or the model's tool-selection. This should have been your first move whenever something seemed broken in earlier lessons; it's the direct equivalent of testing a REST endpoint with curl instead of only through the UI that calls it.
Use the Inspector before you touch Claude Desktop again
Every "it doesn't work" moment from Lessons 2-5 could have been diagnosed faster in the Inspector: call the tool directly, see if IT returns the right thing. If yes, the problem was tool-selection/description (a Claude Desktop-side question). If no, the problem is your code (an Inspector-side question). This single habit collapses "is it my code or is it the model" into a 10-second check.
Packaging: README, pyproject.toml, and one honest test
The real test is a directory that doesn't already work
Testing your own install by running it again in the same folder you developed in proves nothing -- your uv environment, your seeded database, your ~/mcp-toolkit-workspace directory all already exist. Copy the project to a genuinely fresh directory (or better, have someone else clone your repo), run only the commands your README says to run, and see what breaks. Almost every packaging gap surfaces this way and nowhere else.
A README for this server needs, at minimum: prerequisites (Python/uv version), install commands (uv sync), the exact claude_desktop_config.json snippet to add (with a placeholder for the absolute path, clearly marked), the seed command (uv run seed_db.py), and — critically, since Lesson 3's notify tool needs it — a line about setting NOTIFY_WEBHOOK_URL before the notification tool will work.
You test your own install in a fresh directory and it works — but only because you forgot you still have NOTIFY_WEBHOOK_URL set as a shell environment variable from earlier testing, not because your README mentions it. What's the actual state of your packaging?
A fresh directory controls for stale files (leftover venvs, databases, workspace folders) but not stale shell state -- environment variables persist across directories in the same terminal session. The only way to catch this specific gap is to test in a genuinely clean shell (a new terminal window with nothing exported) or, better, have someone else who was never in your shell run the install from your README alone.
Ship it
Push to GitHub, and do the fresh-directory (or better: someone-else's-machine) test for real before you call this done. That's the actual capstone deliverable — not "the code works," but "the instructions work, for someone who is not you."
Ship Prompt: Post your 5 tools + a screenshot of Claude using at least 3 of them in one conversation. What would tool #6 be if you kept going?