13 / 20Tools7 MIN READ

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.

A tool call going out and a result coming backClaude on the left issues a Grep call along the upper path to the environment on the right, and the matching lines return along the lower path as a result.CLAUDEGrep("retryWithBackoff")3 files · 7 matching linesENVIRONMENT

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 Read or a Grep rather than recalled, which is the difference between an answer and a guess.
  • It gives you one vocabulary for control. Read, Edit, Bash name the same things in permission rules, subagent definitions, and hook matchers.
  • It bounds cost. Grep returning file paths is cheap; Read on the same files is not. Which tool Claude reaches for is most of what a turn costs.

How it works

  1. 01Claude picks a tool and Claude Code checks permissions

    Read-only tools run without prompting inside the working directory. Bash prompts except for a built-in read-only command set. Edit, Write, and NotebookEdit prompt unless the mode or a rule approves them.

  2. 02Search narrows before reading

    Glob returns up to 100 paths sorted by modification time and does not respect .gitignore by default. Grep does respect it, and defaults to returning file paths only; content mode adds the matching lines.

  3. 03Read pages large files instead of failing

    A whole-file read past the token limit returns the first page with a PARTIAL view notice telling Claude how to continue with offset and limit. A read that already passes those and still overflows errors instead.

  4. 04Edit requires an exact, unique match

    Three checks must pass: Claude has read the file in this conversation, old_string appears exactly as written, and it appears exactly once. Otherwise Claude supplies more surrounding context or sets replace_all.

  5. 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.

  6. 06Verification is a separate tool call

    An Edit returning success means the string was replaced, not that the code works. The LSP tool reports type errors after each edit automatically; a test run is still a Bash call Claude has to make.

How to implement it

  1. 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.

  2. 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.

  3. 03Restrict the tool set where the boundary matters

    Use permissions.deny for the session, a subagent’s tools list for delegated work, and a skill’s disallowed-tools for the turn a skill is active.

  4. 04Set the Bash limits your project needs

    BASH_DEFAULT_TIMEOUT_MS sets the default timeout and BASH_MAX_TIMEOUT_MS the ceiling. BASH_MAX_OUTPUT_LENGTH raises the read-back window from 30,000 characters up to 150,000 for verbose builds.

  5. 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

A grounded workflowbash
# 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."
Search, inspect, edit, test, verify — each step is a separate tool call, and each one is cheaper than reading everything up front.
.claude/settings.jsonjson
{
  "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"
  }
}
Restricting the tool set three ways: whole tools, scoped paths, and specific commands.

Use it when

  • Tracing a symbol through a codebase with Grep and then reading only the ranges that matter.
  • Restricting a review subagent to Read, Grep, Glob so it cannot modify what it is reviewing.
  • Blocking WebSearch and WebFetch in a repository that must not reach the network.
  • Raising BASH_MAX_OUTPUT_LENGTH so a verbose build log reaches Claude instead of being written to a file.
  • Matching a hook on Edit|Write so 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 Read and Edit; a Write(docs/**) or Glob(src/**) rule is accepted and ignored, with a startup warning.
  • You are trying to constrain behaviour that a tool restriction cannot express. Removing Bash does 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 -50 costs 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 as interface\{\}. As of v2.1.208 a rejected pattern returns ripgrep’s diagnostic instead of No files found.

  • SYMPTOMAn Edit fails repeatedly with a match error on a string you can see in the file.

    FIXold_string must match exactly, including whitespace, and appear exactly once. Give more surrounding context to pin one occurrence, or set replace_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_modules or dist.

    FIXGlob does not respect .gitignore by default, unlike Grep. Narrow the pattern, or set CLAUDE_CODE_GLOB_NO_IGNORE=false before launching.

  • SYMPTOMA permission rule written as Stop Task never 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 Read and Edit deny 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. 1.Open a project with at least one file over 1,000 lines. Run claude, then /context and note the total.
  2. 2.Ask: "Read <that file> and tell me which functions handle errors." Run /context again.
  3. 3.Run /clear, then ask: "Grep for catch and rescue in <that file>, then read 10 lines around each hit and tell me which functions handle errors."
  4. 4.Run /context a third time and compare the two totals.
  5. 5.Add "deny": ["Read(<that file>)"] to .claude/settings.json, restart, and confirm both the Read tool and cat on that path are refused.

Verified against code.claude.com/docs/en/tools-reference on 2026-08-09. See content/SOURCES.md for the full table.

← / → MOVE BETWEEN CONCEPTS