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 with routers/, services/, repositories/, models/, schemas/
  • A Makefile with 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:

  1. Project overview — what it does, stack, language version
  2. Setup commands — from fresh clone to running locally (include Docker for Postgres)
  3. Common commands — test, lint, type-check, dev server, migrations
  4. Project structure — annotated directory tree showing what lives where
  5. Architecture conventions — the patterns Claude must follow when adding code
  6. Coding style — what is enforced by tooling vs what is convention
  7. Known gotchas — at least two things that would trip up a developer new to this codebase
  8. 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:

  1. Reads the JSON payload from stdin
  2. Checks whether the tool is Bash (or mcp__postgres__execute / mcp__postgres__query)
  3. Inspects the command/query string for any of these dangerous SQL patterns (case-insensitive):
    • DROP TABLE
    • DROP DATABASE
    • TRUNCATE TABLE
    • DELETE FROM without a WHERE clause (optional stretch)
  4. If a dangerous pattern is found: exits with code 1 and writes a clear, actionable error message to stderr
  5. If no dangerous pattern: exits with code 0

Requirements:

  • Script must have a proper shebang (#!/bin/bash)
  • Must handle the case where jq is 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.sh

Add 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

  1. Add the module 04 MCP server to ~/.claude/settings.json under mcp.servers. Name it "learning-tools" (or whatever fits your server’s purpose).
  2. Set any required environment variables in the env section.
  3. Add permission rules in permissions.allow for the server’s tools.

Part B — Verification

  1. Start a new Claude Code session.
  2. Run /doctor and confirm your server appears in the MCP server list as healthy.
  3. Ask Claude: “What tools does the learning-tools MCP server provide?” — Claude should be able to list them from the registered tool registry.
  4. 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 that command is 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 command may 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:

  1. Use !git log --since="7 days ago" to gather commit history for the current repository
  2. 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
  3. Format the output as Markdown so it can be pasted into a Slack message or GitHub comment
  4. 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:

  1. Start a new Claude Code session in a git repository.
  2. Run /weekly-report and observe the output.
  3. 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 --since parameter 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.md file(s) go in a monorepo (root + per-service)
  • What .claude/settings.json should 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 permissions block: what to allow globally vs what each service needs
  • The hooks block: which hooks make sense for the whole team (logging, blocking, formatting)
  • The mcp block: 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-prompts flag: 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.md created with full CLAUDE.md content
  • Exercise 2: exercises/ex02-drop-table-hook.sh created, all test cases pass
  • Exercise 3: exercises/ex03-mcp-integration.md created with config and test results
  • Exercise 4: ~/.claude/skills/weekly-report.md created and tested in a live session; exercises/ex04-weekly-report-skill.md documents the final version
  • Exercise 5: exercises/ex05-team-setup.md created with all six sections complete