Skip to main content

Tool Architecture

The Tool system is the core abstraction of Claude Code — every action the AI takes (reading files, running commands, searching code) goes through a tool.

The Tool Interface

Every tool implements a rich interface that handles validation, permissions, execution, and rendering. Click any step to see the details:

Tool Execution Pipelineclick any step to expand

Core Type

Tool.ts serves as a shared type hub — it imports and re-exports types from commands, notifications, MCP, agents, messages, permissions, app-state, hooks, themes, and more. The Tool interface itself uses JSON Schema for API-facing definitions:

// API-facing schema (sent to the model)
type ToolInputJSONSchema = {
type: 'object'
properties?: Record<string, JSONSchemaProperty>
required?: string[]
}

// The full Tool interface
type Tool<Input, Output, Progress> = {
// Identity
name: string
aliases?: string[]

// Schema — JSON Schema for API, Zod used internally by buildTool()
inputSchema: ToolInputJSONSchema

// Execution
call(
args: Input,
context: ToolContext,
canUseTool: PermissionChecker,
parentMessage: Message,
onProgress: (progress: Progress) => void
): Promise<ToolResult<Output>>

// Permissions
checkPermissions(input: Input, context: ToolContext): PermissionResult
isReadOnly(input: Input): boolean
isDestructive(input: Input): boolean
isConcurrencySafe(input: Input): boolean

// Description (dynamic, based on input)
description(input: Input, options: DescriptionOptions): string

// Rendering
renderToolUseMessage(input: Input, options: RenderOptions): ReactNode
renderToolResultMessage(output: Output, progress: Progress, options: RenderOptions): ReactNode

// ... 20+ additional methods
}

buildTool() Factory

Tools are created via buildTool(), which fills in safe defaults for the many interface methods. You only supply the parts you care about — name, schema, and call():

const MyTool = buildTool({
name: 'MyTool',
inputSchema: z.object({
path: z.string().describe('File path to process'),
}),

async call(args, context, canUseTool, parentMsg, onProgress) {
// Permission check
const { allowed, updatedInput } = await canUseTool(args)
if (!allowed) return { data: null }

// Execute
const result = await doWork(updatedInput.path)

// Report progress
onProgress({ toolUseID: context.toolUseID, data: { type: 'output', content: result } })

return { data: result }
},

isReadOnly() { return true },
isConcurrencySafe() { return true },
})

What buildTool() Provides

  • Default description() / description() from the tool name
  • Default renderToolUseMessage() / render_tool_use() showing input summary
  • Default renderToolResultMessage() / render_tool_result() showing output
  • Default isDestructive() / is_destructive() returning False
  • Default checkPermissions() / check_permissions() returning allow
  • Schema validation wrapper around call() (Zod in TS, Pydantic in Python)

Tool Categories

CategoryToolsPermission Level
File ReadRead, Glob, GrepRead-only, concurrent-safe
File WriteFileEdit, FileWriteRequires approval in default mode
ShellBash, PowerShellRequires approval, destructive
SearchWebSearch, WebFetchRead-only
AgentAgent, SendMessageSpawns sub-processes
TaskTaskCreate, TaskUpdate, TaskList, TaskGet, TaskOutput, TaskStopManages background work
PlanningEnterPlanMode, ExitPlanModeMode switches
MCP AccessReadMcpResource, ListMcpResourcesRead-only access to MCP resources
MCP WrappersMCPTool, McpAuthRuntime-generated wrappers around connected MCP servers
InfrastructureSkillTool, ToolSearch, SleepInternal

Tool Registration

Tools are registered during initialization in main.tsx from four sources:

  1. Built-in tools loaded from src/tools/ (40+)
  2. MCP tools wrapped as MCPTool instances
  3. Plugin tools loaded dynamically from manifests
  4. All merged into a single tools array
  5. Tool definitions included in every API call

See Tool Sources for details on each source, including MCP wrapping, plugin loading, and how skills integrate.

Key Source Files

FilePurpose
src/Tool.tsTool interface and types (~466 lines)
src/tools/45+ built-in tool implementations
src/services/tools/StreamingToolExecutor.tsExecution engine
src/services/tools/toolOrchestration.tsOrchestration logic