SPB Git

Repository Public

tool-search-tool.md 34.9 KB 875 lines markdown

1---2title: Tool search tool3url: https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool4description: Scale to hundreds or thousands of tools by letting Claude search your tool catalog and load only the tools it needs.5---67The tool search tool lets Claude work with hundreds or thousands of tools by discovering and loading them on demand. Instead of loading all tool definitions into the context window up front, Claude searches your tool catalog (including tool names, descriptions, argument names, and argument descriptions) and loads only the tools it needs.89Loading every tool definition up front causes two problems as a tool library grows:1011* **Context bloat:** A typical multiserver setup (GitHub, Slack, Sentry, Grafana, and Splunk) can consume \~55k tokens in definitions before Claude does any work. Tool search typically reduces this by over 85 percent, loading only the 3–5 tools Claude needs for a given request.12* **Tool selection accuracy:** Claude's ability to pick the right tool degrades once you exceed 30–50 available tools. Because tool search loads only a focused set of relevant tools on demand, selection accuracy stays high even across thousands of tools.1314For the models that support tool search, see [Model compatibility](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool#model-compatibility).1516<Tip>17  For background on the scaling challenges that tool search solves, see [Advanced tool use](https://www.anthropic.com/engineering/advanced-tool-use). Tool search's on-demand loading is also an instance of the broader just-in-time retrieval principle described in [Effective context engineering](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents).18</Tip>1920Tool search runs as a server-side tool, but you can also implement your own client-side tool search. See [Custom tool search implementation](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool#custom-tool-search-implementation) for details.2122<Note>23  Share feedback on this feature through the [feedback form](https://forms.gle/MhcGFFwLxuwnWTkYA).24</Note>2526<Note>27  To learn how zero data retention (ZDR) applies to this feature, see [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention).28</Note>2930<Warning>31  On Amazon Bedrock, server-side tool search is available only through the [InvokeModel API](https://docs.aws.amazon.com/bedrock/latest/userguide/bedrock-runtime_example_bedrock-runtime_InvokeModel_AnthropicClaude_section.html), not the Converse API.32</Warning>3334<Note>35  On [Claude Platform on AWS](https://platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws), server-side tool search works identically to the Claude API. Claude Platform on AWS uses the Anthropic Messages API directly, so there is no InvokeModel or Converse distinction.36</Note>3738## Model compatibility3940Both tool search variants are available on the following models:4142| Model                                          | Tool versions                                                       |43| ---------------------------------------------- | ------------------------------------------------------------------- |44| Claude Fable 5.1 (claude-fable-5-1)            | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |45| Claude Mythos 5.1 (claude-mythos-5-1)          | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |46| Claude Fable 5 (claude-fable-5)                | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |47| Claude Mythos 5 (claude-mythos-5)              | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |48| Claude Opus 5 (claude-opus-5)                  | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |49| Claude Opus 4.8 (claude-opus-4-8)              | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |50| Claude Opus 4.7 (claude-opus-4-7)              | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |51| Claude Opus 4.6 (claude-opus-4-6)              | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |52| Claude Sonnet 4.6 (claude-sonnet-4-6)          | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |53| Claude Opus 4.5 (claude-opus-4-5-20251101)     | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |54| Claude Sonnet 4.5 (claude-sonnet-4-5-20250929) | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |55| Claude Haiku 4.5 (claude-haiku-4-5-20251001)   | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |5657Claude Opus 4.1 and earlier models don't support the tool search tool.5859## How tool search works6061There are two tool search variants:6263* **Regex** (`tool_search_tool_regex_20251119`): Claude constructs regex patterns to search for tools.64* **BM25** (`tool_search_tool_bm25_20251119`): Claude uses natural language queries to search for tools.6566When you enable the tool search tool:67681. You include a tool search tool (for example, `tool_search_tool_regex_20251119` or `tool_search_tool_bm25_20251119`) in your `tools` list.692. You provide every tool definition in the `tools` array and set `defer_loading: true` on the tools that shouldn't load up front. At least one tool, normally the tool search tool itself, must stay non-deferred.703. Initially, Claude's context contains only the tool search tool and any non-deferred tools.714. When Claude needs additional tools, it searches using a tool search tool.725. The API runs the search and returns the matching tools as `tool_reference` blocks (up to 5 by default; Claude can set a `limit` in its search input).736. The API automatically expands these references into full tool definitions.747. Claude selects from the discovered tools and calls them.7576## Quick start7778The following example includes the tool search tool and two deferred tools:7980<CodeGroup>81  ```bash cURL82  curl https://api.anthropic.com/v1/messages \83      -H "x-api-key: $ANTHROPIC_API_KEY" \84      -H "anthropic-version: 2023-06-01" \85      -H "content-type: application/json" \86      -d '{87          "model": "claude-opus-5",88          "max_tokens": 2048,89          "messages": [90              {91                  "role": "user",92                  "content": "What is the weather in San Francisco?"93              }94          ],95          "tools": [96              {97                  "type": "tool_search_tool_regex_20251119",98                  "name": "tool_search_tool_regex"99              },100              {101                  "name": "get_weather",102                  "description": "Get the weather at a specific location",103                  "input_schema": {104                      "type": "object",105                      "properties": {106                          "location": {"type": "string"},107                          "unit": {108                              "type": "string",109                              "enum": ["celsius", "fahrenheit"]110                          }111                      },112                      "required": ["location"]113                  },114                  "defer_loading": true115              },116              {117                  "name": "search_files",118                  "description": "Search through files in the workspace",119                  "input_schema": {120                      "type": "object",121                      "properties": {122                          "query": {"type": "string"},123                          "file_types": {124                              "type": "array",125                              "items": {"type": "string"}126                          }127                      },128                      "required": ["query"]129                  },130                  "defer_loading": true131              }132          ]133      }'134  ```135136  ```bash CLI137  ant messages create <<'YAML'138  model: claude-opus-5139  max_tokens: 2048140  messages:141    - role: user142      content: What is the weather in San Francisco?143  tools:144    - type: tool_search_tool_regex_20251119145      name: tool_search_tool_regex146    - name: get_weather147      description: Get the weather at a specific location148      input_schema:149        type: object150        properties:151          location:152            type: string153          unit:154            type: string155            enum: [celsius, fahrenheit]156        required: [location]157      defer_loading: true158    - name: search_files159      description: Search through files in the workspace160      input_schema:161        type: object162        properties:163          query:164            type: string165          file_types:166            type: array167            items:168              type: string169        required: [query]170      defer_loading: true171  YAML172  ```173174  ```python Python175  client = anthropic.Anthropic()176177  response = client.messages.create(178      model="claude-opus-5",179      max_tokens=2048,180      messages=[{"role": "user", "content": "What is the weather in San Francisco?"}],181      tools=[182          {"type": "tool_search_tool_regex_20251119", "name": "tool_search_tool_regex"},183          {184              "name": "get_weather",185              "description": "Get the weather at a specific location",186              "input_schema": {187                  "type": "object",188                  "properties": {189                      "location": {"type": "string"},190                      "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},191                  },192                  "required": ["location"],193              },194              "defer_loading": True,195          },196          {197              "name": "search_files",198              "description": "Search through files in the workspace",199              "input_schema": {200                  "type": "object",201                  "properties": {202                      "query": {"type": "string"},203                      "file_types": {"type": "array", "items": {"type": "string"}},204                  },205                  "required": ["query"],206              },207              "defer_loading": True,208          },209      ],210  )211212  print(response)213  ```214215  ```typescript TypeScript216  const client = new Anthropic();217218  const response = await client.messages.create({219    model: "claude-opus-5",220    max_tokens: 2048,221    messages: [222      {223        role: "user",224        content: "What is the weather in San Francisco?"225      }226    ],227    tools: [228      {229        type: "tool_search_tool_regex_20251119",230        name: "tool_search_tool_regex"231      },232      {233        name: "get_weather",234        description: "Get the weather at a specific location",235        input_schema: {236          type: "object" as const,237          properties: {238            location: { type: "string" },239            unit: {240              type: "string",241              enum: ["celsius", "fahrenheit"]242            }243          },244          required: ["location"]245        },246        defer_loading: true247      },248      {249        name: "search_files",250        description: "Search through files in the workspace",251        input_schema: {252          type: "object" as const,253          properties: {254            query: { type: "string" },255            file_types: {256              type: "array",257              items: { type: "string" }258            }259          },260          required: ["query"]261        },262        defer_loading: true263      }264    ]265  });266267  console.log(response);268  ```269270  ```csharp C#271  AnthropicClient client = new();272273  var parameters = new MessageCreateParams274  {275      Model = Model.ClaudeOpus5,276      MaxTokens = 2048,277      Messages = [278          new() {279              Role = Role.User,280              Content = "What is the weather in San Francisco?"281          }282      ],283      Tools = [284          new ToolUnion(new ToolSearchToolRegex20251119285          {286              Type = ToolSearchToolRegex20251119Type.ToolSearchToolRegex20251119287          }),288          new ToolUnion(new Tool()289          {290              Name = "get_weather",291              Description = "Get the weather at a specific location",292              InputSchema = new InputSchema()293              {294                  Properties = new Dictionary<string, JsonElement>295                  {296                      ["location"] = JsonSerializer.SerializeToElement(new { type = "string" }),297                      ["unit"] = JsonSerializer.SerializeToElement(new { type = "string", @enum = new[] { "celsius", "fahrenheit" } }),298                  },299                  Required = ["location"],300              },301              DeferLoading = true,302          }),303          new ToolUnion(new Tool()304          {305              Name = "search_files",306              Description = "Search through files in the workspace",307              InputSchema = new InputSchema()308              {309                  Properties = new Dictionary<string, JsonElement>310                  {311                      ["query"] = JsonSerializer.SerializeToElement(new { type = "string" }),312                      ["file_types"] = JsonSerializer.SerializeToElement(new { type = "array", items = new { type = "string" } }),313                  },314                  Required = ["query"],315              },316              DeferLoading = true,317          }),318      ]319  };320321  var message = await client.Messages.Create(parameters);322  Console.WriteLine(message);323  ```324325  ```go Go326  client := anthropic.NewClient()327328  response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{329  	Model:     anthropic.ModelClaudeOpus5,330  	MaxTokens: 2048,331  	Messages: []anthropic.MessageParam{332  		anthropic.NewUserMessage(anthropic.NewTextBlock("What is the weather in San Francisco?")),333  	},334  	Tools: []anthropic.ToolUnionParam{335  		{OfToolSearchToolRegex20251119: &anthropic.ToolSearchToolRegex20251119Param{336  			Type: anthropic.ToolSearchToolRegex20251119TypeToolSearchToolRegex20251119,337  		}},338  		{OfTool: &anthropic.ToolParam{339  			Name:        "get_weather",340  			Description: anthropic.String("Get the weather at a specific location"),341  			InputSchema: anthropic.ToolInputSchemaParam{342  				Properties: map[string]any{343  					"location": map[string]any{"type": "string"},344  					"unit": map[string]any{345  						"type": "string",346  						"enum": []string{"celsius", "fahrenheit"},347  					},348  				},349  				Required: []string{"location"},350  			},351  			DeferLoading: anthropic.Bool(true),352  		}},353  		{OfTool: &anthropic.ToolParam{354  			Name:        "search_files",355  			Description: anthropic.String("Search through files in the workspace"),356  			InputSchema: anthropic.ToolInputSchemaParam{357  				Properties: map[string]any{358  					"query":      map[string]any{"type": "string"},359  					"file_types": map[string]any{"type": "array", "items": map[string]any{"type": "string"}},360  				},361  				Required: []string{"query"},362  			},363  			DeferLoading: anthropic.Bool(true),364  		}},365  	},366  })367  if err != nil {368  	log.Fatal(err)369  }370  fmt.Println(response.RawJSON())371  ```372373  ```java Java374  import com.anthropic.models.messages.ToolSearchToolRegex20251119;375376  void main() {377      AnthropicClient client = AnthropicOkHttpClient.fromEnv();378379      InputSchema weatherSchema = InputSchema.builder()380          .properties(JsonValue.from(Map.of(381              "location", Map.of("type", "string"),382              "unit", Map.of(383                  "type", "string",384                  "enum", List.of("celsius", "fahrenheit")385              )386          )))387          .putAdditionalProperty("required", JsonValue.from(List.of("location")))388          .build();389390      InputSchema searchSchema = InputSchema.builder()391          .properties(JsonValue.from(Map.of(392              "query", Map.of("type", "string"),393              "file_types", Map.of(394                  "type", "array",395                  "items", Map.of("type", "string")396              )397          )))398          .putAdditionalProperty("required", JsonValue.from(List.of("query")))399          .build();400401      MessageCreateParams params = MessageCreateParams.builder()402          .model(Model.CLAUDE_OPUS_5)403          .maxTokens(2048L)404          .addUserMessage("What is the weather in San Francisco?")405          .addTool(ToolSearchToolRegex20251119.builder()406              .type(ToolSearchToolRegex20251119.Type.TOOL_SEARCH_TOOL_REGEX_20251119)407              .build())408          .addTool(Tool.builder()409              .name("get_weather")410              .description("Get the weather at a specific location")411              .inputSchema(weatherSchema)412              .deferLoading(true)413              .build())414          .addTool(Tool.builder()415              .name("search_files")416              .description("Search through files in the workspace")417              .inputSchema(searchSchema)418              .deferLoading(true)419              .build())420          .build();421422      Message response = client.messages().create(params);423      IO.println(response);424  }425  ```426427  ```php PHP428  $client = new Client();429430  $message = $client->messages->create(431      maxTokens: 2048,432      messages: [433          ['role' => 'user', 'content' => 'What is the weather in San Francisco?'],434      ],435      model: 'claude-opus-5',436      tools: [437          [438              'type' => 'tool_search_tool_regex_20251119',439              'name' => 'tool_search_tool_regex',440          ],441          [442              'name' => 'get_weather',443              'description' => 'Get the weather at a specific location',444              'input_schema' => [445                  'type' => 'object',446                  'properties' => [447                      'location' => ['type' => 'string'],448                      'unit' => [449                          'type' => 'string',450                          'enum' => ['celsius', 'fahrenheit'],451                      ],452                  ],453                  'required' => ['location'],454              ],455              'defer_loading' => true,456          ],457          [458              'name' => 'search_files',459              'description' => 'Search through files in the workspace',460              'input_schema' => [461                  'type' => 'object',462                  'properties' => [463                      'query' => ['type' => 'string'],464                      'file_types' => [465                          'type' => 'array',466                          'items' => ['type' => 'string'],467                      ],468                  ],469                  'required' => ['query'],470              ],471              'defer_loading' => true,472          ],473      ],474  );475476  echo $message;477  ```478479  ```ruby Ruby480  client = Anthropic::Client.new481482  message = client.messages.create(483    model: "claude-opus-5",484    max_tokens: 2048,485    messages: [486      { role: "user", content: "What is the weather in San Francisco?" }487    ],488    tools: [489      {490        type: "tool_search_tool_regex_20251119",491        name: "tool_search_tool_regex"492      },493      {494        name: "get_weather",495        description: "Get the weather at a specific location",496        input_schema: {497          type: "object",498          properties: {499            location: { type: "string" },500            unit: {501              type: "string",502              enum: ["celsius", "fahrenheit"]503            }504          },505          required: ["location"]506        },507        defer_loading: true508      },509      {510        name: "search_files",511        description: "Search through files in the workspace",512        input_schema: {513          type: "object",514          properties: {515            query: { type: "string" },516            file_types: {517              type: "array",518              items: { type: "string" }519            }520          },521          required: ["query"]522        },523        defer_loading: true524      }525    ]526  )527528  puts message529  ```530</CodeGroup>531532Claude searches the catalog, discovers `get_weather`, and calls it. The response ends with `stop_reason: "tool_use"`. Execute the discovered tool and return a `tool_result` as in [Handle tool calls](https://platform.claude.com/docs/en/agents-and-tools/tool-use/handle-tool-calls). [Response format](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool#response-format) shows the blocks you get back and what to send next.533534## Tool definition535536The tool search tool has two variants:537538```json JSON539{540  "type": "tool_search_tool_regex_20251119",541  "name": "tool_search_tool_regex"542}543```544545```json JSON546{547  "type": "tool_search_tool_bm25_20251119",548  "name": "tool_search_tool_bm25"549}550```551552<Warning>553  **Regex variant query format: Python regex, not natural language**554555  With `tool_search_tool_regex_20251119`, Claude writes Python `re.search()` patterns, not natural language queries. Matching is case-insensitive. Common patterns include the following:556557  * `"weather"`: matches tool names and descriptions containing "weather"558  * `"get_.*_data"`: matches tools such as `get_user_data` and `get_weather_data`559  * `"database.*query|query.*database"`: matches either word order560561  Maximum pattern length: 200 characters562</Warning>563564<Note>565  **BM25 variant query format: natural language**566567  With `tool_search_tool_bm25_20251119`, Claude searches with natural language queries. Maximum query length: 500 characters.568</Note>569570### Deferred tool loading571572Mark tools for on-demand loading by adding `defer_loading: true`:573574```json JSON575{576  "name": "get_weather",577  "description": "Get current weather for a location",578  "input_schema": {579    "type": "object",580    "properties": {581      "location": { "type": "string" },582      "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] }583    },584    "required": ["location"]585  },586  "defer_loading": true587}588```589590`defer_loading` controls what enters the context window, not what you send in the request:591592* You still send every tool's full definition in the `tools` array on every request, including the deferred ones. The API needs them server-side to run the search and expand `tool_reference` blocks.593* Tools without `defer_loading` load into context immediately.594* Tools with `defer_loading: true` load only when Claude discovers them through search.595* Never set `defer_loading: true` on the tool search tool itself.596* Keep your 3–5 most frequently used tools non-deferred so Claude can call them without searching first.597598The computer use and browser use toolsets (`computer_toolset_20260801` and `browser_toolset_20260801`) take `defer_loading` per member tool inside the entry's `configs` object, not on the entry itself; a request that sets it at the entry level is rejected. Because a toolset defers and expands as a unit, `defer_loading` must resolve to the same value on every enabled member, and when Claude discovers the toolset through search, every enabled member loads at once. See [Client toolsets](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-reference#client-toolsets) for the `configs` format.599600Both tool search variants (`regex` and `bm25`) search tool names, descriptions, argument names, and argument descriptions.601602Internally, the API excludes deferred tools from the system-prompt prefix. When Claude discovers a deferred tool through tool search, the API appends a `tool_reference` block inline in the conversation, then expands it into the full tool definition before passing it to Claude. The prefix is untouched, so prompt caching is preserved. The grammar for [strict mode](https://platform.claude.com/docs/en/agents-and-tools/tool-use/strict-tool-use) (the rules that constrain tool-call output to match your schemas) builds from the full toolset, so `defer_loading` and strict mode compose without grammar recompilation.603604## Response format605606When Claude uses the tool search tool, the response includes the following block types:607608```json JSON609{610  "role": "assistant",611  "content": [612    {613      "type": "text",614      "text": "I'll search for tools to help with the weather information."615    },616    {617      "type": "server_tool_use",618      "id": "srvtoolu_01ABC123",619      "name": "tool_search_tool_regex",620      "input": {621        "pattern": "weather",622        "limit": 10623      }624    },625    {626      "type": "tool_search_tool_result",627      "tool_use_id": "srvtoolu_01ABC123",628      "content": {629        "type": "tool_search_tool_search_result",630        "tool_references": [{ "type": "tool_reference", "tool_name": "get_weather" }]631      }632    },633    {634      "type": "text",635      "text": "I found a weather tool. Let me get the weather for San Francisco."636    },637    {638      "type": "tool_use",639      "id": "toolu_01XYZ789",640      "name": "get_weather",641      "input": { "location": "San Francisco", "unit": "fahrenheit" }642    }643  ],644  "stop_reason": "tool_use"645}646```647648### Understanding the response649650* **`server_tool_use`:** Claude's call to the tool search tool. The search runs on Anthropic's servers. Never return a `tool_result` for its `srvtoolu_...` ID. The `input` holds the search (`pattern` for the regex variant, `query` for BM25) and may include an optional `limit`, an integer from 1 to 10,000 that caps how many matching tools the search returns (default: 5).651* **`tool_search_tool_result`:** the search results, in a nested `tool_search_tool_search_result` object. Keep it in the message history as is.652* **`tool_references`:** an array of `tool_reference` objects pointing to discovered tools. The API expands these for Claude. You never expand them yourself.653* **`tool_use`:** Claude's call to a discovered tool. Execute it and return a `tool_result` exactly as in standard tool use.654655The API automatically expands `tool_reference` blocks into full tool definitions before showing them to Claude. You don't need to handle this expansion yourself, as long as you provide all matching tool definitions in the `tools` parameter.656657### Continuing the conversation658659On the next request, pass the assistant's content back unchanged, including the `server_tool_use` and `tool_search_tool_result` blocks. Add your `tool_result` for the discovered tool in a user message, and send the same `tools` array: the search tool plus every deferred definition. Don't return a `tool_result` for the `srvtoolu_...` ID: the API rejects the request. The API expands `tool_reference` blocks throughout the conversation history, so Claude can reuse discovered tools in later turns without re-searching. A search that matches nothing returns a `tool_search_tool_search_result` with an empty `tool_references` array, not an error.660661## MCP integration662663If your tools come from MCP servers through the [MCP connector](https://platform.claude.com/docs/en/agents-and-tools/mcp-connector), you don't set `defer_loading` on individual tool definitions. Instead, set it once on the `mcp_toolset` entry's `default_config` for the whole server, or per tool in its `configs`. See [MCP toolset configuration](https://platform.claude.com/docs/en/agents-and-tools/mcp-connector#mcp-toolset-configuration).664665## Custom tool search implementation666667You can implement your own tool search logic (for example, using embeddings or semantic search) by returning `tool_reference` blocks from a custom tool. When Claude calls your custom search tool, return a standard `tool_result` with `tool_reference` blocks in the content array:668669```json JSON670{671  "type": "tool_result",672  "tool_use_id": "toolu_your_tool_id",673  "content": [{ "type": "tool_reference", "tool_name": "discovered_tool_name" }]674}675```676677Every tool referenced must have a corresponding tool definition in the top-level `tools` parameter, normally with `defer_loading: true`. This lets you use search methods the built-in variants don't provide, such as embedding-based retrieval, and the API expands the returned `tool_reference` blocks the same way.678679<Note>680  The `tool_search_tool_result` format shown in the [Response format](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool#response-format) section is the server-side format used internally by Anthropic's built-in tool search. For custom client-side implementations, always use the standard `tool_result` format with `tool_reference` content blocks as shown in the preceding example.681</Note>682683For a complete example using embeddings, see the [tool search with embeddings](https://platform.claude.com/cookbook/tool-use-tool-search-with-embeddings) recipe.684685## Error handling686687<Note>688  [Tool use examples](https://platform.claude.com/docs/en/agents-and-tools/tool-use/define-tools#providing-tool-use-examples) work with tool search: when Claude discovers a deferred tool, the API expands its `input_examples` along with its definition.689</Note>690691### HTTP errors (400 status)692693These errors prevent the API from processing the request:694695**All tools deferred:**696697```json698{699  "type": "error",700  "error": {701    "type": "invalid_request_error",702    "message": "At least one tool must have defer_loading=false. All tools cannot be deferred."703  }704}705```706707**Missing tool definition:**708709```json710{711  "type": "error",712  "error": {713    "type": "invalid_request_error",714    "message": "Tool reference 'unknown_tool' not found in available tools"715  }716}717```718719### Tool result errors (200 status)720721When a tool search operation fails during execution, the API returns a 200 response with the error in the body:722723```json JSON724{725  "type": "tool_search_tool_result",726  "tool_use_id": "srvtoolu_01ABC123",727  "content": {728    "type": "tool_search_tool_result_error",729    "error_code": "invalid_tool_input",730    "error_message": "Invalid regular expression pattern: missing ) at position 1"731  }732}733```734735The `error_code` field has four possible values:736737* `invalid_tool_input`: the search input was invalid, for example a malformed regex pattern or a pattern over the 200-character limit738* `unavailable`: the search couldn't run, for example because it timed out or the service was unavailable739* `too_many_requests`: rate limit exceeded for tool search operations740* `execution_time_exceeded`: the search exceeded its execution time limit741742### Common mistakes743744<Accordion title="400 error: all tools are deferred">745  **Cause:** You set `defer_loading: true` on every tool, including the tool search tool.746747  **Fix:** Remove `defer_loading` from the tool search tool:748749  ```json750  {751    "type": "tool_search_tool_regex_20251119",752    "name": "tool_search_tool_regex"753  }754  ```755</Accordion>756757<Accordion title="400 error: missing tool definition">758  **Cause:** A `tool_reference` points to a tool not in your `tools` array.759760  **Fix:** Ensure every tool that could be discovered has a complete definition:761762  ```json763  {764    "name": "my_tool",765    "description": "Full description here",766    "input_schema": {767      "type": "object"768    },769    "defer_loading": true770  }771  ```772</Accordion>773774<Accordion title="Claude doesn't find expected tools">775  **Cause:** The regex pattern doesn't match the tool's name, description, argument names, or argument descriptions.776777  **Debugging steps:**778779  1. Check tool name, description, argument names, and argument descriptions. Claude searches all of these fields.780  2. Test your pattern: `import re; re.search(r"your_pattern", "tool_name", re.IGNORECASE)`.781  3. Matching is case-insensitive, so casing differences aren't the problem.782  4. Claude uses broad patterns such as `".*weather.*"`, not exact matches.783784  **Tip:** Add common keywords to tool descriptions to improve discoverability.785</Accordion>786787## Prompt caching788789To learn how `defer_loading` preserves prompt caching, see [Tool use with prompt caching](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-use-with-prompt-caching).790791A tool with `defer_loading: true` can't also carry `cache_control`: the API returns a 400. Put the cache breakpoint on a non-deferred tool.792793## Streaming794795With streaming enabled, you'll receive tool search events as part of the stream:796797```sse798event: content_block_start799data: {"type": "content_block_start", "index": 1, "content_block": {"type": "server_tool_use", "id": "srvtoolu_xyz789", "name": "tool_search_tool_regex"}}800801// Search pattern streamed802event: content_block_delta803data: {"type": "content_block_delta", "index": 1, "delta": {"type": "input_json_delta", "partial_json": "{\"pattern\":\"weather\"}"}}804805// Pause while search executes806807// Search results streamed808event: content_block_start809data: {"type": "content_block_start", "index": 2, "content_block": {"type": "tool_search_tool_result", "tool_use_id": "srvtoolu_xyz789", "content": {"type": "tool_search_tool_search_result", "tool_references": [{"type": "tool_reference", "tool_name": "get_weather"}]}}}810811// Claude continues with discovered tools812```813814## Batch requests815816You can include the tool search tool in the [Messages Batches API](https://platform.claude.com/docs/en/build-with-claude/batch-processing).817818## Limits and best practices819820### Limits821822* **Maximum deferred tools:** 10,000 tools with `defer_loading: true` per request823* **Search results:** each search returns up to 5 matching tools by default; Claude can set `limit` in its search input to any integer from 1 to 10,000824* **Pattern and query length:** maximum 200 characters for regex patterns and 500 characters for BM25 queries825* **Model support:** see [Model compatibility](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool#model-compatibility)826827### When to use tool search828829Use tool search when any of the following apply:830831* You have 10 or more tools available.832* Your tool definitions consume more than 10k tokens.833* Tool selection accuracy drops as your toolset grows.834* You aggregate multiple MCP servers (200+ tools).835* Your tool library grows over time.836837Standard tool calling, without tool search, is a better fit when you have fewer than 10 tools, every tool is used in every request, or your tool definitions are small (less than 100 tokens total).838839### Optimization tips840841* Keep your 3–5 most frequently used tools non-deferred.842* Write clear, descriptive tool names and descriptions.843* Use consistent namespacing in tool names: prefix by service or resource (for example, `github_`, `slack_`) so one search matches the whole group.844* Use keywords in descriptions that match how users describe tasks.845* Add a system prompt section describing available tool categories: "You can search for tools to interact with Slack, GitHub, and Jira."846* Monitor which tools Claude discovers to refine your descriptions.847848## Usage849850Tool search isn't metered as a separate server tool. The response's `usage.server_tool_use` object has no tool search field, and the tool definitions that search loads into context count as input tokens like any other tool definition.851852## Next steps853854<CardGroup cols={2}>855  <Card title="Memory tool" icon="brain" href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/memory-tool">856    Let Claude store and retrieve information across conversations by implementing the memory tool's file operations in your application.857  </Card>858859  <Card title="Tool reference" icon="book" href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-reference">860    Directory of Anthropic-provided tools and reference for optional tool definition properties.861  </Card>862863  <Card title="MCP connector" icon="link" href="https://platform.claude.com/docs/en/agents-and-tools/mcp-connector">864    Configure MCP toolsets with deferred loading.865  </Card>866867  <Card title="Tool use with prompt caching" icon="bolt" href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-use-with-prompt-caching">868    Cache tool definitions across turns and understand what invalidates your cache.869  </Card>870871  <Card title="Define tools" icon="hammer" href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/define-tools">872    Specify tool schemas, write effective descriptions, and control when Claude calls your tools.873  </Card>874</CardGroup>875
Files main
Menu

Theme