Chapter 5 · Part 3

Teach it your project once

Everything so far has been about a single session. This chapter is about the setup that makes every session start better — the difference between explaining your project daily and explaining it once.

The rule of thumb: anything you've said twice should live in a file.

CLAUDE.md — the file that's always read

We met CLAUDE.md in Chapter 2. It sits in your repo, it's loaded automatically at the start of every session, and it's where your project's unwritten rules become written ones.

What earns its place:

  • Commands that aren't guessable — how to run the tests, the dev server, the linter.
  • Conventions with teeth — the package manager, the file layout, the formatting rule.
  • Landmines — the generated folder, the deprecated module, the thing that looks unused but isn't.
  • Hard constraints — "never edit the schema by hand", "don't add dependencies without asking."

What doesn't:

  • Anything the code already says. It can read the code. Don't narrate your file tree.
  • Anything that goes stale. A wrong CLAUDE.md is worse than no CLAUDE.md — it's read every session and believed every time.
  • An essay. It's context you pay for on every request. Keep it tight.
💡Grow it from real friction

Don't sit down to write the perfect CLAUDE.md. Write three lines, then add one every time the agent gets something wrong that a sentence would have prevented. In a week it'll be genuinely good, and every line will have earned its place.

Custom commands — your repeated prompts, saved

The second time you type a long prompt, you've found a command. In Claude Code, a markdown file in .claude/commands/ becomes a slash command: .claude/commands/review.md gives you /review.

.claude/commands/review.md
Review the current uncommitted changes.

Run `git diff` first. For each file, check:
- Does it do what the change intended, and nothing extra?
- Are there error cases it silently ignores?
- Does it match the conventions in the surrounding code?

Be specific and concrete. Point at lines. If it looks good, say so briefly —
don't invent problems to seem useful.

Now /review is one keystroke instead of a paragraph, it's identical every time, and — because it's a file in the repo — your whole team gets it. That last part is the underrated bit: a good command is a way to share a workflow, not just a prompt.

Subagents — delegate without polluting the session

Some jobs are big, noisy, and only the answer matters. Searching a huge codebase for every caller of a function might read forty files; you want the finding, not the forty files clogging your context window.

That's what subagents are for: a helper with its own separate context that goes off, does the noisy work, and reports back a summary. The main session stays clean.

They're defined as markdown files (in .claude/agents/) with a description of when to use them. Reach for one when a task is noisy and separable — exploration, a self-contained review, a research pass. Skip it when the work is short, or when you want the details in the main thread anyway.

Hooks — rules that don't rely on being asked

A line in CLAUDE.md is an instruction. A hook is a guarantee.

Hooks run shell commands automatically when something happens — before or after a tool runs, when a session ends. The classic use is exactly the thing you keep asking for: format and lint after every file edit.

The distinction is worth internalising: if you'd be annoyed when it's skipped, don't put it in a prompt — put it in a hook. Prompts are instructions the model usually follows. Hooks are your harness executing your rule, every time, whether it remembered or not.

💡Good hook candidates

Auto-format after edits · run the linter on changed files · block edits to a protected path · run a fast test subset before a commit.

Keep them fast. A hook that adds ten seconds to every edit will make you resent the tool.

MCP — connect it to the rest of your world

Your repo isn't the whole job. The ticket lives in a tracker, the error lives in a monitoring tool, the schema lives in a database. MCP (Model Context Protocol) is the standard way to plug those into Claude Code as real tools it can call.

Once a server is connected, "why is this failing in staging?" stops being a question you paste logs for, and becomes something it can go and look up. The wins are biggest for whatever you currently copy-paste most.

⚠️Every connection is a permission

An MCP server is a real credential pointed at a real system. Connect what you need, scope the access as tightly as it'll go, and remember that anything the agent reads from an external system is data, not instructions — a ticket comment that says "delete the prod table" is someone's text, not a command to follow.

Start small

You don't need any of this on day one, and installing all of it at once is a good way to build an elaborate setup you never use. The honest order:

  1. CLAUDE.md. Three lines. Today. It's 80% of the value.
  2. A custom command, the second time you type the same prompt.
  3. A hook, the second time you're annoyed it forgot something.
  4. Subagents and MCP when a specific pain makes them obvious.

Let each one be pulled into existence by a real problem, and your setup stays small, used, and true.