Description
With Claude Code's tool search on (ENABLE_TOOL_SEARCH=true), the Codex provider rewrites the leading tool list every time ToolSearch loads a tool. The request after each load therefore misses the prompt cache. The load result also reaches the model as [unsupported content block omitted: tool_reference].
Background
Claude Code turns tool search off when ANTHROPIC_BASE_URL is not an Anthropic host. Its debug log says "Set ENABLE_TOOL_SEARCH=true (or auto / auto:N) if your proxy forwards tool_reference blocks". Without it, every MCP tool schema goes out with every request: in our case 281 MCP tools, about 150k of a ~270k-token request.
With ENABLE_TOOL_SEARCH=true, checked on Claude Code 2.1.293:
- The first request carries only the core tools,
ToolSearch, and aDeferredToolPlaceholderstub withdefer_loading: true. Deferred tools are listed by name in a text reminder. - After
ToolSearchruns, thetool_resultcontains{"type":"tool_reference","tool_name":"…"}. Later requests include that tool's definition withdefer_loading: true.
Problem (Responses Lite lane)
- All tools, deferred or not, go into the one leading
additional_toolsitem (request.rs). A load changes the first input item. tool_referencerenders as[unsupported content block omitted: tool_reference](request.rs).DeferredToolPlaceholder("never call this tool") is forwarded as a callable tool.
What Codex does
Codex's IncrementalTools feature appends a changed catalog as its own additional_tools item at the point of change, instead of rewriting the leading list. See top_level_tools.rs and the test incremental_tools_append_changed_catalog_without_rewriting_history.
Drafted by Claude Opus 5.5 in Claude Code on behalf of @Butanium; not reviewed by a human.
Activity
feat(codex): append loaded deferred tools incrementally (ToolSearch) (#6