tool-search-tool changedagents-and-tools/tool-use/tool-search-tool
Nearest release: v2.1.232, published 7 hours before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
## Model compatibility ## How tool search works ## Quick start ## Tool definition ### Deferred tool loading ## Response format ### Understanding the response ### Continuing the conversation ## MCP integration ## Custom tool search implementation ## Error handling ### HTTP errors (400 status) ### Tool result errors (200 status) ### Common mistakes ## Prompt caching ## Streaming ## Batch requests ## Limits and best practices ### Limits ### When to use tool search ### Optimization tips ## Usage ## Next steps
The whole hunk
870 lines, first recordedThe first capture of this source. The page was already there, and this is what it said.
---
title: Tool search tool
url: https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool
description: Scale to hundreds or thousands of tools by letting Claude search your tool catalog and load only the tools it needs.
---
The 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.
Loading every tool definition up front causes two problems as a tool library grows:
* **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.
* **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.
Tool search is generally available on the Claude API. For supported models, see [Model compatibility](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool#model-compatibility).
<Tip>
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).
</Tip>
Tool 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.
<Note>
Share feedback on this feature through the [feedback form](https://forms.gle/MhcGFFwLxuwnWTkYA).
</Note>
<Note>
For 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).
</Note>
<Warning>
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.
</Warning>
<Note>
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.
</Note>
## Model compatibility
Both tool search variants are available on the following models:
| Model | Tool versions |
| ---------------------------------------------- | ------------------------------------------------------------------- |
| Claude Fable 5 (claude-fable-5) | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |
| Claude Mythos 5 (claude-mythos-5) | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |
| Claude Opus 5 (claude-opus-5) | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |
| Claude Opus 4.8 (claude-opus-4-8) | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |
| Claude Opus 4.7 (claude-opus-4-7) | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |
| Claude Opus 4.6 (claude-opus-4-6) | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |
| Claude Sonnet 4.6 (claude-sonnet-4-6) | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |
| Claude Opus 4.5 (claude-opus-4-5-20251101) | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |
| Claude Sonnet 4.5 (claude-sonnet-4-5-20250929) | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |
| Claude Haiku 4.5 (claude-haiku-4-5-20251001) | `tool_search_tool_regex_20251119`, `tool_search_tool_bm25_20251119` |
Claude Opus 4.1 and earlier models don't support the tool search tool.
## How tool search works
There are two tool search variants:
* **Regex** (`tool_search_tool_regex_20251119`): Claude constructs regex patterns to search for tools.
* **BM25** (`tool_search_tool_bm25_20251119`): Claude uses natural language queries to search for tools.
When you enable the tool search tool:
1. You include a tool search tool (for example, `tool_search_tool_regex_20251119` or `tool_search_tool_bm25_20251119`) in your `tools` list.
2. 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.
3. Initially, Claude's context contains only the tool search tool and any non-deferred tools.
4. When Claude needs additional tools, it searches using a tool search tool.
5. 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).
6. The API automatically expands these references into full tool definitions.
7. Claude selects from the discovered tools and calls them.
## Quick start
The following example includes the tool search tool and two deferred tools:
<CodeGroup>
```bash cURL
curl https://api.anthropic.com/v1/messages \
--header "x-api-key: $ANTHROPIC_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "content-type: application/json" \
--data '{
"model": "claude-opus-5",
"max_tokens": 2048,
"messages": [
{
"role": "user",
"content": "What is the weather in San Francisco?"
}
],
"tools": [
{
"type": "tool_search_tool_regex_20251119",
"name": "tool_search_tool_regex"
},
{
"name": "get_weather",
"description": "Get the weather at a specific location",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string"},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
},
"defer_loading": true
},
{
"name": "search_files",
"description": "Search through files in the workspace",
"input_schema": {
"type": "object",
"properties": {
"query": {"type": "string"},
"file_types": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["query"]
},
"defer_loading": true
}
]
}'
```
```bash CLI
ant messages create <<'YAML'
model: claude-opus-5
max_tokens: 2048
messages:
- role: user
content: What is the weather in San Francisco?
tools:
- type: tool_search_tool_regex_20251119
name: tool_search_tool_regex
- name: get_weather
description: Get the weather at a specific location
input_schema:
type: object
properties:
location:
type: string
unit:
type: string
enum: [celsius, fahrenheit]
required: [location]
defer_loading: true
- name: search_files
description: Search through files in the workspace
input_schema:
type: object
properties:
query:
type: string
file_types:
type: array
items:
type: string
required: [query]
defer_loading: true
YAML
```
```python Python
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=2048,
messages=[{"role": "user", "content": "What is the weather in San Francisco?"}],
tools=[
{"type": "tool_search_tool_regex_20251119", "name": "tool_search_tool_regex"},
{
"name": "get_weather",
"description": "Get the weather at a specific location",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["location"],
},
"defer_loading": True,
},
{
"name": "search_files",
"description": "Search through files in the workspace",
"input_schema": {
"type": "object",
"properties": {
"query": {"type": "string"},
"file_types": {"type": "array", "items": {"type": "string"}},
},
"required": ["query"],
},
"defer_loading": True,
},
],
)
print(response)
```
```typescript TypeScript
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-opus-5",
max_tokens: 2048,
messages: [
{
role: "user",
content: "What is the weather in San Francisco?"
}
],
tools: [
{
type: "tool_search_tool_regex_20251119",
name: "tool_search_tool_regex"
},
{
name: "get_weather",
description: "Get the weather at a specific location",
input_schema: {
type: "object" as const,
properties: {
location: { type: "string" },
unit: {
type: "string",
enum: ["celsius", "fahrenheit"]
}
},
required: ["location"]
},
defer_loading: true
},
{
name: "search_files",
description: "Search through files in the workspace",
input_schema: {
type: "object" as const,
properties: {
query: { type: "string" },
file_types: {
type: "array",
items: { type: "string" }
}
},
required: ["query"]
},
defer_loading: true
}
]
});
console.log(response);
```
```csharp C#
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Model.ClaudeOpus5,
MaxTokens = 2048,
Messages = [
new() {
Role = Role.User,
Content = "What is the weather in San Francisco?"
}
],
Tools = [
new ToolUnion(new ToolSearchToolRegex20251119
{
Type = ToolSearchToolRegex20251119Type.ToolSearchToolRegex20251119
}),
new ToolUnion(new Tool()
{
Name = "get_weather",
Description = "Get the weather at a specific location",
InputSchema = new InputSchema()
{
Properties = new Dictionary<string, JsonElement>
{
["location"] = JsonSerializer.SerializeToElement(new { type = "string" }),
["unit"] = JsonSerializer.SerializeToElement(new { type = "string", @enum = new[] { "celsius", "fahrenheit" } }),
},
Required = ["location"],
},
DeferLoading = true,
}),
Cut at 300 lines. The page has the rest.
No line in this hunk matches that.