Claude Code is not just a coding assistant you talk to. It is a programmable development environment. Most developers use about 20% of it — the chat part. The other 80% is a system of memory, automation, agents, and integrations that most people never touch because the documentation describes what features do, not how to combine them into something useful.
This guide covers all 10 core feature areas, from the simplest to the most powerful, with real templates you can copy and use today.
How Claude Code is structured
Before diving in, here is the mental model that makes everything click:
┌─────────────────────────────────────────────────────────────┐
│ YOUR PROJECT │
│ │
│ CLAUDE.md ──────────── persistent memory / context │
│ .claude/commands/ ───── slash commands you define │
│ .claude/skills/ ─────── auto-triggered capabilities │
│ .claude/hooks/ ──────── event-driven automation │
│ .claude/plugins/ ────── bundled feature collections │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌───────────────┐ │
│ │ Main Agent │───▶│ Subagents │───▶│ MCP Servers │ │
│ │ (you chat) │ │ (delegated) │ │ (ext. tools) │ │
│ └─────────────┘ └──────────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────────────┘
Each layer adds capability. You can use just the first layer (chat) and still be productive. Add more layers and Claude Code starts handling entire workflows on its own.
Learning path
| Level | Features | Time |
|---|---|---|
| Beginner | Slash Commands, Memory, Checkpoints, CLI | ~3 hours |
| Intermediate | Skills, Hooks, MCP, Subagents | ~5 hours |
| Advanced | Advanced Features, Plugins, combined workflows | ~5 hours |
Not sure where you are? Ask Claude: /self-assessment — it will quiz you across 8 areas and tell you exactly where to start.
1. Slash Commands — your own shortcuts
Slash commands are Markdown files that become instant commands. You type /optimize and Claude runs a specific, carefully crafted analysis. No re-explaining. No copy-pasting prompts.
How they work
.claude/
commands/
optimize.md → becomes /optimize
pr.md → becomes /pr
generate-api-docs.md → becomes /generate-api-docs
Each file contains a prompt template. Claude reads it when you invoke the command.
Create your first slash command
Create .claude/commands/optimize.md:
Analyze the selected code or current file for performance issues.
Review in this order:
1. **Performance bottlenecks** — O(n²) patterns, unnecessary loops
2. **Memory management** — leaks, circular references
3. **Algorithm selection** — better data structures or algorithms
4. **Computation** — cacheable repeated calculations
5. **Threading** — race conditions, synchronization problems
For each issue found, provide:
- Severity: Critical / High / Medium / Low
- Location: exact file and line number
- Problem: one sentence explanation
- Fix: corrected code snippet
Now type /optimize on any file. Same prompt, every time, no typing.
More useful commands to create
.claude/commands/
pr.md — generate a pull request description
review.md — full code review with security focus
test.md — generate unit tests for selected code
docs.md — write JSDoc/docstrings for a function
explain.md — explain complex code in plain English
security.md — scan for security vulnerabilities
refactor.md — suggest refactoring improvements
What to put in a command file
# Good slash command structure
## Context
[What this command is for — one sentence]
## Instructions
[Step-by-step what Claude should do]
## Output format
[Exactly how you want the response structured]
## Example
[Optional: show Claude an example of ideal output]
The more specific your command, the more consistent the output. Vague commands give vague results.
2. Memory — context that survives across sessions
By default, Claude forgets everything when a session ends. Memory files fix that. They are CLAUDE.md files that Claude reads automatically at the start of every session.
The three levels of memory
~/.claude/CLAUDE.md ← personal global memory
(your preferences, style, how you work)
./CLAUDE.md ← project memory
(what this project is, decisions made)
./src/api/CLAUDE.md ← directory memory
(rules specific to this part of the code)
Claude reads all three at startup, from most general to most specific. Directory-level rules override project-level rules, which override global rules.
Global memory template (~/.claude/CLAUDE.md)
# About me
I am a senior data engineer working primarily in Python and PySpark.
I prefer concise explanations — skip the preamble.
When I ask for code, give me the code first, explanation after.
I use Ubuntu. Terminal commands should be bash-compatible.
# Code style preferences
- Python: type hints on all function signatures
- Line length: 100 characters max
- Docstrings: Google style
- Variable names: snake_case, descriptive, no abbreviations
# Things to always check
- New functions should have unit tests
- Database queries should consider index usage
- API responses should include error handling
Project memory template (./CLAUDE.md)
# Project: [Name]
## What this is
[One paragraph describing the project]
## Tech stack
- Language: Python 3.12
- Framework: FastAPI
- Database: PostgreSQL with SQLAlchemy
- Cache: Redis
- Tests: pytest
## Architecture decisions
- We use repository pattern for data access
- All API endpoints are versioned (/api/v1/)
- Authentication via JWT tokens
## Current focus
[What we are actively working on right now]
## Things to never do
- Never use raw SQL strings — always use SQLAlchemy ORM
- Never commit credentials — use environment variables
- Never skip input validation on API endpoints
Directory memory (./src/api/CLAUDE.md)
# API Directory Rules
All endpoints in this directory must:
- Have input validation using Pydantic models
- Return standardized response format: {data, error, meta}
- Include rate limiting decorator
- Log requests at INFO level with request ID
This is powerful for large codebases. When Claude is working in /src/api/, it automatically follows those rules. Different rules in /src/jobs/. Different rules in /src/models/.
3. Checkpoints — safe experimentation
Checkpoints are session snapshots. They let you try something risky, and if it goes wrong, rewind to exactly where you were.
The basic pattern
# Before doing anything risky:
/checkpoint save "before-refactor"
# Do the risky thing
# (Claude rewrites half your codebase)
# Not happy with the result?
/checkpoint restore "before-refactor"
# Back to exactly before
# Happy with the result?
/checkpoint clear "before-refactor"
# Clean up the saved state
When to use checkpoints
✓ Before a large refactor
✓ Before changing a core interface
✓ When experimenting with a different approach
✓ Before updating dependencies
✓ Before asking Claude to "simplify everything"
✓ Any time you think "I might want to undo this"
Managing checkpoints
/checkpoint list # see all saved checkpoints
/checkpoint save "name" # save current state
/checkpoint restore "name" # go back
/checkpoint diff "name" # compare current vs saved
/checkpoint clear "name" # delete one
/checkpoint clear-all # delete all
Think of checkpoints as manual save points in a video game. Use them before every boss fight.
4. Skills — automation that runs itself
Skills are different from slash commands in one important way: you do not have to call them. They trigger automatically based on what you are doing.
Slash command vs skill
Slash command: You type /optimize → Claude runs
Skill: You edit a file → Claude automatically runs code review
You add a PR → Claude automatically checks style
Skills watch for triggers and act without being asked.
Skill structure
.claude/skills/
code-review/
skill.md ← defines when and how to trigger
review.sh ← optional supporting script
brand-voice/
skill.md
voice-guide.md ← reference document the skill uses
doc-generator/
skill.md
Create a code review skill
Create .claude/skills/code-review/skill.md:
# Skill: Automatic Code Review
## Trigger
Run after every file save in src/ directory.
Run after every git add command.
## What to do
Review the changed code for:
1. Security issues (top priority — block if found)
2. Logic errors
3. Missing error handling
4. Test coverage gaps
## Output format
If issues found:
REVIEW FINDINGS — [filename]
──────────────────────────
[SEVERITY] [Category]: Description
Line X: specific problem
Suggestion: what to do instead
If no issues found:
✓ [filename] — no issues
## Do not review
- node_modules/
- dist/
- *.test.* files (these are the tests themselves)
- *.md files
Install to global skills directory
# Project-level (only this project)
cp -r code-review/ .claude/skills/
# Global (all projects)
cp -r code-review/ ~/.claude/skills/
5. Hooks — event-driven automation
Hooks are shell scripts that run when Claude does something. They let you enforce rules, run tests, log actions, notify people, or block operations automatically.
The 25+ hook events
PreToolUse ← before Claude uses any tool
PostToolUse ← after Claude uses any tool
PreFileWrite ← before writing to a file
PostFileWrite ← after writing to a file
PreBashRun ← before running a bash command
PostBashRun ← after running a bash command
SessionStart ← when a new session begins
SessionEnd ← when a session ends
PreCommit ← before a git commit
PostCommit ← after a git commit
Exit code 0 = allow. Exit code 1 = block.
Example 1: Run tests before every commit
Create .claude/hooks/pre-commit.sh:
#!/bin/bash
echo "🧪 Running tests before commit..."
# Node.js
if [ -f "package.json" ]; then
npm test
if [ $? -ne 0 ]; then
echo "❌ Tests failed — commit blocked"
exit 1
fi
fi
# Python
if [ -f "pytest.ini" ] || [ -f "setup.py" ]; then
pytest
if [ $? -ne 0 ]; then
echo "❌ Tests failed — commit blocked"
exit 1
fi
fi
# Go
if [ -f "go.mod" ]; then
go test ./...
if [ $? -ne 0 ]; then
echo "❌ Tests failed — commit blocked"
exit 1
fi
fi
echo "✅ All tests passed"
exit 0
Register it in .claude/settings.json:
{
"hooks": {
"PreCommit": [
{
"command": "bash .claude/hooks/pre-commit.sh"
}
]
}
}
Example 2: Security scan on file writes
Create .claude/hooks/security-scan.sh:
#!/bin/bash
FILE="$1"
# Block commits containing hardcoded secrets
if grep -rE "(password|secret|api_key|token)\s*=\s*['\"][^'\"]{8,}" "$FILE" 2>/dev/null; then
echo "❌ Possible hardcoded secret detected in $FILE"
echo " Use environment variables instead"
exit 1
fi
# Block console.log in production files (not test files)
if [[ "$FILE" == src/* ]] && [[ "$FILE" != *.test.* ]]; then
if grep -n "console\.log" "$FILE" 2>/dev/null; then
echo "⚠️ console.log found in $FILE — remove before committing"
exit 1
fi
fi
exit 0
Example 3: Log everything Claude runs
Create .claude/hooks/log-bash.sh:
#!/bin/bash
COMMAND="$1"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
LOG_FILE="$HOME/.claude/activity.log"
echo "[$TIMESTAMP] BASH: $COMMAND" >> "$LOG_FILE"
exit 0
Register it for PostBashRun and you have a full audit trail of every command Claude ever ran on your machine.
Example 4: Validate prompts before Claude acts
Create .claude/hooks/validate-prompt.sh:
#!/bin/bash
PROMPT="$1"
# Block dangerous operations
DANGEROUS_PATTERNS=("rm -rf /" "DROP TABLE" "DELETE FROM.*WHERE 1=1" "format c:")
for pattern in "${DANGEROUS_PATTERNS[@]}"; do
if echo "$PROMPT" | grep -qi "$pattern"; then
echo "❌ Blocked: dangerous pattern detected: $pattern"
exit 1
fi
done
exit 0
Hook decision flow
Event fires
│
▼
Hook script runs
│
├── exit 0 ──▶ Claude proceeds normally
│
└── exit 1 ──▶ Operation blocked
Claude sees the error message
Claude can try a different approach
6. Subagents — delegate to specialists
Subagents are separate Claude instances with their own context, permissions, and focus. You use them to delegate work you do not want cluttering your main session, or work that requires different capabilities.
Main agent vs subagent
Main Agent (you)
├── Full context of your conversation
├── Can read/write anywhere
├── Your general assistant
│
└── Spawns subagents for specific tasks:
│
├── Code Reviewer ──── read-only, security-focused
├── Test Engineer ───── writes only to test files
├── Doc Writer ─────── writes only to docs/
└── Implementation ─── full access, does the actual coding
Create a code reviewer subagent
Create .claude/subagents/code-reviewer.md:
# Code Reviewer Agent
## Role
Senior code reviewer ensuring high standards of code quality and security.
## Trigger
Activate automatically after any code modification.
Run `git diff` to see what changed.
## Review priorities (in order)
1. Security vulnerabilities — authentication, authorization, data exposure
2. Performance — inefficient algorithms, N+1 queries, memory problems
3. Code quality — readability, naming, structure
4. Test coverage — are the important paths tested?
5. Design patterns — does this fit the existing architecture?
## For each issue, report
- Severity: Critical / High / Medium / Low
- Category: Security / Performance / Quality / Testing / Design
- Location: file:line
- Problem: what is wrong
- Fix: corrected code
- Impact: what breaks if this is not fixed
## Permissions
- Read: all files
- Write: none (you only review, never modify)
- Bash: git diff, git log only
Create a test engineer subagent
Create .claude/subagents/test-engineer.md:
# Test Engineer Agent
## Role
Write comprehensive tests for new and modified code.
## Trigger
Activate when asked to "add tests" or "improve test coverage".
## Approach
1. Read the implementation file
2. Identify all code paths (happy path, edge cases, error cases)
3. Check existing tests to avoid duplication
4. Write tests that are:
- Independent (no test depends on another)
- Descriptive (test name explains what is being tested)
- Complete (covers the failure modes, not just the happy path)
## Permissions
- Read: all source files
- Write: test files only (*.test.*, tests/, __tests__/)
- Bash: run tests to verify they pass
Create a documentation writer subagent
Create .claude/subagents/documentation-writer.md:
# Documentation Writer Agent
## Role
Write clear, accurate technical documentation.
## Trigger
Activate when asked to "document" anything.
## Documentation standards
- API docs: include all parameters, return values, error codes, examples
- Function docs: one-line summary, parameters, returns, raises, example
- README sections: what it is, why you would use it, how to install, quickstart
- Avoid "this function does X" — instead describe the purpose and when to call it
## Permissions
- Read: all files
- Write: docs/, README.md, *.md files only
- Bash: none
The power of read-only subagents
The most important use of permissions is restricting write access. A code reviewer that can only read cannot accidentally modify your code. A documentation writer that can only touch docs/ cannot break your source. This is safety by design.
Subagent permissions matrix:
Read Write Bash
Code Reviewer All None git diff, git log
Test Engineer All Tests only pytest, jest
Doc Writer All Docs only None
Implementation All All All
Security Auditor All None None
7. MCP — connect Claude to anything
MCP (Model Context Protocol) is how Claude reaches outside itself — to databases, GitHub, external APIs, filesystems, and any service that has an MCP server.
What MCP looks like in practice
Without MCP:
You: "What are the open GitHub issues in this repo?"
Claude: "I don't have access to GitHub — please copy and paste them."
With MCP:
You: "What are the open GitHub issues in this repo?"
Claude: [queries GitHub directly]
"There are 7 open issues. The highest priority is #142..."
MCP configuration
MCP servers are defined in .claude/mcp.json:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
Common MCP configurations
GitHub access:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
Database access:
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "${DATABASE_URL}"
}
}
}
}
Filesystem with restrictions:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/home/neel/projects",
"/tmp"
]
}
}
}
Multiple servers together:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" }
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": { "POSTGRES_CONNECTION_STRING": "${DATABASE_URL}" }
},
"slack": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-slack"],
"env": { "SLACK_BOT_TOKEN": "${SLACK_TOKEN}" }
}
}
}
With all three active, Claude can read your database, check GitHub issues, and post to Slack — all in one conversation.
MCP capability map
MCP Server What Claude can do with it
─────────────────────────────────────────────────────
GitHub Read/write issues, PRs, comments, files
PostgreSQL Query tables, schema inspection, data analysis
Filesystem Read/write files outside the project
Slack Send messages, read channels, manage threads
Notion Read/write pages, databases, blocks
Google Drive Read/write documents and spreadsheets
Jira Create/update tickets, query boards
AWS S3 Read/write objects, list buckets
8. Plugins — bundle everything together
Plugins package slash commands, skills, hooks, and MCP configs into a single installable unit. Instead of setting up a code review workflow piece by piece, a plugin gives you everything at once.
Plugin structure
.claude/plugins/
pr-review/
plugin.json ← metadata and what it includes
commands/
review-pr.md
approve.md
skills/
auto-review/
skill.md
hooks/
post-push.sh
devops-automation/
plugin.json
commands/
deploy.md
rollback.md
hooks/
validate-deploy.sh
Plugin manifest
Create .claude/plugins/pr-review/plugin.json:
{
"name": "pr-review",
"version": "1.0.0",
"description": "Automated PR review pipeline with security and quality checks",
"author": "your-name",
"commands": ["commands/review-pr.md", "commands/approve.md"],
"skills": ["skills/auto-review/"],
"hooks": {
"PostPush": ["hooks/post-push.sh"]
},
"requires": {
"mcp": ["github"]
}
}
Install a plugin
# Install from local path
claude plugin install .claude/plugins/pr-review/
# Install globally (available in all projects)
claude plugin install --global .claude/plugins/pr-review/
# List installed plugins
claude plugin list
# Remove
claude plugin remove pr-review
When to create a plugin vs individual files
Individual files are better when:
- You are still figuring out your workflow
- The feature is specific to one project
- You are experimenting
A plugin is better when:
- The workflow is stable and proven
- You want to use it across multiple projects
- You want to share it with a team
- It has multiple components that work together
9. Advanced features
Planning mode
Planning mode is for complex, multi-step tasks where you want Claude to think before touching anything.
# Turn on planning mode
/plan
# Now describe the task
"Refactor the authentication system to use JWT tokens instead of sessions.
The change affects login, logout, middleware, and 14 API endpoints."
# Claude will:
# 1. Analyse the codebase
# 2. List every file that needs to change
# 3. Describe what change is needed in each
# 4. Identify risks and dependencies
# 5. Wait for your approval before doing anything
# Review the plan, then:
/plan execute # proceed with the plan
/plan abort # cancel everything
/plan adjust # modify the plan before executing
Use planning mode any time the task touches more than 3 files or changes a shared interface.
Extended thinking
Extended thinking gives Claude more time to reason through a problem before responding. It is slower but significantly better for hard problems.
# Enable extended thinking
/think
# Ask your hard question
"Why are our API response times spiking at exactly 14:00 every day?"
# Claude will:
# - Think through all possible causes
# - Consider correlations with other events
# - Check logs and metrics (if MCP is configured)
# - Present a reasoned hypothesis with evidence
Useful for: debugging complex issues, architecture decisions, performance analysis, security reviews.
Background tasks
Background tasks let Claude work on long-running jobs without blocking your session.
# Start a background task
/background "Run the full test suite and summarise any failures"
# Your session is free — keep working
# Claude runs the task in parallel
# Check status
/background status
# Get the result when done
/background result
Use this for: running test suites, generating documentation for large codebases, scanning security vulnerabilities across many files.
10. CLI reference
The most useful flags and commands you will actually use:
Session management
claude # start new session in current directory
claude --continue # continue the last session
claude --session-id abc123 # resume a specific session by ID
claude --list-sessions # show all past sessions
Context control
claude --context ./src/api/ # only load files from this directory
claude --no-memory # ignore CLAUDE.md files this session
claude --profile work # use a named profile
Output control
claude --output json # machine-readable output
claude --no-stream # wait for full response before printing
claude --max-tokens 4096 # limit response length
Non-interactive mode (for scripts and CI)
# Run a single command and exit
claude --print "Run all tests and return exit code 1 if any fail"
# Pipe input
echo "Review this file for security issues" | claude --file src/auth.py
# In a CI pipeline
claude --print "Check if there are any TODO comments in src/" \
--no-memory \
--output json
Putting it all together — real workflows
The real power comes from combining features. Here are three complete workflows.
Workflow 1: Automated code review on every PR
You push code
│
▼
PostPush hook fires
│
▼
Hook script:
- Run linter
- Run tests
- Block if either fails
│
▼ (tests pass)
Code Review subagent activates automatically
- Reads git diff
- Security check (Priority 1)
- Performance check (Priority 2)
- Quality check (Priority 3)
│
▼
Report written to .claude/reviews/pr-{number}.md
│
▼
Slack MCP notifies the team
What you need:
PostPushhook for tests- Code reviewer subagent
- Slack MCP server
PostFileWritehook to trigger Slack notification
Workflow 2: Safe large refactor
Step 1: /checkpoint save "before-auth-refactor"
Step 2: /plan
"Convert session auth to JWT across all 14 endpoints"
Step 3: Review the plan Claude produces
Step 4: /plan execute
Step 5: Test Engineer subagent activates
Writes tests for all changed endpoints
Step 6: Tests run (PreCommit hook)
Step 7: All pass → commit
Any fail → /checkpoint restore "before-auth-refactor"
Workflow 3: New developer onboarding
Create .claude/commands/onboard.md:
A new developer has joined the team. Help them understand this codebase.
1. Read CLAUDE.md and summarise the project in 3 sentences
2. List the 5 most important files to understand first, and why
3. Describe the main data flow from API request to database
4. List the 3 most common development tasks and how to do them
5. Point out any gotchas or non-obvious things they should know early
Format this as a welcome document they can save and refer to.
Any new developer runs /onboard and gets a custom orientation document generated from the actual current state of the codebase.
Quick setup checklist
Copy this and work through it once to get everything configured:
Global setup (~/.claude/)
□ CLAUDE.md — your personal preferences and style
□ skills/ — any skills you want in every project
Project setup (.claude/)
□ CLAUDE.md — what this project is, tech stack, rules
□ commands/ — your most common slash commands
□ settings.json — hook registrations
□ mcp.json — which external services to connect
□ hooks/ — pre-commit test runner at minimum
Per-directory
□ CLAUDE.md in any directory that needs special rules
Verify it works
□ Start Claude, check it reads CLAUDE.md (ask: "what do you know about this project?")
□ Run /self-assessment to find gaps
□ Make a checkpoint, make a change, restore it
□ Trigger a hook intentionally to confirm it fires
Common mistakes
Not using directory-level CLAUDE.md. Global and project-level memory is good. Directory-level is where you get precision. Different parts of a large codebase have different rules.
Slash commands that are too vague. /review with no instructions gives inconsistent results. /review that specifies exactly what to check, in what order, in what format — that gives consistent, useful output every time.
Hooks without logging. If a hook is blocking something, you want to know why. Always add an echo statement before every exit 1.
Subagents without permission restrictions. A subagent that can write anywhere is just a second main agent. Restrict write permissions to exactly what the subagent needs, nothing more.
Setting up MCP without environment variable validation. If GITHUB_TOKEN is not set and your MCP config references it, the server fails silently. Add a check in your hook or CLAUDE.md:
## Required environment variables
GITHUB_TOKEN — GitHub personal access token (for MCP)
DATABASE_URL — PostgreSQL connection string (for MCP)
If these are not set, MCP features will not work.
What to do next
Start with the layer that gives you the most immediate value:
- If you retype the same instructions a lot → Slash Commands
- If Claude keeps forgetting your preferences → Memory (CLAUDE.md)
- If you are nervous about large changes → Checkpoints
- If you want automated quality checks → Hooks + Skills
- If you need Claude to access GitHub or your database → MCP
- If you want to delegate specific tasks cleanly → Subagents
- If you want everything bundled for a team → Plugins
Add one layer at a time. Each one multiplies the value of the ones you already have.