litellm - ✅(Solved) Fix [Bug]: `mcp_semantic_tool_filter` drops non-MCP tools and returns all tools on zero matches [2 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
BerriAI/litellm#24984Fetched 2026-04-08 02:35:16
View on GitHub
Comments
0
Participants
1
Timeline
10
Reactions
0
Participants
Timeline (top)
cross-referenced ×3labeled ×3mentioned ×1referenced ×1

Error Message

  1. Send a vague query ("hello") — all 161 tools pass through, provider rejects with tool limit error

Root Cause

Both stem from the same root cause: filter_tools() doesn't separate MCP tools from non-MCP tools before filtering.

Fix Action

Fixed

PR fix notes

PR #24986: fix(mcp): preserve non-MCP tools in semantic filter

Description (problem / solution / changelog)

Relevant issues

Fixes #24984

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Delays in PR merge?

If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Type

🐛 Bug Fix

Changes

The semantic filter hook treated all tools equally — it didn't distinguish between MCP tools (which it should filter) and non-MCP built-in tools (which should pass through untouched). This caused non-MCP tools to be dropped on match, and all tools returned on zero match.

  • Move MCP/non-MCP separation into the hook (hook.py): only pass MCP tools (identified by server-name prefix via is_tool_name_prefixed()) to filter_tools(), always recombine with non-MCP tools after
  • filter_tools() returns empty list on zero matches instead of all tools — the hook adds non-MCP tools back
  • 2 new tests: zero-match returns empty, hook preserves non-MCP tools on match
  • 1 existing test updated: tool names prefixed to reflect MCP tool format

Changed files

  • litellm/proxy/_experimental/mcp_server/semantic_tool_filter.py (modified, +4/-1)
  • litellm/proxy/hooks/mcp_semantic_filter/hook.py (modified, +22/-3)
  • tests/test_litellm/proxy/_experimental/mcp_server/test_semantic_tool_filter.py (modified, +166/-8)

PR #24990: fix(mcp): return only non-MCP tools when semantic filter finds zero matches

Description (problem / solution / changelog)

What

When the semantic tool filter finds zero matches for a query, it now returns only non-MCP (built-in) tools instead of returning all available tools.

Why

When zero semantic matches exist (e.g., an irrelevant query like "hello"), filter_tools() fell back to returning ALL tools. With 100+ MCP tools configured, this exceeds OpenAI"s 128 tool limit and causes requests to fail. See: #24984

How

In semantic_tool_filter.py, the fallback when matched_tool_names is empty now filters to only non-MCP tools using is_tool_name_prefixed() from utils.py. MCP tools are identifiable by their server-name prefix (contains MCP_TOOL_PREFIX_SEPARATOR). Built-in tools like web_search or code_interpreter pass through unaffected.

Testing

  • Added test_semantic_filter_zero_matches_returns_only_non_mcp_tools — verifies that on zero matches, only non-prefixed tools are returned
  • Existing tests continue to pass
  • ruff check passes

Checklist

  • Tests added
  • Linter passes
  • No breaking change for non-MCP tools

Closes #24984

Changed files

  • litellm/proxy/_experimental/mcp_server/semantic_tool_filter.py (modified, +15/-1)
  • tests/test_litellm/proxy/_experimental/mcp_server/test_semantic_tool_filter.py (modified, +102/-0)

Code Example

# On match — built-in tools dropped:
Semantic tool filter: 161->3 tools
# (31 non-MCP tools silently removed)

# On zero match — all tools returned:
Semantic tool filter: 161->161 tools
# Provider rejects: too many tools
RAW_BUFFERClick to expand / collapse

Check for existing issues

  • I have searched the existing issues and checked that my issue is not a duplicate.

What happened?

The semantic tool filter treats all tools in the request equally — it doesn't distinguish between MCP tools (which it should filter) and non-MCP built-in tools (which it should pass through). This causes two failure modes:

  1. When matches are found: The filter returns only matched MCP tools and drops all non-MCP built-in tools (terminal, file operations, code execution, etc.) that the client intentionally sent. The model loses access to core functionality.

  2. When zero matches are found (e.g., user says "hello"): The filter falls back to returning ALL tools unfiltered, which can exceed provider tool limits (e.g., OpenAI's 128 tool limit).

Both stem from the same root cause: filter_tools() doesn't separate MCP tools from non-MCP tools before filtering.

Expected: The filter should only operate on MCP tools. Non-MCP tools should always pass through untouched.

Steps to Reproduce

  1. Enable mcp_semantic_tool_filter with a working embedding model
  2. Use a client that sends both MCP tools (~130) and built-in tools (~31) via /v1/chat/completions
  3. Send a query with clear tool intent ("What time is it?") — built-in tools are dropped from the response
  4. Send a vague query ("hello") — all 161 tools pass through, provider rejects with tool limit error

Relevant log output

# On match — built-in tools dropped:
Semantic tool filter: 161->3 tools
# (31 non-MCP tools silently removed)

# On zero match — all tools returned:
Semantic tool filter: 161->161 tools
# Provider rejects: too many tools

What part of LiteLLM is this about?

Proxy

What LiteLLM version are you on ?

v1.83.0

Related

  • PR #20296 — original implementation
  • Issue #22445 — prefix matching bug (fix in PR #24982)
  • Issue #20879 — semantic filter improvements

Twitter / LinkedIn details

@lazyskyline7 / https://www.linkedin.com/in/klhsu/

extent analysis

TL;DR

Modify the filter_tools() function to separate and preserve non-MCP built-in tools before filtering MCP tools.

Guidance

  • Review the filter_tools() implementation to ensure it distinguishes between MCP and non-MCP tools, filtering only the former.
  • Verify the fix by testing with both clear tool intent queries (e.g., "What time is it?") and vague queries (e.g., "hello") to ensure non-MCP tools are preserved and the provider tool limit is not exceeded.
  • Check the relevant log output to confirm the semantic tool filter is operating correctly, passing through non-MCP tools untouched.
  • Consider updating the test suite to cover these scenarios and prevent regressions.

Example

No explicit code example is provided due to the lack of implementation details in the issue, but the fix should involve modifying the filter_tools() function to correctly handle non-MCP tools.

Notes

The solution assumes that the filter_tools() function can be modified to separate MCP and non-MCP tools. If this is not feasible, alternative approaches may be necessary.

Recommendation

Apply a workaround by modifying the filter_tools() function to preserve non-MCP built-in tools, as this directly addresses the root cause of the issue and prevents the loss of core functionality and provider tool limit errors.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

litellm - ✅(Solved) Fix [Bug]: `mcp_semantic_tool_filter` drops non-MCP tools and returns all tools on zero matches [2 pull requests, 1 participants]