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:
Tin Chi Lo 2026-07-07 11:58:11 -07:00
parent aa2baa8590
commit 6517b1a764
3 changed files with 55 additions and 14 deletions

View file

@ -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(

View file

@ -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

View file

@ -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,