InkdownInkdown
Start writing

Claude-Code

62 files·4 subfolders

Shared Workspace

Claude-Code
codex

12-tool-interface

Shared from "Claude-Code" on Inkdown

Tool Interface Contract

The complete Tool type system — every method, every hook, every rendering path.


Overview

Tool.ts (792 lines) defines the complete interface that every tool must implement. This is one of the most important type definitions in the codebase.


The Tool Interface

TypeScript
0000_start_here_index_and_recommended_reading_order.md
0100_project_overview_tech_stack_runtime_modes_and_folder_map.md
0200_startup_flow_entry_points_and_cold_start_sequence.md
0300_codebase_modules_layers_state_models_and_schemas.md
0400_system_architecture_and_design_rationale.md
0500_interactive_repl_request_flow_end_to_end.md
0600_headless_sdk_and_print_mode_request_flow_end_to_end.md
0700_mcp_integration_connection_and_tool_call_flow.md
0800_external_services_sdks_storage_and_local_dependencies.md
0900_environment_variables_settings_feature_flags_and_failure_modes.md
1000_non_obvious_patterns_gotchas_and_debugging_traps.md
1100_full_codebase_file_inventory_grouped_by_directory.md
kimi
00-overview.md
01-entrypoints.md
02-state-management.md
03-query-system.md
04-tools-system.md
05-tasks-system.md
06-ui-components.md
07-bridge-remote.md
08-services.md
09-skills-plugins.md
10-commands.md
11-testing-architecture.md
12-permission-system.md
13-build-system.md
14-ink-internals.md
15-git-internals.md
16-context-compaction.md
17-vim-mode.md
18-mailbox-notifications.md
19-session-persistence.md
20-hooks-system.md
21-error-recovery.md
README.md
qwen
00-overview.md
01-entry-points.md
02-query-engine.md
03-tools-and-tasks.md
04-commands-and-skills.md
05-state-management.md
06-ink-rendering.md
07-bridge-remote.md
08-mcp-services.md
09-services-overview.md
10-multi-agent.md
11-system-prompt-constants.md
12-tool-interface.md
13-memory-system.md
14-buddy-companion.md
15-keybindings.md
16-stop-hooks.md
17-vim-mode.md
18-upstreamproxy.md
19-cost-tracking-history.md
20-contexts-styles-onboarding.md
21-hooks.md
22-screens.md
tweets-explain
claude-code-memory-analysis.md
compact
memory-system
agentic-architecture
interface Tool<Input = unknown, Output = unknown, P = unknown> { // ─── Identity ─────────────────────────────────────────── name: string // Unique identifier (e.g., "Bash") description: string // Shown to model in system prompt // ─── Schema ───────────────────────────────────────────── parameters: JSONSchema7 // JSON Schema for input validation optionsSchema?: JSONSchema7 // Optional options schema // ─── Runtime Checks ───────────────────────────────────── isEnabled(): boolean // Is this tool available right now? isAutoApproved(context): boolean // Skip permission prompt? // ─── Execution ────────────────────────────────────────── call(input, context): AsyncIterable<ToolResult<Output>> // ─── Input Validation ─────────────────────────────────── validateInput?(input): ValidationResult // ─── Rendering (UI display) ───────────────────────────── renderToolUseMessage(block, context): ReactNode renderToolResultMessage(result, context): ReactNode renderToolUseProgressMessage(progress, context): ReactNode renderToolUseErrorMessage(error, context): ReactNode renderToolUseRejectedMessage(context): ReactNode renderGroupedToolUse?(blocks, context): ReactNode // ─── Activity Description (status bar) ────────────────── getActivityDescription?(input): string // ─── Auto-Classifier ──────────────────────────────────── toAutoClassifierInput?(input): AutoClassifierInput // ─── Tool Classification ──────────────────────────────── isSearchOrReadCommand(): boolean isConcurrencySafe(): boolean isReadOnly(): boolean isDestructive(): boolean // ─── Interrupt Behavior ───────────────────────────────── interruptBehavior: InterruptBehavior // ─── Deferral ─────────────────────────────────────────── shouldDefer?(input, context): boolean // ─── Always Load ──────────────────────────────────────── alwaysLoad: boolean // Always include in system prompt // ─── Observable Input Backfill ────────────────────────── backfillObservableInput?(input): void // ─── MCP Info ─────────────────────────────────────────── mcpInfo?: { serverName: string; toolName: string } }

ToolResult

What a tool returns from call():

TypeScript
type ToolResult<T> = {
  content: ToolResultContent[]    // The result content
  newMessages?: Message[]         // Optional messages to inject
  contextModifier?: (ctx) => ctx // Optional context modification
}

ToolUseContext

The massive context object passed to every tool call:

TypeScript
interface ToolUseContext {
  // Abort control
  abortController: AbortController

  // App state access
  getAppState(): AppState
  setAppState(updater): void

  // Query tracking
  queryTracking: { chainId: string; depth: number }

  // Tool pool
  options: {
    tools: Tool[]
    mainLoopModel: string
    thinkingConfig: ThinkingConfig
    agentDefinitions: AgentDefinitions
    isNonInteractiveSession: boolean
    appendSystemPrompt?: string
  }

  // Agent identity
  agentId?: string

  // Notification system
  addNotification(notification): void

  // File state cache
  fileStateCache: FileStateCache

  // Content replacement state
  contentReplacementState?: ContentReplacementState

  // Messages (current conversation)
  messages: Message[]
}

ToolPermissionContext

Immutable permission rules:

TypeScript
interface ToolPermissionContext {
  mode: PermissionMode  // 'default' | 'yolo' | 'plan' | 'bypassPermissions'

  // Rule sources (for debugging/display)
  alwaysAllow: Rule[]   // Auto-approved patterns
  alwaysDeny: Rule[]    // Auto-denied patterns
  alwaysAsk: Rule[]     // Always prompt user
}

Interrupt Behavior

How a tool behaves when the user interrupts:

TypeScript
enum InterruptBehavior {
  KILL = 'kill',           // Kill the process immediately
  WAIT = 'wait',           // Let it finish gracefully
  IGNORE = 'ignore',       // Continue running in background
}

buildTool() Factory

Creates a tool with safe defaults:

TypeScript
function buildTool<Input, Output, P>(
  partial: PartialTool<Input, Output, P>
): Tool<Input, Output, P> {
  return {
    alwaysLoad: false,
    interruptBehavior: InterruptBehavior.KILL,
    isEnabled: () => true,
    isAutoApproved: () => false,
    isSearchOrReadCommand: () => false,
    isConcurrencySafe: () => false,
    isReadOnly: () => false,
    isDestructive: () => false,
    shouldDefer: () => false,
    validateInput: () => ({ valid: true }),
    ...partial,
  }
}

Progress Types

Re-exported progress types for UI rendering:

TypeScript
// Progress types for each tool
AgentToolProgress
BashProgress
MCPProgress
TaskProgress
TeamProgress
ComputerUseProgress
WebBrowserProgress
// ... etc

Tool Method Details

renderToolUseMessage

Called when the model calls the tool. Returns the UI to display:

Plain text
┌──────────────────────────────────────┐
│  $ npm test                          │
│  Running tests...                    │
└──────────────────────────────────────┘
renderToolResultMessage

Called when the tool completes. Returns the result UI:

Plain text
┌──────────────────────────────────────┐
│  ✓ 42 tests passed (3.2s)            │
└──────────────────────────────────────┘
renderToolUseProgressMessage

Called during streaming progress:

Plain text
┌──────────────────────────────────────┐
│  Running tests... 23/42 passed       │
│  ████████████░░░░░░░░  55%           │
└──────────────────────────────────────┘
getActivityDescription

Returns the one-liner shown in the status bar:

TypeScript
getActivityDescription({ command: "npm test" })
// → "Running tests"

Key Files Reference

FilePurpose
src/Tool.tsComplete tool interface (792 lines)
src/tools.tsTool assembly and merging
src/tools/shared/Shared tool utilities
src/tools/utils.tsTool utility functions
src/utils/permissions/Permission system
src/services/tools/Tool orchestration