Skip to content
ARTICLES
MenuClose
Claude

Claude Code tools: the permission model and how the core ones behave

AUTHOR
Bartłomiej Krupa
PUBLISHED
2026.07.06
READ_TIME
8 min

Claude Code ships 42 built-in tools, and only 13 of them ever ask for permission. The split is the design: tools that only read (Read, Grep, Glob, LSP, Agent) run freely; tools that mutate state or leave the machine (Bash, Edit, Write, WebFetch) are gated. Every tool name doubles as the exact string you use in permission rules, hook matchers, and subagent tool lists - so knowing the inventory is knowing the control surface.

Definition

Tool - a typed action the model can invoke: read a file, run a command, search the web. Each result feeds back into the agentic loop and informs the next decision. Without tools, Claude can only reply with text.

Anthropic groups the primary tools into five categories:

CategoryTools
File operationsRead, Edit, Write, NotebookEdit
SearchGlob (file names), Grep (file contents)
ExecutionBash, PowerShell, Monitor
WebWebFetch, WebSearch
Code intelligenceLSP (Language Server Protocol - definitions, references, type errors; needs a language plugin)

The rest are orchestration: Agent spawns subagents, Skill runs skills, TaskCreate/TaskUpdate/TaskList track work, EnterPlanMode/ExitPlanMode gate planning, plus session utilities (scheduled prompts, worktrees, MCP resource readers).

The permission split

The everyday core, with what actually gates each tool:

ToolWhat it doesAsks permission
ReadFile contents with line numbers; also images, PDFs, notebooksNo
GlobFind files by name patternNo
GrepSearch file contents (ripgrep)No
LSPType errors, go-to-definition, referencesNo
AgentSpawn a subagent in its own context windowNo
EditExact string replacement in a fileYes
WriteCreate or overwrite a whole fileYes
BashRun shell commandsYes
MonitorWatch logs/commands in the backgroundYes
WebFetchFetch a URL, extract via promptYes
WebSearchWeb search, titles + URLs onlyYes
SkillExecute a skillYes

Agent deserves a note: launching a subagent never prompts, but the subagent’s own tool calls are checked against your permission rules as they happen. A subagent with Bash in its tool list still can’t run an unapproved command silently.

Behaviors that bite

The table tells you what exists; these are the mechanics that actually change how sessions go.

Edit enforces read-before-edit. Three checks must pass: Claude read the file in the current conversation (and it hasn’t changed on disk since), old_string matches exactly - one whitespace character off is a miss - and it appears exactly once, or replace_all is set. Viewing a file with plain cat, head, tail, sed -n, or grep on a single file also counts as the read; piped output doesn’t. Write has the same rule for overwrites: an existing file must have been read first, new files are exempt.

Glob and Grep disagree about .gitignore. Grep respects it - gitignored files are invisible to content search unless Claude passes the path directly. Glob doesn’t by default, so a name-pattern search happily returns files - sorted by modification time, capped at 100 - from node_modules equivalents that Grep would skip. Grep, for its part, uses ripgrep regex syntax, not POSIX grep.

Bash is stateless between commands. Each command runs in a separate process: export doesn’t survive to the next call, though cd carries over to the next command, as long as the new working directory stays inside the project. Two limits bound every command - a 2-minute default timeout (Claude can request up to 10) and 30,000 characters of output, beyond which the full output lands in a file and Claude gets the path plus a preview.

WebFetch is lossy by design. It doesn’t hand Claude the page. A small, fast model reads the fetched content and answers Claude’s extraction prompt; that answer is all Claude sees. A result claiming a page “doesn’t mention” something may only mean the prompt didn’t ask. Responses cache for 15 minutes, and cross-host redirects are returned to Claude instead of followed. WebSearch is the complement: it returns result titles and URLs only - reading any of them takes a follow-up WebFetch.

Restrict and disable: ToolName(specifier)

Tool names are the permission vocabulary. The same rule format works in settings.json, the --allowedTools/--disallowedTools CLI flags, subagent frontmatter, skill allowed-tools, and hook conditions:

RuleApplies toMatches
Bash(npm run *)Bash, MonitorCommand patterns
Read(~/secrets/**)Read, Grep, Glob, LSPPath patterns
Edit(/src/**)Edit, Write, NotebookEditPath patterns
WebFetch(domain:example.com)WebFetchDomains
Agent(Explore)AgentSubagent types
WebSearchWebSearchWhole tool only - no specifier

A working example:

{
  "permissions": {
    "allow": ["Bash(pnpm test *)", "WebFetch(domain:docs.astro.build)"],
    "deny": ["Read(./.env*)", "WebSearch"]
  }
}

Two rules worth memorizing: an Edit(...) allow also grants Read on the same path, so you don’t need both; and a bare tool name in deny removes the tool entirely - the official way to switch one off.

One boundary to know: Read/Edit deny rules also cover file commands Claude Code recognizes inside Bash (cat, sed, grep), but not arbitrary subprocesses - a Python script that opens the file itself walks past them. OS-level enforcement takes the sandbox.

MCP tools: names now, schemas on demand

Custom tools arrive via MCP (Model Context Protocol) servers, and Claude Code defers their definitions by default: only tool names load at startup, and the full schema loads through the built-in ToolSearch tool when Claude actually needs one. That default exists because definitions are expensive - Anthropic measured the same deferred-loading pattern on the API side cutting upfront tool tokens from ~77K to ~8.7K, an 85% reduction. Run /context for the breakdown and /mcp for per-server costs; the agentic-loop article covers the rest of the startup tax.

Bottom line

Learn the inventory once and you get two things: a model of what Claude can actually do in your project, and the exact vocabulary - 42 names, ToolName(specifier) - to allow, gate, or remove any of it. The permission split does the daily work: reads are free, mutations ask, and everything is deniable. For the daily shortcuts, prefixes, and slash commands, see Claude Code commands cheatsheet. To wire those tools into a minimal repo harness, start from the ten-file starter.

FAQ

What tools does Claude Code have built in?
42 built-in tools as of July 2026, spanning file operations (Read, Edit, Write), search (Glob, Grep), execution (Bash, Monitor), web (WebFetch, WebSearch), code intelligence (LSP), and orchestration (Agent, Skill, task and session tools). The tool names are the exact strings used in permission rules, hook matchers, and subagent tool lists.
Which Claude Code tools require permission?
13 of the 42: the ones that mutate state or reach outside the machine - Bash, Edit, Write, NotebookEdit, PowerShell, Monitor, WebFetch, WebSearch, Skill, Workflow, Artifact, ExitPlanMode, and ShareOnboardingGuide. The other 29, including Read, Grep, Glob, LSP, and Agent, run without asking.
How do I restrict or disable a Claude Code tool?
Add rules to permissions.allow or permissions.deny in settings.json using the ToolName(specifier) format - Bash(npm run *) for command patterns, Read(~/secrets/**) or Edit(/src/**) for path patterns, WebFetch(domain:example.com) for domains. A bare tool name in the deny array disables the tool entirely.