Skip to content

feat(anthropic): support defer_loading tool search expansion#109

Open
juslintek wants to merge 2 commits intojwadow:mainfrom
juslintek:feat/defer-loading-expansion
Open

feat(anthropic): support defer_loading tool search expansion#109
juslintek wants to merge 2 commits intojwadow:mainfrom
juslintek:feat/defer-loading-expansion

Conversation

@juslintek
Copy link
Copy Markdown

What

Enables Claude Code's MCP Tool Search feature to work through the gateway by handling defer_loading tools and expanding tool_reference blocks.

Why

When Claude Code has ENABLE_TOOL_SEARCH=true, it sends MCP tools with defer_loading: true instead of including them all in every request. The model then requests specific tools on-demand via tool_reference blocks. Without this, the gateway either sends all deferred tools (wasting tokens) or drops them entirely.

How it works

  1. convert_anthropic_tools() reads defer_loading from each tool, stores it on UnifiedTool._defer_loading
  2. anthropic_to_kiro() separates deferred vs active tools
  3. Scans messages for tool_reference blocks (both top-level and inside tool_result content)
  4. Expands referenced deferred tools into the active set
  5. Only active tools are sent to Kiro API

Also skips Anthropic built-in server tools (no input_schema) that the Kiro API cannot handle.

Changes

  • converters_core.py: Add _defer_loading: bool field to UnifiedTool dataclass
  • converters_anthropic.py:
    • convert_anthropic_tools(): Read defer_loading, skip server tools without input_schema
    • anthropic_to_kiro(): Defer/expand logic with tool_reference scanning

Dependencies

Depends on #108 (tool search content block models)

Testing

All 1413 existing tests pass. Verified locally with live Claude Code traffic — logs show:

[Tool Search] 9 active, 2 deferred, 0 expanded from tool_reference

…ol_result content blocks

Claude Code v2.1.69+ sends tool_reference blocks inside tool_result content
when using the deferred tool search feature (ENABLE_TOOL_SEARCH=true).
The Anthropic API also returns server_tool_use and tool_search_tool_result
blocks for server-side tool search invocations.

Without these models, Pydantic validation rejects requests containing
these block types with 422 errors.

Changes:
- Add ToolReferenceContentBlock model (type='tool_reference')
- Add ServerToolUseContentBlock model (type='server_tool_use')
- Add ToolSearchResultContentBlock model (type='tool_search_tool_result')
- Add ToolReferenceContentBlock to ToolResultContentBlock.content union
- Add all three to ContentBlock union
- Add model_config extra=allow to ToolResultContentBlock for cache_control

Related: jwadow#90, jwadow#96, jwadow#82 (different approaches to the same 422 issue)
When Claude Code sends tools with defer_loading=true (ENABLE_TOOL_SEARCH),
the gateway now:
1. Separates deferred tools from active tools
2. Only sends active tools to Kiro API (reducing token usage)
3. Scans messages for tool_reference blocks
4. Expands referenced deferred tools into the active set

This enables Claude Code's MCP Tool Search feature to work through
the gateway, where the model requests tools on-demand instead of
sending all MCP tools in every request.

Also skips Anthropic built-in server tools (no input_schema) that
the Kiro API cannot handle.

Depends on: jwadow#108 (tool search content block models)
@cla-bot
Copy link
Copy Markdown

cla-bot bot commented Mar 21, 2026

Thanks for the PR! 🎉

Before merge, we need a one-time CLA confirmation.
It confirms that you have the right to contribute this code and allow the project to use it.

Full CLA text:
https://github.com/jwadow/kiro-gateway/blob/main/CLA.md

Please reply once with:

I have read the CLA and I accept its terms

You need to write once, all further messages from me can be ignored.

@juslintek
Copy link
Copy Markdown
Author

I have read the CLA and I accept its terms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant