"""MCP tool for Prometheus metric-label discovery.""" import json from typing import Any from pydantic import ValidationError as PydanticValidationError from src.models.metric_labels import ListMetricLabelsRequest from src.services.auth import get_valid_server_auth from src.services.prometheus import ( DISCOVERY_TIMEOUT, MAX_LABEL_ITEMS, get_prometheus_client_for_cluster, ) from src.tools.query_range import mcp from src.utils.errors import ( AuthorizationError, AuthServiceError, NetworkError, PrometheusAPIError, PrometheusTimeoutError, ValidationError, ) from src.utils.logging_utils import get_logger from src.utils.tool_response import format_tool_error, tool_text_response logger = get_logger("tool.list_metric_labels") @mcp.tool() async def list_metric_labels( cluster_id: str, env: str, deploy_type: str, match: str | None = None, start: str | None = None, end: str | None = None, limit: int = MAX_LABEL_ITEMS, ) -> list[dict[str, Any]]: """ Use after `list_metrics` to find available labels. List labels matches the series selector defined in `match`. """ try: logger.info( "tool_call_start name=list_metric_labels cluster_id=%s env=%s " "deploy_type=%s has_match=%s", cluster_id, env, deploy_type, bool(match), ) await get_valid_server_auth() try: request = ListMetricLabelsRequest.model_validate( { "cluster_id": str(cluster_id).strip(), "env": env.strip(), "deploy_type": deploy_type.strip(), "match": match, "start": start, "end": end, "limit": limit, } ) except (ValueError, PydanticValidationError) as e: raise ValidationError(str(e)) from e client = await get_prometheus_client_for_cluster( cluster_id=request.cluster_id, env=request.env, deploy_type=request.deploy_type, timeout=DISCOVERY_TIMEOUT, ) labels = await client.list_labels( match=request.match, start=request.start, end=request.end, limit=request.limit, timeout=DISCOVERY_TIMEOUT, ) result = sorted(labels) response: dict[str, Any] = {"status": "success", "data": result} logger.info( "tool_call_success name=list_metric_labels cluster_id=%s label_count=%s", request.cluster_id, len(result), ) return tool_text_response(json.dumps(response, ensure_ascii=False)) except ( AuthServiceError, AuthorizationError, ValidationError, NetworkError, PrometheusTimeoutError, PrometheusAPIError, ) as e: logger.warning("tool_call_error name=list_metric_labels type=%s", e.__class__.__name__) return tool_text_response(format_tool_error(e)) except Exception as e: logger.exception("tool_call_unexpected_error name=list_metric_labels") return tool_text_response(format_tool_error(e))