Missing tool descriptions: get_deployment has no description at all; many GET tools have minimal descriptions (20-40 chars) that fail to explain WHEN to use them vs similar tools or what structured data they return.
Incomplete parameter schemas: Most tools accept a 'namespace' parameter with only a description, no enum of valid namespaces, no pattern validation, no min/max length constraints. Parameter types are present but lack validation rules. Container parameter in get_pod_logs is marked 'optional' in description but schema definition not visible.
Add comprehensive descriptions (50-150 chars each) to ALL tools explaining: (1) what it does, (2) when to use it vs similar tools, (3) any prerequisites. Example for get_pods: 'List all running pods in a namespace. Returns pod names, statuses, and restart counts. Call this first to discover available workloads before inspecting individual pods.'
Document complete output schemas for every tool. Specify whether get_pods returns ['pod1', 'pod2'] or structured objects with {name, status, restartCount, createdAt}. Include example output in docstrings.
Add parameter validation and constraints: (a) enum for 'namespace' values or a reference to call get_namespaces() first; (b) regex patterns for pod_name, replicaset_name; (c) min/max for replicas (1-100); (d) timeout values for container parameter.
Implement error handling with recovery guidance. Wrap all Kubernetes API calls in try/except blocks. Return structured errors like: {error: 'PodNotFound', message: 'Pod nginx-1 not found in namespace default. Try: get_pods(namespace="default") to list available pods.'} instead of raw stack traces.
Separate Kubernetes tools from stock ticker tools. Remove get_current_stock_price and get_historical_stock_splits from this server, they belong in a financial data server. Focus this MCP on Kubernetes only.
Fix duplicate definitions: Merge get_replicasets from k8s_client.py and k8s_replicasets.py into one canonical implementation with namespace parameter.
Add pagination to all list operations: limit (default 20, max 100) and offset/cursor parameters. Return {items: [...], total: N, nextOffset: O} structures. Document limits in descriptions.
Undocumented output schemas: None of the 33 tools document their return type structure. LLMs cannot infer whether get_pods returns ['pod1', 'pod2'] or {items: [{name, namespace, status}]}. create_pod returns a plain string 'Pod created successfully' with no structured result or pod_id for chaining.
No error handling or recovery guidance: Source code shows naked Kubernetes API calls with no try/catch, no error categorization (retryable vs user-fixable vs fatal), and no actionable error messages. If a pod doesn't exist, the tool will throw a raw ApiException with no guidance on what to try next.
Duplicate tool definitions with inconsistent signatures: get_replicasets appears in both k8s_client.py (no namespace param, returns list of names) and src/k8s_replicasets.py (namespace param available). LLM may call the wrong variant. Pattern violation: composition.
Domain-inappropriate tools mixed with Kubernetes operations: Stock ticker tools (get_current_stock_price, get_historical_stock_splits) have no place in a Kubernetes management server. This violates the single-responsibility principle and confuses agent tool selection.
Destructive operations lack confirmation or dry-run support: delete_pod and delete_replicaset can permanently remove resources with no confirmation step, dry-run mode, or warning in the description that this is irreversible.
create_pod has no idempotency guarantees and vague defaults: pod_name, image default to 'default-pod' and 'nginx:latest', and replicas parameter is unused in the implementation. If called twice, it will create two identical pods with the same name, causing failure on the second call.
Parameter descriptions lack actionable constraints: 'Kubernetes namespace' does not tell the LLM which namespaces exist, whether to list them first, or what happens if an invalid namespace is passed. 'Container name (optional)' does not explain what happens if omitted.
No pagination support on list operations: Tools like get_pods, get_events, get_deployments return all items with no limit or offset parameters. In a cluster with thousands of pods, this will exhaust context windows and cause timeouts.
Inconsistent naming conventions: Some tools use get_ prefix (correct), but parameter naming is inconsistent: pod_name vs replicaset_name (should be 'name' with 'resource_type' prefix in tool name). 'get_pvc' uses an abbreviation instead of 'get_persistent_volume_claims', LLM may not recognize 'pvc' abbreviation.
Add dry-run support to all destructive tools (delete_pod, delete_replicaset). Example: delete_pod(namespace, pod_name, dry_run=false). Require explicit confirmation for irreversible operations.
Fix create_pod to be idempotent: require pod_name and image as non-default parameters. Return structured result {pod_name, namespace, created_at, pod_id} so LLM can reference it in follow-up calls.
Standardize parameter names: use 'name' instead of 'pod_name'/'replicaset_name'. Tool name already specifies the resource type. Reduces parameter verbosity and mental load on LLM.
Add tool annotations (MCP 2025 spec) to mark read-only vs destructive operations: @mcp.tool(destructiveHint=true) on delete_pod, readOnlyHint=true on get_pods. Helps agents reason about safety.
Add detailed descriptions to optional parameters: 'container (optional): If omitted, logs from the first container are returned. Use to fetch logs from sidecar or init containers.' This prevents silent failures when parameter is ignored.