Static source inference · medium confidence · evidence: Streamable HTTP
Current-spec patterns detected
Summary
This server has significant structural and documentation gaps. Of 13 tools, all have basic descriptions (10-80 chars) but most are vague about what values they accept or when to use them. Parameter schemas are present for 12/13 tools but lack proper typing and constraints. Critical issues: (1) No input validation or error guidance in responses, errors return raw Python exceptions. (2) Parameter naming inconsistencies (e.g., 'podName' vs 'pod_name') force LLMs to guess. (3) Many parameters lack descriptions entirely (tail_lines, port). (4) No output schema documentation, tools return raw API responses or strings without structure. (5) Tool descriptions are too short (avg 40 chars) to guide LLM selection, e.g., 'Fetch logs from a specific Kubernetes pod' doesn't explain when to use this vs get_pod_details. (6) Response objects lack pagination, structured fields, or chaining IDs. (7) One tool (tool_k8s_fetch_pods) has ZERO input parameters documented but the schema shows it accepts params={}. (8) Destructive tools (restart, scale) lack confirmation patterns. All tools are READ_ONLY or WRITE, but no tool annotations (readOnlyHint/destructiveHint) are present. The codebase is functional but would require significant refactoring for production agent use.
Parameter naming inconsistencies across tools (podName vs pod_name, serviceName vs service_name) will force LLMs to reason about naming conventions instead of focusing on logic. This violates the DRY principle and increases hallucination risk.
Many parameters lack descriptions entirely (tail_lines in tool_k8s_fetch_pod_logs, port in tool_k8s_port_check, replicas in tool_k8s_scale_deployment have descriptions but others are sparse).
Tool descriptions are too short (avg 42 chars) to guide LLM selection. 'List all Kubernetes pods' does not explain when to call this vs get_pod_details, or what fields are returned.
Recommendations
Standardize parameter naming to snake_case across all tools. Rename podName → pod_name, serviceName → service_name, deploymentName → deployment_name for consistency.
Expand tool descriptions from avg 42 chars to 150-250 chars. Include: WHAT (what does it do), WHEN (when to use vs similar tools), RETURN (what fields are in the response). E.g., 'List all Kubernetes pods in the cluster. Call this to discover available pods before fetching details or logs. Returns array of pod objects with name, namespace, status, and creation_time.'
Add descriptions to all parameters. For numeric params, include min/max bounds. E.g., tail_lines: 'Number of log lines to tail from the end of the pod log (1-10000, default 100).'
Document output schemas for all tools. Define what fields each response contains, their types, and whether they are nullable. E.g., tool_k8s_fetch_pods returns {"pods": [{"name": string, "namespace": string, "status": string, "age_seconds": integer}], "total": integer}.
Implement actionable error messages. Instead of returning raw exceptions, parse them and return: (1) Error category (NotFound, InvalidInput, Timeout, etc.), (2) What went wrong, (3) What the LLM should do next. E.g., {"error": "pod_not_found", "message": "Pod 'my-app-xyz' not found in namespace 'default'.", "recovery": "Call tool_k8s_fetch_pods with namespace='default' to list available pods."}
Add dry-run or confirmation parameters to destructive tools. E.g., tool_k8s_restart_deployment should accept dry_run=true by default, returning what would happen without executing it. For destructive operations, require explicit confirm=true.
Score history
Overall score trend
↑ 7 points across a rubric change (v1 → v2)
43/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
F
43
2026-07-28+
v2
2026-03-09
F
36
-
v1
tool_k8s_get_service_details
read onlysource verified60/100
Retrieve detailed information about a specific Kubernetes service
tool_k8s_port_checkread onlysource verified50/100
Check if a specific port is open on a Kubernetes pod
No output schemas documented. Tools return raw httpx responses or unstructured text. LLMs cannot know what fields to extract or how to chain results to downstream tools. For example, tool_k8s_fetch_pods returns JSON but no schema is defined for what fields are present.
Error handling is generic and non-actionable. All tools return {"status": "error", "message": str(e)} with raw Python exceptions. Per pattern:recovery-guide, errors should tell the LLM what to do next. E.g., 'Pod not found in namespace default. Call tool_k8s_fetch_pods to list available pods.'
Destructive tools (tool_k8s_restart_deployment, tool_k8s_restart_pod, tool_k8s_scale_deployment, tool_k8s_fix_service_port) lack confirmation/dry-run patterns. Agents can trigger production outages without confirmation. Per pattern:confirmation-request, irreversible operations should support dry-run or require explicit approval.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). LLMs cannot distinguish which tools are safe to retry and which have side effects. All 13 tools should be annotated according to current MCP spec.
Parameter schemas lack proper typing and constraints. For example, tail_lines is documented as 'integer' but has no min/max bounds. An LLM could pass tail_lines=999999 and cause a timeout.
No pagination support. Tools like tool_k8s_fetch_pods and tool_k8s_fetch_deployments return all results without limit or pagination. If a namespace has 1000 pods, the entire list is returned, wasting tokens and degrading LLM reasoning. Per pattern:paginated-result, list tools should accept limit and return cursors.
Parameter names mix conventions (some snake_case, some camelCase). This forces LLMs to maintain a mental mapping of which tool expects which convention. Standardize to snake_case throughout.
Add tool annotations to schemas: readOnlyHint=true for all list/get tools, destructiveHint=true for restart/scale/fix-port tools, idempotentHint=true where applicable.
Add pagination to list tools. tool_k8s_fetch_pods, tool_k8s_fetch_deployments, tool_k8s_fetch_services should accept limit (default 20, max 100) and next_cursor parameters. Return {"items": [...], "total": int, "next_cursor": string|null}.
Add input validation with clear error messages. Validate namespace format, pod_name length, port range (1-65535), replicas count (1-10000). Return errors like {"error": "invalid_port", "message": "Port must be 1-65535, got 99999."}
Include chaining IDs in responses. When tool_k8s_fetch_pods returns pod objects, include pod_name and namespace in each object so the LLM can immediately call tool_k8s_get_pod_details or tool_k8s_fetch_pod_logs without extra lookups.
Strip irrelevant API metadata from responses. Return only user-facing fields (name, status, age) not internal fields (resourceVersion, uid, managedFields).
Add a 'human-readable' status field to destructive operation responses. Instead of 'status: success', return a complete sentence: 'Successfully restarted deployment my-app in namespace default. 3 pod replicas are being rolled out.'
Consider adding a tool_k8s_search_pods tool that accepts a label selector or name pattern and returns matching pods, to reduce the need for full list calls.