Read-only kubectl/helm MCP server. Cluster-wide get/list/watch via the in-pod SA's ClusterRoleBinding; incoming auth via kube-rbac-proxy K8s SA TokenReview.
mcp-k8s demonstrates solid fundamentals: all 9 tools have clear verb-noun naming (list_*, get_*, delete_*, describe_*, rollout_*), comprehensive descriptions (100-300 chars each), and well-structured JSON Schema inputs with type and description on every parameter. Tool composition is clean, each tool does one thing. However, output schemas are not explicitly documented in the source (tools return dicts but no schema definition visible), and error handling lacks recovery guidance. Risk annotations (READ_ONLY, REVERSIBLE, DESTRUCTIVE) are present in metadata but not exposed as toolAnnotations in the MCP protocol. Parameter descriptions are strong but could be more prescriptive about constraints (e.g., 'limit' lacks min/max bounds in schema).
Delete a Kubernetes pod by name. Useful when a controller is wedged but its parent StatefulSet/Deployment is fine. Pod deletion is recoverable: the parent recreates it.
Delete a Kubernetes resource by kind and name. Generic kubectl delete for non-pod kinds (mostly namespace-cleanup territory). NOT recoverable; gated on a confirm_name guard matching the existing Azure-tool cleanup pattern.
Describe one Kubernetes resource with `kubectl describe`. Useful when you want events + computed fields rather than the raw spec — e.g. to see why a pod is Pending. `max_chars` caps large descriptions.
Read Kubernetes pod logs from a container. Use as `kubectl logs` for debugging running, failed, or crash-looping pods. previous=True reads the previous container instance (useful when the current one is in CrashLoopBackOff). `tail_lines`, `line_contains`, and `max_chars` keep responses tractable.
Get one Kubernetes resource as full JSON. Use as `kubectl get KIND NAME -o json` when you need spec, status, labels, annotations, owner references, or controller fields.
Output schemas not documented. Tools return dicts (e.g., list_namespaces returns list[dict[str, Any]]) but no explicit schema definition is visible in source. LLMs cannot plan downstream tool calls or extract fields without knowing the response structure.
Risk annotations (READ_ONLY, REVERSIBLE, DESTRUCTIVE) present in code comments but not exposed as MCP toolAnnotations (readOnlyHint, destructiveHint, idempotentHint). Agents cannot infer safety/reversibility from the protocol.
Numeric parameters (limit, tail_lines, max_chars, grace_period_seconds) lack min/max bounds in schema. 'limit' defaults to 100 but no maximum enforced in schema; LLMs could pass 999999. Code clamps to 500 internally but schema should declare this.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 66 | 2026-07-28+ | v2 |
List recent Kubernetes events, optionally filtered by namespace or involved object. Use to diagnose Pending pods, failed scheduling, image pull errors, failed mounts, unhealthy controllers, or rollout problems. `field_selector` example: `involvedObject.name=session-foo`. `limit` caps returned rows after timestamp sorting.
List Kubernetes namespaces in the cluster, optionally filtered. Use to discover namespace names before listing pods, services, deployments, events, Helm releases, or other namespaced resources. `label_selector` and `field_selector` map to kubectl selectors, `name_contains` filters client-side, and `limit` caps returned rows.
List Kubernetes resources by kind, namespace, and optional label selector. Use as `kubectl get` for pods, deployments, services, jobs, CRDs, nodes, namespaces, and custom resources. Cluster-scoped kinds (Node, Namespace, ClusterRole, etc.) ignore namespace. Use all_namespaces=True for namespaced kinds across the cluster. label_selector is a standard '-l' string ('app=foo,role=bar'). `field_selector`, `name_contains`, and `limit` further narrow large result sets.
Trigger a rolling restart of a Kubernetes workload by patching its pod-template annotation. Same semantics as `kubectl rollout restart`.
Error handling surfaces raw kubectl/helm stderr but does not guide recovery. E.g., 'kubectl exited 1: error: the server doesn't have a resource type "Pod"' tells the agent nothing about what to try next. Should suggest alternatives or clarify the error category.
delete_resource requires confirm_name parameter to match resource name, but no guidance on what happens if it doesn't match. Should explicitly state: 'If confirm_name does not match resource name, deletion is aborted with an error.'