Currently ToolSearchProcessor only accepts a static Record<string, Tool> at construction time and indexes everything immediately in the BM25 index. This means tools that are
resolved dynamically per-request (like MCP tools from MCPClient.listTools()) can't benefit from the search/load pattern.
The problem:
We have ~20+ MCP tools fetched per-request (they require user auth tokens), plus ~15 static tools. All MCP tools are always sent in the prompt, consuming significant tokens.
We'd like to use ToolSearchProcessor for both static and MCP tools to reduce context size.
What happens today:
- processInputStep receives args.tools which already contains the resolved MCP tools, but ToolSearchProcessor ignores them — it only searches against this.allTools set in the
constructor.
Proposed solution:
Allow ToolSearchProcessor to also index tools from args.tools (the per-request resolved tools). This could be:
1. An option like includeResolvedTools: true — on each processInputStep call, merge args.tools into the searchable index (re-indexing new tools that aren't already indexed).
2. A lazy/async tools source — accept tools as Record<string, Tool> | (() => Promise<Record<string, Tool>>) in the constructor.
Option 1 seems most natural since the framework already resolves MCP tools and passes them in args.tools. The BM25 index could be extended incrementally per-step for any new
tools not yet indexed.
This would allow agents with many MCP tools to get the same token savings that static tools already enjoy with ToolSearchProcessor.