mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-31 06:56:59 +00:00
* refactor(mcp): drop the experimental label from the MCP server and client paths Move litellm/proxy/_experimental/mcp_server to litellm/proxy/mcp_server and litellm/experimental_mcp_client to litellm/mcp_client, with the mirrored tests moved under tests/unit/proxy/mcp_server and tests/unit/mcp_client. Both old packages stay as shims that warn with DeprecationWarning, re-export the new package's public names and alias every submodule in sys.modules so deep imports keep resolving to the same objects. The OpenAPI docs gate now puts the merge base's enterprise package on PYTHONPATH so its base counts do not mix the checked-out enterprise code with the base litellm tree Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * ci(mcp): keep tests/unit/proxy/_experimental as a sharded root for the shim tests Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(mcp): alias namespace subpackages and bind attributes in the deprecated MCP shims pkgutil.walk_packages skipped mcp_server/auth because it has no __init__.py, so old imports of litellm.proxy._experimental.mcp_server.auth.* failed, and sys.modules entries alone left litellm.experimental_mcp_client.tools unreachable as an attribute. Walk the package on disk and setattr each alias on its old parent. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
84 lines
2.6 KiB
Python
84 lines
2.6 KiB
Python
"""
|
|
Performance benchmarks for the MCP tool hot path.
|
|
|
|
Two layers are covered: the client-side translation between MCP and OpenAI
|
|
function-calling formats, and the server-side tool-name prefixing that the proxy
|
|
runs on every list-tools (prefix each tool) and call-tool (strip prefix to route)
|
|
request. Both are pure-CPU and deterministic.
|
|
"""
|
|
|
|
import pytest
|
|
from mcp.types import Tool as MCPTool
|
|
|
|
from litellm.mcp_client.tools import (
|
|
transform_mcp_tool_to_openai_tool,
|
|
transform_openai_tool_call_request_to_mcp_tool_call_request,
|
|
)
|
|
from litellm.proxy.mcp_server.utils import (
|
|
add_server_prefix_to_name,
|
|
split_server_prefix_from_name,
|
|
)
|
|
|
|
|
|
def _make_tool(index: int) -> MCPTool:
|
|
return MCPTool(
|
|
name=f"tool_{index}",
|
|
description=f"Test tool number {index} that performs an operation",
|
|
inputSchema={
|
|
"type": "object",
|
|
"properties": {
|
|
"query": {"type": "string", "description": "The search query"},
|
|
"limit": {"type": "integer", "description": "Max results"},
|
|
},
|
|
"required": ["query"],
|
|
},
|
|
)
|
|
|
|
|
|
SINGLE_TOOL = _make_tool(0)
|
|
TOOL_LIST = tuple(_make_tool(i) for i in range(20))
|
|
TOOL_NAMES = tuple(t.name for t in TOOL_LIST)
|
|
|
|
SERVER_NAME = "github_mcp"
|
|
PREFIXED_TOOL_NAME = add_server_prefix_to_name("tool_0", SERVER_NAME)
|
|
|
|
OPENAI_TOOL_CALL = {
|
|
"id": "call_abc123",
|
|
"type": "function",
|
|
"function": {
|
|
"name": "tool_0",
|
|
"arguments": '{"query": "weather in San Francisco", "limit": 5}',
|
|
},
|
|
}
|
|
|
|
|
|
@pytest.mark.benchmark
|
|
def test_transform_single_mcp_tool_to_openai():
|
|
"""Benchmark translating one MCP tool into OpenAI tool format."""
|
|
transform_mcp_tool_to_openai_tool(mcp_tool=SINGLE_TOOL)
|
|
|
|
|
|
@pytest.mark.benchmark
|
|
def test_transform_mcp_tool_list_to_openai():
|
|
"""Benchmark translating a full list-tools response into OpenAI format."""
|
|
for tool in TOOL_LIST:
|
|
transform_mcp_tool_to_openai_tool(mcp_tool=tool)
|
|
|
|
|
|
@pytest.mark.benchmark
|
|
def test_transform_openai_tool_call_to_mcp():
|
|
"""Benchmark translating an OpenAI tool call into an MCP call request."""
|
|
transform_openai_tool_call_request_to_mcp_tool_call_request(openai_tool=OPENAI_TOOL_CALL)
|
|
|
|
|
|
@pytest.mark.benchmark
|
|
def test_mcp_server_prefix_tool_list():
|
|
"""Benchmark the proxy prefixing every tool name on a list-tools response."""
|
|
for name in TOOL_NAMES:
|
|
add_server_prefix_to_name(name, SERVER_NAME)
|
|
|
|
|
|
@pytest.mark.benchmark
|
|
def test_mcp_server_strip_prefix_on_call():
|
|
"""Benchmark the proxy stripping the server prefix to route a tool call."""
|
|
split_server_prefix_from_name(PREFIXED_TOOL_NAME)
|