Tool Use Overview

Purpose and Scope

Tool use lets Claude ask your application to perform actions, fetch data, or operate a controlled environment while the SDK manages the parts that are easy to get wrong: matching tool names, parsing model-supplied input, returning results, and continuing the conversation. In this repository, the central abstraction is a runnable tool: a tool definition that can also parse input and run local code. The helper layer is beta-oriented, but it spans both the Messages API loop and Managed Agents session events, so the same local tool shape can serve different Claude execution surfaces. Sources: src/lib/tools/BetaRunnableTool.ts, src/lib/tools/BetaToolRunner.ts, src/lib/tools/SessionToolRunner.ts

A tool definition describes what Claude may call, while a tool call is the model’s request to execute one of those definitions with concrete input. The SDK adds a runner around that contract. Instead of asking the application to inspect every assistant response, find tool-use blocks, execute handlers, append tool-result messages, and issue another request, the runner performs that cycle automatically. The official Claude docs describe this as an agentic loop with error wrapping and type safety; the TypeScript implementation exposes that loop through async iterables for regular message generation and a session-event runner for Managed Agents. Sources: src/lib/tools/BetaToolRunner.ts, src/lib/tools/ToolRunner.ts, src/lib/tools/SessionToolRunner.ts

Relevant Source Files

  • src/lib/tools/BetaRunnableTool.ts — Defines the runnable tool contract, supported client-runnable beta tool types, shared tool-use context, tool-name resolution, and error-content normalization.
  • src/lib/tools/BetaToolRunner.ts — Implements the current beta Messages tool runner, including async iteration, request options, helper headers, stream handling, conversation mutation, and compaction warnings.
  • src/lib/tools/SessionToolRunner.ts — Implements the Managed Agents session-event tool runner, including session polling or streaming behavior, tool dispatch, idle shutdown, abort handling, managed-agents beta header usage, and cleanup expectations.
  • src/lib/tools/ToolError.ts — Defines the structured error type that tools can throw when they need to return rich error content to Claude rather than a plain string.
  • src/lib/tools/ToolRunner.ts — Shows the earlier local implementation of the beta tool runner loop and remains useful for understanding the core state machine without newer request-option plumbing.
  • src/resources/beta/agents/index.ts — Re-exports generated Managed Agents types for custom tools, MCP toolsets, agent toolsets, skills, models, and tool configuration used when agents are configured with tools.

Core Primitives

The first primitive is the runnable tool itself. In the SDK type model, a runnable tool extends the API tool definition with three application-owned behaviors: parse the raw input, run the tool, and optionally close resources. Its result may be a string or an array of tool-result content blocks, which allows tools to return text and richer content in the same shape the API expects. The runnable set intentionally covers client-executable beta tools such as custom tools, memory, bash, computer use, and text editor variants, while excluding server-side tools such as code execution, web search, and MCP toolsets. Sources: src/lib/tools/BetaRunnableTool.ts

The second primitive is the tool-use context passed into a tool run. The context carries the actual model request that triggered execution plus an abort signal when available. That triggering value can come from a Messages tool-use content block or from Managed Agents session events named for built-in and custom tool use. The SDK keeps a deprecated alias for older code, but the newer name is more accurate because a session event is not literally a Messages content block. Tool authors can write portable code by reading common fields such as identifier, name, and input, then narrowing when they need surface-specific details. Sources: src/lib/tools/BetaRunnableTool.ts, src/lib/tools/SessionToolRunner.ts

The third primitive is the runner. A Messages runner is an async iterable that yields either message objects or message streams depending on whether streaming was requested. It owns mutable conversation state, tracks whether it has already been consumed, limits iterations when configured, and appends assistant messages and tool results as the loop advances. The current implementation also builds helper headers, carries request options, and warns that local compaction control is deprecated in favor of server-side compaction edits. This design gives applications a simple iteration interface while preserving the full request and response semantics underneath. Sources: src/lib/tools/BetaToolRunner.ts, src/lib/tools/ToolRunner.ts

System-to-Code Mapping

ConceptSDK contractImplementation notes
Local runnable toolBetaRunnableToolCombines a beta tool definition with parse, run, and optional close.
Tool-use triggerBetaToolUseRepresents either a Messages tool-use block or a Managed Agents tool-use event.
Tool result failureToolErrorCarries string or content-block error output and is reported with error status.
Messages loopBetaToolRunnerPerforms repeated message requests, tool execution, and conversation updates.
Session loopSessionToolRunnerResponds to Managed Agents tool-use events and sends matching result events.
Managed agent configurationGenerated beta agent exportsProvides custom tool, MCP toolset, agent toolset, skill, and model types.

Tool lookup is deliberately shared. The helper named for resolving a tool’s model-addressable key uses the ordinary tool name when the object has one, and uses an MCP server name for MCP toolsets. That matters because Claude addresses tools by registry key, not by a local JavaScript variable name. Keeping the lookup rule in one shared helper prevents the Messages runner and the session runner from disagreeing about which local handler should answer a call. In practice, a tool author should treat the public name as stable API: changing it can break existing prompts, cached prefixes, and agent configurations. Sources: src/lib/tools/BetaRunnableTool.ts

Execution Flow

A typical Messages workflow begins with an Anthropic client call that includes normal message parameters and an array of tools. When the assistant returns a response containing tool use, the runner parses the requested input through the matched runnable tool, calls the tool’s run function, and packages the returned value as a tool result. If the model still needs more work, the runner issues another request with the expanded conversation. Streaming follows the same conceptual path, except each iteration may yield a stream and later await its final message before deciding whether tool execution is required. Sources: src/lib/tools/BetaToolRunner.ts, src/lib/tools/ToolRunner.ts

Managed Agents use the same local runnable shape but a different transport. The session runner watches session events and dispatches only the event types that the application is expected to answer locally: ordinary agent tool use and custom agent tool use. It intentionally does not handle server-side MCP tool-use events. When a result is ready, the runner pairs the event with the matching user result event type, retries sends, observes timeout and idle behavior, and can call each tool’s optional cleanup hook when iteration ends. This keeps long-lived process resources such as shells from leaking after a session finishes. Sources: src/lib/tools/SessionToolRunner.ts, src/lib/tools/BetaRunnableTool.ts

Error Handling and Edge Cases

Tool failures should be returned in a form Claude can reason about. For ordinary thrown values, the shared formatter converts the exception into a text error message. When a tool throws the SDK’s structured error class, the runner uses the error’s stored content directly and marks the tool result as an error. That is useful when failure information is multimodal or when the model needs machine-readable details embedded in content blocks. The class also builds a readable JavaScript error message by joining text blocks and summarizing non-text blocks, which helps logs remain useful for operators. Sources: src/lib/tools/ToolError.ts, src/lib/tools/BetaRunnableTool.ts

There are two important boundaries to keep in mind when designing tool workflows. First, local runners execute client-runnable tools; server-side capabilities such as web search, code execution, and MCP toolsets follow API-managed paths rather than local JavaScript handlers. Second, advanced Claude tool features such as computer use and prompt caching may require feature-specific configuration. Official docs recommend placing cache breakpoints on stable tool definitions and explain that deferred tool loading can preserve cached prefixes. The SDK types expose the versioned computer, bash, text editor, memory, custom tool, and managed-agent toolset shapes needed to model these capabilities correctly. Sources: src/lib/tools/BetaRunnableTool.ts, src/resources/beta/agents/index.ts

Minimal Usage Pattern

Define each tool with a stable name, an input schema in the API tool definition, a parser that turns unknown model input into the TypeScript shape your code expects, and a runner that returns text or content blocks. Then pass those runnable tools to the beta Messages tool runner when you want an automatic loop, or to the session-event runner when operating a Managed Agents session. Use the automatic runner when the application can safely execute calls immediately. Prefer a manual loop when tool execution requires human approval, custom policy checks, or conditional logging before a result is returned.

const getWeatherTool = {
  name: 'get_weather',
  description: 'Get weather for a location',
  input_schema: {
    type: 'object',
    properties: { location: { type: 'string' } },
    required: ['location'],
  },
  parse(input: unknown) {
    return input as { location: string };
  },
  async run({ location }: { location: string }) {
    return `Weather for ${location}: sunny`;
  },
};

After this overview, read the Tool Helpers page for the public helper entry points and the JSON Schema and Zod Helpers page for typed parsing patterns. If your tools are part of a Managed Agents application, continue to Managed Agents Overview and Managed Agent Sessions to understand how sessions, threads, and event streams interact with local tool execution. For integrations that rely on MCP, read the MCP Integration page because MCP toolsets are named and dispatched differently from local runnable tools. For production workflows, pair this page with Request Options, Errors, and Retries so tool loops have explicit timeout, abort, retry, and logging behavior.