Skip to main content
Every capability Claude Code can exercise — reading a file, running a shell command, fetching a URL, spawning a sub-agent — is a tool. Tools are the atomic unit of action in the agent loop. When the Claude API returns a tool_use block, the loop looks up the matching tool by name, validates the input, checks permissions, and calls it.

The Tool interface

Every tool is a TypeScript object that satisfies the Tool<Input, Output, Progress> type defined in src/Tool.ts. The interface is divided into four groups of methods.

Lifecycle methods

These methods run in sequence for every tool invocation.
MethodSignatureDescription
validateInput()(input, context) => Promise<ValidationResult>Reject malformed or out-of-bounds inputs before any permission check. Returns { result: true } or { result: false, message, errorCode }. Optional — omit to skip.
checkPermissions()(input, context) => Promise<PermissionResult>Tool-specific authorization (e.g., path sandboxing for file tools). Called after the general permission system approves the call.
call()(args, context, canUseTool, parentMessage, onProgress?) => Promise<ToolResult<Output>>Execute the tool and return the result. The onProgress callback streams incremental updates to the UI.

Capability flags

These methods let the executor and permission system know how to handle a tool safely.
MethodDefaultDescription
isEnabled()trueFeature gate — return false to hide the tool entirely from the model.
isConcurrencySafe(input)falseWhen true, this tool can run in parallel with other concurrency-safe tools. Defaults to false (assume writes).
isReadOnly(input)falseWhen true, the tool has no side effects. Informs the permission dialog.
isDestructive(input)falseWhen true, the operation is irreversible (delete, overwrite, send). Shown prominently in the permission UI.
interruptBehavior()'block'What happens when the user submits a new message while this tool runs. 'cancel' stops it immediately; 'block' lets it finish while the new message waits.

Rendering methods

Tools render their own UI in the terminal (React/Ink). The loop never dictates how a tool looks.
MethodWhen it runs
renderToolUseMessage(input, options)Immediately when the tool_use block starts streaming — input may be partial.
renderToolUseProgressMessage(progressMessages, options)While the tool is executing, to show spinners and live output.
renderToolResultMessage(content, progressMessages, options)After the tool completes, to display the final result.
renderGroupedToolUse(toolUses, options)When multiple instances of the same tool ran in parallel — renders them as a group instead of individually.
renderToolUseRejectedMessage(input, options)When the user denied the tool. Optional — falls back to <FallbackToolUseRejectedMessage />.
renderToolUseErrorMessage(result, options)When the tool threw an error. Optional — falls back to <FallbackToolUseErrorMessage />.

AI-facing methods

These methods shape how the model sees the tool.
MethodDescription
prompt(options)Returns the tool’s description string included in the system prompt. Can be dynamic based on current context.
description(input, options)One-line summary shown in permission dialogs and compact views.
mapToolResultToToolResultBlockParam(content, toolUseID)Serialize the tool output into the ToolResultBlockParam format the API expects.
toAutoClassifierInput(input)Returns a compact text representation for the auto-mode security classifier. Security-relevant tools must override this; return '' to skip.
userFacingName(input)Short display name shown in the terminal UI. Defaults to name.

buildTool() factory

All tools are created through the buildTool() factory function in src/Tool.ts. It merges safe defaults for the commonly-stubbed methods so that callers never need ?.() ?? default.
// src/Tool.ts
export function buildTool<D extends AnyToolDef>(def: D): BuiltTool<D> {
  return {
    ...TOOL_DEFAULTS,
    userFacingName: () => def.name,
    ...def,
  } as BuiltTool<D>
}
The defaults applied by buildTool() are all fail-closed where it matters:
const TOOL_DEFAULTS = {
  isEnabled: () => true,
  isConcurrencySafe: (_input?) => false,   // assume not safe
  isReadOnly: (_input?) => false,           // assume writes
  isDestructive: (_input?) => false,
  checkPermissions: (input, _ctx?) =>
    Promise.resolve({ behavior: 'allow', updatedInput: input }),
  toAutoClassifierInput: (_input?) => '',   // skip classifier by default
  userFacingName: (_input?) => '',
}
Every tool in the codebase goes through buildTool(). The factory also ensures that userFacingName always returns the tool’s name even when the tool definition omits it.

Complete tool inventory

File operations

Tools that read, write, and edit files on the local filesystem.
ToolDescription
FileReadToolRead file contents. Supports PDF, image, and text. Result size is unbounded (never persisted to disk — the tool self-bounds).
FileEditToolString-replace editing. Applies a targeted diff rather than rewriting the full file.
FileWriteToolFull file creation or overwrite.
NotebookEditToolEdit Jupyter notebook cells (.ipynb).

Search & discovery

Tools for finding files and content across the codebase.
ToolDescription
GlobToolFile pattern matching (**/*.ts). Returns matches sorted by modification time.
GrepToolContent search using ripgrep. Supports full regex.
ToolSearchToolKeyword search across the tool registry itself. Used when deferred tools are enabled.

Execution

Tools that run code or system commands.
ToolDescription
BashToolShell command execution. Most-used tool in the system.
PowerShellToolPowerShell command execution (Windows).

Web & network

Tools that access the internet.
ToolDescription
WebFetchToolHTTP fetch, converts response to Markdown by default.
WebSearchToolWeb search, returns structured results.

Agent & task management

Tools for spawning and coordinating agents and tasks.
ToolDescription
AgentToolSpawn a sub-agent with a fresh messages[]. Supports default, fork, worktree, and remote modes.
SendMessageToolSend a message to a named teammate agent.
TeamCreateTool / TeamDeleteToolCreate and delete persistent teammate agents.
TaskCreateTool / TaskUpdateTool / TaskGetTool / TaskListTool / TaskStopTool / TaskOutputToolFile-based task graph with status tracking.

Planning & workflow

Tools for structured planning and worktree management.
ToolDescription
EnterPlanModeTool / ExitPlanModeToolSwitch to/from read-only planning mode.
EnterWorktreeTool / ExitWorktreeToolBind sub-agent to an isolated git worktree.
TodoWriteToolManage a persistent todo list for the current session.

MCP protocol

Tools for interacting with Model Context Protocol servers.
ToolDescription
MCPToolWrapper around any tool exposed by a connected MCP server. Named mcp__<server>__<tool>.
ListMcpResourcesToolList resources available from a connected MCP server.
ReadMcpResourceToolRead a specific resource from a connected MCP server.

System & interaction

Tools for user interaction, configuration, and system management.
ToolDescription
AskUserQuestionToolRequest input from the user mid-task.
BriefToolDisplay a brief message to the user without requesting input.
ConfigToolRead and write Claude Code settings.
SkillToolLoad and invoke a skill from the memdir/ system.
LSPToolLanguage server protocol queries (go-to-definition, diagnostics).
ScheduleCronToolRegister a cron-style scheduled task.

Tool result size limits

Every tool sets a maxResultSizeChars property. When a result exceeds this limit, the output is saved to a temporary file and Claude receives a preview with the file path instead of the full content. This prevents single large tool results from consuming the entire context window. FileReadTool sets maxResultSizeChars to Infinity — it self-bounds through its own read limits and persisting would create a circular Read → file → Read loop.

Deferred tools

When the shouldDefer flag is true on a tool, it is sent to the model with defer_loading: true and its full schema is omitted from the initial system prompt. The model must call ToolSearchTool first to locate and load the tool’s schema. This reduces prompt size when many tools are registered. Set alwaysLoad: true on a tool to force its schema into the initial prompt regardless of deferral settings. For MCP tools, this is controlled via _meta['anthropic/alwaysLoad'].

Build docs developers (and LLMs) love