Skip to content
Raj Bhensdadiya

Claude Code 101: A Complete Tutorial From Install to Agentic Workflows

30 min readRaj Bhensdadiya

On this page
  1. 1. What is Claude Code?
  2. 2. How to install Claude Code
  3. 3. Your first session
  4. 4. CLAUDE.md: teach Claude your project
  5. 5. Permission modes: how much freedom to give
  6. 6. Models: which Claude should you use?
  7. 7. Effort levels: how hard Claude thinks
  8. 8. A workflow that works: explore, plan, code, commit
  9. 9. Skills: automate tasks you repeat
  10. 10. Subagents: hand work to a helper
  11. 11. Skills vs subagents, and where everything else fits
  12. 12. MCP servers: connect Claude to your tools
  13. 13. Hooks: rules that always run
  14. 14. Plugins: a full setup in one command
  15. 15. Beyond the terminal
  16. 16. Hands-on demo: build a Bookmarks API end to end
  17. 17. Common mistakes (and what to do instead)
  18. 18. FAQ
  19. Wrapping up

Claude Code is a coding agent that works inside your project. You tell it what you want in plain English, and it reads your files, writes code, runs commands and checks its own work.

I use Claude Code as my main development setup every day. This tutorial is the walkthrough I would give a friend who is starting today. It goes from installing it to running a full agentic workflow with skills, subagents, hooks and MCP servers.

This guide is for you if:

  • You have never used Claude Code and want to set it up the right way
  • You use it a bit, but skills, subagents and MCP still feel fuzzy

At the end you will build a small Bookmarks API using plan mode, a custom skill, a review subagent, hooks and an MCP server. Everything runs on your own laptop.

Last tested: October 2026 on Claude Code 2.1. Claude Code changes fast, so check the changelog at the bottom for updates.

What's inside:

  1. What is Claude Code?
  2. How to install Claude Code
  3. Your first session
  4. CLAUDE.md: teach Claude your project
  5. Permission modes
  6. Models
  7. Effort levels
  8. A workflow that works
  9. Skills
  10. Subagents
  11. Skills vs subagents
  12. MCP servers
  13. Hooks
  14. Plugins
  15. Beyond the terminal
  16. Hands-on demo
  17. Common mistakes
  18. FAQ

Read it top to bottom, or jump to the part you need.

1. What is Claude Code?#

Claude Code is Anthropic's coding agent. "Agent" just means it can take actions, not only answer questions. It can:

  • Read and search your whole codebase
  • Create and edit files
  • Run terminal commands like tests, builds and git
  • Look at the results and try again when something fails

How is it different from the Claude chat app? In the chat app you paste code in and copy answers out. Claude Code works directly in your project folder, so it sees your real files and runs your real commands.

How is it different from autocomplete tools? Autocomplete suggests the next line while you type. With Claude Code you hand over a task, and it works through the steps until the task is done or it needs your input.

The agentic loop

The agentic loop. You hand Claude Code a task, such as adding a check that the email field is not empty on signup and running the tests. It reads and searches the codebase, edits files, runs commands like tests, builds and git, and checks the results. When a check fails it goes round the loop again. When it passes, the task is done. It also stops when it needs your input.

Where it runs#

WhereGood for
Terminal (CLI)The full feature set. This guide uses it.
VS Code and CursorReviewing diffs inside your editor
JetBrains IDEsThe same idea for IntelliJ, PyCharm, WebStorm and friends
Desktop appA visual interface if you don't live in the terminal
Web (claude.ai/code)Running sessions in the browser with nothing to install
Mobile appStarting or checking on tasks from your phone
SlackAsking @Claude for help right in a channel
GitHub ActionsLetting Claude review PRs and fix issues in CI

Project files like CLAUDE.md and the .claude folder live in your repo, so they come with you to the editor, desktop and web versions too.

What you need#

Claude Code needs a paid account: a Claude Pro, Max, Team or Enterprise plan, or an Anthropic Console account that bills by API usage. The free Claude plan does not include it. Companies can also run it through Amazon Bedrock, Google Cloud's Agent Platform or Microsoft Foundry.

Prices and limits change often, so check the official pricing page instead of trusting numbers in any blog post, including this one.

2. How to install Claude Code#

Installing takes one command. First, check your machine meets the basics:

  • macOS 13 or newer, Windows 10 (version 1809) or newer, Ubuntu 20.04+, Debian 10+ or Alpine 3.19+
  • 4 GB of RAM
  • An internet connection

macOS, Linux and WSL#

Open a terminal and run the native installer:

Shell
curl -fsSL https://claude.ai/install.sh | bash

Windows (PowerShell)#

PowerShell
irm https://claude.ai/install.ps1 | iex

On Windows, it's worth installing Git for Windows too. It gives Claude Code Git Bash for running shell commands. Without it, Claude Code uses PowerShell instead. You don't need it inside WSL.

Other ways to install#

If you prefer a package manager:

Shell
# macOS with Homebrew
brew install --cask claude-code

# Windows with WinGet
winget install Anthropic.ClaudeCode

# npm (needs Node.js 22 or newer)
npm install -g @anthropic-ai/claude-code

Don't run the npm command with sudo. If npm gives you a permissions error, use the native installer instead.

Check that it worked#

Shell
claude --version
claude doctor

claude doctor checks your setup and tells you if anything looks wrong. Run it first whenever something feels off.

Keep it updated#

The native installer and npm installs update Claude Code in the background. Homebrew and WinGet installs don't, and claude update won't upgrade them for you, so use the package manager:

Shell
# Homebrew
brew upgrade claude-code

# WinGet
winget upgrade Anthropic.ClaudeCode

To update an npm install by hand, run npm install -g @anthropic-ai/claude-code@latest. Skip npm update -g, which may not move you to the newest release.

Log in#

Go to any project folder and run claude. The first time, it opens your browser so you can log in with your Claude account or your Console account. After that, you stay logged in.

3. Your first session#

Open a terminal in any project you have and start Claude Code:

Shell
cd my-project
claude

You get a prompt box. Type what you want in normal English and press Enter.

Start with questions, not changes. It's the quickest way to see how Claude reads your code:

Text
give me an overview of this codebase
how is authentication handled?
find the files that handle user signup

Then try something small, like add a check that the email field is not empty on signup, then run the tests. Depending on your permission mode, Claude will ask before it edits files or runs commands.

Small things that make a big difference#

  • Point at files with @. explain the logic in @src/utils/auth.ts pulls that file straight in.
  • Run your own commands with !. !git status runs it without leaving Claude Code.
  • Paste screenshots. Copy an image and press Ctrl+V (Alt+V on Windows) to show Claude an error or a design.
  • Stop anytime. Press Esc to stop Claude mid-task. Your edits so far stay.
  • Go back. Press Esc twice with an empty prompt (or run /rewind) to return to an earlier point, including file changes.
  • Pick up later. claude --continue resumes your last session in that folder. claude --resume lets you choose from a list.

10 commands every beginner needs#

Type / to see every command. These are the ones you will use most:

CommandWhat it does
/helpLists commands and help
/initWrites a starter CLAUDE.md for your project
/clearStarts a fresh conversation. Your files stay as they are.
/compactSummarizes a long conversation to free up space
/modelSwitches the model
/effortChanges how hard Claude thinks
/usageShows how much of your plan or budget you've used
/resumeOpens an earlier session
/rewindGoes back to an earlier point in the session
/btwAsks a quick side question that doesn't get added to the main conversation

Shortcuts worth learning#

KeysWhat they do
Shift+TabCycles permission modes (more on this in section 5)
EscStops Claude
Esc, EscOpens rewind when the prompt is empty. With text in the prompt, it clears the draft.
Ctrl+BSends a running task to the background
Ctrl+GOpens your prompt or plan in your text editor
Ctrl+RSearches your past prompts
Alt+P (Option+P on Mac)Switches model. On a Mac, your terminal must treat Option as Meta.

4. CLAUDE.md: teach Claude your project#

Every new session starts with a clean conversation. CLAUDE.md is how Claude knows your project's basics from the first message. It's a plain markdown file that Claude reads at the start of every session.

Create one#

Inside Claude Code, run:

Text
/init

Claude scans your project and writes a starter CLAUDE.md. If you already have one, it suggests improvements instead. Read what it wrote and delete anything wrong or obvious.

Where it lives#

FileWho it's forCommit it?
~/.claude/CLAUDE.mdYou, in every projectNo, it lives on your machine
./CLAUDE.md or ./.claude/CLAUDE.mdEveryone on the projectYes
./CLAUDE.local.mdJust you, in this projectNo, add it to .gitignore

What to put in it#

Write what you would tell a new teammate on their first day. Here's an example for a small API:

Markdown
# Bookmarks API

## Commands
- `npm run dev` starts the server on port 3000
- `npm test` runs all tests with Vitest
- `npm run lint` checks style

## Code style
- TypeScript strict mode, no `any`
- One route file per resource in `src/routes/`
- Every new route needs tests in `tests/`

## Don't
- Don't edit `.env` or commit secrets
- Don't add new dependencies without asking

A few tips:

  • Keep it short. Aim for under 200 lines. Every line gets loaded into every session.
  • Be specific. "Use 2-space indentation" works. "Write clean code" does nothing.
  • Link instead of pasting. Add a line like See @docs/api-conventions.md for API rules and Claude pulls that file in.
  • Already use AGENTS.md? Claude Code reads it when there's no CLAUDE.md.

Auto memory#

Claude also keeps its own notes as it works, such as a build command it figured out or a quirk in your setup. Run /memory to see them, edit them, or turn auto memory off.

One important limit#

CLAUDE.md is guidance. Claude follows it most of the time, but not every single time. If something must always happen (like formatting) or must never happen (like editing .env), use a hook. Hooks are covered in section 13.

5. Permission modes: how much freedom to give#

Out of the box, Claude asks before it edits a file or runs most commands. That's safe, but it gets slow once you trust what it's doing. Permission modes let you choose how much freedom to give.

ModeWhat happensUse it when
Manual (default)Asks the first time it uses each toolYou're new, or the repo is unfamiliar
Accept editsEdits files without asking, still asks for most commandsYou're watching and reviewing diffs
PlanReads and explores only, then gives you a plan to approveStarting any bigger change
AutoNo routine prompts. A background check reviews commands and network requests firstLonger tasks where you trust the direction
Don't askRefuses anything you haven't already allowedLocked-down setups and scripts
Bypass permissionsSkips the promptsOnly inside a container or VM

Press Shift+Tab to cycle through modes. The current mode shows at the bottom of the screen. On recent versions a new session may start in auto mode, so glance at that label before you begin.

You can also start in a mode directly:

Shell
claude --permission-mode plan

Allow and block specific actions#

You can pre-approve safe commands and block risky ones. Add this to .claude/settings.json in your project:

JSON
{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(git commit *)"
    ],
    "deny": [
      "Bash(git push *)",
      "Read(./.env)"
    ]
  }
}

How a request meets these rules

Claude wants to

Claude asks youNo rule matches, so your permission mode decides. Manual asks first.

Five requests checked against the settings above. Deny rules are checked first, then allow rules, and anything neither list matches falls back to your permission mode. npm run test matches Bash(npm run *) and git commit matches Bash(git commit *), so both run without asking. git push origin main matches the deny rule Bash(git push *) and reading .env matches Read(./.env), so both are blocked, because deny always wins. npm install zod matches no rule, so the permission mode decides, and in Manual mode Claude asks you.

Now Claude can run any npm script and make commits without asking. It can never push, and it can't read your .env file. Deny rules always win over allow rules.

Settings can live in three places:

FileApplies to
~/.claude/settings.jsonYou, in every project
.claude/settings.jsonEveryone on the project (commit it)
.claude/settings.local.jsonJust you, in this project

Prefer not to edit JSON? Run /permissions inside Claude Code to manage the same rules from a menu.

6. Models: which Claude should you use?#

Claude Code can run on several Claude models. Here's the lineup as of October 2026:

ModelAliasGood forTrade-off
Opus 5.5opusThe default. Hard problems, big changes, planningHeavier on usage than Sonnet
Sonnet 5.5sonnetEveryday coding at good speedA bit less depth on the hardest tasks
Haiku 5.5haikuQuick, simple jobs and cheap subagentsNot for complex reasoning
FablefableAnthropic's top-tier model for the toughest workNot the default. Check /model to see if your plan offers it.

There are also a few handy aliases:

  • opusplan uses Opus while you're in plan mode and Sonnet when it's writing the code. You get careful planning and faster building.
  • default goes back to whatever your account uses by default.

You may see opus[1m] and sonnet[1m] in older guides. They select a 1 million token context window, but Opus 5.5 and Sonnet 5.5 already run with one by default, so on these models the suffix changes nothing.

How to switch#

Inside Claude Code:

Text
/model
/model sonnet

The first opens a picker. The second switches straight to Sonnet. You can also press Alt+P (Option+P on a Mac, once your terminal treats Option as Meta).

When starting a session:

Shell
claude --model sonnet

Or set it for good in your settings file with "model": "sonnet".

Which one should you pick?#

Stay on the default for most work. Switch to Sonnet when you're doing lots of small, clear tasks and want speed. Use Haiku for subagents that only search or summarize. Try opusplan if you plan a lot and want to save usage on the coding part.

Models change often, so treat this table as a snapshot. /model always shows what's available to you right now.

7. Effort levels: how hard Claude thinks#

Effort is how much Claude reasons before it acts. On low effort it answers quickly and directly. On high effort it takes longer, weighs more options and double-checks its work.

LevelWhat it feels likeUse it for
lowFast and shortRenames, typo fixes, simple edits
mediumBalanced. The default on the 5.5 models.Most everyday work
highThinks things throughTricky bugs, features that touch several files
xhighVery thoroughDesign decisions, hard debugging
maxEverything it hasRare, really hard problems

How to set it#

Inside Claude Code:

Text
/effort
/effort high

The first opens a slider. The second sets it directly. When starting a session:

Shell
claude --effort high

ultrathink#

Want one deep answer without changing your setting? Put the word ultrathink anywhere in your prompt:

Text
ultrathink: why does this test pass locally but fail in CI?

Claude reasons more deeply for that one turn, then goes back to your normal level. Phrases like "think hard" are not special keywords anymore, so they don't change anything.

The trade-off#

Higher effort is slower and uses more of your plan limits. Lower effort is faster, but it can miss things on complex work. If Claude keeps getting something wrong, a clearer prompt and a higher effort level are the first two things to try.

Model vs effort#

These two get mixed up a lot. The model is which brain you use. Effort is how long that brain thinks about this task. A good starting point is the default model on medium effort, and adjust from there.

Model vs effort: two separate dials

Starting point

Opus 5.5, medium effort. Section 7

A good starting point is the default model on medium effort, and adjust from there.

/model default/effort medium
one turn, deeper
A grid with the models as rows (Haiku 5.5, Sonnet 5.5, Opus 5.5 which is the default, and Fable if your plan offers it) and the effort levels as columns (low, medium which is the default, high, xhigh and max). The starting point is Opus on medium. Planning the Bookmarks API moves to Opus on high with /effort high. Renaming a folder moves to Sonnet on low with /model sonnet and /effort low. Design decisions and hard debugging move to Opus on xhigh. ultrathink thinks deeper for one turn without changing the setting.

8. A workflow that works: explore, plan, code, commit#

The quickest way to get a mess is to type "build me X" and walk away. The best results come from a simple four-step loop.

Explore, plan, code, commit

The four-step loop for a bigger change. Explore: Claude reads the relevant code and changes nothing. Plan: in plan mode, reached with Shift+Tab, you read the plan, edit it with Ctrl+G and approve it; this is the cheapest moment to catch a bad idea. Code: Claude builds it with a way to check its own work, running npm test after each step and fixing anything that fails. Commit: you read the diff yourself, then commit or open a pull request. For small, obvious changes, skip the plan.

Step 1: Explore#

Ask Claude to read the relevant code first, with no changes:

Text
read the files that handle bookmarks and explain how saving works. don't change anything yet.

Step 2: Plan#

Press Shift+Tab until you're in plan mode, then ask for a plan:

Text
I want to add tags to bookmarks. make a plan: which files change, what the data looks like, and which tests we need.

Read the plan carefully. This is the cheapest moment to catch a bad idea. Press Ctrl+G to open the plan in your text editor and change anything you don't like. Approve it when it looks right.

Step 3: Code#

Let Claude build it. Give it a way to check its own work:

Text
implement the plan. run npm test after each step and fix anything that fails.

Step 4: Commit#

Read the diff yourself. Then ask Claude to commit, or to open a pull request:

Text
commit these changes with a clear message

For small, obvious changes, skip the plan. Planning a one-line fix just wastes time.

Let Claude check its own work#

If you take one tip from this guide, take this one. Claude does its best work when it can see whether something worked. Tests, a build, a linter, a screenshot of the page: tell it which one to use.

A nice pattern for bugs is test first:

Text
write a failing test for the bug where empty URLs are accepted. then fix the code until the test passes.

Keep the context clean#

Claude has a context window, which is how much it can keep in mind at once. Long sessions fill it up, and quality drops as it fills.

  • Run /clear when you switch to an unrelated task
  • Run /compact during a long task to summarize and keep going
  • Hand big searches to a subagent (section 10), so only the answer comes back

What fills the context window

A long session. Old, unrelated conversation fills the window.

  • During a long task: summarize and keep going.
  • Switching to an unrelated task: start a fresh conversation. Your files stay as they are.
The context window fills as a session runs: CLAUDE.md, your prompt, files read, test output, more files and an unrelated task. Quality drops as it fills. /compact, for use during a long task, summarizes the conversation so you can keep going. /clear, for when you switch to an unrelated task, starts a fresh conversation; your files stay as they are and CLAUDE.md loads again.

Weak prompt vs strong prompt#

Weak:

Text
fix the login bug

Strong:

Text
users get logged out after 5 minutes even with "remember me" checked.
look at src/auth/session.ts and the cookie settings.
write a test that reproduces it, then fix it. run npm test before you finish.

The strong version says what's wrong, where to look, and how to prove the fix works.

9. Skills: automate tasks you repeat#

A skill is a set of instructions Claude pulls in when it needs them. Think of it as a recipe card. Instead of explaining your PR format or your release steps every single time, you write them down once.

How skills work#

Each skill is a folder with a SKILL.md file inside. At the start of a session, Claude only sees each skill's short description. When your request matches a description, Claude loads the full instructions. You can also run any skill yourself by typing / and its name.

This keeps things light. A skill costs almost nothing until it's actually used.

If you used custom slash commands before (files in .claude/commands/), those are skills now. Your old command files still work.

How a skill loads

  1. 1.
    Session starts. Claude sees only each skill's short description.
  2. 2.
    You ask in plain English.

    “write a PR description for this branch”

  3. 3.
    Your words match pr-summary's description.
  4. 4.
    The full SKILL.md loads.
  5. 5.
    Its ! lines run first. Their output replaces them.
  6. 6.
    Claude follows the instructions and writes the PR description.

A skill costs almost nothing until it's actually used.

At the start of a session Claude only has each skill's short description in context, which costs almost nothing. When you ask for a PR description, or type /pr-summary yourself, the full pr-summary SKILL.md loads. Its shell command lines run first and their output replaces them, $ARGUMENTS becomes whatever you typed after the skill name, and Claude follows the instructions to write the PR description.

Where skills live#

LocationWho can use it
~/.claude/skills/<name>/SKILL.mdYou, in every project
.claude/skills/<name>/SKILL.mdEveryone on the project (commit it to git)
Inside a pluginAnyone who installs that plugin

Build your first skill: /pr-summary#

This skill writes a pull request description from your branch's changes.

1. Create the folder

Shell
mkdir -p ~/.claude/skills/pr-summary

2. Create ~/.claude/skills/pr-summary/SKILL.md

Markdown
---
name: pr-summary
description: Writes a pull request description for the current branch. Use when the user asks for a PR description, a PR summary, or what changed on this branch.
---

## Commits on this branch

!`git log --oneline main..HEAD`

## Files changed

!`git diff main...HEAD --stat`

## Instructions

Write a pull request description with these sections:

1. **What changed**: two or three plain sentences.
2. **Why**: the problem this solves.
3. **How to test**: numbered steps a reviewer can follow.
4. **Risks**: anything that could break. Write "None found" if there are none.

Keep it under 200 words. No marketing language.

Extra notes from the user: $ARGUMENTS

Two things to notice:

  • Lines starting with !` run a shell command before Claude sees the skill. The output replaces the line, so Claude gets real data from your repo.
  • $ARGUMENTS is replaced with whatever you type after the skill name.

If your main branch is called master, change main to master in both commands.

3. Use it

Text
/pr-summary
/pr-summary mention that this fixes issue #42

Or just ask "write a PR description for this branch". Claude matches your words to the description and loads the skill on its own. Type / or run /skills to check that it shows up.

Frontmatter fields worth knowing#

FieldWhat it does
nameThe command name. Defaults to the folder name.
descriptionTells Claude when to use the skill. The most important line in the file.
disable-model-invocationSet to true so only you can run it with /name. Use it for deploys and anything with side effects.
allowed-toolsTools Claude can use without asking while the skill runs, like Bash(git add *) Bash(git commit *)
modelRuns the skill on a specific model
effortRuns the skill at a specific effort level
context: forkRuns the skill in a subagent, so it doesn't fill your main conversation

Write descriptions Claude can match#

Claude decides whether to load a skill from the description alone. Say what it does and when to use it, using the words people actually type.

  • Too vague: Helps with PRs.
  • Good: Writes a pull request description for the current branch. Use when the user asks for a PR description or PR summary.

Add supporting files#

A skill folder can also hold reference docs, templates and scripts. Link them from SKILL.md, and Claude reads them only when it needs them. Keep SKILL.md itself under 500 lines.

Text
my-skill/
  SKILL.md
  reference.md
  examples.md
  scripts/
    helper.py

When to make a skill#

My rule: if I've typed the same instructions three times, it becomes a skill. Good candidates:

  • PR descriptions and release notes
  • Adding a new API endpoint the way your team does it
  • Writing database migrations
  • Your team's code review checklist
  • Setting up a new component with its test and story files

10. Subagents: hand work to a helper#

A subagent is a helper that Claude can hand a job to. It gets its own fresh context window, its own instructions, its own tools and even its own model. It does the work, then reports back a short summary. Your main conversation only sees that summary, not every file the helper read along the way.

Where the reading happens

The same job, investigating how an auth system handles token refresh, done two ways. Without a subagent, every file Claude reads lands in your main conversation's context, which fills up. With a subagent, Claude hands the job to a helper with its own fresh context window, instructions, tools and model. The files land in the subagent's context, and only a short summary comes back to the main conversation.

Why use one#

  • Clean context. Big searches and reviews don't clutter your main conversation.
  • Parallel work. Several subagents can run at the same time.
  • Lower cost. A subagent that only searches can run on Haiku or Sonnet.
  • Safety. You can give a reviewer read-only tools so it can't change your code.

Built-in subagents#

Claude Code ships with a few, and Claude uses them on its own:

SubagentWhat it does
ExploreFast, read-only search through your codebase
PlanRead-only research while you're in plan mode
general-purposeFull tools for bigger multi-step tasks

You can also ask for one directly:

Text
use a subagent to investigate how our auth system handles token refresh

Make your own: a code reviewer#

Subagents are markdown files in .claude/agents/ (for the project) or ~/.claude/agents/ (for you, in every project). Create .claude/agents/code-reviewer.md:

Markdown
---
name: code-reviewer
description: Reviews code changes for bugs, security problems and missing tests. Use after writing or changing code, before committing.
tools: Read, Grep, Glob, Bash
model: sonnet
---

You are a careful senior code reviewer.

1. Run `git diff` to see what changed.
2. Read the changed files and anything they call.
3. Look for bugs, unhandled errors, security issues, missing tests,
   and code that doesn't follow the rules in CLAUDE.md.
4. Report findings in three groups: Must fix, Should fix, Nice to have.
   Include the file and line for each one.

Do not edit any files. Only report.

The tools line leaves out Edit and Write, so the reviewer has no editing tools. It keeps Bash to run git diff, though, and Bash can still write files. For a strictly read-only reviewer, also add permissionMode: plan. The description tells Claude when to call it.

If it doesn't show up right away, restart Claude Code. Then use it:

Text
use the code-reviewer agent to review my changes

I run a review agent like this before every push. It catches the small stuff before it reaches a pull request.

Fields you can set#

FieldWhat it does
nameThe agent's name (required)
descriptionWhen Claude should use it (required)
toolsWhich tools it can use. Leave it out to give it the same tools as the main session.
modelsonnet, opus, haiku, fable, or inherit to match the main session
permissionModeSets its permission mode, for example plan for read-only work
isolation: worktreeRuns it in its own git worktree so its edits don't collide with yours

Background and parallel work#

Press Ctrl+B to send a running task to the background and keep working. Claude can also run several subagents at once, like one checking the database layer while another reviews the API routes.

Agent teams (experimental)#

There's also an experimental feature called agent teams. A lead agent coordinates several teammates that share a task list and can message each other. It's off by default and uses far more tokens than normal subagents. If you want to try it, set CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 before starting Claude Code.

11. Skills vs subagents, and where everything else fits#

Here's the short version. A skill adds instructions to your current conversation. A subagent does a job in a separate conversation and hands back the result.

Use a skill when you want Claude to do something your way, like writing a PR description in your format. Use a subagent when the job is big or separate, and you only care about the answer, like reviewing a diff or searching a large codebase.

Claude Code has six ways to extend it, and they're easy to mix up:

FeatureWhat it isUse it forExample
CLAUDE.mdNotes loaded in every sessionFacts and rules that are always true"Run tests with npm test"
SkillInstructions loaded when neededRepeatable how-to tasks/pr-summary
SubagentA helper with its own contextBig or separate jobs, parallel workcode-reviewer
HookA command that runs on an eventThings that must happen every timeFormat after each edit
MCP serverA connection to an outside toolData and actions outside your repoGitHub, Notion, Sentry
PluginA bundle of the aboveSharing a setup with your teamA team review kit

Which one do I need?#

Work down these questions and stop at the first yes.

Which one do I need?

Try one:
  1. Must it happen every time, with no exceptions? → Hook

  2. Does Claude need data or actions from outside your repo? → MCP server

  3. Is it a big or separate job where you only need the answer? → Subagent

  4. Is it a how-to you keep explaining the same way? → Skill

  5. Is it a fact or rule that is always true for this project? → CLAUDE.md

Five questions to pick a Claude Code feature, answered in order until the first yes. If it must happen every time, use a hook. If Claude needs data or actions from outside your repo, use an MCP server. If it is a big or separate job where you only need the answer, use a subagent. If it is a how-to you keep explaining the same way, use a skill. If it is a fact or rule that is always true for the project, put it in CLAUDE.md.

Once you have a few of these set up and want your team to have them too, bundle them into a plugin (section 14).

They work together#

These aren't either-or. A skill can run inside a subagent with context: fork. A plugin can ship skills, agents, hooks and MCP servers together. A hook can run your tests every time Claude finishes. Most good setups use a bit of each.

12. MCP servers: connect Claude to your tools#

MCP stands for Model Context Protocol. It's an open standard that lets Claude Code plug into outside tools. Once a server is connected, Claude can use its tools: read GitHub issues, check errors in Sentry, query a database or update a Notion page.

There are two kinds of servers:

  • Remote (HTTP): runs on the provider's side. You add a URL. Use this when a provider offers one.
  • Local (stdio): runs on your machine as a command, often through npx.

Two kinds of MCP server

  • Remote (HTTP): runs on the provider's side. You add a URL.
  • Local (stdio): runs on your machine as a command, often through npx.
Where an MCP server runs. Claude Code runs on your machine. A remote server runs on the provider's side: Claude Code calls its URL over HTTP, Notion's at mcp.notion.com/mcp with a browser login through /mcp, and GitHub's at api.githubcopilot.com/mcp/ with a bearer token in the Authorization header. A local server also runs on your machine: Claude Code starts airtable-mcp-server with npx, talks to it over stdio, and that process calls Airtable with the AIRTABLE_API_KEY you gave it.

Add a remote server#

Shell
claude mcp add --transport http notion https://mcp.notion.com/mcp

Then, inside Claude Code, run /mcp and follow the browser login. Claude Code stores the login and refreshes it for you.

Some servers use a token instead of a browser login. GitHub is a common one:

Shell
claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
  --header "Authorization: Bearer YOUR_GITHUB_PAT"

Claude Code saves this without checking the token. Run /mcp afterward and make sure the server says connected.

Add a local server#

Shell
claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable \
  -- npx -y airtable-mcp-server

Everything after -- is the command that starts the server. Everything before it is for Claude Code. Keep another option between --env and the server name: if the name comes right after --env, Claude Code reads it as another KEY=value pair and rejects the command.

Choose who gets the server#

ScopeWho gets itStored in
local (default)Just you, in this project~/.claude.json
projectEveryone on the project.mcp.json in your repo
userJust you, in every project~/.claude.json

To share a server with your team, add --scope project:

Shell
claude mcp add --transport http --scope project notion https://mcp.notion.com/mcp

That creates a .mcp.json file you can commit:

JSON
{
  "mcpServers": {
    "notion": {
      "type": "http",
      "url": "https://mcp.notion.com/mcp"
    }
  }
}

Never commit real tokens in that file. It supports environment variables like ${GITHUB_TOKEN}, so each person can use their own.

Manage your servers#

Shell
claude mcp list           # see all servers
claude mcp get github     # details for one
claude mcp remove github  # remove one

Inside a session, /mcp shows each server's status and lets you log in or out.

Use it#

Once connected, just ask in plain English:

Text
show me all open PRs assigned to me
create an issue for the bug we just found

A few tips#

  • Add only what you use. Every server brings tools that Claude has to keep track of. Claude Code loads tool details on demand by default, but fewer servers still means less noise.
  • Watch big outputs. Claude Code caps MCP output at 25,000 tokens by default. Set MAX_MCP_OUTPUT_TOKENS to change it.
  • Trust matters. A server can see what you send it and acts with your credentials. Only add servers from sources you trust.

13. Hooks: rules that always run#

Hooks are shell commands that run automatically at set moments, like right after Claude edits a file or right before it runs a command. CLAUDE.md is a request. A hook is a rule. It runs every time, no matter what.

The events you'll use most:

EventWhen it runs
PreToolUseBefore Claude uses a tool. It can block the action.
PostToolUseAfter a tool finishes successfully
UserPromptSubmitWhen you send a prompt
StopWhen Claude finishes responding
SessionStartWhen a session starts or resumes
NotificationWhen Claude needs your attention

The examples below use jq to read the JSON that Claude Code passes to each hook. Install it first with brew install jq on macOS or sudo apt-get install jq on Ubuntu. On Windows, these work through Git Bash or WSL.

Example 1: format every file Claude edits#

Add this to .claude/settings.json:

JSON
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
          }
        ]
      }
    ]
  }
}

The matcher means this runs only after the Edit and Write tools. The command grabs the file path and runs Prettier on it. Your formatting is now consistent without anyone asking.

Example 2: block edits to secret files#

First, save this script as .claude/hooks/protect-files.sh:

Shell
#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

PROTECTED_PATTERNS=(".env" "package-lock.json" ".git/")

for pattern in "${PROTECTED_PATTERNS[@]}"; do
  if [[ "$FILE_PATH" == *"$pattern"* ]]; then
    echo "Blocked: $FILE_PATH matches protected pattern '$pattern'" >&2
    exit 2
  fi
done

exit 0

Make it executable:

Shell
chmod +x .claude/hooks/protect-files.sh

Then register it in .claude/settings.json:

JSON
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
          }
        ]
      }
    ]
  }
}

Exit code 2 is the key part. It blocks the action and sends your message back to Claude, so Claude knows why it was stopped and can try another way.

If you use both examples, put both events inside the same "hooks" object, one under PostToolUse and one under PreToolUse. Claude Code notices changes to hooks in your settings files on its own, so there's no need to restart. Run /hooks to see the hooks it has loaded.

Where hooks run in a turn

The hook events in one turn, in order: SessionStart when a session starts, UserPromptSubmit when you send a prompt, then Claude calls a tool. PreToolUse runs before the tool and can block it. If it allows it, the tool runs and PostToolUse runs after it finishes successfully. Stop runs when Claude finishes responding. Notification runs whenever Claude needs your attention. In the first run Claude edits src/routes/bookmarks.ts: protect-files.sh exits 0, the edit runs, and npx prettier --write formats the file. In the second run Claude tries to write .env: protect-files.sh exits 2 with the message that .env matches the protected pattern, the write never runs, PostToolUse never fires, and the message goes back to Claude so it can try another way.

Good uses for hooks#

  • Format or lint after every edit
  • Block edits to secrets, lock files or generated code
  • Run tests when Claude finishes (Stop)
  • Send a desktop notification when Claude needs you (Notification)
  • Load extra context when a session starts (SessionStart)

14. Plugins: a full setup in one command#

A plugin is a package of skills, subagents, hooks and MCP servers that you install in one go. It's how teams share a setup without copying files around.

Open the plugin manager inside Claude Code:

Text
/plugin

The Discover tab lists plugins from the marketplaces you've added. Anthropic's official marketplace is added for you the first time you start Claude Code.

You can also install a plugin directly by name and marketplace:

Text
/plugin install commit-commands@claude-plugins-official

To add another marketplace, such as your company's:

Text
/plugin marketplace add your-org/claude-plugins

Plugins run with your permissions, just like any package you install. Read what a plugin does before you add it.

Want to make your own? A plugin is just a folder with a .claude-plugin/plugin.json manifest, plus the skills, agents, hooks and MCP config you want to ship. The plugins docs walk through it.

15. Beyond the terminal#

Once you're comfortable, Claude Code can run in scripts, in CI and in parallel.

Headless mode: claude -p#

The -p flag runs one prompt, prints the answer and exits. It works like any other command line tool, so you can pipe data in and out:

Shell
claude -p "list every TODO comment in this repo with its file and line"

git log --oneline -20 | claude -p "summarize these recent commits"

claude -p "find unused exports" --output-format json

In scripts, limit what Claude can do with --allowedTools. Pass each rule as its own quoted argument:

Shell
claude -p "fix the lint errors in src/" --allowedTools "Read" "Edit" "Bash(npm run *)"

GitHub Actions#

Inside Claude Code, run:

Text
/install-github-app

It walks you through installing the GitHub app and adding the workflow to your repo. After that, mention @claude in an issue or pull request comment, and Claude will answer questions, review code or push a fix.

Parallel sessions with worktrees#

Want Claude fixing a bug in one terminal while you build a feature in another? Use a git worktree:

Shell
claude --worktree feature-auth

Each worktree is a separate checkout on its own branch, so the two sessions never edit the same files. Run the same command with a different name in a second terminal. Your repo needs at least one commit first.

Other places to use it#

  • VS Code and Cursor: install the Claude Code extension to see diffs inline
  • JetBrains: install the plugin, then use the CLI inside the IDE
  • Desktop app and web: the same agent with a visual interface, handy for long tasks
  • Mobile: start or check on tasks from your phone

Build your own agent#

If you want to build a product on the same engine, the Claude Agent SDK gives you Claude Code's tools and agent loop as a library. It's available for Python (claude-agent-sdk) and TypeScript (@anthropic-ai/claude-agent-sdk).

16. Hands-on demo: build a Bookmarks API end to end#

Time to put it all together. You'll build a small REST API for saving bookmarks, and along the way you'll use plan mode, the agentic loop, CLAUDE.md, hooks, a skill, a subagent, model and effort switching, an MCP server and headless mode.

Time: about an hour.

You need: Claude Code installed and logged in, Node.js 22 or newer, git, and jq (for the hooks). A GitHub account is only needed for step 9, which is optional.

Claude writes the code, so your files won't match mine line for line. That's fine. What matters is the workflow.

The demo, step by step

The ten demo steps drawn to time, 65 minutes in all, or 55 without the optional step 9. Step 1, Create the project, 2 minutes, teaches Your first session. Step 2, Plan it in plan mode, 10 minutes, teaches Plan mode and effort. Step 3, Build it and let the tests drive, 10 minutes, teaches Agentic loop. Step 4, Write CLAUDE.md, 5 minutes, teaches CLAUDE.md. Step 5, Add hooks, 8 minutes, teaches Hooks. Step 6, Create a skill, 10 minutes, teaches Skills. Step 7, Review with a subagent, 5 minutes, teaches Subagents. Step 8, Switch model and effort, 3 minutes, teaches Model switching. Step 9, Connect GitHub with MCP, 10 minutes, teaches MCP servers, optional. Step 10, Bonus, headless mode, 2 minutes, teaches Headless mode.

Step 1: Create the project (2 min)#

Shell
mkdir bookmarks-api && cd bookmarks-api
git init
claude

Step 2: Plan it in plan mode (10 min)#

Press Shift+Tab until the bottom of the screen shows plan mode. Then turn up the effort, since planning is where thinking pays off:

Text
/effort high

Now paste this prompt:

Text
Plan a small REST API for saving bookmarks.

Stack: TypeScript, Express, Vitest. Use npm.
Run the server on port 3000.

Endpoints:
- POST /bookmarks saves a bookmark (url, title, optional tags)
- GET /bookmarks lists all bookmarks
- DELETE /bookmarks/:id deletes one

Store data in a JSON file in data/ for now.
Reject any url that isn't http or https.
Every endpoint needs tests.
Add npm scripts for dev, test and lint.
Keep dependencies to a minimum.

Claude may ask a question or two, then shows a plan. Read it. Press Ctrl+G if you want to change something in your editor. When it looks right, approve it. If Claude asks how to continue, choose the option that lets it edit files while you watch.

Step 3: Build it and let the tests drive (10 min)#

This is the agentic loop in action. Claude writes the code, installs packages, runs the tests, reads any errors, fixes them and runs the tests again until they pass. Approve commands as it asks, and watch how it reacts to failures.

When it says it's done, check for yourself:

Text
!npm test

Then start the server in a second terminal with npm run dev and try it:

Shell
curl -X POST localhost:3000/bookmarks \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "title": "Example"}'

curl localhost:3000/bookmarks

Happy with it? Ask Claude to commit:

Text
review the changes, make sure node_modules is in .gitignore, then commit with a clear message

Step 4: Write CLAUDE.md (5 min)#

Now that there's real code, let Claude describe it:

Text
/init

Open the new CLAUDE.md and add your house rules at the bottom:

Markdown
## House rules
- Every route needs tests in tests/
- One route file per resource in src/routes/
- Don't add dependencies without asking

Step 5: Add hooks (8 min)#

First, ask Claude to add Prettier:

Text
add prettier as a dev dependency with a default config

Then create .claude/hooks/protect-files.sh with the script from section 13 and make it executable with chmod +x. Now create .claude/settings.json with both hooks:

JSON
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
          }
        ]
      }
    ]
  }
}

Claude Code picks up the new hooks on its own. Run /hooks to check that both are listed. Now test the block:

Text
create a .env file with PORT=3000

Claude gets stopped by your hook and tells you why. That's a rule CLAUDE.md alone can't guarantee.

Commit your work.

Step 6: Create a skill (10 min)#

Adding endpoints is something you'll repeat, so make it a skill. Create .claude/skills/add-endpoint/SKILL.md:

Markdown
---
name: add-endpoint
description: Adds a new REST endpoint to the Bookmarks API with a route handler, tests and a README entry. Use when the user asks to add an endpoint or route.
---

Add this endpoint: $ARGUMENTS

Follow these steps in order:

1. Read CLAUDE.md and one existing route in src/routes/ to match the style.
2. Write the tests first in tests/. Cover the success case and at least one error case.
3. Run npm test and confirm the new tests fail.
4. Write the route handler and register it.
5. Run npm test until everything passes.
6. Add the endpoint to the API section of README.md with an example curl request.
7. Finish with a short list of the files you changed.

Now use it:

Text
/add-endpoint GET /bookmarks/search?tag=<tag> returns bookmarks that have that tag

Watch Claude follow your steps in order: tests first, then code, then docs. Don't commit yet.

Step 7: Review with a subagent (5 min)#

Create .claude/agents/code-reviewer.md using the file from section 10. Restart Claude Code if needed, then:

Text
use the code-reviewer agent to review my uncommitted changes

The reviewer runs in its own context on Sonnet, reads the diff and reports back. Ask Claude to fix anything in the Must fix group, run the tests, then commit.

Step 8: Switch model and effort (3 min)#

Not every task needs deep thinking. Drop down for a simple change:

Text
/model sonnet
/effort low
rename the data folder to storage and update every path that uses it. run the tests.

Notice how much faster that goes. Switch back when you're done:

Text
/model default
/effort medium

Step 9: Connect GitHub with MCP (10 min, optional)#

Skip this if you don't have a GitHub account. Everything else still works.

  1. Create an empty repo called bookmarks-api on GitHub.
  2. Create a personal access token with repo access in your GitHub settings.
  3. Exit Claude Code and add the GitHub MCP server:
Shell
claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
  --header "Authorization: Bearer YOUR_GITHUB_PAT"

Start Claude Code again with claude --continue and run /mcp to make sure GitHub shows as connected. Then:

Text
add my GitHub repo bookmarks-api as the origin remote and push the main branch
Text
create a branch called add-pagination. add pagination to GET /bookmarks with page and limit query params, with tests. commit, push the branch, and open a pull request with a clear description.

Claude uses git to push and the GitHub MCP server to open the pull request. Check GitHub and you'll see it waiting for review.

Step 10: Bonus, headless mode (2 min)#

Exit Claude Code and run this in your terminal:

Shell
git log -5 --oneline | claude -p "Write a short CHANGELOG entry in markdown for these commits" > CHANGELOG.md

One command, no chat, and you have a changelog.

What you just used#

FeatureWhere
Plan mode and effortSteps 2 and 8
Agentic loop (code, test, fix)Step 3
CLAUDE.mdStep 4
HooksStep 5
SkillsStep 6
SubagentsStep 7
Model switchingSteps 7 and 8
MCP serversStep 9
Headless modeStep 10

17. Common mistakes (and what to do instead)#

Using one session for everything. Old, unrelated conversation fills the context and quality drops. Run /clear when you switch tasks.

Vague prompts. "Fix the bug" makes Claude guess. Say what's wrong, where to look and how to check the fix.

No way for Claude to check its work. Without tests or a build to run, Claude can only hope it's right. Always tell it how to verify.

Arguing with Claude in circles. If you've corrected the same mistake twice, stop. Press Esc twice with an empty prompt to rewind to before things went wrong, or /clear and start again with a better prompt. A fresh start beats a long, confused thread.

A 500-line CLAUDE.md. It loads every session, and the important rules get lost in the noise. Keep it short and move how-to details into skills.

Ten MCP servers you never use. Each one adds tools for Claude to keep track of. Remove the ones you don't need with claude mcp remove.

Bypass permissions on your main machine. It skips every safety prompt. Keep it for containers and throwaway VMs.

Committing without reading the diff. You own the code, not Claude. Read what changed before it goes into your history.

18. FAQ#

Is Claude Code free?#

No. You need a Claude Pro, Max, Team or Enterprise plan, or an Anthropic Console account that pays per use. The free Claude plan doesn't include Claude Code.

Does Claude Code work on Windows?#

Yes. Install it with the PowerShell one-liner or WinGet. Git for Windows is recommended so Claude Code can use Git Bash, but without it Claude Code falls back to PowerShell. It also works inside WSL.

How is Claude Code different from the Claude app?#

The Claude app is a chat. Claude Code works inside your project: it reads your files, edits code and runs commands like tests and git.

What's the difference between skills and subagents?#

A skill adds instructions to your current conversation when they're needed, like a recipe. A subagent does a job in its own separate context and sends back only the result, like a helper you delegate to.

How do I add an MCP server to Claude Code?#

Run claude mcp add --transport http <name> <url> for a remote server, then run /mcp inside Claude Code to log in and check that it's connected.

Which model should I use in Claude Code?#

The default (Opus 5.5) is right for most work. Use Sonnet when you want more speed on simple tasks, and Haiku for lightweight subagents. Run /model to see what your plan offers.

What does ultrathink do?#

Adding the word "ultrathink" to a prompt asks Claude to reason more deeply for that one turn, without changing your effort setting.

Can I use Claude Code in VS Code?#

Yes. There's an official extension for VS Code and Cursor, and a plugin for JetBrains IDEs.

Can I undo what Claude did?#

Yes. Press Esc twice with an empty prompt, or run /rewind, to go back to an earlier point in the session, including file changes. Git is still your best safety net, so commit often.

Wrapping up#

If you remember five things from this guide, make it these:

  1. Give Claude context with a short CLAUDE.md.
  2. Plan before big changes, and give Claude a way to check its own work.
  3. Turn repeated instructions into skills.
  4. Hand big or separate jobs to subagents.
  5. Use hooks for hard rules and MCP to connect your other tools.

The best way to learn Claude Code is to use it on a real task this week. Start small, keep the loop tight, and add skills and agents as you notice yourself repeating things.

Further reading#

Changelog#

  • October 12, 2026: First version. Covers Claude Code 2.1, the Opus 5.5 model lineup, effort levels, skills, subagents, MCP, hooks and plugins.