Claude Code ships with roughly 60 built-in tools spanning file I/O, shell access, web fetches, MCP integrations, and session management. The --tools, --allowedTools, and --disallowedTools flags let you restrict, expand, or eliminate that tool set — turning Claude into anything from a read-only analyzer to a pure text generator with zero tool access.
Default Tool Set
Every session starts with a full complement of tools. They fall into six categories:
Built-in Tool Categories
| Category | Tools | Purpose |
|---|---|---|
| File I/O | Bash, Read, Write, Edit, Glob, Grep, NotebookEdit | Shell commands, file reading/writing, pattern search |
| Web | WebFetch, WebSearch | Fetch URL contents and search the web |
| Session | EnterPlanMode, ExitPlanMode, EnterWorktree, ExitWorktree, AskUserQuestion, Skill | Plan mode, git worktrees, user interaction, slash commands |
| Task | Task, TaskOutput, TaskStop, TodoWrite | Launch subagent tasks, read output, manage todo lists |
| Scheduling | CronCreate, CronDelete, CronList | Create, delete, and list scheduled tasks |
| Meta / MCP | ToolSearch, LSP, ListMcpResourcesTool, ReadMcpResourceTool, mcp__* | Deferred tool loading, language server, MCP server integrations |
MCP tools follow the mcp__servername__toolname naming convention. For example, a Chrome DevTools server exposes tools like mcp__chrome-devtools__click, mcp__chrome-devtools__navigate_page, and mcp__chrome-devtools__take_screenshot. A Notion server exposes mcp__claude_ai_Notion__notion-search and similar.
Restriction Methods
Three flags control which tools Claude can use. They serve different purposes and can be combined, but they interact through a strict permission hierarchy where deny always wins.
Tool Restriction Flags
| Flag | Effect | Use Case |
|---|---|---|
—tools "" | Disable ALL tools — pure text generation | Summarization, classification, translation |
—tools “Tool1,Tool2” | Replace the entire tool set with only these tools | Custom agent with a precise capability set |
—allowedTools “Tool1,Tool2” | Allow only these tools (intersection with defaults) | Read-only mode, git-only mode |
—disallowedTools “Tool1,Tool2” | Block these specific tools (deny filter) | Air-gapped mode (block web tools), no-write mode |
The permission hierarchy is strict and runs top-down:
Managed deny (org admin) overrides--disallowedTools (CLI flag) overrides--allowedTools (CLI flag) overridesDefault tool setThis means: if an org admin blocks a tool via managed-mcp.json, nothing can re-enable it. --disallowedTools always wins over --allowedTools. And --allowedTools restricts the default set by intersection, not union — you cannot use it to add tools that do not already exist.
Pattern Syntax
The most powerful restriction feature is Bash pattern matching. Instead of allowing or blocking Bash entirely, you can scope it to specific commands using glob patterns:
# Allow only git commands--allowedTools "Bash(git *)"
# Allow git and npm commands--allowedTools "Bash(git *),Bash(npm *)"
# Allow only read-only git commands--allowedTools "Bash(git status*),Bash(git log*),Bash(git diff*)"The space before the asterisk in Bash(git *) is critical. With the space, git * matches git status and git log —oneline but NOT gitk. Without the space, git* matches gitk, git with no args, and everything else starting with git. This is a glob pattern, not regex.
Pattern Matching Behavior
| Pattern | Matches | Does NOT Match |
|---|---|---|
Bash(git *) | git status, git log —oneline | gitk, git (no args) |
Bash(git*) | git status, gitk, git | — |
Bash(ls *) | ls -la, ls /tmp | lsof |
Bash(ls*) | ls -la, lsof, ls /tmp | — |
Zero Tool Mode
Passing --tools "" disables every tool. Claude responds from pure knowledge with no file access, no shell, and no web search. This is the right mode for summarization, translation, classification, and any task where tool calls add cost without value.
claude -p "What is 2+2?" --output-format json --tools ""The num_turns: 1 confirms zero tool calls. The permission_denials array is empty because Claude did not attempt to use any tools — they simply were not available. Note the high cache_creation_input_tokens on the first call; subsequent --tools "" calls in the same session benefit from cache hits and cost significantly less.
Read-Only Mode
Use --allowedTools to whitelist only non-destructive tools:
claude -p "List files in current directory" \ --output-format json --allowedTools "Read,Glob"Claude used Glob to list directory contents and returned the result. Bash, Write, Edit — all unavailable. The permission_denials array is empty because Claude adapted to the constraint and only used the tools it was given.
Tool Fallback Behavior
Blocking individual tools is not always sufficient. Claude is resourceful and will try alternative paths to accomplish a task. Here is what happens when you block Write and Edit but leave Bash available:
claude -p "Write hello to /tmp/test_disallow.txt" \ --output-format json --disallowedTools "Write,Edit"The sequence was: Claude could not use Write (blocked), could not use Edit (blocked), fell back to Bash with echo -n "hello" > /tmp/test_disallow.txt, and that was blocked by the filesystem sandbox because the path was outside the working directory.
Blocking Write alone does not prevent file writes. Claude will fall back to Bash and run echo > file. For a truly read-only agent, use —allowedTools “Read,Glob,Grep” to whitelist only what you want rather than trying to blacklist every write path.
ToolSearch: Deferred Loading
When MCP servers contribute many tools, loading every tool schema into the context window becomes expensive. An MCP server with 80 tools could consume 40K tokens just for schema descriptions. ToolSearch solves this by deferring schema loading until a tool is actually needed.
It activates automatically when MCP tool descriptions would consume more than 10% of the context window. When active:
- Tools are listed by name only in the init event (no schemas loaded)
- When Claude determines it needs a specific tool, it calls
ToolSearchto fetch the full schema - Context usage drops from roughly 40K tokens to roughly 2K tokens for the tool listing
You do not need to configure ToolSearch. It is entirely automatic. You can observe it in stream-json output — all MCP tools appear in the tools array of the init event, but their schemas are absent until ToolSearch fetches them on demand.
Common Recipes
Here are the most useful tool restriction patterns for automation:
# Pure text generation -- no tools at allclaude -p "Summarize this text: ..." --tools ""
# Read-only analyzer -- can inspect but never modifyclaude -p "Review this codebase" --allowedTools "Read,Glob,Grep"
# Git-only mode -- read files and run git commandsclaude -p "Summarize recent changes" \ --allowedTools "Bash(git *),Read,Glob,Grep"
# Air-gapped mode -- no internet accessclaude -p "Analyze this code" \ --disallowedTools "WebFetch,WebSearch"
# Block an entire MCP serverclaude -p "Do the task" \ --disallowedTools "mcp__chrome-devtools__*"Tool names are case-sensitive and exact-match. —allowedTools “bash” will not match Bash. —allowedTools “read” will not match Read. Always use the exact capitalization shown in the tool list.
MCP tools follow the mcp__servername__toolname convention. To block a single tool: —disallowedTools “mcp__chrome-devtools__click”. To block an entire server, use a wildcard: —disallowedTools “mcp__chrome-devtools__*”.