A Model Context Protocol server for interacting with multiple Kubernetes clusters through the MCP
This MCP server defines 4 tools for Kubernetes multi-cluster management and Prometheus queries. Tools are registered with descriptions and Zod schemas, but the implementation has significant quality gaps. Naming is action-oriented (clusters, connect_cluster, kubectl, prometheus) but some descriptions lack clarity on when to use each tool vs. others. Parameter descriptions exist but are inconsistent in detail and guidance. The kubectl and prometheus tools accept dangerous/complex inputs without sufficient validation guidance in descriptions. Output schemas are not explicitly documented, forcing LLMs to infer structure. No tool annotations (readOnlyHint, destructiveHint) despite having READ_ONLY and DESTRUCTIVE risk classifications available. Error handling delegates to implementation files not provided in the code sample, so recovery guidance cannot be verified. The server uses Zod for input validation (good practice) but descriptions do not reference constraint details that Zod enforces.
Retrieves a list of Kubernetes clusters (also known as managed clusters or spoke clusters).
Generates the 'KUBECONFIG' for the managed cluster and binds it to the specified ClusterRole (default: cluster-admin).
Securely run a kubectl command or apply YAML. Provide either 'command' or 'yaml'.
Queries a Prometheus server (snapshot or range) and returns metrics formatted for charting.
Tool 'kubectl' lacks safety guardrails in description. Accepts both command and yaml parameters with no guidance on destructive operations, no confirmation step, and no dry-run option. Description says 'Securely run' but provides no detail on what 'securely' means or what safeguards exist.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite metadata declaring READ_ONLY and DESTRUCTIVE risk levels. These hints should be surfaced in tool definitions so clients/LLMs know which tools are safe to retry and which require confirmation.
Output schemas are not documented. Tool descriptions do not explain what structure each tool returns. LLMs must infer the output format, risking incorrect parsing of results. See pattern:tool.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 48 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 44 | - | v1 |
Parameter 'command' in kubectl tool accepts free-form strings starting with 'kubectl'. Description says 'Must start with kubectl' but does not validate against injection attacks (command injection). LLMs could be tricked into passing malicious payloads. No sanitization guidance in description.
prometheus tool's 'ql' parameter accepts arbitrary PromQL strings with no examples, format constraints, or complexity limits. Description lacks guidance on query optimization or timeout behavior. 'group_by' has a vague description ('Label to group results by, such as pod or namespace') but does not explain behavior when query already uses aggregation.
connect_cluster description says 'binds it to the specified ClusterRole' but does not explain: What happens if the cluster already has a binding? Is this idempotent? Can it be called multiple times safely? Does it overwrite existing access?
Parameter descriptions in prometheus tool use informal language and examples instead of formal constraints. E.g., 'group_by' says 'such as pod or namespace' (examples, not a comprehensive list). Use enums or regex patterns instead, and state those formally in descriptions.
No indication of pagination or result limits. The 'clusters' tool might return 0 or 1000+ clusters, no limit stated. The prometheus tool's range query could return thousands of data points, no guidance on step selection or sample limits. Large results can exhaust context windows.
connect_cluster and kubectl tools accept a 'cluster' parameter defaulting to 'default' or 'hub cluster', but the clusters() tool returns a list of cluster names. No guidance on whether returned cluster names can be passed directly to 'cluster' params, or if a lookup is needed first.