Provider-side tool search middleware.
Leverages server-side tool search: the full client tool catalog is forwarded
to the provider, with deferred tools marked defer_loading so the provider
discloses them on demand via its own search. A tool is deferred when it is
named in searchableTools or built with extras.defer_loading: true.
Requires a model with server-side tool search support: OpenAI gpt-5.4+ or Anthropic Claude Sonnet 4+/Opus 4+/Haiku 4.5+. Non-Anthropic/OpenAI providers throw; an in-family model that is too old surfaces the provider's own API error rather than being gated here.
providerToolSearchMiddleware(
config: ProviderToolSearchMiddlewareConfig = {}
): AgentMiddleware<undefined, undefined, unknown, readonly ClientTool | ServerTool[], readonly []>| Name | Type | Description |
|---|---|---|
config | ProviderToolSearchMiddlewareConfig | Default: {}Configuration options for the middleware |
import { createAgent, providerToolSearchMiddleware } from "langchain";
import { ChatAnthropic } from "@langchain/anthropic";
const agent = createAgent({
model: new ChatAnthropic({ model: "claude-sonnet-4-5" }),
tools: [getWeather, ...nicheTools],
middleware: [
// Defer the niche tools behind the provider's tool search; the model
// discovers them on demand instead of receiving every schema up front.
providerToolSearchMiddleware({ searchableTools: nicheTools }),
],
});import { tool } from "@langchain/core/tools";
import { createAgent, providerToolSearchMiddleware } from "langchain";
import { ChatAnthropic } from "@langchain/anthropic";
// A tool marked `defer_loading` at construction is deferred on its own ā
// no need to list it in `searchableTools`; the middleware honors the flag.
const sendEmail = tool(sendEmailFn, {
name: "send_email",
description: "Send an email",
schema: sendEmailSchema,
extras: { defer_loading: true },
});
const agent = createAgent({
model: new ChatAnthropic({ model: "claude-sonnet-4-5" }),
tools: [getWeather, sendEmail],
middleware: [providerToolSearchMiddleware()],
});