Module 10 Exercises: Claude Code Mastery
These five exercises progress from mechanical practice (write a file) to synthesis (interview simulation). Complete them in order — each builds on the previous one’s concepts.
Exercise 1: Write a CLAUDE.md for a Hypothetical FastAPI Project
Skill practiced: Understanding what Claude needs to work effectively in a project; CLAUDE.md structure and content selection.
Setup: Imagine you are the lead developer of AuthService — a FastAPI microservice that handles user authentication. It has:
- Python 3.12, FastAPI 0.111, SQLAlchemy 2.0 async
- PostgreSQL 15 (dev via Docker, prod via AWS RDS)
- pytest + httpx for async testing
- Poetry for dependency management
- Alembic for database migrations
- GitHub Actions for CI
- A
src/layout withrouters/,services/,repositories/,models/,schemas/ - A
Makefilewith targets:test,lint,migrate,dev - Coding conventions: dependency injection for DB sessions, repository pattern (no DB access in services), Pydantic v2 schemas for all request/response types
Task: Write a complete CLAUDE.md for this project. Your file should include:
- Project overview — what it does, stack, language version
- Setup commands — from fresh clone to running locally (include Docker for Postgres)
- Common commands — test, lint, type-check, dev server, migrations
- Project structure — annotated directory tree showing what lives where
- Architecture conventions — the patterns Claude must follow when adding code
- Coding style — what is enforced by tooling vs what is convention
- Known gotchas — at least two things that would trip up a developer new to this codebase
- Out-of-scope for CLAUDE.md — write a brief comment at the top or bottom explaining what you deliberately left out and why
Evaluation criteria:
- A Claude instance reading only this file should be able to run the project and write a new endpoint without asking questions
- No secrets or personal preferences present
- Directory structure is accurate and annotated
- Conventions are actionable (not vague like “write clean code”)
Stretch goal: Write a second src/CLAUDE.md that focuses specifically on conventions for the src/ directory — things that are too detailed for the root file but important for anyone writing application code.
Exercise 2: Write a Hook That Blocks SQL DROP TABLE Commands
Skill practiced: Hook anatomy, PreToolUse pattern, stdin JSON parsing, exit code semantics, writing actionable error messages for Claude.
Task: Write a PreToolUse bash hook script that:
- Reads the JSON payload from stdin
- Checks whether the tool is
Bash(ormcp__postgres__execute/mcp__postgres__query) - Inspects the command/query string for any of these dangerous SQL patterns (case-insensitive):
DROP TABLEDROP DATABASETRUNCATE TABLEDELETE FROMwithout aWHEREclause (optional stretch)
- If a dangerous pattern is found: exits with code 1 and writes a clear, actionable error message to stderr
- If no dangerous pattern: exits with code 0
Requirements:
- Script must have a proper shebang (
#!/bin/bash) - Must handle the case where
jqis not installed (exit 0 with a warning, do not crash) - Must handle null or missing tool input fields gracefully
- Error message must explain what was blocked AND suggest a safer alternative
- Must work correctly when the command is entirely unrelated to SQL (should pass through silently)
Test cases to verify your script works:
# Should EXIT 1 (blocked)
echo '{"tool":"Bash","input":{"command":"psql -c \"DROP TABLE users;\""}}' \
| bash your_hook.sh
# Should EXIT 1 (blocked, case-insensitive)
echo '{"tool":"Bash","input":{"command":"psql -c \"drop table sessions\""}}' \
| bash your_hook.sh
# Should EXIT 1 (blocked, MCP tool)
echo '{"tool":"mcp__postgres__query","input":{"query":"TRUNCATE TABLE audit_log"}}' \
| bash your_hook.sh
# Should EXIT 0 (safe — has WHERE clause... stretch goal)
echo '{"tool":"Bash","input":{"command":"psql -c \"DELETE FROM sessions WHERE expires_at < NOW();\""}}' \
| bash your_hook.sh
# Should EXIT 0 (unrelated command)
echo '{"tool":"Bash","input":{"command":"pytest tests/ -v"}}' \
| bash your_hook.sh
# Should EXIT 0 (Read tool — hook should not apply)
echo '{"tool":"Read","input":{"file_path":"/src/models.py"}}' \
| bash your_hook.shAdd the hook to settings.json — write the JSON fragment that would register your hook as a PreToolUse hook.
Stretch goal: Extend the hook to also write a log entry to ~/.claude/blocked_commands.log every time a command is blocked. Include timestamp, session ID, and the blocked command.
Exercise 3: Connect the MCP Server from Module 04 to Claude Code
Skill practiced: End-to-end MCP integration, settings.json configuration, /doctor diagnostics, using MCP tools in Claude Code sessions.
Prerequisites: Complete module 04 (building an MCP server). You should have a working MCP server script.
Task:
Part A — Configuration
- Add the module 04 MCP server to
~/.claude/settings.jsonundermcp.servers. Name it"learning-tools"(or whatever fits your server’s purpose). - Set any required environment variables in the
envsection. - Add permission rules in
permissions.allowfor the server’s tools.
Part B — Verification
- Start a new Claude Code session.
- Run
/doctorand confirm your server appears in the MCP server list as healthy. - Ask Claude: “What tools does the learning-tools MCP server provide?” — Claude should be able to list them from the registered tool registry.
- Run a test call: ask Claude to use one of your server’s tools on a specific input and verify the result is correct.
Part C — Integration test
Write a short test scenario (4-6 natural language prompts) that exercises your MCP server’s tools in a realistic workflow. For example, if your server has a search_docs tool: “Search for documentation on FastAPI middleware, then write a summary to a file called mcp-findings.md.”
Deliverable: Write your settings.json fragment and your Part C scenario into a file called exercises/ex03-mcp-integration.md. Include the output you got from /doctor and from the test call.
Common issues and debugging steps:
- Server not appearing in
/doctor→ check thatcommandis in PATH, run the command manually and watch for errors - Tools not visible → the server started but the MCP handshake failed — check stderr output
- Tool call failing → verify the environment variables are correctly set
- ImportError / ModuleNotFoundError → the virtual environment used by
commandmay differ from your dev env
Exercise 4: Create a /weekly-report Skill
Skill practiced: Skill file format, writing effective prompt templates for Claude, using shell commands in skills, structuring output for humans.
Task: Create a custom skill file at ~/.claude/skills/weekly-report.md that, when invoked as /weekly-report, produces a comprehensive summary of the week’s engineering activity.
The skill must:
- Use
!git log --since="7 days ago"to gather commit history for the current repository - Produce a report with these sections:
- Shipped this week — feature work, with one sentence per significant commit group
- Fixes and maintenance — bug fixes, refactors, dependency updates
- In progress — branches that exist but have not been merged (use
git branch -a) - Open PRs — if the GitHub MCP server is available, list open PRs; if not, note that GitHub is not configured
- Stats — total commits, files changed, lines added/removed
- Format the output as Markdown so it can be pasted into a Slack message or GitHub comment
- Handle the case where there are no commits in the past 7 days gracefully
Skill file format reminder:
---
description: Brief description shown in /help
---
The prompt template goes here. Use !commands to run shell commands.
Reference {{variables}} if needed (optional).After creating the skill:
- Start a new Claude Code session in a git repository.
- Run
/weekly-reportand observe the output. - Iterate on the skill file until the output format is exactly what you would want to share in a team standup.
Stretch goals:
- Add a
--sinceparameter so you can run/weekly-report --since="2 weeks ago" - Add a section for “Blockers or tech debt noticed” where Claude can add its own observations about problematic patterns it sees in the commit history
- Make the skill detect if it is running in a monorepo and ask which service/directory to scope to
Deliverable: Paste the final skill file into exercises/ex04-weekly-report-skill.md.
Exercise 5 (Interview Simulation): Setting Up Claude Code for a New Team
Skill practiced: Synthesis of all module concepts; communicating technical setup decisions clearly; anticipating tradeoffs.
Scenario: You are the senior engineer at a 12-person team about to migrate from Cursor to Claude Code. The codebase is a large Python monorepo (500k+ lines) with 8 services, a shared libs/ directory, GitHub for version control, PostgreSQL and Redis as data stores, and a CI pipeline on GitHub Actions. The team has mixed experience with AI tools — some engineers are power users, most are beginners.
Your task: Write a detailed technical rundown — as if you were presenting to the team in a 30-minute onboarding session — covering:
Section 1: What to put in the repo
- Where the
CLAUDE.mdfile(s) go in a monorepo (root + per-service) - What
.claude/settings.jsonshould contain and why it belongs in version control - What should NOT be in the repo (personal settings, memory files, API keys)
Section 2: Shared configuration
- The
permissionsblock: what to allow globally vs what each service needs - The
hooksblock: which hooks make sense for the whole team (logging, blocking, formatting) - The
mcpblock: which MCP servers the whole team needs (GitHub, Postgres, etc.) - How to handle secrets in MCP env config (environment variables, not hardcoded)
Section 3: Per-developer setup
- What each developer configures in
~/.claude/settings.json(personal preferences, additional MCP servers) - How memory files work and why they are not shared
- Recommended initial memory entries to create on day 1
Section 4: Team skills
- 3-4 custom skills that would be useful for this team
- Where to store shared skills (dotfiles repo? company internal tool?)
Section 5: Onboarding steps
- A numbered checklist: the exact steps a new engineer takes from “just got a MacBook” to “productive with Claude Code in this monorepo”
Section 6: Tradeoffs and risks
- The
--dangerously-skip-promptsflag: when is it safe for this team to use it? - Memory files: are they a privacy concern? What data should not go in memory?
- MCP server access: how do you give Claude access to the production database for debugging without giving it write access?
Format: Write your answer as a structured Markdown document in exercises/ex05-team-setup.md. Aim for thoroughness — this should be detailed enough that a junior engineer could follow it without asking questions. Treat it as real documentation, not a draft.
Evaluation approach: After writing, read it back as if you are the junior engineer on day 1. Ask: “Could I follow this? Is anything ambiguous?” Revise until the answer is yes.
Completion Checklist
- Exercise 1:
exercises/ex01-claude-md.mdcreated with full CLAUDE.md content - Exercise 2:
exercises/ex02-drop-table-hook.shcreated, all test cases pass - Exercise 3:
exercises/ex03-mcp-integration.mdcreated with config and test results - Exercise 4:
~/.claude/skills/weekly-report.mdcreated and tested in a live session;exercises/ex04-weekly-report-skill.mddocuments the final version - Exercise 5:
exercises/ex05-team-setup.mdcreated with all six sections complete