fix(mcp): re-land native tool preservation with typed annotations#30645
fix(mcp): re-land native tool preservation with typed annotations#30645ayushh0110 wants to merge 2 commits into
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Greptile SummaryThis PR fixes the bug where native (non-MCP) tools were silently dropped when
Confidence Score: 5/5The change is safe to merge: it repairs a clear drop-silent bug without altering any external API contract, and all new paths have direct mock-based test coverage. The partitioning and reconstruction logic is internally consistent — No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/proxy/hooks/mcp_semantic_filter/hook.py | Adds native-tool partitioning logic: _is_mcp_tool, _emit_filter_metadata, semantic-filter-only-for-MCP path, order-preserving tool reconstruction, and a .get() guard in the headers hook — all correct and well-bounded. |
| tests/test_litellm/proxy/_experimental/mcp_server/test_semantic_tool_filter.py | Adds four targeted regression tests covering mixed MCP+native, all-native, Responses-API name collision, and original-order preservation — all mock-based, no real network calls. |
Reviews (2): Last reviewed commit: "fix(mcp): tighten _is_mcp_tool Chat Comp..." | Re-trigger Greptile
|
Thanks for the PR! A couple of things to get this over the finish line:
Once those are addressed we'll take another look — appreciate the contribution! |
5d0d375 to
8421d01
Compare
|
Hii @Sameerlite Addressed both items:
Test 1 - Single native tool + tool_choice=auto (exact #26212 repro): Status 200, native tool preserved, LLM calls weather_lookup correctly. No spurious x-litellm-semantic-filter header. Test 2 - Multiple native tools: Both weather_lookup and stock_price preserved and called. Test 3 - No tools: Plain text response, no filter interference. Test 4 - Unit tests: 20/20 pass.
|





Relevant issues
Fixes #26212
Re-lands #26650 (reverted in #30637 due to Any-discipline CI check)
Pre-Submission checklist
make test-unit@greptileaiand received a Confidence Score of at least 4/5 before requesting a maintainer reviewType
Bug Fix
Changes
Same fix as #26650 with all type annotations tightened per the revert feedback.
List[Any], bareset, andAny-typed parameters replaced withobject,list[object],set[int], andset[str]to stay under the any-discipline ceiling.The underlying bug: when
mcp_semantic_tool_filteris enabled and a request has both MCP and native tools, native tools get silently dropped. In the expansion path,_expand_mcp_toolsdiscards non-MCP tools since_parse_mcp_toolsonly returns MCP references. In the filtering path,filter_toolsonly knows about MCP-registered tools, so native tools get no similarity score and are removed.The fix partitions tools into MCP-registered and native before filtering, applies semantic filtering only to MCP tools, then merges results back preserving original order. The expansion path now preserves native tools before calling
_expand_mcp_toolsand concatenates them back after._emit_filter_metadatais extracted with its own try/except so a metadata error can't cause the outer handler to return None afterdata["tools"]was already mutated.async_post_call_response_headers_hookuses.get()instead of bare dict access to prevent KeyError on requests that skipped filtering