diff --git a/pkg/mcp/testdata/toolsets-kiali-tools.json b/pkg/mcp/testdata/toolsets-kiali-tools.json new file mode 100644 index 00000000..c28ed031 --- /dev/null +++ b/pkg/mcp/testdata/toolsets-kiali-tools.json @@ -0,0 +1,284 @@ +[ + { + "annotations": { + "title": "Topology: Mesh, Graph, Health, and Status", + "readOnlyHint": true, + "destructiveHint": false, + "openWorldHint": true + }, + "description": "Returns the topology of a specific namespaces, health, status of the mesh and namespaces. Use this for high-level overviews", + "inputSchema": { + "type": "object", + "properties": { + "graphType": { + "description": "Type of graph to return: 'versionedApp', 'app', 'service', 'workload', 'mesh'. Default: 'versionedApp'", + "type": "string" + }, + "namespace": { + "description": "Optional single namespace to include in the graph (alternative to namespaces)", + "type": "string" + }, + "namespaces": { + "description": "Optional comma-separated list of namespaces to include in the graph", + "type": "string" + }, + "rateInterval": { + "description": "Rate interval for fetching (e.g., '10m', '5m', '1h'). Default: '60s'", + "type": "string" + } + } + }, + "name": "kiali_get_mesh_graph" + }, + { + "annotations": { + "title": "Get Metrics for a Resource", + "readOnlyHint": true, + "destructiveHint": false, + "idempotentHint": true, + "openWorldHint": true + }, + "description": "Gets lists or detailed info for Kubernetes resources (services, workloads) within the mesh", + "inputSchema": { + "type": "object", + "properties": { + "byLabels": { + "description": "Comma-separated list of labels to group metrics by (e.g., 'source_workload,destination_service'). Optional", + "type": "string" + }, + "direction": { + "description": "Traffic direction: 'inbound' or 'outbound'. Optional, defaults to 'outbound'", + "type": "string" + }, + "duration": { + "description": "Time range to get metrics for (optional string - if provided, gets metrics; if empty, get default 1800s).", + "type": "string" + }, + "namespace": { + "description": "Namespace to get resources from", + "type": "string" + }, + "quantiles": { + "description": "Comma-separated list of quantiles for histogram metrics (e.g., '0.5,0.95,0.99'). Optional", + "type": "string" + }, + "rateInterval": { + "description": "Rate interval for metrics (e.g., '1m', '5m'). Optional, defaults to '1m'", + "type": "string" + }, + "reporter": { + "description": "Metrics reporter: 'source', 'destination', or 'both'. Optional, defaults to 'source'", + "type": "string" + }, + "requestProtocol": { + "description": "Filter by request protocol (e.g., 'http', 'grpc', 'tcp'). Optional", + "type": "string" + }, + "resource_name": { + "description": "Name of the resource to get details for (optional string - if provided, gets details; if empty, lists all).", + "type": "string" + }, + "resource_type": { + "description": "Type of resource to get details for (service, workload)", + "enum": [ + "service", + "workload" + ], + "type": "string" + }, + "step": { + "description": "Step between data points in seconds (e.g., '15'). Optional, defaults to 15 seconds", + "type": "string" + } + }, + "required": [ + "resource_type", + "namespace", + "resource_name" + ] + }, + "name": "kiali_get_metrics" + }, + { + "annotations": { + "title": "List or Resource Details", + "readOnlyHint": true, + "destructiveHint": false, + "idempotentHint": true, + "openWorldHint": true + }, + "description": "Gets lists or detailed info for Kubernetes resources (services, workloads) within the mesh", + "inputSchema": { + "type": "object", + "properties": { + "namespaces": { + "description": "Comma-separated list of namespaces to get services from (e.g. 'bookinfo' or 'bookinfo,default'). If not provided, will list services from all accessible namespaces", + "type": "string" + }, + "resource_name": { + "description": "Name of the resource to get details for (optional string - if provided, gets details; if empty, lists all).", + "type": "string" + }, + "resource_type": { + "description": "Type of resource to get details for (service, workload)", + "enum": [ + "service", + "workload" + ], + "type": "string" + } + } + }, + "name": "kiali_get_resource_details" + }, + { + "annotations": { + "title": "Get Traces for a Resource", + "readOnlyHint": true, + "destructiveHint": false, + "idempotentHint": true, + "openWorldHint": true + }, + "description": "Gets traces for a specific resource (app, service, workload) in a namespace", + "inputSchema": { + "type": "object", + "properties": { + "clusterName": { + "description": "Cluster name for multi-cluster environments (optional)", + "type": "string" + }, + "endMicros": { + "description": "End time for traces in microseconds since epoch (optional)", + "type": "string" + }, + "limit": { + "description": "Maximum number of traces to return (default: 100)", + "minimum": 1, + "type": "integer" + }, + "minDuration": { + "description": "Minimum trace duration in microseconds (optional)", + "minimum": 0, + "type": "integer" + }, + "namespace": { + "description": "Namespace to get resources from", + "type": "string" + }, + "resource_name": { + "description": "Name of the resource to get details for (optional string - if provided, gets details; if empty, lists all).", + "type": "string" + }, + "resource_type": { + "description": "Type of resource to get metrics for (app, service, workload)", + "enum": [ + "app", + "service", + "workload" + ], + "type": "string" + }, + "startMicros": { + "description": "Start time for traces in microseconds since epoch (optional)", + "type": "string" + }, + "tags": { + "description": "JSON string of tags to filter traces (optional)", + "type": "string" + } + }, + "required": [ + "resource_type", + "namespace", + "resource_name" + ] + }, + "name": "kiali_get_traces" + }, + { + "annotations": { + "title": "Manage Istio Config: List, Get, Create, Patch, Delete", + "destructiveHint": true, + "idempotentHint": true, + "openWorldHint": true + }, + "description": "Manages Istio configuration objects (Gateways, VirtualServices, etc.). Can list (objects and validations), get, create, patch, or delete objects", + "inputSchema": { + "type": "object", + "properties": { + "action": { + "description": "Action to perform: list, get, create, patch, or delete", + "type": "string" + }, + "group": { + "description": "API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io')", + "type": "string" + }, + "json_data": { + "description": "JSON data to apply or create the object", + "type": "string" + }, + "kind": { + "description": "Kind of the Istio object (e.g., 'DestinationRule', 'VirtualService', 'HTTPRoute', 'Gateway')", + "type": "string" + }, + "name": { + "description": "Name of the Istio object", + "type": "string" + }, + "namespace": { + "description": "Namespace containing the Istio object", + "type": "string" + }, + "version": { + "description": "API version of the Istio object (e.g., 'v1', 'v1beta1')", + "type": "string" + } + }, + "required": [ + "action" + ] + }, + "name": "kiali_manage_istio_config" + }, + { + "annotations": { + "title": "Workload: Logs", + "readOnlyHint": true, + "destructiveHint": false, + "openWorldHint": true + }, + "description": "Get logs for a specific workload's pods in a namespace. Only requires namespace and workload name - automatically discovers pods and containers. Optionally filter by container name, time range, and other parameters. Container is auto-detected if not specified.", + "inputSchema": { + "type": "object", + "properties": { + "container": { + "description": "Optional container name to filter logs. If not provided, automatically detects and uses the main application container (excludes istio-proxy and istio-init)", + "type": "string" + }, + "namespace": { + "description": "Namespace containing the workload", + "type": "string" + }, + "since": { + "description": "Time duration to fetch logs from (e.g., '5m', '1h', '30s'). If not provided, returns recent logs", + "type": "string" + }, + "tail": { + "description": "Number of lines to retrieve from the end of logs (default: 100)", + "minimum": 1, + "type": "integer" + }, + "workload": { + "description": "Name of the workload to get logs for", + "type": "string" + } + }, + "required": [ + "namespace", + "workload" + ] + }, + "name": "workload_logs" + } +] \ No newline at end of file diff --git a/pkg/mcp/toolsets_test.go b/pkg/mcp/toolsets_test.go index f58cb913..552ce8d7 100644 --- a/pkg/mcp/toolsets_test.go +++ b/pkg/mcp/toolsets_test.go @@ -12,6 +12,7 @@ import ( "github.com/containers/kubernetes-mcp-server/pkg/toolsets/config" "github.com/containers/kubernetes-mcp-server/pkg/toolsets/core" "github.com/containers/kubernetes-mcp-server/pkg/toolsets/helm" + "github.com/containers/kubernetes-mcp-server/pkg/toolsets/kiali" "github.com/mark3labs/mcp-go/mcp" "github.com/stretchr/testify/suite" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" @@ -160,6 +161,7 @@ func (s *ToolsetsSuite) TestGranularToolsetsTools() { &core.Toolset{}, &config.Toolset{}, &helm.Toolset{}, + &kiali.Toolset{}, } for _, testCase := range testCases { s.Run("Toolset "+testCase.GetName(), func() {