Jesse A. Green / notebook

Learn Claude Code — User Guide

Generated June 2026 from shareAI-lab/learn-claude-code at ec9ea87

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Learn Claude Code is a hands-on course that teaches you to build an AI coding agent the way Claude Code is built: one small loop, surrounded by the harness mechanisms that make an agent effective. You run real, standalone Python programs — twenty of them — and each one adds exactly one new capability on top of the last. By the end you have built, line by line, a coding agent with permissions, hooks, planning, sub-agents, memory, context compaction, error recovery, a task graph, background jobs, scheduling, multi-agent teams, git-worktree isolation, and MCP tool integration.

This guide shows you how to install the course, run each lesson, point it at the model provider of your choice, and work through the material productively. It is written for the person taking the course — for the architecture of the web platform and the deep internals of each mechanism, see the companion Admin Guide.

Note

Every lesson is a single, runnable file (code.py) you talk to in your terminal. There is nothing to compile and no service to deploy. If you can run python, you can take this course.


1. Quick Start

Get the first agent talking to you in under two minutes.

git clone https://github.com/shareAI-lab/learn-claude-code
cd learn-claude-code
pip install -r requirements.txt
cp .env.example .env          # then edit .env and set ANTHROPIC_API_KEY
python s01_agent_loop/code.py

You will see a prompt. Type a request and press Enter:

s01: Agent Loop
输入问题,回车发送。输入 q 退出。

s01 >> create a file hello.txt with the text "hi" and then show me its contents
$ echo "hi" > hello.txt
$ cat hello.txt
hi
Done — created hello.txt containing "hi".

s01 >> q

That is the whole agent: a loop that calls the model, runs the shell command the model asks for, feeds the result back, and repeats until the model stops. Every later lesson keeps this loop and adds one mechanism around it.

Tip

Type q, exit, or just press Enter on an empty line to quit any lesson. All twenty lessons share the same simple REPL.


2. Requirements

Requirement Detail
Python 3.10 or newer (the code uses str | None union syntax and Path.is_relative_to)
An API key An Anthropic key, or a key for any Anthropic-compatible provider (MiniMax, GLM, Kimi, DeepSeek)
pip packages anthropic>=0.25.0, python-dotenv>=1.0.0, pyyaml>=6.0 (installed by requirements.txt)
git Required only for lesson s18 (worktree isolation) and to clone the repo
Node.js + npm Required only if you want to run the web platform (web/); not needed for the lessons
A terminal macOS, Linux, or Windows. The lessons read input line-by-line and print colored output.

Important

Two environment variables are required for every lesson: ANTHROPIC_API_KEY and MODEL_ID. The starter .env.example already sets MODEL_ID=claude-sonnet-4-6. If MODEL_ID is missing, a lesson exits immediately with a KeyError: 'MODEL_ID'.

Optional Python niceties

  • On macOS/Linux the lessons enable readline for nicer line editing (and apply a fix for backspacing multibyte/Chinese input). If readline is unavailable (common on Windows), the lessons still run — they just skip the line-editing tweaks.

3. Installation

Step 1 — Get the code

git clone https://github.com/shareAI-lab/learn-claude-code
cd learn-claude-code

Step 2 — Install dependencies

The three runtime dependencies are tiny. Install them into a virtual environment to keep things clean:

macOS / Linux

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Windows (PowerShell)

python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt

requirements.txt contains exactly:

anthropic>=0.25.0
python-dotenv>=1.0.0
pyyaml>=6.0

Step 3 — Configure your credentials

Copy the template and open it in an editor:

cp .env.example .env

The template documents every option. At minimum, set your key:

# API Key (required)
ANTHROPIC_API_KEY=sk-ant-xxx

# Model ID (required)
MODEL_ID=claude-sonnet-4-6

# Base URL (optional, for Anthropic-compatible providers)
# ANTHROPIC_BASE_URL=https://api.anthropic.com

Caution

Your .env holds a live API key. Never paste your real key into a file you commit or share, and never paste it into a chat or issue.

Step 4 — Verify

python s01_agent_loop/code.py

If you get a prompt (s01 >>), you are ready. If you get an authentication error, re-check ANTHROPIC_API_KEY; if you get KeyError: 'MODEL_ID', re-check that MODEL_ID is set in .env.


4. Using a Different Model Provider

The course works with any Anthropic-compatible API, so you can take it with open models or providers other than Anthropic. You only change two variables: ANTHROPIC_BASE_URL and MODEL_ID. The agent code is identical — that is part of the lesson.

The benchmark numbers below are reproduced from the project's own .env.example (SWE-bench Verified and Terminal-Bench 2.0, as of Feb 2026) to help you choose.

Provider MODEL_ID SWE-bench International base URL
Anthropic (default) claude-sonnet-4-6 79.6% (default — leave ANTHROPIC_BASE_URL unset)
MiniMax MiniMax-M2.5 80.2% https://api.minimax.io/anthropic
GLM (Zhipu) glm-5 77.8% https://api.z.ai/api/anthropic
Kimi (Moonshot) kimi-k2.5 76.8% https://api.moonshot.ai/anthropic
DeepSeek deepseek-chat 73.0% https://api.deepseek.com/anthropic

To use GLM, for example, set these three lines in .env:

ANTHROPIC_API_KEY=your-zhipu-key
ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic
MODEL_ID=glm-5

Note

China-mainland endpoints differ from the international ones above (for example, GLM uses https://open.bigmodel.cn/api/anthropic and MiniMax uses https://api.minimaxi.com/anthropic). The full mainland list is in .env.example.

Tip

When ANTHROPIC_BASE_URL is set, the lessons automatically clear any ANTHROPIC_AUTH_TOKEN from the environment so your provider key in ANTHROPIC_API_KEY is the one used. You do not need to manage that yourself.


5. How the Course Is Organized

The course is a single straight line: read s01 through s20 in order. Each chapter assumes you have done the previous ones and ends with a hook into the next.

Each chapter lives in its own folder:

s08_context_compact/
  README.md       # full narrative with inline code (Chinese source)
  README.en.md    # English translation
  README.ja.md    # Japanese translation
  code.py         # the standalone, runnable agent
  images/         # SVG diagrams (where the topic needs them)

The twenty lessons group into six stages, building from "make the agent act" up to "coordinate a team of agents":

Stage Theme Chapters
1. Let the agent act The loop and its tools s01 Agent Loop · s02 Tool Use · s03 Permission · s04 Hooks
2. Handle complex work Planning and isolation s05 TodoWrite · s06 Subagent · s08 Context Compact
3. Remember & recover Durability s09 Memory · s10 System Prompt · s11 Error Recovery
4. Run long tasks Time and concurrency s12 Task System · s13 Background Tasks · s14 Cron Scheduler
5. Coordinate many agents Multi-agent platform s15 Agent Teams · s16 Team Protocols · s17 Autonomous Agents · s18 Worktree Isolation
6. Extend & assemble Plug-ins and the finale s07 Skill Loading · s19 MCP Plugin · s20 Comprehensive Agent

Note

The loop never changes. Open any two consecutive chapters side by side and you will see the new file is the previous file plus one section. The unchanged parts are even labelled (for example, # FROM s02-s04 (unchanged)). The whole pedagogy is "spot the one new idea."

The two tracks (don't mix the numbers)

This repository contains two tutorial tracks. Knowing which one you are reading prevents confusion:

  • Current 20-lesson track — the root-level s01_agent_loop/ … s20_comprehensive/ folders. This is the canonical version. Start here.
  • Legacy 12-lesson track — the agents/ folder, the docs/ folder, and the current web/ app. Kept temporarily for old links and existing readers.

The chapter numbers do not line up between tracks. A few examples from the project's own mapping:

Legacy (12-lesson) Current (20-lesson) Topic
agents/s03_todo_write.py s05_todo_write/ TodoWrite
agents/s06_context_compact.py s08_context_compact/ Context Compact
agents/s07_task_system.py s12_task_system/ Task System
agents/s12_worktree_task_isolation.py s18_worktree_isolation/ Worktree Isolation
(new in this version) s03, s04, s09, s10, s11, s14, s19, s20 Permission, Hooks, Memory, System Prompt, Error Recovery, Cron, MCP, Comprehensive

Warning

If you are following an external link or the live web app, you are probably on the legacy 12-lesson track. Avoid quoting chapter numbers across tracks — "s07" means Task System in the legacy track but Skill Loading in the current one.


6. Running the Lessons

Every lesson is launched the same way and behaves the same way.

python s05_todo_write/code.py

You get an interactive prompt named after the lesson (s05 >>). Type a natural-language request, press Enter, and watch the agent work. The agent prints what it is doing as it goes — tool calls, hook messages, plans, sub-agent activity — so you can see the mechanism the chapter just taught.

Everyday usage pattern

  1. Read the chapter's README.en.md first (or README.md if you read Chinese). It explains the one new idea and walks through the code.
  2. Run code.py and give it a task that exercises that idea.
  3. Watch the printed trace. Each mechanism announces itself — e.g. [HOOK] bash, ## Current Tasks, [Subagent spawned], [auto compact], [cron fire].
  4. Quit with q and move to the next chapter.

Tip

Give the agent a real small task in a scratch directory — "list the Python files and count the lines in the biggest one", "write a function that reverses a string and a test for it". Concrete tasks make each mechanism visible far better than abstract questions.

What the agent can do (the tools)

By the time you reach the later chapters the agent has a full toolbox. These are the actions it can take on your machine:

Tool What it does
bash Runs a shell command in the working directory (120-second timeout)
read_file Reads a file (optional limit on number of lines)
write_file Writes content to a file (creates parent directories)
edit_file Replaces an exact string in a file, once
glob Lists files matching a pattern
todo_write (s05+) Records and updates a plan/checklist
task (s06+) Spawns a sub-agent with its own clean context
load_skill (s07+) Loads a full skill document on demand
compact (s08+) Summarizes earlier conversation to free up space
create_task / list_tasks / get_task / claim_task / complete_task (s12+) The persistent task board
schedule_cron / list_crons / cancel_cron (s14+) Time-triggered jobs
spawn_teammate / send_message / check_inbox (s15+) Multi-agent coordination
create_worktree / remove_worktree / keep_worktree (s18+) Isolated git working directories
mcp__{server}__{tool} (s19+) Tools discovered from a connected MCP server

Caution

This agent runs real shell commands and writes real files on your computer. The early lessons have only light guardrails (a deny-list and a workspace boundary), because building those guardrails is the lesson. Run the lessons in a throwaway directory, not in a folder full of work you care about. See §7 (Permission) for what is and isn't blocked.


7. Lesson-by-Lesson Walkthrough

Each lesson below lists its motto, the one mechanism it adds, and something concrete to try. Mottos and key concepts are the project's own.

Stage 1 — Let the agent act

s01 · Agent Loop — "One loop & Bash is all you need"

The smallest useful agent: a while loop that calls the model with a single bash tool, runs whatever command the model returns, feeds the output back, and stops when the model stops (stop_reason != "tool_use"). Try: find out what operating system this is and how much disk is free.

s02 · Tool Use — "Adding a tool means adding one handler"

Four more tools appear — read_file, write_file, edit_file, glob — plus a TOOL_HANDLERS dispatch map. The loop body barely changes: it now looks up TOOL_HANDLERS[block.name] instead of always calling bash. Try: read s01_agent_loop/code.py and write a one-paragraph summary to summary.txt.

s03 · Permission — "Set boundaries first, then grant freedom"

Three gates run before any tool executes: a hard deny-list (e.g. rm -rf /, sudo), rule matching (writing outside the workspace, destructive commands), and user approval for risky actions. Try: ask it to rm something, or to write a file outside the folder, and watch the gate ask Allow? [y/N].

s04 · Hooks — "Hook around the loop, never rewrite the loop"

The permission check moves out of the loop and onto a hook. A small registry fires callbacks on lifecycle events — UserPromptSubmit, PreToolUse, PostToolUse, Stop — so you can add behavior without touching the loop. Try: any task — watch the [HOOK] ... lines that now narrate each step.

Stage 2 — Handle complex work

s05 · TodoWrite — "An agent without a plan drifts"

Adds a todo_write planning tool and a gentle "nag" that reminds the model to update its plan if it goes three rounds without doing so. The plan prints as a live checklist. Try: a multi-step task like set up a tiny Python project: a module, a test, and a README.

s06 · Subagent — "Big tasks split small, each gets clean context"

Adds a task tool that spawns a sub-agent with a fresh message history. The sub-agent does its work (capped at 30 turns) and returns only a short summary; its intermediate chatter is discarded so the main thread stays clean. Sub-agents can't spawn sub-agents. Try: investigate which file in this repo is the largest and why, then summarize.

s08 · Context Compact — "Context always fills up — have a way to make room"

A four-layer compaction pipeline keeps long sessions alive: trim middle messages, replace old tool results with placeholders, spill huge outputs to disk, and (last resort) summarize the whole history with one model call. An emergency path retries if the API ever says the prompt is too long. Try: a long, chatty session with many file reads; watch for [auto compact].

Stage 3 — Remember & recover

s09 · Memory — "Remember what matters, forget what doesn't"

A persistent .memory/ folder survives across sessions. The agent selects relevant memories into context, extracts new ones after each turn, and periodically consolidates duplicates. Try: tell it remember that I prefer tabs over spaces, quit, restart, and ask it to write code.

s10 · System Prompt — "Assembled at runtime, never hardcoded"

The system prompt becomes a product of current state: sections (identity, tools, workspace, memory) are concatenated based on what actually exists, with a small cache so it isn't rebuilt needlessly. Try: run with and without a .memory/ folder and watch which sections load.

s11 · Error Recovery — "Errors aren't the end, they're the start of a retry"

Wraps the model call in three recovery paths: escalate max_tokens (8K → 64K) then ask the model to continue; reactively compact on "prompt too long"; and back off with jitter on rate-limit (429) / overload (529) errors, optionally switching to a FALLBACK_MODEL_ID. Try: set FALLBACK_MODEL_ID in .env and give it a task that produces a very long answer.

Stage 4 — Run long tasks

s12 · Task System — "Big goals break into small tasks, ordered, persisted to disk"

A file-backed task board in .tasks/. Tasks have a subject, status, owner, and blockedBy dependencies; a task can't be claimed until its blockers are complete, and completing one reports what it unblocks. Try: create three tasks where the third is blocked by the first two, then walk them to completion.

s13 · Background Tasks — "Slow ops go background, agent keeps thinking"

Slow commands (installs, builds, tests) run in a daemon thread. The agent gets a placeholder immediately and a <task_notification> is injected when the job finishes. Try: ask it to run something slow with "in the background"; keep chatting while it runs.

s14 · Cron Scheduler — "Fire on schedule, no human kick needed"

A standalone scheduler thread matches 5-field cron expressions and queues prompts; a queue processor wakes the agent to run them when it's idle. Jobs can be recurring and durable (persisted to .scheduled_tasks.json, surviving restarts). Try: schedule a job every minute that writes the current time to heartbeat.log, wait, then list_crons.

Stage 5 — Coordinate many agents

s15 · Agent Teams — "Too big for one agent — delegate to teammates"

A file-based MessageBus (.mailboxes/*.jsonl) lets a "Lead" spawn persistent teammates in background threads and exchange messages; teammate replies are injected into the Lead's history. Try: spawn a teammate to count lines of code while you draft a README, then combine results.

s16 · Team Protocols — "Teammates need shared communication rules"

Adds a request/response protocol with correlation IDs: shutdown handshakes, plan requests, and plan approval, so coordination is contract-based rather than ad-hoc.

s17 · Autonomous Agents — "Teammates check the board, claim work themselves"

Teammates poll the task board, auto-claim unowned tasks whose dependencies are met, and cycle through a WORK → IDLE → SHUTDOWN lifecycle — no leader hand-assigning each item.

s18 · Worktree Isolation — "Each works in its own directory, no interference"

Tasks gain a worktree field bound to a real git worktree (.worktrees/<name>, branch wt/<name>), so parallel agents edit isolated checkouts without clobbering each other. Worktree names are validated against path-traversal. Try: this lesson needs git and a git repo. Create two worktree-bound tasks and let teammates work them in parallel.

Stage 6 — Extend & assemble

s07 · Skill Loading — "Load knowledge on demand, not upfront"

(Numbered s07 in code; the learning path places it here.) Skill names and one-line descriptions sit cheaply in the system prompt; the full SKILL.md body is loaded only when the agent calls load_skill. The bundled skills are agent-builder, code-review, mcp-builder, and pdf. Try: review the code in s02_tool_use/code.py and watch it load_skill("code-review") before working.

s19 · MCP Plugin — "Not enough capability? Plug in more via MCP"

An MCPClient discovers tools from a server and merges them into the agent's tool pool under names like mcp__docs__search, with readOnly/destructive annotations. (The transport here is a teaching mock; the real protocol details are simplified — see the Admin Guide.)

s20 · Comprehensive Agent — "Many mechanisms, one loop"

The finale puts every mechanism back together in one harness: dispatch, permission, hooks, todos, sub-agents, skills, compaction, memory, prompt assembly, error recovery, task graph, background tasks, cron, teams, protocols, autonomous agents, worktrees, and MCP — still around the same single loop. Try: give it a genuinely multi-step coding goal and watch the layers cooperate.


8. Running the Legacy 12-Lesson Track

The older track is preserved in agents/. Each file is self-contained and run directly:

python agents/s01_agent_loop.py
python agents/s12_worktree_task_isolation.py
python agents/s_full.py          # the legacy "everything" agent

Note

Use the legacy track only if you are following an old link or want to compare versions. For learning from scratch, use the root-level s01–s20 track — it is more complete (20 mechanisms vs. 12) and better organized.


9. Running the Web Platform

The repository includes an interactive learning website (web/) — a Next.js app with visualizations of each mechanism, available in English, Chinese, and Japanese.

cd web
npm install
npm run dev          # opens http://localhost:3000

Important

The live web app currently renders the legacy docs/ (s01–s12) track, not the new 20-lesson track. Treat the website as a companion visualization, and use the root-level chapter folders for the authoritative current material.

The npm run dev and npm run build commands automatically run a content-extraction step first (npm run extract), so the site always reflects the latest chapter content. You do not need to run extraction by hand.


10. Troubleshooting

Format: the exact symptom, the cause, the fix, and how to avoid it next time.

Error: KeyError: 'MODEL_ID'

Cause: MODEL_ID is not set in your environment. Every lesson reads it with os.environ["MODEL_ID"] and crashes if it's missing. Solution: ensure your .env contains MODEL_ID=claude-sonnet-4-6 (or your provider's model), and that you ran cp .env.example .env. Prevention: start from the provided .env.example, which sets MODEL_ID for you.

Error: authentication / 401 from the API

Cause: ANTHROPIC_API_KEY is missing, wrong, or doesn't match the provider in ANTHROPIC_BASE_URL. Solution: verify the key; if you set ANTHROPIC_BASE_URL to a non-Anthropic provider, make sure ANTHROPIC_API_KEY is that provider's key. Prevention: change ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY together as a pair.

Error: 400 Bad Request part-way through a session (often in s08 / s13)

Cause: a known edge case (reported in the project's issues) where compaction can split a tool_use block from its matching tool_result, which the API rejects. It tends to surface in the background-tasks and context-compaction lessons. Solution: restart the lesson (state is per-process); keep individual sessions shorter so compaction triggers less aggressively. Prevention: this is a teaching simplification, not a production bug-free implementation — the Admin Guide's "Known limitations" section explains the trade-off.

Symptom: Blocked: 'rm -rf /' (or another command refused)

Cause: the s03/s04 deny-list intentionally refuses dangerous commands such as rm -rf /, sudo, shutdown, reboot, mkfs, and dd if=. Solution: this is correct behavior — rephrase the task to avoid the blocked command. Prevention: none needed; the block is a feature you are learning to build.

Error: ValueError: Path escapes workspace: <path>

Cause: the agent tried to read or write outside the current working directory. The safe_path guard (present from s02 onward) refuses paths that resolve outside the workspace. Solution: run the lesson from the directory you want the agent to operate in, and ask it to use relative paths. Prevention: treat the launch directory as the agent's sandbox.

Error: RuntimeError: Not in a git repository. worktree tools require git.

Cause: lesson s18 (and the legacy worktree lesson) needs to run inside a git repository. Solution: run it from a folder that is a git repo (the cloned learn-claude-code itself is one), and make sure git is installed. Prevention: only the worktree lesson needs git; the others don't.

Symptom: Subagent stopped after 30 turns without final answer.

Cause: a sub-agent (s06+) hit its 30-turn safety limit before finishing. Solution: give the sub-agent a narrower, more concrete task; break the work into smaller task calls. Prevention: sub-agents are for bounded side-quests, not open-ended exploration.

Symptom: readline warning or odd backspace behavior on Windows

Cause: readline isn't always available on Windows; the lessons wrap it in a try/except and continue without it. Solution: nothing required — the lesson runs fine; you just lose inline line-editing niceties. Prevention: use a terminal with pyreadline3 installed if you want the editing features.

Symptom: a scheduled (cron) job didn't fire

Cause: the 5-field expression didn't match, or the agent was busy in another turn when the minute passed. Solution: check list_crons; remember the fields are minute hour day-of-month month day-of-week; the scheduler de-duplicates per calendar minute, so a job fires at most once a minute. Prevention: test with * * * * * (every minute) first, then narrow.


11. Frequently Asked Questions

Q: Do I need an Anthropic subscription, or will any key work? Any Anthropic-compatible key works. The course is explicitly built so that only ANTHROPIC_BASE_URL and MODEL_ID change between providers — see §4 for MiniMax, GLM, Kimi, and DeepSeek settings.

Q: Which chapter should I start with? s01_agent_loop. Read straight through to s20. Each chapter builds on the last and ends with a hook into the next.

Q: Is this the actual Claude Code source code? No. It is a teaching re-implementation that mirrors Claude Code's design patterns in small, readable Python. The project's own words: "This is not 'copy the source code.' This is 'grasp the key designs and build it yourself.'" Some production mechanisms (full hook bus, rule-based permission governance, real MCP transport/OAuth, session resume/fork) are intentionally simplified or omitted.

Q: Why does the same code appear in every file? That's the method. Each code.py is the previous lesson's code plus exactly one new section, with the carried-over parts labelled # FROM sNN (unchanged). You can diff two consecutive files to see precisely what each mechanism adds.

Q: Is it safe to run on my main machine? The agent executes real shell commands and edits real files. Early lessons have only minimal guardrails (deny-list + workspace boundary) by design. Run the lessons in a disposable directory and read §6's caution before pointing the agent at anything important.

Q: What languages is the material in? Each chapter ships README.md (Chinese source), README.en.md (English), and README.ja.md (Japanese). The web platform is also trilingual (en/zh/ja).

Q: Do the lessons share state? No. Each lesson is its own process. Folders like .memory/, .tasks/, .transcripts/, .mailboxes/, and .worktrees/ are created in your working directory as the relevant lessons run; delete them to reset.

Q: The web app shows different chapter numbers than the folders. Why? The web app renders the legacy 12-lesson track; the folders are the current 20-lesson track. The numbering differs — see the mapping table in §5 and avoid mixing numbers across tracks.

Q: What's the difference between s06 (Subagent) and s12 (Task System)? A sub-agent (s06) is an ephemeral helper with throwaway context that returns one summary. The task system (s12) is durable, file-backed work with dependencies and ownership that multiple agents can pick up — it's the foundation for the multi-agent stages.

Q: What do I do after finishing all twenty lessons? You'll understand harness engineering well enough to build your own. The project points to two follow-ons it maintains — a ready-to-use CLI agent and an embeddable agent SDK (links in the repo's README) — and a sister tutorial on turning a "use-and-discard" agent into an always-on assistant (heartbeat + cron + chat channels).