Tools — Complete Real-World Guide
Every action Claude takes is a tool call. Understanding tools helps you understand exactly what Claude is doing and why.
Reads the content of a file.
When Claude uses it: To understand existing code before editing, to check config files, to read test files, to follow import chains.
Real Example
Section titled “Real Example”You say:
Fix the bug where users can't log in after password resetClaude does (internally):
Read("src/auth/reset.ts") ← find the reset logicRead("src/auth/login.ts") ← find the login logicRead("src/models/user.ts") ← check the user modelRead("tests/auth/reset.test.ts") ← check existing testsWhat you see: Claude explains the bug (reset sets a temporary token but doesn’t clear it after use), then fixes it.
Name the file in your prompt to help Claude start in the right place:
# Faster:"Fix the bug in src/auth/reset.ts — users can't log in after password reset"
# Slower (Claude has to search first):"Fix the login bug"Modifies a specific section of an existing file. Claude replaces an exact string with new content.
When Claude uses it: Any time it needs to change existing code — fixing bugs, adding features, refactoring.
Real Example
Section titled “Real Example”You say:
Add input validation to the createUser function in src/services/user.tsClaude does:
Read("src/services/user.ts") ← reads the whole file firstEdit("src/services/user.ts", old: 'async function createUser(data) {\n return db.user.create({ data })', new: 'async function createUser(data) {\n const validated = UserSchema.parse(data)\n return db.user.create({ data: validated })')What you see: The exact line is changed, everything else preserved.
What makes Edit safe
Section titled “What makes Edit safe”Claude edits by exact string match, not by line number. If the file changed since Claude read it, the edit fails (rather than silently editing the wrong place).
Creates a new file or completely overwrites an existing one.
When Claude uses it: Creating new files (tests, components, config), generating boilerplate, writing scripts.
Real Example
Section titled “Real Example”You say:
Create a Zod validation schema for the User model based on prisma/schema.prismaClaude does:
Read("prisma/schema.prisma")Write("src/validators/user.ts", content: `import { z } from 'zod'
export const UserSchema = z.object({ email: z.string().email(), name: z.string().min(1).max(100), role: z.enum(['admin', 'user', 'guest']).default('user'),})
export type UserInput = z.infer<typeof UserSchema>`)Runs a shell command and returns the output.
When Claude uses it: Running tests, installing dependencies, git operations, build commands, checking system state.
Real Example 1: Running Tests
Section titled “Real Example 1: Running Tests”You say:
Add a test for the password reset flow, then run the testsClaude does:
Read("tests/auth/reset.test.ts") ← understand existing test styleWrite("tests/auth/reset-flow.test.ts") ← writes new test fileBash("npm test tests/auth/") ← runs and checks outputIf tests fail:
Bash output: "Error: resetToken is not cleared after use"→ Claude reads the source again, finds the bug, edits it, runs tests againReal Example 2: Git Workflow
Section titled “Real Example 2: Git Workflow”You say:
Commit these changes with a meaningful messageClaude does:
Bash("git status") ← see what changedBash("git diff --staged") ← review staged changesBash('git commit -m "fix: clear reset token after successful login"')Real Example 3: Checking System State
Section titled “Real Example 3: Checking System State”You say:
Why is the dev server failing to start?Claude does:
Bash("npm run dev 2>&1 | head -50") ← capture first 50 lines of outputBash("lsof -i :3000") ← check if port is in useBash("cat .env | grep -v SECRET") ← check env vars (without leaking secrets)Finds files matching a pattern. Returns a list of paths.
When Claude uses it: Discovering project structure, finding all files of a type, finding test files.
Real Example
Section titled “Real Example”You say:
How is error handling done across the codebase?Claude does:
Glob("src/**/*.ts") ← find all TypeScript filesGlob("src/**/*error*") ← find error-related filesGlob("src/**/*Error*")Then reads the relevant ones.
Pattern Reference
Section titled “Pattern Reference”src/**/*.ts all .ts files under src/**/*.test.ts all test files anywheresrc/api/*/index.ts index files in each api subdirectory*.config.{js,ts} config files in the rootSearches file contents with a regex pattern. Faster than reading every file.
When Claude uses it: Finding where a function is defined, finding all usages of a variable, searching for specific patterns.
Real Example 1: Find all usages
Section titled “Real Example 1: Find all usages”You say:
Rename the sendEmail function to sendTransactionalEmail everywhereClaude does:
Grep("sendEmail", "**/*.ts") ← find all usages→ Returns: src/services/mailer.ts:14, src/handlers/auth.ts:87, src/workers/reset.ts:23
Read("src/services/mailer.ts") ← read each fileEdit("src/services/mailer.ts", ...) ← renameEdit("src/handlers/auth.ts", ...)Edit("src/workers/reset.ts", ...)
Bash("npm run build") ← verify no errorsReal Example 2: Security audit
Section titled “Real Example 2: Security audit”You say:
Check if we're exposing any sensitive fields in API responsesClaude does:
Grep("password|secret|token|key", "src/handlers/**/*.ts")Grep("res.json|res.send", "src/handlers/**/*.ts")Reads the matches and reports any leaks.
Pattern Reference
Section titled “Pattern Reference”Grep("TODO:", "**/*.ts") find all TODOsGrep("console\\.log", "src/**") find debug logsGrep("any", "src/**/*.ts") find TypeScript 'any' usageGrep("SELECT \*", "**/*.ts") find unoptimized SQLGrep("0\.0\.0\.0|localhost", "**") find hardcoded hostsWebFetch
Section titled “WebFetch”Fetches the content of a URL.
When Claude uses it: Reading documentation, fetching API specs, checking package changelogs.
Real Example 1: Reading Docs
Section titled “Real Example 1: Reading Docs”You say:
Upgrade our Stripe integration to use the new Payment Intents APIClaude does:
WebFetch("https://stripe.com/docs/api/payment_intents")WebFetch("https://stripe.com/docs/upgrades")Read("src/services/stripe.ts")Edit("src/services/stripe.ts", ...)Real Example 2: Checking a Package
Section titled “Real Example 2: Checking a Package”You say:
Is there a breaking change in the Prisma 5 upgrade?Claude does:
WebFetch("https://www.prisma.io/docs/guides/upgrade-guides/upgrading-versions/upgrading-to-prisma-5")Then summarizes what you need to change.
WebSearch
Section titled “WebSearch”Searches the web and returns relevant results.
When Claude uses it: Finding solutions to errors, researching unfamiliar APIs, finding examples.
Real Example
Section titled “Real Example”You say:
I'm getting "ECONNREFUSED 127.0.0.1:5432" in tests — fix itClaude does:
WebSearch("vitest postgres ECONNREFUSED test setup")WebSearch("prisma test database connection refused jest vitest")Reads the top results, identifies that test setup needs DATABASE_URL pointing to the test DB, fixes vitest.config.ts.
Spawns a subagent — a separate Claude instance with its own context.
When Claude uses it: Complex research tasks, parallel work, tasks requiring isolation.
Real Example
Section titled “Real Example”You say:
Audit the entire codebase for security vulnerabilitiesWithout agents, Claude reads everything into one context window (expensive, slow, limited).
With agents:
Agent("Explore", "scan src/handlers/ for input validation gaps")Agent("Explore", "scan src/services/ for SQL injection risks")Agent("Explore", "scan src/auth/ for authentication weaknesses")Three agents run in parallel, each focused on their domain, each returns a focused report. Claude combines them into one security audit.
Real Example 2: Parallelizing independent tasks
Section titled “Real Example 2: Parallelizing independent tasks”You say:
Write tests for the payment service AND update the API documentationClaude does:
Agent("test-writer", "write tests for src/services/payment.ts")Agent("doc-writer", "update docs/api.md with payment endpoint docs")Both happen simultaneously — done in half the time.
TodoWrite / TodoRead
Section titled “TodoWrite / TodoRead”Manages an in-session task list.
When Claude uses it: Breaking down complex multi-file tasks, tracking progress on long refactors.
Real Example
Section titled “Real Example”You say:
Refactor all the API handlers to use the new error formatClaude does:
Glob("src/handlers/**/*.ts") ← find all handlers: 8 files
TodoWrite([ { id: 1, task: "Update users.ts", status: "pending" }, { id: 2, task: "Update orders.ts", status: "pending" }, { id: 3, task: "Update payment.ts", status: "pending" }, ... 5 more ...])
Read("src/handlers/users.ts")Edit("src/handlers/users.ts", ...)TodoWrite([{ id: 1, status: "done" }, ...]) ← mark complete
... repeats for each file ...You can see the progress as it works through the list.
How Tools Combine: A Full Worked Example
Section titled “How Tools Combine: A Full Worked Example”You say:
Add rate limiting to all API endpoints — max 100 requests per minute per IPHere is every tool call Claude makes, in order:
1. Glob("src/handlers/**/*.ts") ← discover all handlers2. Read("src/handlers/index.ts") ← understand routing3. Read("src/middleware/") ← find existing middleware Glob("src/middleware/**")4. WebSearch("express rate limiting middleware npm 2024")5. Bash("npm list express-rate-limit") ← check if already installed6. Bash("npm install express-rate-limit") ← install package7. Write("src/middleware/rateLimiter.ts") ← create middleware8. Read("src/app.ts") ← find where middleware is applied9. Edit("src/app.ts", ...) ← add the middleware10. Read("tests/middleware/") ← check test patterns Glob("tests/**/*middleware*")11. Write("tests/middleware/rateLimiter.test.ts") ← write tests12. Bash("npm test tests/middleware/") ← run tests13. Bash("npm run build") ← verify TypeScript compiles13 tool calls, all automatic, all building on each other’s output. You wrote one sentence; Claude did the research, the implementation, and the tests.
🧠 Quick Recall
Section titled “🧠 Quick Recall”- Trick: “Grep finds words, Glob finds names, Read before Edit, Bash for the rest.”
👨🏫 Teach It
Section titled “👨🏫 Teach It”- Show: run a task and pause at each tool call: ‘why this tool here?’
- They’ll trip on: pasting file contents into chat instead of letting Read fetch selectively.
Learning path: ⬅ 06-how-claude-code-works.md · Index · ➡ 08-sessions-and-checkpointing.md
Written by Fenil Patel