Claude Code 101: A Complete Tutorial From Install to Agentic Workflows
30 min readRaj Bhensdadiya
On this page
- 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: how much freedom to give
- 6. Models: which Claude should you use?
- 7. Effort levels: how hard Claude thinks
- 8. A workflow that works: explore, plan, code, commit
- 9. Skills: automate tasks you repeat
- 10. Subagents: hand work to a helper
- 11. Skills vs subagents, and where everything else fits
- 12. MCP servers: connect Claude to your tools
- 13. Hooks: rules that always run
- 14. Plugins: a full setup in one command
- 15. Beyond the terminal
- 16. Hands-on demo: build a Bookmarks API end to end
- 17. Common mistakes (and what to do instead)
- 18. FAQ
- 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:
- What is Claude Code?
- How to install Claude Code
- Your first session
- CLAUDE.md: teach Claude your project
- Permission modes
- Models
- Effort levels
- A workflow that works
- Skills
- Subagents
- Skills vs subagents
- MCP servers
- Hooks
- Plugins
- Beyond the terminal
- Hands-on demo
- Common mistakes
- 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
Where it runs#
| Where | Good for |
|---|---|
| Terminal (CLI) | The full feature set. This guide uses it. |
| VS Code and Cursor | Reviewing diffs inside your editor |
| JetBrains IDEs | The same idea for IntelliJ, PyCharm, WebStorm and friends |
| Desktop app | A visual interface if you don't live in the terminal |
| Web (claude.ai/code) | Running sessions in the browser with nothing to install |
| Mobile app | Starting or checking on tasks from your phone |
| Slack | Asking @Claude for help right in a channel |
| GitHub Actions | Letting 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:
curl -fsSL https://claude.ai/install.sh | bash
Windows (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:
# 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#
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:
# 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:
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:
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.tspulls that file straight in. - Run your own commands with !.
!git statusruns 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 --continueresumes your last session in that folder.claude --resumelets you choose from a list.
10 commands every beginner needs#
Type / to see every command. These are the ones you will use most:
| Command | What it does |
|---|---|
/help | Lists commands and help |
/init | Writes a starter CLAUDE.md for your project |
/clear | Starts a fresh conversation. Your files stay as they are. |
/compact | Summarizes a long conversation to free up space |
/model | Switches the model |
/effort | Changes how hard Claude thinks |
/usage | Shows how much of your plan or budget you've used |
/resume | Opens an earlier session |
/rewind | Goes back to an earlier point in the session |
/btw | Asks a quick side question that doesn't get added to the main conversation |
Shortcuts worth learning#
| Keys | What they do |
|---|---|
| Shift+Tab | Cycles permission modes (more on this in section 5) |
| Esc | Stops Claude |
| Esc, Esc | Opens rewind when the prompt is empty. With text in the prompt, it clears the draft. |
| Ctrl+B | Sends a running task to the background |
| Ctrl+G | Opens your prompt or plan in your text editor |
| Ctrl+R | Searches 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:
/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#
| File | Who it's for | Commit it? |
|---|---|---|
~/.claude/CLAUDE.md | You, in every project | No, it lives on your machine |
./CLAUDE.md or ./.claude/CLAUDE.md | Everyone on the project | Yes |
./CLAUDE.local.md | Just you, in this project | No, 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:
# 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 rulesand 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.
| Mode | What happens | Use it when |
|---|---|---|
Manual (default) | Asks the first time it uses each tool | You're new, or the repo is unfamiliar |
| Accept edits | Edits files without asking, still asks for most commands | You're watching and reviewing diffs |
| Plan | Reads and explores only, then gives you a plan to approve | Starting any bigger change |
| Auto | No routine prompts. A background check reviews commands and network requests first | Longer tasks where you trust the direction |
| Don't ask | Refuses anything you haven't already allowed | Locked-down setups and scripts |
| Bypass permissions | Skips the prompts | Only 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:
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:
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)"
],
"deny": [
"Bash(git push *)",
"Read(./.env)"
]
}
}
How a request meets these rules
Claude wants to
Checking
Runs without askingClaude can run any npm script without asking.
Runs without askingCommits are allowed, so Claude makes them without asking.
BlockedIt can never push. Deny rules always win over allow rules.
BlockedIt can't read your .env file.
Claude asks youNo rule matches, so your permission mode decides. Manual asks first.
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:
| File | Applies to |
|---|---|
~/.claude/settings.json | You, in every project |
.claude/settings.json | Everyone on the project (commit it) |
.claude/settings.local.json | Just 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:
| Model | Alias | Good for | Trade-off |
|---|---|---|---|
| Opus 5.5 | opus | The default. Hard problems, big changes, planning | Heavier on usage than Sonnet |
| Sonnet 5.5 | sonnet | Everyday coding at good speed | A bit less depth on the hardest tasks |
| Haiku 5.5 | haiku | Quick, simple jobs and cheap subagents | Not for complex reasoning |
| Fable | fable | Anthropic's top-tier model for the toughest work | Not the default. Check /model to see if your plan offers it. |
There are also a few handy aliases:
opusplanuses Opus while you're in plan mode and Sonnet when it's writing the code. You get careful planning and faster building.defaultgoes 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:
/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:
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.
| Level | What it feels like | Use it for |
|---|---|---|
low | Fast and short | Renames, typo fixes, simple edits |
medium | Balanced. The default on the 5.5 models. | Most everyday work |
high | Thinks things through | Tricky bugs, features that touch several files |
xhigh | Very thorough | Design decisions, hard debugging |
max | Everything it has | Rare, really hard problems |
How to set it#
Inside Claude Code:
/effort
/effort high
The first opens a slider. The second sets it directly. When starting a session:
claude --effort high
ultrathink#
Want one deep answer without changing your setting? Put the word ultrathink anywhere in your prompt:
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.
Plan the Bookmarks API
Opus 5.5, high effort. Demo, step 2
Turn up the effort on the default model, since planning is where thinking pays off.
Rename a folder
Sonnet 5.5, low effort. Demo, step 8
Not every task needs deep thinking. Drop down for a simple change.
Design decisions, hard debugging
Opus 5.5, xhigh effort. Section 7
Very thorough, on the default model. Slower, and it uses more of your plan limits.
/model default/effort medium8. 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
Step 1: Explore#
Ask Claude to read the relevant code first, with no changes:
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:
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:
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:
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:
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
/clearwhen you switch to an unrelated task - Run
/compactduring 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.
Weak prompt vs strong prompt#
Weak:
fix the login bug
Strong:
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 loadsHow a skill loads, step 6 of 6
- 1.Session starts. Claude sees only each skill's short description.Session starts. Claude sees only each skill's short description.
- 2.You ask in plain English.You type the skill's name, with a note after it.
“write a PR description for this branch”/pr-summary mention that this fixes issue #42
- 3.Your words match pr-summary's description.Typing /pr-summary runs it directly. No matching needed.
- 4.The full SKILL.md loads.The full SKILL.md loads.
- 5.Its ! lines run first. Their output replaces them.Its ! lines run first, and $ARGUMENTS becomes your note.
- 6.Claude follows the instructions and writes the PR description.Claude follows the instructions and writes the PR description.
A skill costs almost nothing until it's actually used.
Where skills live#
| Location | Who can use it |
|---|---|
~/.claude/skills/<name>/SKILL.md | You, in every project |
.claude/skills/<name>/SKILL.md | Everyone on the project (commit it to git) |
| Inside a plugin | Anyone 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
mkdir -p ~/.claude/skills/pr-summary
2. Create ~/.claude/skills/pr-summary/SKILL.md
---
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. $ARGUMENTSis 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
/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#
| Field | What it does |
|---|---|
name | The command name. Defaults to the folder name. |
description | Tells Claude when to use the skill. The most important line in the file. |
disable-model-invocation | Set to true so only you can run it with /name. Use it for deploys and anything with side effects. |
allowed-tools | Tools Claude can use without asking while the skill runs, like Bash(git add *) Bash(git commit *) |
model | Runs the skill on a specific model |
effort | Runs the skill at a specific effort level |
context: fork | Runs 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.
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
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:
| Subagent | What it does |
|---|---|
| Explore | Fast, read-only search through your codebase |
| Plan | Read-only research while you're in plan mode |
| general-purpose | Full tools for bigger multi-step tasks |
You can also ask for one directly:
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:
---
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:
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#
| Field | What it does |
|---|---|
name | The agent's name (required) |
description | When Claude should use it (required) |
tools | Which tools it can use. Leave it out to give it the same tools as the main session. |
model | sonnet, opus, haiku, fable, or inherit to match the main session |
permissionMode | Sets its permission mode, for example plan for read-only work |
isolation: worktree | Runs 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:
| Feature | What it is | Use it for | Example |
|---|---|---|---|
| CLAUDE.md | Notes loaded in every session | Facts and rules that are always true | "Run tests with npm test" |
| Skill | Instructions loaded when needed | Repeatable how-to tasks | /pr-summary |
| Subagent | A helper with its own context | Big or separate jobs, parallel work | code-reviewer |
| Hook | A command that runs on an event | Things that must happen every time | Format after each edit |
| MCP server | A connection to an outside tool | Data and actions outside your repo | GitHub, Notion, Sentry |
| Plugin | A bundle of the above | Sharing a setup with your team | A team review kit |
Which one do I need?#
Work down these questions and stop at the first yes.
Which one do I need?
Must it happen every time, with no exceptions? → Hook
Does Claude need data or actions from outside your repo? → MCP server
Is it a big or separate job where you only need the answer? → Subagent
Is it a how-to you keep explaining the same way? → Skill
Is it a fact or rule that is always true for this project? → 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.
Add a remote server#
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:
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#
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#
| Scope | Who gets it | Stored in |
|---|---|---|
local (default) | Just you, in this project | ~/.claude.json |
project | Everyone on the project | .mcp.json in your repo |
user | Just you, in every project | ~/.claude.json |
To share a server with your team, add --scope project:
claude mcp add --transport http --scope project notion https://mcp.notion.com/mcp
That creates a .mcp.json file you can commit:
{
"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#
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:
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_TOKENSto 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:
| Event | When it runs |
|---|---|
PreToolUse | Before Claude uses a tool. It can block the action. |
PostToolUse | After a tool finishes successfully |
UserPromptSubmit | When you send a prompt |
Stop | When Claude finishes responding |
SessionStart | When a session starts or resumes |
Notification | When 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:
{
"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:
#!/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:
chmod +x .claude/hooks/protect-files.sh
Then register it in .claude/settings.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
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:
/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:
/plugin install commit-commands@claude-plugins-official
To add another marketplace, such as your company's:
/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:
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:
claude -p "fix the lint errors in src/" --allowedTools "Read" "Edit" "Bash(npm run *)"
GitHub Actions#
Inside Claude Code, run:
/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:
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
65of 65 min
About an hour. 55 min without the optional step 9.
- 1Create the project2 minYour first session
- 2Plan it in plan mode10 minPlan mode and effort
- 3Build it and let the tests drive10 minAgentic loop
- 4Write CLAUDE.md5 minCLAUDE.md
- 5Add hooks8 minHooks
- 6Create a skill10 minSkills
- 7Review with a subagent5 minSubagents
- 8Switch model and effort3 minModel switching
- 9Connect GitHub with MCP10 minMCP servers, optional
- 10Bonus, headless mode2 minHeadless mode
Step 1: Create the project (2 min)#
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:
/effort high
Now paste this prompt:
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:
!npm test
Then start the server in a second terminal with npm run dev and try it:
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:
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:
/init
Open the new CLAUDE.md and add your house rules at the bottom:
## 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:
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:
{
"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:
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:
---
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:
/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:
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:
/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:
/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.
- Create an empty repo called
bookmarks-apion GitHub. - Create a personal access token with repo access in your GitHub settings.
- Exit Claude Code and add the GitHub MCP server:
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:
add my GitHub repo bookmarks-api as the origin remote and push the main branch
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:
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#
| Feature | Where |
|---|---|
| Plan mode and effort | Steps 2 and 8 |
| Agentic loop (code, test, fix) | Step 3 |
| CLAUDE.md | Step 4 |
| Hooks | Step 5 |
| Skills | Step 6 |
| Subagents | Step 7 |
| Model switching | Steps 7 and 8 |
| MCP servers | Step 9 |
| Headless mode | Step 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:
- Give Claude context with a short CLAUDE.md.
- Plan before big changes, and give Claude a way to check its own work.
- Turn repeated instructions into skills.
- Hand big or separate jobs to subagents.
- 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.