Tools
Tools are the named capabilities Claude Code exposes to the model — reading files, searching, running shell commands, editing, fetching the web, delegating to subagents — and their exact names are what permission rules, subagent tool lists, and hook matchers match against.
What it is
The core working set is small. Glob finds files by name pattern. Grep searches file contents and is built on ripgrep, so patterns use ripgrep regex, not POSIX. Read returns a file with line numbers, and handles images, PDFs, and notebooks. Edit does exact string replacement. Write creates or overwrites a whole file. Bash runs shell commands. WebFetch and WebSearch reach the network. Agent spawns a subagent. Skill runs a skill.
Around that sit the rest: LSP for language-server intelligence, Monitor for watching a command or socket in the background, NotebookEdit for Jupyter cells, PowerShell where it is enabled, the Task* family for the session checklist, ToolSearch for loading deferred MCP tools, and Artifact for publishing a page. TodoWrite is disabled by default as of v2.1.142 in favour of the Task tools.
The names matter because three separate systems match on them: permission rules as ToolName(specifier), subagent tools and disallowedTools lists, and hook matchers as bare names. The label shown in the transcript is not always the canonical name — the tool labelled Stop Task is TaskStop — and rules match the canonical name only.
What it does for you
- It gives Claude a way to check its work. Every claim about your codebase can be grounded in a
Reador aGreprather than recalled, which is the difference between an answer and a guess. - It gives you one vocabulary for control.
Read,Edit,Bashname the same things in permission rules, subagent definitions, and hook matchers. - It bounds cost.
Grepreturning file paths is cheap;Readon the same files is not. Which tool Claude reaches for is most of what a turn costs.
How it works
01Claude picks a tool and Claude Code checks permissions
Read-only tools run without prompting inside the working directory.
Bashprompts except for a built-in read-only command set.Edit,Write, andNotebookEditprompt unless the mode or a rule approves them.02Search narrows before reading
Globreturns up to 100 paths sorted by modification time and does not respect.gitignoreby default.Grepdoes respect it, and defaults to returning file paths only;contentmode adds the matching lines.03Read pages large files instead of failing
A whole-file read past the token limit returns the first page with a
PARTIAL viewnotice telling Claude how to continue withoffsetandlimit. A read that already passes those and still overflows errors instead.04Edit requires an exact, unique match
Three checks must pass: Claude has read the file in this conversation,
old_stringappears exactly as written, and it appears exactly once. Otherwise Claude supplies more surrounding context or setsreplace_all.05Bash results are truncated by size and by outcome
A valid result arrives inline up to roughly 30,000 characters; past that Claude gets a file path plus a preview. A failure arrives inline up to roughly 10,000 characters as a head-and-tail excerpt with no file path.
06Verification is a separate tool call
An
Editreturning success means the string was replaced, not that the code works. TheLSPtool reports type errors after each edit automatically; a test run is still aBashcall Claude has to make.
How to implement it
01Learn the canonical names
Read the tools reference and use those exact strings. A deny or ask rule naming an unknown tool produces a startup warning, which is how you catch a typo.
02Ask for the search step explicitly when it matters
"Grep for X, then read 20 lines around each hit" costs a fraction of "read the file", and produces the same answer.
03Restrict the tool set where the boundary matters
Use
permissions.denyfor the session, a subagent’stoolslist for delegated work, and a skill’sdisallowed-toolsfor the turn a skill is active.04Set the Bash limits your project needs
BASH_DEFAULT_TIMEOUT_MSsets the default timeout andBASH_MAX_TIMEOUT_MSthe ceiling.BASH_MAX_OUTPUT_LENGTHraises the read-back window from 30,000 characters up to 150,000 for verbose builds.05Ask for verification as a step, not an assumption
End the request with "then run the tests and show me the output". A tool call that succeeded is not evidence that the change is correct.
Examples
# 1. SEARCH — Grep returns paths, not contents. Cheap.
"Grep for 'retryWithBackoff' across src/ and list the files."
# 2. INSPECT — Read only what the search found, by range.
"Read 30 lines either side of each hit."
# 3. EDIT — exact string replacement, one call per site.
"Change the base delay from 100ms to 250ms in each of those call sites.
Do not reformat lines you did not need to touch."
# 4. TEST — a Bash call Claude has to make; it is not implied by the edit.
"Run 'npm test -- retry' and show me the output."
# 5. VERIFY — check the change landed everywhere, not just where you looked.
"Grep for '100' in those files again and confirm nothing was missed."{
"permissions": {
"deny": [
"WebSearch",
"Read(~/.ssh/**)",
"Edit(**/*.generated.ts)",
"Bash(rm -rf *)"
],
"allow": [
"Bash(npm run test *)",
"WebFetch(domain:code.claude.com)"
]
},
"env": {
"BASH_DEFAULT_TIMEOUT_MS": "300000",
"BASH_MAX_OUTPUT_LENGTH": "80000"
}
}Use it when
- Tracing a symbol through a codebase with
Grepand then reading only the ranges that matter. - Restricting a review subagent to
Read, Grep, Globso it cannot modify what it is reviewing. - Blocking
WebSearchandWebFetchin a repository that must not reach the network. - Raising
BASH_MAX_OUTPUT_LENGTHso a verbose build log reaches Claude instead of being written to a file. - Matching a hook on
Edit|Writeso a formatter runs after exactly the tools that change files.
Avoid it when
- You would name a tool in a permission rule that Claude Code never consults. Path rules are only checked for
ReadandEdit; aWrite(docs/**)orGlob(src/**)rule is accepted and ignored, with a startup warning. - You are trying to constrain behaviour that a tool restriction cannot express. Removing
Bashdoes not stop Claude from asking you to run the command; a hook or a sandbox boundary does. - You would raise the Bash output limit to avoid narrowing the command. A
| tail -50costs nothing and puts the relevant lines in front of Claude instead of burying them. - You want the entire file. Reading a 3,000-line file to answer one question is the single most common avoidable context cost in a session.
Common mistakes
SYMPTOMA Grep pattern with regex metacharacters silently returns nothing.
FIXGrep uses ripgrep syntax, so
interface{}needs escaping asinterface\{\}. As of v2.1.208 a rejected pattern returns ripgrep’s diagnostic instead ofNo files found.SYMPTOMAn
Editfails repeatedly with a match error on a string you can see in the file.FIX
old_stringmust match exactly, including whitespace, and appear exactly once. Give more surrounding context to pin one occurrence, or setreplace_all: true.SYMPTOMA build command exits 1 with useful output and Claude treats it as a total failure.
FIXOnly a fixed list of commands —
grep,rg,find,diff,test,git diff, and a few others — have exit 1 read as benign. Everything else exiting 1 is a failure, and failures are truncated to roughly 10,000 characters with no file path.SYMPTOMA Glob search turns up files inside
node_modulesordist.FIX
Globdoes not respect.gitignoreby default, unlikeGrep. Narrow the pattern, or setCLAUDE_CODE_GLOB_NO_IGNORE=falsebefore launching.SYMPTOMA permission rule written as
Stop Tasknever matches.FIXTranscript labels differ from canonical names. Rules and hook matchers match the canonical name only —
TaskStop. Deny and ask rules naming an unknown tool produce a startup warning.
Best practices
- Search before you read, and read ranges rather than whole files.
- Use the canonical tool names from the tools reference everywhere, and let the startup warning catch your typos.
- Give subagents the narrowest tool list that lets them finish the job.
- Ask for verification explicitly: a successful edit is not a passing test.
- Narrow noisy commands at the source with
tail,--quiet, or a filter, rather than raising the output limit. - Remember that
ReadandEditdeny rules do not cover a subprocess that opens a file itself — that needs the sandbox.
Try it in five minutes
Compare the cost of reading a file with the cost of searching it.
- 1.Open a project with at least one file over 1,000 lines. Run
claude, then/contextand note the total. - 2.Ask: "Read <that file> and tell me which functions handle errors." Run
/contextagain. - 3.Run
/clear, then ask: "Grep forcatchandrescuein <that file>, then read 10 lines around each hit and tell me which functions handle errors." - 4.Run
/contexta third time and compare the two totals. - 5.Add
"deny": ["Read(<that file>)"]to.claude/settings.json, restart, and confirm both the Read tool andcaton that path are refused.
Related concepts
Verified against code.claude.com/docs/en/tools-reference on 2026-08-09. See content/SOURCES.md for the full table.
← / → MOVE BETWEEN CONCEPTS