""" MCP tool for executing Loki instant queries. This tool allows authorized AI agents and developers to query log data from Loki at a single point in time. Returns JSON in Loki API format: {"status": "success", "data": {"resultType": "streams", "result": [...], "warnings": []}}. """ import json from typing import Any from pydantic import ValidationError as PydanticValidationError from src.models.loki_queries import LokiQueryInstantRequest from src.services.auth import get_valid_server_auth from src.services.loki_resolve import add_env_to_query, get_loki_client_for_cluster from src.tools.query_range import mcp from src.utils.errors import ( AuthorizationError, AuthServiceError, LokiAPIError, LokiTimeoutError, NetworkError, ValidationError, ) from src.utils.tool_response import format_tool_error, tool_text_response @mcp.tool() async def query_loki_instant( query: str, cluster_id: str, env: str, deploy_type: str, time: str | None = None, limit: int = 100, direction: str = "backward", ) -> list[dict[str, Any]]: """ Execute a Loki instant query to retrieve log data at a single point in time. Returns JSON in the same format as Loki /loki/api/v1/query: {"status": "success", "data": {"resultType": "streams", "result": [...], "warnings": []}}. Args: query: LogQL query string (e.g., '{app="mysql", level="error"}') cluster_id: Cluster identifier. env: Environment name (e.g. prod, staging, dev). Will be added as label filter. deploy_type: Deploy type (dedicated, premium, resource_pool, starter, essential). time: Optional evaluation timestamp in RFC3339 format (defaults to now) limit: Maximum number of log entries to return (default: 100, max: 10000) direction: Query direction - "forward" or "backward" (default: "backward") Returns: List containing a single dict with 'type': 'text' and 'text': Loki-format JSON Raises: Various errors for authorization, validation, network, and timeout issues Examples: # Query MySQL error logs at current time query='{app="mysql", level="error"}' # Query all logs from a specific namespace at specific time query='{namespace="production"}' time='2024-01-01T12:00:00Z' # Query with label filters query='{app="tidb", component="tikv"} |= "error"' """ try: await get_valid_server_auth() try: request = LokiQueryInstantRequest( query=query, cluster_id=cluster_id.strip(), env=env.strip(), deploy_type=deploy_type.strip(), time=time, limit=limit, direction=direction, ) except (ValueError, PydanticValidationError) as e: raise ValidationError(f"Invalid Loki instant query parameters: {str(e)}") from e client, region = await get_loki_client_for_cluster( cluster_id=request.cluster_id, env=request.env, deploy_type=request.deploy_type, timeout=10.0, ) enriched_query = add_env_to_query(request.query, request.env) response = await client.query_instant( query=enriched_query, time=request.time, limit=request.limit, direction=request.direction, ) return tool_text_response(json.dumps(response, ensure_ascii=False)) except ( AuthServiceError, AuthorizationError, ValidationError, NetworkError, LokiTimeoutError, LokiAPIError, ) as e: return tool_text_response(format_tool_error(e)) except Exception as e: return tool_text_response(format_tool_error(e))