kubectl-mcp-server 1.14.0__py3-none-any.whl → 1.15.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,10 @@
1
1
  import logging
2
- from typing import Any, Dict, Optional
2
+ from typing import Any, Dict, List, Optional
3
3
 
4
4
  from mcp.types import ToolAnnotations
5
5
 
6
+ from ..k8s_config import get_k8s_client, get_storage_client
7
+
6
8
  logger = logging.getLogger("mcp-server")
7
9
 
8
10
 
@@ -15,12 +17,18 @@ def register_storage_tools(server, non_destructive: bool):
15
17
  readOnlyHint=True,
16
18
  ),
17
19
  )
18
- def get_persistent_volumes(name: Optional[str] = None) -> Dict[str, Any]:
19
- """Get Persistent Volumes in the cluster."""
20
+ def get_persistent_volumes(
21
+ name: Optional[str] = None,
22
+ context: str = ""
23
+ ) -> Dict[str, Any]:
24
+ """Get Persistent Volumes in the cluster.
25
+
26
+ Args:
27
+ name: Specific PV name to get (all PVs if not specified)
28
+ context: Kubernetes context to use (uses current context if not specified)
29
+ """
20
30
  try:
21
- from kubernetes import client, config
22
- config.load_kube_config()
23
- v1 = client.CoreV1Api()
31
+ v1 = get_k8s_client(context)
24
32
 
25
33
  if name:
26
34
  pv = v1.read_persistent_volume(name)
@@ -39,6 +47,7 @@ def register_storage_tools(server, non_destructive: bool):
39
47
 
40
48
  return {
41
49
  "success": True,
50
+ "context": context or "current",
42
51
  "persistentVolumes": [
43
52
  {
44
53
  "name": pv.metadata.name,
@@ -66,12 +75,18 @@ def register_storage_tools(server, non_destructive: bool):
66
75
  readOnlyHint=True,
67
76
  ),
68
77
  )
69
- def get_pvcs(namespace: Optional[str] = None) -> Dict[str, Any]:
70
- """Get Persistent Volume Claims in a namespace or cluster-wide."""
78
+ def get_pvcs(
79
+ namespace: Optional[str] = None,
80
+ context: str = ""
81
+ ) -> Dict[str, Any]:
82
+ """Get Persistent Volume Claims in a namespace or cluster-wide.
83
+
84
+ Args:
85
+ namespace: Namespace to list PVCs from (all namespaces if not specified)
86
+ context: Kubernetes context to use (uses current context if not specified)
87
+ """
71
88
  try:
72
- from kubernetes import client, config
73
- config.load_kube_config()
74
- v1 = client.CoreV1Api()
89
+ v1 = get_k8s_client(context)
75
90
 
76
91
  if namespace:
77
92
  pvcs = v1.list_namespaced_persistent_volume_claim(namespace)
@@ -80,6 +95,7 @@ def register_storage_tools(server, non_destructive: bool):
80
95
 
81
96
  return {
82
97
  "success": True,
98
+ "context": context or "current",
83
99
  "pvcs": [
84
100
  {
85
101
  "name": pvc.metadata.name,
@@ -103,17 +119,20 @@ def register_storage_tools(server, non_destructive: bool):
103
119
  readOnlyHint=True,
104
120
  ),
105
121
  )
106
- def get_storage_classes() -> Dict[str, Any]:
107
- """Get Storage Classes in the cluster."""
122
+ def get_storage_classes(context: str = "") -> Dict[str, Any]:
123
+ """Get Storage Classes in the cluster.
124
+
125
+ Args:
126
+ context: Kubernetes context to use (uses current context if not specified)
127
+ """
108
128
  try:
109
- from kubernetes import client, config
110
- config.load_kube_config()
111
- storage = client.StorageV1Api()
129
+ storage = get_storage_client(context)
112
130
 
113
131
  scs = storage.list_storage_class()
114
132
 
115
133
  return {
116
134
  "success": True,
135
+ "context": context or "current",
117
136
  "storageClasses": [
118
137
  {
119
138
  "name": sc.metadata.name,
tests/test_browser.py CHANGED
@@ -501,11 +501,11 @@ class TestServerIntegration:
501
501
  tools = asyncio.run(server.server.list_tools())
502
502
  tool_names = [t.name for t in tools]
503
503
 
504
- # Should have browser tools (127 + 26 = 153)
504
+ # Should have browser tools (131 + 26 = 157)
505
505
  assert "browser_open" in tool_names
506
506
  assert "browser_screenshot" in tool_names
507
507
  assert "browser_connect_cdp" in tool_names # v0.7 tool
508
- assert len(tools) == 153, f"Expected 153 tools (127 + 26), got {len(tools)}"
508
+ assert len(tools) == 157, f"Expected 157 tools (131 + 26), got {len(tools)}"
509
509
 
510
510
 
511
511
  import asyncio
tests/test_tools.py CHANGED
@@ -1,8 +1,8 @@
1
1
  """
2
2
  Unit tests for all MCP tools in kubectl-mcp-server.
3
3
 
4
- This module contains comprehensive tests for all 121 Kubernetes tools
5
- provided by the MCP server.
4
+ This module contains comprehensive tests for all 125 Kubernetes tools
5
+ provided by the MCP server (131 total with UI tools).
6
6
  """
7
7
 
8
8
  import pytest
@@ -12,7 +12,7 @@ from unittest.mock import patch, MagicMock
12
12
  from datetime import datetime
13
13
 
14
14
 
15
- # Complete list of all 127 tools that must be registered (121 core + 6 UI)
15
+ # Complete list of all 131 tools that must be registered (125 core + 6 UI)
16
16
  EXPECTED_TOOLS = [
17
17
  # Pods (pods.py)
18
18
  "get_pods", "get_logs", "get_pod_events", "check_pod_health", "exec_in_pod",
@@ -24,10 +24,11 @@ EXPECTED_TOOLS = [
24
24
  # Core (core.py)
25
25
  "get_namespaces", "get_configmaps", "get_secrets", "get_events",
26
26
  "get_resource_quotas", "get_limit_ranges",
27
- # Cluster (cluster.py)
28
- "get_current_context", "switch_context", "list_contexts", "list_kubeconfig_contexts",
27
+ # Cluster (cluster.py) - includes multi-cluster config tools
28
+ "get_current_context", "switch_context", "list_contexts_tool",
29
29
  "get_context_details", "set_namespace_for_context", "get_cluster_info",
30
30
  "get_cluster_version", "get_nodes", "get_api_resources", "health_check",
31
+ "kubeconfig_view", "get_api_versions", "check_crd_exists", "list_crds", "get_nodes_summary",
31
32
  # Networking (networking.py)
32
33
  "get_services", "get_endpoints", "get_ingress", "port_forward",
33
34
  "diagnose_network_connectivity", "check_dns_resolution", "trace_service_chain",
@@ -68,11 +69,11 @@ EXPECTED_TOOLS = [
68
69
 
69
70
 
70
71
  class TestAllToolsRegistered:
71
- """Comprehensive tests to verify all 127 tools are registered (121 core + 6 UI)."""
72
+ """Comprehensive tests to verify all 131 tools are registered (125 core + 6 UI)."""
72
73
 
73
74
  @pytest.mark.unit
74
75
  def test_all_127_tools_registered(self):
75
- """Verify all 127 expected tools are registered (excluding optional browser tools)."""
76
+ """Verify all 131 expected tools are registered (excluding optional browser tools)."""
76
77
  import os
77
78
  from kubectl_mcp_tool.mcp_server import MCPServer
78
79
 
@@ -93,8 +94,8 @@ class TestAllToolsRegistered:
93
94
  tools = asyncio.run(get_tools())
94
95
  tool_names = {t.name for t in tools}
95
96
 
96
- # Verify count (127 tools = 121 core + 6 UI, browser tools disabled)
97
- assert len(tools) == 127, f"Expected 127 tools, got {len(tools)}"
97
+ # Verify count (131 tools = 125 core + 6 UI, browser tools disabled)
98
+ assert len(tools) == 131, f"Expected 131 tools, got {len(tools)}"
98
99
 
99
100
  # Check for missing tools
100
101
  missing_tools = set(EXPECTED_TOOLS) - tool_names