Skip to main content
Every example on this page is a complete script. They show dynamic_tools working across the three situations that trigger it: local Python tools, MCP servers, and max_loops="auto". For the concepts behind these examples — the search algorithm, pre-warming, and prompt-cache interaction — see Dynamic Tool Loading.

Install

ENV

Deferring Local Tools

The default. Both tools are registered and executable, but neither schema is sent until the model searches for it.

Inspecting What Is Deferred

agent.tool_loader lets you see the catalog before, during, and after a run. This script needs no API key.
Output:
Only tool_search ships with the request. The other three are one search away.

Driving the Search Directly

run_search is the handler behind the tool_search tool. Calling it yourself is the fastest way to see how ranking behaves.
Output:
Stopwords are filtered before matching. run_search("weather in a city") returns only get_weather; run_search("please can you help with the") returns a miss rather than loading the whole catalog.

Narrowing Results with a Score Threshold

min_score_ratio drops matches scoring below a fraction of the best match. Use it when the query is long enough that common words give weak matches a nonzero score.
search ranks without loading, so you can tune a threshold before wiring it into anything.

Counting the Savings

Deferral is a token optimization, so measure it. This compares the eager tool array against the deferred one.
The gap widens with catalog size — with two tools it is modest, with an MCP server exposing forty it is most of the tool array.

MCP Servers

A single MCP server can contribute dozens of schemas. With dynamic_tools=True they join the catalog instead of shipping on every request. DeepWiki needs no API key.

Inspecting an MCP Catalog Before Running

MCP deferral is lazy — the server is contacted while the LLM is built, not at construction. Build the LLM yourself to see the catalog first.
The fetch happens once per agent and is cached, so rebuilding the LLM does not re-contact the server. If the server is unreachable the agent still builds — the failure is logged, nothing is deferred, and tool_search finds nothing.

Budgeting Turns for a Deferred MCP Call

A deferred tool needs three turns: search, call, then answer. With a fixed max_loops, budget for it.
With max_loops=1 the model can search but never call what it found. Either raise max_loops, or set dynamic_tools=False so the schema ships on turn one.

The Autonomous Loop

With max_loops="auto", deferral activates even with no tools argument — the loop’s own file, shell, and sub-agent tools go into the catalog while the control tools stay loaded.
The agent calls create_plan first. That plan text is used as a search query to pre-load the tools the plan implies — up to 8 of them, at no extra turn cost — and the create_plan result tells the model what it already has:

Combining Loop Tools with Your Own

User tools join the same catalog. They are not eagerly re-integrated after planning when dynamic_tools is on.

Restricting What Can Be Found

selected_tools filters the loop’s built-in tools before deferral, so an excluded tool never enters the catalog and cannot be found by tool_search at all.

Registering Extra Schemas

Schemas appended to tools_list_dictionary after construction are clobbered the next time a search refreshes the tool array. Register them with defer_tool_schemas instead.
A schema registered this way is searchable and advertised once loaded, but it has no local callable attached — dispatch it yourself, the way MCP tools are dispatched through the MCP manager.

Turning Deferral Off

For two or three tools, or when the tool must be callable on turn one, eager registration is the better trade.

Choosing Between Them

Notes

  • dynamic_tools=True alone does nothing. Deferral needs tools, an MCP connection, or max_loops="auto".
  • Deferred is not disabled. A model that guesses a correct tool name can still execute it — only the schema is withheld.
  • A tool of your own named tool_search is dropped from the catalog with a warning and becomes unreachable. Rename it.
  • Every load changes the tool array and invalidates the provider’s cached prefix. Load everything for a subtask in one tool_search call.
  • MCP tools never appear in loader.handlers(); they route through the MCP manager by design.

Next Steps

Dynamic Tool Loading

The concepts: search ranking, pre-warming, and caching behavior

DynamicToolLoader API

Full class reference for the loader and its methods

Agent with Tools

Defining tools, schemas, and execution basics

MCP Integration

Connecting MCP servers to an agent

Source