mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(mcp): carry preview length warnings for OpenAPI specs and the form alias
Per review: the create-server preview request now includes the alias the user typed so warnings measure the prefix the runtime will actually apply, and the OpenAPI spec preview branch returns the same warnings array as the MCP branch since registered OpenAPI tools get the server prefix too
This commit is contained in:
parent
aa2baa8590
commit
6517b1a764
3 changed files with 55 additions and 14 deletions
|
|
@ -1294,9 +1294,25 @@ if MCP_AVAILABLE:
|
|||
|
||||
new_mcp_server_request = _inherit_credentials_from_existing_server(new_mcp_server_request)
|
||||
|
||||
def _preview_warnings(tool_names: List[str]) -> List[str]:
|
||||
# In short-prefix mode the 3-char prefix derives from the server_id
|
||||
# assigned at create time, so without one the final length is
|
||||
# unknowable; skip speculative warnings (runtime exclusion still warns).
|
||||
if is_short_mcp_tool_prefix_enabled() and not new_mcp_server_request.server_id:
|
||||
return []
|
||||
return tool_name_length_warnings(
|
||||
tool_names,
|
||||
get_server_prefix(new_mcp_server_request),
|
||||
MCP_MAX_TOOL_NAME_LENGTH,
|
||||
)
|
||||
|
||||
# For OpenAPI spec servers, generate tools from the spec directly
|
||||
if new_mcp_server_request.spec_path:
|
||||
return await _preview_openapi_tools(new_mcp_server_request.spec_path)
|
||||
openapi_preview = await _preview_openapi_tools(new_mcp_server_request.spec_path)
|
||||
return {
|
||||
**openapi_preview,
|
||||
"warnings": _preview_warnings([tool["name"] for tool in openapi_preview.get("tools") or []]),
|
||||
}
|
||||
|
||||
from litellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcp import (
|
||||
MCPRequestHandler,
|
||||
|
|
@ -1326,23 +1342,11 @@ if MCP_AVAILABLE:
|
|||
list_tools_response = await client.run_with_session(_list_tools_session_operation)
|
||||
list_tools_result: List[MCPTool] = list_tools_response.tools
|
||||
model_dumped_tools: List[dict] = [tool.model_dump() for tool in list_tools_result]
|
||||
# In short-prefix mode the 3-char prefix derives from the server_id
|
||||
# assigned at create time, so without one the final length is
|
||||
# unknowable; skip speculative warnings (runtime exclusion still warns).
|
||||
warnings = (
|
||||
[]
|
||||
if is_short_mcp_tool_prefix_enabled() and not new_mcp_server_request.server_id
|
||||
else tool_name_length_warnings(
|
||||
[tool.name for tool in list_tools_result],
|
||||
get_server_prefix(new_mcp_server_request),
|
||||
MCP_MAX_TOOL_NAME_LENGTH,
|
||||
)
|
||||
)
|
||||
return {
|
||||
"tools": model_dumped_tools,
|
||||
"error": None,
|
||||
"message": "Successfully retrieved tools",
|
||||
"warnings": warnings,
|
||||
"warnings": _preview_warnings([tool.name for tool in list_tools_result]),
|
||||
}
|
||||
|
||||
return await _execute_with_mcp_client(
|
||||
|
|
|
|||
|
|
@ -688,6 +688,40 @@ class TestTestToolsList:
|
|||
|
||||
assert result["warnings"] == []
|
||||
|
||||
async def test_openapi_preview_flags_tool_names_exceeding_provider_limit(self, monkeypatch):
|
||||
"""The OpenAPI spec preview must carry the same length warnings as the MCP
|
||||
preview, since registered OpenAPI tools get the server prefix too."""
|
||||
from litellm.constants import MCP_MAX_TOOL_NAME_LENGTH
|
||||
from litellm.proxy._types import LitellmUserRoles
|
||||
|
||||
alias = "network_config_audit"
|
||||
fitting = "t" * (MCP_MAX_TOOL_NAME_LENGTH - len(alias) - 1)
|
||||
too_long = "t" * (MCP_MAX_TOOL_NAME_LENGTH - len(alias))
|
||||
|
||||
async def fake_preview(spec_path):
|
||||
return {
|
||||
"tools": [{"name": fitting}, {"name": too_long}],
|
||||
"error": None,
|
||||
"message": "Found 2 tools from OpenAPI spec",
|
||||
}
|
||||
|
||||
monkeypatch.setattr(rest_endpoints, "_preview_openapi_tools", fake_preview, raising=False)
|
||||
|
||||
result = await rest_endpoints.test_tools_list(
|
||||
_build_request(),
|
||||
NewMCPServerRequest(
|
||||
server_name="example",
|
||||
alias=alias,
|
||||
spec_path="/tmp/spec.json",
|
||||
auth_type=MCPAuth.none,
|
||||
),
|
||||
user_api_key_dict=UserAPIKeyAuth(user_role=LitellmUserRoles.PROXY_ADMIN),
|
||||
)
|
||||
|
||||
assert len(result["tools"]) == 2
|
||||
assert len(result["warnings"]) == 1
|
||||
assert f"{alias}-{too_long}" in result["warnings"][0]
|
||||
|
||||
|
||||
class TestListToolsRestAPI:
|
||||
pytestmark = pytest.mark.asyncio
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { AUTH_TYPE, OAUTH_FLOW, TRANSPORT } from "@/components/mcp_tools/types";
|
|||
interface MCPServerConfig {
|
||||
server_id?: string;
|
||||
server_name?: string;
|
||||
alias?: string;
|
||||
url?: string;
|
||||
spec_path?: string;
|
||||
transport?: string;
|
||||
|
|
@ -140,6 +141,7 @@ export const useTestMCPConnection = ({
|
|||
const mcpServerConfig: MCPServerConfig = {
|
||||
server_id: formValues.server_id || "",
|
||||
server_name: formValues.server_name || "",
|
||||
alias: formValues.alias,
|
||||
url: formValues.url,
|
||||
spec_path: formValues.spec_path,
|
||||
transport: effectiveTransport,
|
||||
|
|
@ -214,6 +216,7 @@ export const useTestMCPConnection = ({
|
|||
formValues.spec_path,
|
||||
formValues.transport,
|
||||
formValues.auth_type,
|
||||
formValues.alias,
|
||||
accessToken,
|
||||
enabled,
|
||||
oauthAccessToken,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue