mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-30 01:52:18 +00:00
fix(mcp): narrow liveness failures and clarify health tooltip
This commit is contained in:
parent
dca1d06065
commit
ae25511430
3 changed files with 22 additions and 16 deletions
|
|
@ -6917,14 +6917,16 @@ class MCPServerManager:
|
|||
async def _check_mcp_liveness(url: str) -> tuple[Literal["healthy", "unhealthy", "unknown"], str | None]:
|
||||
async def probe() -> None:
|
||||
endpoint: Final = httpx.URL(url).copy_with(username="", password="")
|
||||
async with httpx.AsyncClient(
|
||||
verify=get_ssl_configuration(),
|
||||
trust_env=False,
|
||||
follow_redirects=False,
|
||||
timeout=MCP_HEALTH_CHECK_TIMEOUT,
|
||||
) as client:
|
||||
async with client.stream("GET", endpoint, auth=None):
|
||||
pass
|
||||
async with (
|
||||
httpx.AsyncClient(
|
||||
verify=get_ssl_configuration(),
|
||||
trust_env=False,
|
||||
follow_redirects=False,
|
||||
timeout=MCP_HEALTH_CHECK_TIMEOUT,
|
||||
) as client,
|
||||
client.stream("GET", endpoint, auth=None),
|
||||
):
|
||||
pass
|
||||
|
||||
try:
|
||||
await asyncio.wait_for(probe(), timeout=MCP_HEALTH_CHECK_TIMEOUT)
|
||||
|
|
@ -6933,7 +6935,7 @@ class MCPServerManager:
|
|||
return "unhealthy", f"Health check timed out after {MCP_HEALTH_CHECK_TIMEOUT} seconds"
|
||||
except asyncio.CancelledError:
|
||||
return "unknown", "Health check was cancelled"
|
||||
except Exception as exc:
|
||||
except (httpx.HTTPError, httpx.InvalidURL, OSError, ValueError) as exc:
|
||||
return "unhealthy", f"Liveness check failed ({type(exc).__name__})"
|
||||
|
||||
async def health_check_server(self, server_id: str, mcp_auth_header: str | None = None) -> LiteLLM_MCPServerTable:
|
||||
|
|
@ -6994,12 +6996,14 @@ class MCPServerManager:
|
|||
):
|
||||
liveness_status, liveness_error = await self._check_mcp_liveness(server.url)
|
||||
return self._build_mcp_server_table(server).model_copy(
|
||||
update={
|
||||
"status": liveness_status,
|
||||
"health_check_error": liveness_error,
|
||||
"health_check_type": "liveness",
|
||||
"last_health_check": datetime.now(),
|
||||
}
|
||||
update=MappingProxyType(
|
||||
{
|
||||
"status": liveness_status,
|
||||
"health_check_error": liveness_error,
|
||||
"health_check_type": "liveness",
|
||||
"last_health_check": datetime.now(),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
if not should_skip_health_check:
|
||||
|
|
|
|||
|
|
@ -725,6 +725,7 @@ class TestListMCPServers:
|
|||
# Mock health check result as LiteLLM_MCPServerTable
|
||||
mock_health_result = generate_mock_mcp_server_db_record(server_id="server-1", alias="Server 1")
|
||||
mock_health_result.status = "healthy"
|
||||
mock_health_result.health_check_type = "liveness"
|
||||
mock_health_result.last_health_check = datetime.now()
|
||||
mock_health_result.health_check_error = None
|
||||
|
||||
|
|
@ -762,6 +763,7 @@ class TestListMCPServers:
|
|||
assert result.credentials is None
|
||||
assert mock_server.credentials == {"auth_value": "top-secret"}
|
||||
assert result.status == "healthy"
|
||||
assert result.health_check_type == "liveness"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_single_mcp_server_preserves_upstream_resource_for_admin(self):
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ const HealthChip: FC<HealthChipProps> = ({
|
|||
</Badge>
|
||||
}
|
||||
/>
|
||||
<TooltipContent side="top" className="max-w-xs">
|
||||
<TooltipContent side="top" className="block max-w-xs">
|
||||
<div className="mb-1 font-semibold">Health: {label}</div>
|
||||
{healthCheckType === "liveness" && (
|
||||
<div className="mb-1 text-xs">Authentication and tools were not checked</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue