Skip to main content

ToolSearchProcessor

The ToolSearchProcessor is an input processor that enables dynamic tool discovery and loading. Instead of providing all tools to the agent upfront, it gives the agent two meta-tools (search_tools and load_tool) that let it find and load tools on demand. This reduces context token usage when working with large tool libraries.

Usage example
Direct link to Usage example

import { ToolSearchProcessor } from '@mastra/core/processors'

const toolSearch = new ToolSearchProcessor({
tools: {
createIssue: githubTools.createIssue,
sendEmail: emailTools.send,
getWeather: weatherTools.forecast,
// ... many more tools
},
search: {
topK: 5,
minScore: 0.1,
},
})

Constructor parameters
Direct link to Constructor parameters

options:

ToolSearchProcessorOptions
Configuration options for the tool search processor
ToolSearchProcessorOptions

tools:

Record<string, Tool>
All tools that can be searched and loaded dynamically. These tools are not immediately available to the agent — they must be discovered via search and loaded on demand.

search?:

{ topK?: number; minScore?: number }
Configuration for the search behavior.

search.topK?:

number
Maximum number of tools to return in search results.

search.minScore?:

number
Minimum relevance score (0-1) for including a tool in search results.

ttl?:

number
Time-to-live for thread state in milliseconds. After this duration of inactivity, thread state will be cleaned up. Set to 0 to disable cleanup.

filter?:

(args: ToolSearchFilterArgs) => boolean | Promise<boolean>
Optional request-aware hook for hiding tools from search results, blocking tool loading, or hiding already-loaded tools for the current request.

Returns
Direct link to Returns

id:

string
Processor identifier set to 'tool-search'

name:

string
Processor display name set to 'Tool Search Processor'

processInputStep:

(args: ProcessInputStepArgs) => Promise<ProcessInputStepResult>
Processes each step to inject search/load meta-tools and any previously loaded tools into the agent's tool set.

Request-aware filtering
Direct link to Request-aware filtering

Use filter to apply request-specific policy to dynamic tools. The hook receives the resolved tool ID as toolName, the tool, request context, and phase. toolName is the ID returned by search_tools, which may differ from the key used in the tools object.

import { ToolSearchProcessor } from '@mastra/core/processors'

const toolSearch = new ToolSearchProcessor({
tools: allTools,
filter: ({ toolName, requestContext, phase }) => {
const plan = requestContext?.get('plan')

if (phase === 'search') {
return true
}

return plan === 'pro' || !toolName.startsWith('premium_')
},
})

The phase value describes where the filter is being applied:

  • search: Filters results returned by search_tools.
  • load: Blocks load_tool from loading disallowed tools.
  • active: Hides already-loaded tools from the current request if they are no longer allowed.

If the hook throws or rejects, ToolSearchProcessor treats the tool as disallowed for that request. The hook may run for every matching search candidate, so keep async policy checks cheap or cached. The meta-tools search_tools and load_tool are always available. Tools passed directly through the agent or processInputStep remain available unless you filter them outside ToolSearchProcessor.

Extended usage example
Direct link to Extended usage example

src/mastra/agents/dynamic-tools-agent.ts
import { Agent } from '@mastra/core/agent'
import { ToolSearchProcessor } from '@mastra/core/processors'

// Tools from various integrations
import { githubTools } from './tools/github'
import { slackTools } from './tools/slack'
import { dbTools } from './tools/database'

const toolSearch = new ToolSearchProcessor({
tools: {
...githubTools, // createIssue, listPRs, mergePR, ...
...slackTools, // sendMessage, createChannel, ...
...dbTools, // query, insert, update, ...
},
search: {
topK: 5,
minScore: 0.1,
},
})

const agent = new Agent({
name: 'dynamic-tools-agent',
instructions:
'You are a helpful assistant with access to many tools. Use search_tools to find relevant tools, then load_tool to make them available.',
model: 'openai/gpt-5.5',
inputProcessors: [toolSearch],
})

The agent workflow is:

  1. Agent receives a user message
  2. Agent calls search_tools with keywords (e.g., "github issue")
  3. Agent reviews results and calls load_tool with the tool name
  4. The loaded tool becomes available on the next turn
  5. Agent uses the loaded tool normally

Combining with other processors
Direct link to Combining with other processors

import { Agent } from '@mastra/core/agent'
import { ToolSearchProcessor, TokenLimiter } from '@mastra/core/processors'

const agent = new Agent({
name: 'my-agent',
model: 'openai/gpt-5.5',
inputProcessors: [
new ToolSearchProcessor({
tools: allTools,
search: { topK: 5 },
}),
// Place TokenLimiter last to ensure context fits
new TokenLimiter(127000),
],
})