#
tokens: 48043/50000 11/144 files (page 3/4)
lines: off (toggle) GitHub
raw markdown copy
This is page 3 of 4. Use http://codebase.md/manusa/kubernetes-mcp-server?page={x} to view the full context.

# Directory Structure

```
├── .github
│   ├── dependabot.yml
│   └── workflows
│       ├── build.yaml
│       ├── release-image.yml
│       └── release.yaml
├── .gitignore
├── AGENTS.md
├── build
│   ├── keycloak.mk
│   ├── kind.mk
│   └── tools.mk
├── CLAUDE.md
├── cmd
│   └── kubernetes-mcp-server
│       ├── main_test.go
│       └── main.go
├── dev
│   └── config
│       ├── cert-manager
│       │   └── selfsigned-issuer.yaml
│       ├── ingress
│       │   └── nginx-ingress.yaml
│       ├── keycloak
│       │   ├── client-scopes
│       │   │   ├── groups.json
│       │   │   ├── mcp-openshift.json
│       │   │   └── mcp-server.json
│       │   ├── clients
│       │   │   ├── mcp-client.json
│       │   │   ├── mcp-server-update.json
│       │   │   ├── mcp-server.json
│       │   │   └── openshift.json
│       │   ├── deployment.yaml
│       │   ├── ingress.yaml
│       │   ├── mappers
│       │   │   ├── groups-membership.json
│       │   │   ├── mcp-server-audience.json
│       │   │   ├── openshift-audience.json
│       │   │   └── username.json
│       │   ├── rbac.yaml
│       │   ├── realm
│       │   │   ├── realm-create.json
│       │   │   └── realm-events-config.json
│       │   └── users
│       │       └── mcp.json
│       └── kind
│           └── cluster.yaml
├── Dockerfile
├── docs
│   └── images
│       ├── kubernetes-mcp-server-github-copilot.jpg
│       └── vibe-coding.jpg
├── go.mod
├── go.sum
├── hack
│   └── generate-placeholder-ca.sh
├── internal
│   ├── test
│   │   ├── env.go
│   │   ├── kubernetes.go
│   │   ├── mcp.go
│   │   ├── mock_server.go
│   │   └── test.go
│   └── tools
│       └── update-readme
│           └── main.go
├── LICENSE
├── Makefile
├── npm
│   ├── kubernetes-mcp-server
│   │   ├── bin
│   │   │   └── index.js
│   │   └── package.json
│   ├── kubernetes-mcp-server-darwin-amd64
│   │   └── package.json
│   ├── kubernetes-mcp-server-darwin-arm64
│   │   └── package.json
│   ├── kubernetes-mcp-server-linux-amd64
│   │   └── package.json
│   ├── kubernetes-mcp-server-linux-arm64
│   │   └── package.json
│   ├── kubernetes-mcp-server-windows-amd64
│   │   └── package.json
│   └── kubernetes-mcp-server-windows-arm64
│       └── package.json
├── pkg
│   ├── api
│   │   ├── toolsets_test.go
│   │   └── toolsets.go
│   ├── config
│   │   ├── config_default_overrides.go
│   │   ├── config_default.go
│   │   ├── config_test.go
│   │   ├── config.go
│   │   ├── provider_config_test.go
│   │   └── provider_config.go
│   ├── helm
│   │   └── helm.go
│   ├── http
│   │   ├── authorization_test.go
│   │   ├── authorization.go
│   │   ├── http_test.go
│   │   ├── http.go
│   │   ├── middleware.go
│   │   ├── sts_test.go
│   │   ├── sts.go
│   │   └── wellknown.go
│   ├── kubernetes
│   │   ├── accesscontrol_clientset.go
│   │   ├── accesscontrol_restmapper.go
│   │   ├── accesscontrol.go
│   │   ├── common_test.go
│   │   ├── configuration.go
│   │   ├── events.go
│   │   ├── impersonate_roundtripper.go
│   │   ├── kubernetes_derived_test.go
│   │   ├── kubernetes.go
│   │   ├── manager_test.go
│   │   ├── manager.go
│   │   ├── namespaces.go
│   │   ├── nodes.go
│   │   ├── openshift.go
│   │   ├── pods.go
│   │   ├── provider_kubeconfig_test.go
│   │   ├── provider_kubeconfig.go
│   │   ├── provider_registry_test.go
│   │   ├── provider_registry.go
│   │   ├── provider_single_test.go
│   │   ├── provider_single.go
│   │   ├── provider_test.go
│   │   ├── provider.go
│   │   ├── resources.go
│   │   └── token.go
│   ├── kubernetes-mcp-server
│   │   └── cmd
│   │       ├── root_test.go
│   │       ├── root.go
│   │       └── testdata
│   │           ├── empty-config.toml
│   │           └── valid-config.toml
│   ├── mcp
│   │   ├── common_test.go
│   │   ├── configuration_test.go
│   │   ├── events_test.go
│   │   ├── helm_test.go
│   │   ├── m3labs.go
│   │   ├── mcp_middleware_test.go
│   │   ├── mcp_test.go
│   │   ├── mcp_tools_test.go
│   │   ├── mcp.go
│   │   ├── modules.go
│   │   ├── namespaces_test.go
│   │   ├── nodes_test.go
│   │   ├── pods_exec_test.go
│   │   ├── pods_test.go
│   │   ├── pods_top_test.go
│   │   ├── resources_test.go
│   │   ├── testdata
│   │   │   ├── helm-chart-no-op
│   │   │   │   └── Chart.yaml
│   │   │   ├── helm-chart-secret
│   │   │   │   ├── Chart.yaml
│   │   │   │   └── templates
│   │   │   │       └── secret.yaml
│   │   │   ├── toolsets-config-tools.json
│   │   │   ├── toolsets-core-tools.json
│   │   │   ├── toolsets-full-tools-multicluster-enum.json
│   │   │   ├── toolsets-full-tools-multicluster.json
│   │   │   ├── toolsets-full-tools-openshift.json
│   │   │   ├── toolsets-full-tools.json
│   │   │   └── toolsets-helm-tools.json
│   │   ├── tool_filter_test.go
│   │   ├── tool_filter.go
│   │   ├── tool_mutator_test.go
│   │   ├── tool_mutator.go
│   │   └── toolsets_test.go
│   ├── output
│   │   ├── output_test.go
│   │   └── output.go
│   ├── toolsets
│   │   ├── config
│   │   │   ├── configuration.go
│   │   │   └── toolset.go
│   │   ├── core
│   │   │   ├── events.go
│   │   │   ├── namespaces.go
│   │   │   ├── nodes.go
│   │   │   ├── pods.go
│   │   │   ├── resources.go
│   │   │   └── toolset.go
│   │   ├── helm
│   │   │   ├── helm.go
│   │   │   └── toolset.go
│   │   ├── toolsets_test.go
│   │   └── toolsets.go
│   └── version
│       └── version.go
├── python
│   ├── kubernetes_mcp_server
│   │   ├── __init__.py
│   │   ├── __main__.py
│   │   └── kubernetes_mcp_server.py
│   ├── pyproject.toml
│   └── README.md
├── README.md
└── smithery.yaml
```

# Files

--------------------------------------------------------------------------------
/pkg/mcp/pods_top_test.go:
--------------------------------------------------------------------------------

```go
package mcp

import (
	"net/http"
	"regexp"
	"testing"

	"github.com/BurntSushi/toml"
	"github.com/containers/kubernetes-mcp-server/internal/test"
	"github.com/mark3labs/mcp-go/mcp"
	"github.com/stretchr/testify/suite"
)

type PodsTopSuite struct {
	BaseMcpSuite
	mockServer *test.MockServer
}

func (s *PodsTopSuite) SetupTest() {
	s.BaseMcpSuite.SetupTest()
	s.mockServer = test.NewMockServer()
	s.Cfg.KubeConfig = s.mockServer.KubeconfigFile(s.T())
}

func (s *PodsTopSuite) TearDownTest() {
	s.BaseMcpSuite.TearDownTest()
	if s.mockServer != nil {
		s.mockServer.Close()
	}
}

func (s *PodsTopSuite) TestPodsTopMetricsUnavailable() {
	s.mockServer.Handle(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		// Request Performed by DiscoveryClient to Kube API (Get API Groups legacy -core-)
		if req.URL.Path == "/api" {
			_, _ = w.Write([]byte(`{"kind":"APIVersions","versions":[],"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0"}]}`))
			return
		}
		// Request Performed by DiscoveryClient to Kube API (Get API Groups)
		if req.URL.Path == "/apis" {
			_, _ = w.Write([]byte(`{"kind":"APIGroupList","apiVersion":"v1","groups":[]}`))
			return
		}
	}))
	s.InitMcpClient()

	s.Run("pods_top with metrics API not available", func() {
		result, err := s.CallTool("pods_top", map[string]interface{}{})
		s.NoError(err, "call tool failed %v", err)
		s.Require().NoError(err)
		s.True(result.IsError, "call tool should have returned an error")
		s.Equalf("failed to get pods top: metrics API is not available", result.Content[0].(mcp.TextContent).Text,
			"call tool returned unexpected content: %s", result.Content[0].(mcp.TextContent).Text)
	})
}

func (s *PodsTopSuite) TestPodsTopMetricsAvailable() {
	s.mockServer.Handle(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		// Request Performed by DiscoveryClient to Kube API (Get API Groups legacy -core-)
		if req.URL.Path == "/api" {
			_, _ = w.Write([]byte(`{"kind":"APIVersions","versions":["metrics.k8s.io/v1beta1"],"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0"}]}`))
			return
		}
		// Request Performed by DiscoveryClient to Kube API (Get API Groups)
		if req.URL.Path == "/apis" {
			_, _ = w.Write([]byte(`{"kind":"APIGroupList","apiVersion":"v1","groups":[]}`))
			return
		}
		// Request Performed by DiscoveryClient to Kube API (Get API Resources)
		if req.URL.Path == "/apis/metrics.k8s.io/v1beta1" {
			_, _ = w.Write([]byte(`{"kind":"APIResourceList","apiVersion":"v1","groupVersion":"metrics.k8s.io/v1beta1","resources":[{"name":"pods","singularName":"","namespaced":true,"kind":"PodMetrics","verbs":["get","list"]}]}`))
			return
		}
		// Pod Metrics from all namespaces
		if req.URL.Path == "/apis/metrics.k8s.io/v1beta1/pods" {
			if req.URL.Query().Get("labelSelector") == "app=pod-ns-5-42" {
				_, _ = w.Write([]byte(`{"kind":"PodMetricsList","apiVersion":"metrics.k8s.io/v1beta1","items":[` +
					`{"metadata":{"name":"pod-ns-5-42","namespace":"ns-5"},"containers":[{"name":"container-1","usage":{"cpu":"42m","memory":"42Mi","swap":"42Mi"}}]}` +
					`]}`))
			} else {
				_, _ = w.Write([]byte(`{"kind":"PodMetricsList","apiVersion":"metrics.k8s.io/v1beta1","items":[` +
					`{"metadata":{"name":"pod-1","namespace":"default"},"containers":[{"name":"container-1","usage":{"cpu":"100m","memory":"200Mi","swap":"13Mi"}},{"name":"container-2","usage":{"cpu":"200m","memory":"300Mi","swap":"37Mi"}}]},` +
					`{"metadata":{"name":"pod-2","namespace":"ns-1"},"containers":[{"name":"container-1-ns-1","usage":{"cpu":"300m","memory":"400Mi","swap":"42Mi"}}]}` +
					`]}`))

			}
			return
		}
		// Pod Metrics from configured namespace
		if req.URL.Path == "/apis/metrics.k8s.io/v1beta1/namespaces/default/pods" {
			_, _ = w.Write([]byte(`{"kind":"PodMetricsList","apiVersion":"metrics.k8s.io/v1beta1","items":[` +
				`{"metadata":{"name":"pod-1","namespace":"default"},"containers":[{"name":"container-1","usage":{"cpu":"10m","memory":"20Mi","swap":"13Mi"}},{"name":"container-2","usage":{"cpu":"30m","memory":"40Mi","swap":"37Mi"}}]}` +
				`]}`))
			return
		}
		// Pod Metrics from ns-5 namespace
		if req.URL.Path == "/apis/metrics.k8s.io/v1beta1/namespaces/ns-5/pods" {
			_, _ = w.Write([]byte(`{"kind":"PodMetricsList","apiVersion":"metrics.k8s.io/v1beta1","items":[` +
				`{"metadata":{"name":"pod-ns-5-1","namespace":"ns-5"},"containers":[{"name":"container-1","usage":{"cpu":"10m","memory":"20Mi","swap":"42Mi"}}]}` +
				`]}`))
			return
		}
		// Pod Metrics from ns-5 namespace with pod-ns-5-5 pod name
		if req.URL.Path == "/apis/metrics.k8s.io/v1beta1/namespaces/ns-5/pods/pod-ns-5-5" {
			_, _ = w.Write([]byte(`{"kind":"PodMetrics","apiVersion":"metrics.k8s.io/v1beta1",` +
				`"metadata":{"name":"pod-ns-5-5","namespace":"ns-5"},` +
				`"containers":[{"name":"container-1","usage":{"cpu":"13m","memory":"37Mi","swap":"42Mi"}}]` +
				`}`))
		}
	}))
	s.InitMcpClient()

	s.Run("pods_top(defaults) returns pod metrics from all namespaces", func() {
		result, err := s.CallTool("pods_top", map[string]interface{}{})
		s.Require().NotNil(result)
		s.NoErrorf(err, "call tool failed %v", err)
		textContent := result.Content[0].(mcp.TextContent).Text
		s.Falsef(result.IsError, "call tool failed %v", textContent)

		expectedHeaders := regexp.MustCompile(`(?m)^\s*NAMESPACE\s+POD\s+NAME\s+CPU\(cores\)\s+MEMORY\(bytes\)\s+SWAP\(bytes\)\s*$`)
		s.Regexpf(expectedHeaders, textContent, "expected headers '%s' not found in output:\n%s", expectedHeaders.String(), textContent)
		expectedRows := []string{
			"default\\s+pod-1\\s+container-1\\s+100m\\s+200Mi\\s+13Mi",
			"default\\s+pod-1\\s+container-2\\s+200m\\s+300Mi\\s+37Mi",
			"ns-1\\s+pod-2\\s+container-1-ns-1\\s+300m\\s+400Mi\\s+42Mi",
		}

		for _, row := range expectedRows {
			s.Regexpf(row, textContent, "expected row '%s' not found in output:\n%s", row, textContent)
		}

		expectedTotal := regexp.MustCompile(`(?m)^\s+600m\s+900Mi\s+92Mi\s*$`)
		s.Regexpf(expectedTotal, textContent, "expected total row '%s' not found in output:\n%s", expectedTotal.String(), textContent)
	})

	s.Run("pods_top(allNamespaces=false) returns pod metrics from configured namespace", func() {
		result, err := s.CallTool("pods_top", map[string]interface{}{
			"all_namespaces": false,
		})
		s.Require().NotNil(result)
		s.NoErrorf(err, "call tool failed %v", err)
		textContent := result.Content[0].(mcp.TextContent).Text
		s.Falsef(result.IsError, "call tool failed %v", textContent)

		expectedRows := []string{
			"default\\s+pod-1\\s+container-1\\s+10m\\s+20Mi\\s+13Mi",
			"default\\s+pod-1\\s+container-2\\s+30m\\s+40Mi\\s+37Mi",
		}
		for _, row := range expectedRows {
			s.Regexpf(row, textContent, "expected row '%s' not found in output:\n%s", row, textContent)
		}

		expectedTotal := regexp.MustCompile(`(?m)^\s+40m\s+60Mi\s+50Mi\s*$`)
		s.Regexpf(expectedTotal, textContent, "expected total row '%s' not found in output:\n%s", expectedTotal.String(), textContent)
	})

	s.Run("pods_top(namespace=ns-5) returns pod metrics from provided namespace", func() {
		result, err := s.CallTool("pods_top", map[string]interface{}{
			"namespace": "ns-5",
		})
		s.Require().NotNil(result)
		s.NoErrorf(err, "call tool failed %v", err)
		textContent := result.Content[0].(mcp.TextContent).Text
		s.Falsef(result.IsError, "call tool failed %v", textContent)

		expectedRow := regexp.MustCompile(`ns-5\s+pod-ns-5-1\s+container-1\s+10m\s+20Mi\s+42Mi`)
		s.Regexpf(expectedRow, textContent, "expected row '%s' not found in output:\n%s", expectedRow.String(), textContent)

		expectedTotal := regexp.MustCompile(`(?m)^\s+10m\s+20Mi\s+42Mi\s*$`)
		s.Regexpf(expectedTotal, textContent, "expected total row '%s' not found in output:\n%s", expectedTotal.String(), textContent)
	})

	s.Run("pods_top(namespace=ns-5,name=pod-ns-5-5) returns pod metrics from provided namespace and name", func() {
		result, err := s.CallTool("pods_top", map[string]interface{}{
			"namespace": "ns-5",
			"name":      "pod-ns-5-5",
		})
		s.Require().NotNil(result)
		s.NoErrorf(err, "call tool failed %v", err)
		textContent := result.Content[0].(mcp.TextContent).Text
		s.Falsef(result.IsError, "call tool failed %v", textContent)

		expectedRow := regexp.MustCompile(`ns-5\s+pod-ns-5-5\s+container-1\s+13m\s+37Mi\s+42Mi`)
		s.Regexpf(expectedRow, textContent, "expected row '%s' not found in output:\n%s", expectedRow.String(), textContent)

		expectedTotal := regexp.MustCompile(`(?m)^\s+13m\s+37Mi\s+42Mi\s*$`)
		s.Regexpf(expectedTotal, textContent, "expected total row '%s' not found in output:\n%s", expectedTotal.String(), textContent)
	})

	s.Run("pods_top[label_selector=app=pod-ns-5-42] returns pod metrics from pods matching selector", func() {
		result, err := s.CallTool("pods_top", map[string]interface{}{
			"label_selector": "app=pod-ns-5-42",
		})
		s.Require().NotNil(result)
		s.NoErrorf(err, "call tool failed %v", err)
		textContent := result.Content[0].(mcp.TextContent).Text
		s.Falsef(result.IsError, "call tool failed %v", textContent)

		expectedRow := regexp.MustCompile(`ns-5\s+pod-ns-5-42\s+container-1\s+42m\s+42Mi`)
		s.Regexpf(expectedRow, textContent, "expected row '%s' not found in output:\n%s", expectedRow.String(), textContent)

		expectedTotal := regexp.MustCompile(`(?m)^\s+42m\s+42Mi\s+42Mi\s*$`)
		s.Regexpf(expectedTotal, textContent, "expected total row '%s' not found in output:\n%s", expectedTotal.String(), textContent)
	})
}

func (s *PodsTopSuite) TestPodsTopDenied() {
	s.Require().NoError(toml.Unmarshal([]byte(`
		denied_resources = [ { group = "metrics.k8s.io", version = "v1beta1" } ]
	`), s.Cfg), "Expected to parse denied resources config")
	s.mockServer.Handle(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		// Request Performed by DiscoveryClient to Kube API (Get API Groups legacy -core-)
		if req.URL.Path == "/api" {
			_, _ = w.Write([]byte(`{"kind":"APIVersions","versions":["metrics.k8s.io/v1beta1"],"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0"}]}`))
			return
		}
		// Request Performed by DiscoveryClient to Kube API (Get API Groups)
		if req.URL.Path == "/apis" {
			_, _ = w.Write([]byte(`{"kind":"APIGroupList","apiVersion":"v1","groups":[]}`))
			return
		}
		// Request Performed by DiscoveryClient to Kube API (Get API Resources)
		if req.URL.Path == "/apis/metrics.k8s.io/v1beta1" {
			_, _ = w.Write([]byte(`{"kind":"APIResourceList","apiVersion":"v1","groupVersion":"metrics.k8s.io/v1beta1","resources":[{"name":"pods","singularName":"","namespaced":true,"kind":"PodMetrics","verbs":["get","list"]}]}`))
			return
		}
	}))
	s.InitMcpClient()

	s.Run("pods_top (denied)", func() {
		result, err := s.CallTool("pods_top", map[string]interface{}{})
		s.Require().NotNil(result, "toolResult should not be nil")
		s.Run("has error", func() {
			s.Truef(result.IsError, "call tool should fail")
			s.Nilf(err, "call tool should not return error object")
		})
		s.Run("describes denial", func() {
			expectedMessage := "failed to get pods top: resource not allowed: metrics.k8s.io/v1beta1, Kind=PodMetrics"
			s.Equalf(expectedMessage, result.Content[0].(mcp.TextContent).Text,
				"expected descriptive error '%s', got %v", expectedMessage, result.Content[0].(mcp.TextContent).Text)
		})
	})
}

func TestPodsTop(t *testing.T) {
	suite.Run(t, new(PodsTopSuite))
}

```

--------------------------------------------------------------------------------
/pkg/mcp/helm_test.go:
--------------------------------------------------------------------------------

```go
package mcp

import (
	"context"
	"encoding/base64"
	"path/filepath"
	"runtime"
	"strings"
	"testing"

	"github.com/BurntSushi/toml"
	"github.com/mark3labs/mcp-go/mcp"
	"github.com/stretchr/testify/suite"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"sigs.k8s.io/yaml"
)

type HelmSuite struct {
	BaseMcpSuite
}

func (s *HelmSuite) SetupTest() {
	s.BaseMcpSuite.SetupTest()
	clearHelmReleases(s.T().Context(), kubernetes.NewForConfigOrDie(envTestRestConfig))
}

func (s *HelmSuite) TestHelmInstall() {
	s.InitMcpClient()
	s.Run("helm_install(chart=helm-chart-no-op)", func() {
		_, file, _, _ := runtime.Caller(0)
		chartPath := filepath.Join(filepath.Dir(file), "testdata", "helm-chart-no-op")
		toolResult, err := s.CallTool("helm_install", map[string]interface{}{
			"chart": chartPath,
		})
		s.Run("no error", func() {
			s.Nilf(err, "call tool failed %v", err)
			s.Falsef(toolResult.IsError, "call tool failed")
		})
		s.Run("returns installed chart", func() {
			var decoded []map[string]interface{}
			err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded)
			s.Run("has yaml content", func() {
				s.Nilf(err, "invalid tool result content %v", err)
			})
			s.Run("has 1 item", func() {
				s.Lenf(decoded, 1, "invalid helm install count, expected 1, got %v", len(decoded))
			})
			s.Run("has valid name", func() {
				s.Truef(strings.HasPrefix(decoded[0]["name"].(string), "helm-chart-no-op-"), "invalid helm install name, expected no-op-*, got %v", decoded[0]["name"])
			})
			s.Run("has valid namespace", func() {
				s.Equalf("default", decoded[0]["namespace"], "invalid helm install namespace, expected default, got %v", decoded[0]["namespace"])
			})
			s.Run("has valid chart", func() {
				s.Equalf("no-op", decoded[0]["chart"], "invalid helm install name, expected release name, got empty")
			})
			s.Run("has valid chartVersion", func() {
				s.Equalf("1.33.7", decoded[0]["chartVersion"], "invalid helm install version, expected 1.33.7, got empty")
			})
			s.Run("has valid status", func() {
				s.Equalf("deployed", decoded[0]["status"], "invalid helm install status, expected deployed, got %v", decoded[0]["status"])
			})
			s.Run("has valid revision", func() {
				s.Equalf(float64(1), decoded[0]["revision"], "invalid helm install revision, expected 1, got %v", decoded[0]["revision"])
			})
		})
	})
}

func (s *HelmSuite) TestHelmInstallDenied() {
	s.Require().NoError(toml.Unmarshal([]byte(`
		denied_resources = [ { version = "v1", kind = "Secret" } ]
	`), s.Cfg), "Expected to parse denied resources config")
	s.InitMcpClient()
	s.Run("helm_install(chart=helm-chart-secret, denied)", func() {
		_, file, _, _ := runtime.Caller(0)
		chartPath := filepath.Join(filepath.Dir(file), "testdata", "helm-chart-secret")
		toolResult, err := s.CallTool("helm_install", map[string]interface{}{
			"chart": chartPath,
		})
		s.Run("has error", func() {
			s.Truef(toolResult.IsError, "call tool should fail")
			s.Nilf(err, "call tool should not return error object")
		})
		s.Run("describes denial", func() {
			s.Truef(strings.HasPrefix(toolResult.Content[0].(mcp.TextContent).Text, "failed to install helm chart"), "expected descriptive error, got %v", toolResult.Content[0].(mcp.TextContent).Text)
			expectedMessage := ": resource not allowed: /v1, Kind=Secret"
			s.Truef(strings.HasSuffix(toolResult.Content[0].(mcp.TextContent).Text, expectedMessage), "expected descriptive error '%s', got %v", expectedMessage, toolResult.Content[0].(mcp.TextContent).Text)
		})
	})
}

func (s *HelmSuite) TestHelmListNoReleases() {
	s.InitMcpClient()
	s.Run("helm_list() with no releases", func() {
		toolResult, err := s.CallTool("helm_list", map[string]interface{}{})
		s.Run("no error", func() {
			s.Nilf(err, "call tool failed %v", err)
			s.Falsef(toolResult.IsError, "call tool failed")
		})
		s.Run("returns not found", func() {
			s.Equalf("No Helm releases found", toolResult.Content[0].(mcp.TextContent).Text, "unexpected result %v", toolResult.Content[0].(mcp.TextContent).Text)
		})
	})
}

func (s *HelmSuite) TestHelmList() {
	kc := kubernetes.NewForConfigOrDie(envTestRestConfig)
	_, err := kc.CoreV1().Secrets("default").Create(s.T().Context(), &corev1.Secret{
		ObjectMeta: metav1.ObjectMeta{
			Name:   "sh.helm.release.v1.release-to-list",
			Labels: map[string]string{"owner": "helm", "name": "release-to-list"},
		},
		Data: map[string][]byte{
			"release": []byte(base64.StdEncoding.EncodeToString([]byte("{" +
				"\"name\":\"release-to-list\"," +
				"\"info\":{\"status\":\"deployed\"}" +
				"}"))),
		},
	}, metav1.CreateOptions{})
	s.Require().NoError(err)
	s.InitMcpClient()
	s.Run("helm_list() with deployed release", func() {
		toolResult, err := s.CallTool("helm_list", map[string]interface{}{})
		s.Run("no error", func() {
			s.Nilf(err, "call tool failed %v", err)
			s.Falsef(toolResult.IsError, "call tool failed")
		})
		s.Run("returns release", func() {
			var decoded []map[string]interface{}
			err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded)
			s.Run("has yaml content", func() {
				s.Nilf(err, "invalid tool result content %v", err)
			})
			s.Run("has 1 item", func() {
				s.Lenf(decoded, 1, "invalid helm list count, expected 1, got %v", len(decoded))
			})
			s.Run("has valid name", func() {
				s.Equalf("release-to-list", decoded[0]["name"], "invalid helm list name, expected release-to-list, got %v", decoded[0]["name"])
			})
			s.Run("has valid status", func() {
				s.Equalf("deployed", decoded[0]["status"], "invalid helm list status, expected deployed, got %v", decoded[0]["status"])
			})
		})
	})
	s.Run("helm_list(namespace=ns-1) with deployed release in other namespaces", func() {
		toolResult, err := s.CallTool("helm_list", map[string]interface{}{"namespace": "ns-1"})
		s.Run("no error", func() {
			s.Nilf(err, "call tool failed %v", err)
			s.Falsef(toolResult.IsError, "call tool failed")
		})
		s.Run("returns not found", func() {
			s.Equalf("No Helm releases found", toolResult.Content[0].(mcp.TextContent).Text, "unexpected result %v", toolResult.Content[0].(mcp.TextContent).Text)
		})
	})
	s.Run("helm_list(namespace=ns-1, all_namespaces=true) with deployed release in all namespaces", func() {
		toolResult, err := s.CallTool("helm_list", map[string]interface{}{"namespace": "ns-1", "all_namespaces": true})
		s.Run("no error", func() {
			s.Nilf(err, "call tool failed %v", err)
			s.Falsef(toolResult.IsError, "call tool failed")
		})
		s.Run("returns release", func() {
			var decoded []map[string]interface{}
			err = yaml.Unmarshal([]byte(toolResult.Content[0].(mcp.TextContent).Text), &decoded)
			s.Run("has yaml content", func() {
				s.Nilf(err, "invalid tool result content %v", err)
			})
			s.Run("has 1 item", func() {
				s.Lenf(decoded, 1, "invalid helm list count, expected 1, got %v", len(decoded))
			})
			s.Run("has valid name", func() {
				s.Equalf("release-to-list", decoded[0]["name"], "invalid helm list name, expected release-to-list, got %v", decoded[0]["name"])
			})
			s.Run("has valid status", func() {
				s.Equalf("deployed", decoded[0]["status"], "invalid helm list status, expected deployed, got %v", decoded[0]["status"])
			})
		})
	})
}

func (s *HelmSuite) TestHelmUninstallNoReleases() {
	s.InitMcpClient()
	s.Run("helm_uninstall(name=release-to-uninstall) with no releases", func() {
		toolResult, err := s.CallTool("helm_uninstall", map[string]interface{}{
			"name": "release-to-uninstall",
		})
		s.Run("no error", func() {
			s.Nilf(err, "call tool failed %v", err)
			s.Falsef(toolResult.IsError, "call tool failed")
		})
		s.Run("returns not found", func() {
			s.Equalf("Release release-to-uninstall not found", toolResult.Content[0].(mcp.TextContent).Text, "unexpected result %v", toolResult.Content[0].(mcp.TextContent).Text)
		})
	})
}

func (s *HelmSuite) TestHelmUninstall() {
	kc := kubernetes.NewForConfigOrDie(envTestRestConfig)
	_, err := kc.CoreV1().Secrets("default").Create(s.T().Context(), &corev1.Secret{
		ObjectMeta: metav1.ObjectMeta{
			Name:   "sh.helm.release.v1.existent-release-to-uninstall.v0",
			Labels: map[string]string{"owner": "helm", "name": "existent-release-to-uninstall"},
		},
		Data: map[string][]byte{
			"release": []byte(base64.StdEncoding.EncodeToString([]byte("{" +
				"\"name\":\"existent-release-to-uninstall\"," +
				"\"info\":{\"status\":\"deployed\"}" +
				"}"))),
		},
	}, metav1.CreateOptions{})
	s.Require().NoError(err)
	s.InitMcpClient()
	s.Run("helm_uninstall(name=existent-release-to-uninstall) with deployed release", func() {
		toolResult, err := s.CallTool("helm_uninstall", map[string]interface{}{
			"name": "existent-release-to-uninstall",
		})
		s.Run("no error", func() {
			s.Nilf(err, "call tool failed %v", err)
			s.Falsef(toolResult.IsError, "call tool failed")
		})
		s.Run("returns uninstalled", func() {
			s.Truef(strings.HasPrefix(toolResult.Content[0].(mcp.TextContent).Text, "Uninstalled release existent-release-to-uninstall"), "unexpected result %v", toolResult.Content[0].(mcp.TextContent).Text)
			_, err = kc.CoreV1().Secrets("default").Get(s.T().Context(), "sh.helm.release.v1.existent-release-to-uninstall.v0", metav1.GetOptions{})
			s.Truef(errors.IsNotFound(err), "expected release to be deleted, but it still exists")
		})

	})
}

func (s *HelmSuite) TestHelmUninstallDenied() {
	s.Require().NoError(toml.Unmarshal([]byte(`
		denied_resources = [ { version = "v1", kind = "Secret" } ]
	`), s.Cfg), "Expected to parse denied resources config")
	kc := kubernetes.NewForConfigOrDie(envTestRestConfig)
	_, err := kc.CoreV1().Secrets("default").Create(s.T().Context(), &corev1.Secret{
		ObjectMeta: metav1.ObjectMeta{
			Name:   "sh.helm.release.v1.existent-release-to-uninstall.v0",
			Labels: map[string]string{"owner": "helm", "name": "existent-release-to-uninstall"},
		},
		Data: map[string][]byte{
			"release": []byte(base64.StdEncoding.EncodeToString([]byte("{" +
				"\"name\":\"existent-release-to-uninstall\"," +
				"\"info\":{\"status\":\"deployed\"}," +
				"\"manifest\":\"apiVersion: v1\\nkind: Secret\\nmetadata:\\n  name: secret-to-deny\\n  namespace: default\\n\"" +
				"}"))),
		},
	}, metav1.CreateOptions{})
	s.Require().NoError(err)
	s.InitMcpClient()
	s.Run("helm_uninstall(name=existent-release-to-uninstall) with deployed release (denied)", func() {
		toolResult, err := s.CallTool("helm_uninstall", map[string]interface{}{
			"name": "existent-release-to-uninstall",
		})
		s.Run("has error", func() {
			s.Truef(toolResult.IsError, "call tool should fail")
			s.Nilf(err, "call tool should not return error object")
		})
		s.Run("describes denial", func() {
			s.T().Skipf("Helm won't report what underlying resource caused the failure, so we can't assert on it")
			expectedMessage := "failed to uninstall release: resource not allowed: /v1, Kind=Secret"
			s.Equalf(expectedMessage, toolResult.Content[0].(mcp.TextContent).Text, "expected descriptive error '%s', got %v", expectedMessage, toolResult.Content[0].(mcp.TextContent).Text)
		})
	})
}

func clearHelmReleases(ctx context.Context, kc *kubernetes.Clientset) {
	secrets, _ := kc.CoreV1().Secrets("default").List(ctx, metav1.ListOptions{})
	for _, secret := range secrets.Items {
		if strings.HasPrefix(secret.Name, "sh.helm.release.v1.") {
			_ = kc.CoreV1().Secrets("default").Delete(ctx, secret.Name, metav1.DeleteOptions{})
		}
	}
}

func TestHelm(t *testing.T) {
	suite.Run(t, new(HelmSuite))
}

```

--------------------------------------------------------------------------------
/pkg/kubernetes-mcp-server/cmd/root_test.go:
--------------------------------------------------------------------------------

```go
package cmd

import (
	"bytes"
	"io"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"strings"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"k8s.io/cli-runtime/pkg/genericiooptions"
)

func captureOutput(f func() error) (string, error) {
	originalOut := os.Stdout
	defer func() {
		os.Stdout = originalOut
	}()
	r, w, _ := os.Pipe()
	os.Stdout = w
	err := f()
	_ = w.Close()
	out, _ := io.ReadAll(r)
	return string(out), err
}

func testStream() (genericiooptions.IOStreams, *bytes.Buffer) {
	out := &bytes.Buffer{}
	return genericiooptions.IOStreams{
		In:     &bytes.Buffer{},
		Out:    out,
		ErrOut: io.Discard,
	}, out
}

func TestVersion(t *testing.T) {
	ioStreams, out := testStream()
	rootCmd := NewMCPServer(ioStreams)
	rootCmd.SetArgs([]string{"--version"})
	if err := rootCmd.Execute(); out.String() != "0.0.0\n" {
		t.Fatalf("Expected version 0.0.0, got %s %v", out.String(), err)
	}
}

func TestConfig(t *testing.T) {
	t.Run("defaults to none", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1"})
		expectedConfig := `" - Config: "`
		if err := rootCmd.Execute(); !strings.Contains(out.String(), expectedConfig) {
			t.Fatalf("Expected config to be %s, got %s %v", expectedConfig, out.String(), err)
		}
	})
	t.Run("set with --config", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		_, file, _, _ := runtime.Caller(0)
		emptyConfigPath := filepath.Join(filepath.Dir(file), "testdata", "empty-config.toml")
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1", "--config", emptyConfigPath})
		_ = rootCmd.Execute()
		expected := `(?m)\" - Config\:[^\"]+empty-config\.toml\"`
		if m, err := regexp.MatchString(expected, out.String()); !m || err != nil {
			t.Fatalf("Expected config to be %s, got %s %v", expected, out.String(), err)
		}
	})
	t.Run("invalid path throws error", func(t *testing.T) {
		ioStreams, _ := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1", "--config", "invalid-path-to-config.toml"})
		err := rootCmd.Execute()
		if err == nil {
			t.Fatal("Expected error for invalid config path, got nil")
		}
		expected := "open invalid-path-to-config.toml: "
		if !strings.HasPrefix(err.Error(), expected) {
			t.Fatalf("Expected error to be %s, got %s", expected, err.Error())
		}
	})
	t.Run("set with valid --config", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		_, file, _, _ := runtime.Caller(0)
		validConfigPath := filepath.Join(filepath.Dir(file), "testdata", "valid-config.toml")
		rootCmd.SetArgs([]string{"--version", "--config", validConfigPath})
		_ = rootCmd.Execute()
		expectedConfig := `(?m)\" - Config\:[^\"]+valid-config\.toml\"`
		if m, err := regexp.MatchString(expectedConfig, out.String()); !m || err != nil {
			t.Fatalf("Expected config to be %s, got %s %v", expectedConfig, out.String(), err)
		}
		expectedListOutput := `(?m)\" - ListOutput\: yaml"`
		if m, err := regexp.MatchString(expectedListOutput, out.String()); !m || err != nil {
			t.Fatalf("Expected config to be %s, got %s %v", expectedListOutput, out.String(), err)
		}
		expectedReadOnly := `(?m)\" - Read-only mode: true"`
		if m, err := regexp.MatchString(expectedReadOnly, out.String()); !m || err != nil {
			t.Fatalf("Expected config to be %s, got %s %v", expectedReadOnly, out.String(), err)
		}
		expectedDisableDestruction := `(?m)\" - Disable destructive tools: true"`
		if m, err := regexp.MatchString(expectedDisableDestruction, out.String()); !m || err != nil {
			t.Fatalf("Expected config to be %s, got %s %v", expectedDisableDestruction, out.String(), err)
		}
	})
	t.Run("set with valid --config, flags take precedence", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		_, file, _, _ := runtime.Caller(0)
		validConfigPath := filepath.Join(filepath.Dir(file), "testdata", "valid-config.toml")
		rootCmd.SetArgs([]string{"--version", "--list-output=table", "--disable-destructive=false", "--read-only=false", "--config", validConfigPath})
		_ = rootCmd.Execute()
		expected := `(?m)\" - Config\:[^\"]+valid-config\.toml\"`
		if m, err := regexp.MatchString(expected, out.String()); !m || err != nil {
			t.Fatalf("Expected config to be %s, got %s %v", expected, out.String(), err)
		}
		expectedListOutput := `(?m)\" - ListOutput\: table"`
		if m, err := regexp.MatchString(expectedListOutput, out.String()); !m || err != nil {
			t.Fatalf("Expected config to be %s, got %s %v", expectedListOutput, out.String(), err)
		}
		expectedReadOnly := `(?m)\" - Read-only mode: false"`
		if m, err := regexp.MatchString(expectedReadOnly, out.String()); !m || err != nil {
			t.Fatalf("Expected config to be %s, got %s %v", expectedReadOnly, out.String(), err)
		}
		expectedDisableDestruction := `(?m)\" - Disable destructive tools: false"`
		if m, err := regexp.MatchString(expectedDisableDestruction, out.String()); !m || err != nil {
			t.Fatalf("Expected config to be %s, got %s %v", expectedDisableDestruction, out.String(), err)
		}
	})
}

func TestToolsets(t *testing.T) {
	t.Run("available", func(t *testing.T) {
		ioStreams, _ := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--help"})
		o, err := captureOutput(rootCmd.Execute) // --help doesn't use logger/klog, cobra prints directly to stdout
		if !strings.Contains(o, "Comma-separated list of MCP toolsets to use (available toolsets: config, core, helm).") {
			t.Fatalf("Expected all available toolsets, got %s %v", o, err)
		}
	})
	t.Run("default", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1"})
		if err := rootCmd.Execute(); !strings.Contains(out.String(), "- Toolsets: core, config, helm") {
			t.Fatalf("Expected toolsets 'full', got %s %v", out, err)
		}
	})
	t.Run("set with --toolsets", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1", "--toolsets", "helm,config"})
		_ = rootCmd.Execute()
		expected := `(?m)\" - Toolsets\: helm, config\"`
		if m, err := regexp.MatchString(expected, out.String()); !m || err != nil {
			t.Fatalf("Expected toolset to be %s, got %s %v", expected, out.String(), err)
		}
	})
}

func TestListOutput(t *testing.T) {
	t.Run("available", func(t *testing.T) {
		ioStreams, _ := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--help"})
		o, err := captureOutput(rootCmd.Execute) // --help doesn't use logger/klog, cobra prints directly to stdout
		if !strings.Contains(o, "Output format for resource list operations (one of: yaml, table)") {
			t.Fatalf("Expected all available outputs, got %s %v", o, err)
		}
	})
	t.Run("defaults to table", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1"})
		if err := rootCmd.Execute(); !strings.Contains(out.String(), "- ListOutput: table") {
			t.Fatalf("Expected list-output 'table', got %s %v", out, err)
		}
	})
	t.Run("set with --list-output", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1", "--list-output", "yaml"})
		_ = rootCmd.Execute()
		expected := `(?m)\" - ListOutput\: yaml\"`
		if m, err := regexp.MatchString(expected, out.String()); !m || err != nil {
			t.Fatalf("Expected list-output to be %s, got %s %v", expected, out.String(), err)
		}
	})
}

func TestReadOnly(t *testing.T) {
	t.Run("defaults to false", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1"})
		if err := rootCmd.Execute(); !strings.Contains(out.String(), " - Read-only mode: false") {
			t.Fatalf("Expected read-only mode false, got %s %v", out, err)
		}
	})
	t.Run("set with --read-only", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1", "--read-only"})
		_ = rootCmd.Execute()
		expected := `(?m)\" - Read-only mode\: true\"`
		if m, err := regexp.MatchString(expected, out.String()); !m || err != nil {
			t.Fatalf("Expected read-only mode to be %s, got %s %v", expected, out.String(), err)
		}
	})
}

func TestDisableDestructive(t *testing.T) {
	t.Run("defaults to false", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1"})
		if err := rootCmd.Execute(); !strings.Contains(out.String(), " - Disable destructive tools: false") {
			t.Fatalf("Expected disable destructive false, got %s %v", out, err)
		}
	})
	t.Run("set with --disable-destructive", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1", "--disable-destructive"})
		_ = rootCmd.Execute()
		expected := `(?m)\" - Disable destructive tools\: true\"`
		if m, err := regexp.MatchString(expected, out.String()); !m || err != nil {
			t.Fatalf("Expected disable-destructive mode to be %s, got %s %v", expected, out.String(), err)
		}
	})
}

func TestAuthorizationURL(t *testing.T) {
	t.Run("invalid authorization-url without protocol", func(t *testing.T) {
		ioStreams, _ := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--require-oauth", "--port=8080", "--authorization-url", "example.com/auth", "--server-url", "https://example.com:8080"})
		err := rootCmd.Execute()
		if err == nil {
			t.Fatal("Expected error for invalid authorization-url without protocol, got nil")
		}
		expected := "--authorization-url must be a valid URL"
		if !strings.Contains(err.Error(), expected) {
			t.Fatalf("Expected error to contain %s, got %s", expected, err.Error())
		}
	})
	t.Run("valid authorization-url with https", func(t *testing.T) {
		ioStreams, _ := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--require-oauth", "--port=8080", "--authorization-url", "https://example.com/auth", "--server-url", "https://example.com:8080"})
		err := rootCmd.Execute()
		if err != nil {
			t.Fatalf("Expected no error for valid https authorization-url, got %s", err.Error())
		}
	})
}

func TestStdioLogging(t *testing.T) {
	t.Run("stdio disables klog", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--log-level=1"})
		err := rootCmd.Execute()
		require.NoErrorf(t, err, "Expected no error executing command, got %v", err)
		assert.Equalf(t, "0.0.0\n", out.String(), "Expected only version output, got %s", out.String())
	})
	t.Run("http mode enables klog", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--log-level=1", "--port=1337"})
		err := rootCmd.Execute()
		require.NoErrorf(t, err, "Expected no error executing command, got %v", err)
		assert.Containsf(t, out.String(), "Starting kubernetes-mcp-server", "Expected klog output, got %s", out.String())
	})
}

func TestDisableMultiCluster(t *testing.T) {
	t.Run("defaults to false", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1"})
		if err := rootCmd.Execute(); !strings.Contains(out.String(), " - ClusterProviderStrategy: auto-detect (it is recommended to set this explicitly in your Config)") {
			t.Fatalf("Expected ClusterProviderStrategy kubeconfig, got %s %v", out, err)
		}
	})
	t.Run("set with --disable-multi-cluster", func(t *testing.T) {
		ioStreams, out := testStream()
		rootCmd := NewMCPServer(ioStreams)
		rootCmd.SetArgs([]string{"--version", "--port=1337", "--log-level=1", "--disable-multi-cluster"})
		_ = rootCmd.Execute()
		expected := `(?m)\" - ClusterProviderStrategy\: disabled\"`
		if m, err := regexp.MatchString(expected, out.String()); !m || err != nil {
			t.Fatalf("Expected ClusterProviderStrategy %s, got %s %v", expected, out.String(), err)
		}
	})
}

```

--------------------------------------------------------------------------------
/pkg/kubernetes-mcp-server/cmd/root.go:
--------------------------------------------------------------------------------

```go
package cmd

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"errors"
	"flag"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"

	"github.com/coreos/go-oidc/v3/oidc"
	"github.com/spf13/cobra"

	"k8s.io/cli-runtime/pkg/genericiooptions"
	"k8s.io/klog/v2"
	"k8s.io/klog/v2/textlogger"
	"k8s.io/kubectl/pkg/util/i18n"
	"k8s.io/kubectl/pkg/util/templates"

	"github.com/containers/kubernetes-mcp-server/pkg/config"
	internalhttp "github.com/containers/kubernetes-mcp-server/pkg/http"
	"github.com/containers/kubernetes-mcp-server/pkg/mcp"
	"github.com/containers/kubernetes-mcp-server/pkg/output"
	"github.com/containers/kubernetes-mcp-server/pkg/toolsets"
	"github.com/containers/kubernetes-mcp-server/pkg/version"
)

var (
	long     = templates.LongDesc(i18n.T("Kubernetes Model Context Protocol (MCP) server"))
	examples = templates.Examples(i18n.T(`
# show this help
kubernetes-mcp-server -h

# shows version information
kubernetes-mcp-server --version

# start STDIO server
kubernetes-mcp-server

# start a SSE server on port 8080
kubernetes-mcp-server --port 8080

# start a SSE server on port 8443 with a public HTTPS host of example.com
kubernetes-mcp-server --port 8443 --sse-base-url https://example.com:8443

# start a SSE server on port 8080 with multi-cluster tools disabled
kubernetes-mcp-server --port 8080 --disable-multi-cluster
`))
)

const (
	flagVersion              = "version"
	flagLogLevel             = "log-level"
	flagConfig               = "config"
	flagSSEPort              = "sse-port"
	flagHttpPort             = "http-port"
	flagPort                 = "port"
	flagSSEBaseUrl           = "sse-base-url"
	flagKubeconfig           = "kubeconfig"
	flagToolsets             = "toolsets"
	flagListOutput           = "list-output"
	flagReadOnly             = "read-only"
	flagDisableDestructive   = "disable-destructive"
	flagRequireOAuth         = "require-oauth"
	flagOAuthAudience        = "oauth-audience"
	flagValidateToken        = "validate-token"
	flagAuthorizationURL     = "authorization-url"
	flagServerUrl            = "server-url"
	flagCertificateAuthority = "certificate-authority"
	flagDisableMultiCluster  = "disable-multi-cluster"
)

type MCPServerOptions struct {
	Version              bool
	LogLevel             int
	Port                 string
	SSEPort              int
	HttpPort             int
	SSEBaseUrl           string
	Kubeconfig           string
	Toolsets             []string
	ListOutput           string
	ReadOnly             bool
	DisableDestructive   bool
	RequireOAuth         bool
	OAuthAudience        string
	ValidateToken        bool
	AuthorizationURL     string
	CertificateAuthority string
	ServerURL            string
	DisableMultiCluster  bool

	ConfigPath   string
	StaticConfig *config.StaticConfig

	genericiooptions.IOStreams
}

func NewMCPServerOptions(streams genericiooptions.IOStreams) *MCPServerOptions {
	return &MCPServerOptions{
		IOStreams:    streams,
		StaticConfig: config.Default(),
	}
}

func NewMCPServer(streams genericiooptions.IOStreams) *cobra.Command {
	o := NewMCPServerOptions(streams)
	cmd := &cobra.Command{
		Use:     "kubernetes-mcp-server [command] [options]",
		Short:   "Kubernetes Model Context Protocol (MCP) server",
		Long:    long,
		Example: examples,
		RunE: func(c *cobra.Command, args []string) error {
			if err := o.Complete(c); err != nil {
				return err
			}
			if err := o.Validate(); err != nil {
				return err
			}
			if err := o.Run(); err != nil {
				return err
			}

			return nil
		},
	}

	cmd.Flags().BoolVar(&o.Version, flagVersion, o.Version, "Print version information and quit")
	cmd.Flags().IntVar(&o.LogLevel, flagLogLevel, o.LogLevel, "Set the log level (from 0 to 9)")
	cmd.Flags().StringVar(&o.ConfigPath, flagConfig, o.ConfigPath, "Path of the config file.")
	cmd.Flags().IntVar(&o.SSEPort, flagSSEPort, o.SSEPort, "Start a SSE server on the specified port")
	cmd.Flag(flagSSEPort).Deprecated = "Use --port instead"
	cmd.Flags().IntVar(&o.HttpPort, flagHttpPort, o.HttpPort, "Start a streamable HTTP server on the specified port")
	cmd.Flag(flagHttpPort).Deprecated = "Use --port instead"
	cmd.Flags().StringVar(&o.Port, flagPort, o.Port, "Start a streamable HTTP and SSE HTTP server on the specified port (e.g. 8080)")
	cmd.Flags().StringVar(&o.SSEBaseUrl, flagSSEBaseUrl, o.SSEBaseUrl, "SSE public base URL to use when sending the endpoint message (e.g. https://example.com)")
	cmd.Flags().StringVar(&o.Kubeconfig, flagKubeconfig, o.Kubeconfig, "Path to the kubeconfig file to use for authentication")
	cmd.Flags().StringSliceVar(&o.Toolsets, flagToolsets, o.Toolsets, "Comma-separated list of MCP toolsets to use (available toolsets: "+strings.Join(toolsets.ToolsetNames(), ", ")+"). Defaults to "+strings.Join(o.StaticConfig.Toolsets, ", ")+".")
	cmd.Flags().StringVar(&o.ListOutput, flagListOutput, o.ListOutput, "Output format for resource list operations (one of: "+strings.Join(output.Names, ", ")+"). Defaults to "+o.StaticConfig.ListOutput+".")
	cmd.Flags().BoolVar(&o.ReadOnly, flagReadOnly, o.ReadOnly, "If true, only tools annotated with readOnlyHint=true are exposed")
	cmd.Flags().BoolVar(&o.DisableDestructive, flagDisableDestructive, o.DisableDestructive, "If true, tools annotated with destructiveHint=true are disabled")
	cmd.Flags().BoolVar(&o.RequireOAuth, flagRequireOAuth, o.RequireOAuth, "If true, requires OAuth authorization as defined in the Model Context Protocol (MCP) specification. This flag is ignored if transport type is stdio")
	_ = cmd.Flags().MarkHidden(flagRequireOAuth)
	cmd.Flags().StringVar(&o.OAuthAudience, flagOAuthAudience, o.OAuthAudience, "OAuth audience for token claims validation. Optional. If not set, the audience is not validated. Only valid if require-oauth is enabled.")
	_ = cmd.Flags().MarkHidden(flagOAuthAudience)
	cmd.Flags().BoolVar(&o.ValidateToken, flagValidateToken, o.ValidateToken, "If true, validates the token against the Kubernetes API Server using TokenReview. Optional. If not set, the token is not validated. Only valid if require-oauth is enabled.")
	_ = cmd.Flags().MarkHidden(flagValidateToken)
	cmd.Flags().StringVar(&o.AuthorizationURL, flagAuthorizationURL, o.AuthorizationURL, "OAuth authorization server URL for protected resource endpoint. If not provided, the Kubernetes API server host will be used. Only valid if require-oauth is enabled.")
	_ = cmd.Flags().MarkHidden(flagAuthorizationURL)
	cmd.Flags().StringVar(&o.ServerURL, flagServerUrl, o.ServerURL, "Server URL of this application. Optional. If set, this url will be served in protected resource metadata endpoint and tokens will be validated with this audience. If not set, expected audience is kubernetes-mcp-server. Only valid if require-oauth is enabled.")
	_ = cmd.Flags().MarkHidden(flagServerUrl)
	cmd.Flags().StringVar(&o.CertificateAuthority, flagCertificateAuthority, o.CertificateAuthority, "Certificate authority path to verify certificates. Optional. Only valid if require-oauth is enabled.")
	_ = cmd.Flags().MarkHidden(flagCertificateAuthority)
	cmd.Flags().BoolVar(&o.DisableMultiCluster, flagDisableMultiCluster, o.DisableMultiCluster, "Disable multi cluster tools. Optional. If true, all tools will be run against the default cluster/context.")

	return cmd
}

func (m *MCPServerOptions) Complete(cmd *cobra.Command) error {
	if m.ConfigPath != "" {
		cnf, err := config.Read(m.ConfigPath)
		if err != nil {
			return err
		}
		m.StaticConfig = cnf
	}

	m.loadFlags(cmd)

	m.initializeLogging()

	if m.StaticConfig.RequireOAuth && m.StaticConfig.Port == "" {
		// RequireOAuth is not relevant flow for STDIO transport
		m.StaticConfig.RequireOAuth = false
	}

	return nil
}

func (m *MCPServerOptions) loadFlags(cmd *cobra.Command) {
	if cmd.Flag(flagLogLevel).Changed {
		m.StaticConfig.LogLevel = m.LogLevel
	}
	if cmd.Flag(flagPort).Changed {
		m.StaticConfig.Port = m.Port
	} else if cmd.Flag(flagSSEPort).Changed {
		m.StaticConfig.Port = strconv.Itoa(m.SSEPort)
	} else if cmd.Flag(flagHttpPort).Changed {
		m.StaticConfig.Port = strconv.Itoa(m.HttpPort)
	}
	if cmd.Flag(flagSSEBaseUrl).Changed {
		m.StaticConfig.SSEBaseURL = m.SSEBaseUrl
	}
	if cmd.Flag(flagKubeconfig).Changed {
		m.StaticConfig.KubeConfig = m.Kubeconfig
	}
	if cmd.Flag(flagListOutput).Changed {
		m.StaticConfig.ListOutput = m.ListOutput
	}
	if cmd.Flag(flagReadOnly).Changed {
		m.StaticConfig.ReadOnly = m.ReadOnly
	}
	if cmd.Flag(flagDisableDestructive).Changed {
		m.StaticConfig.DisableDestructive = m.DisableDestructive
	}
	if cmd.Flag(flagToolsets).Changed {
		m.StaticConfig.Toolsets = m.Toolsets
	}
	if cmd.Flag(flagRequireOAuth).Changed {
		m.StaticConfig.RequireOAuth = m.RequireOAuth
	}
	if cmd.Flag(flagOAuthAudience).Changed {
		m.StaticConfig.OAuthAudience = m.OAuthAudience
	}
	if cmd.Flag(flagValidateToken).Changed {
		m.StaticConfig.ValidateToken = m.ValidateToken
	}
	if cmd.Flag(flagAuthorizationURL).Changed {
		m.StaticConfig.AuthorizationURL = m.AuthorizationURL
	}
	if cmd.Flag(flagServerUrl).Changed {
		m.StaticConfig.ServerURL = m.ServerURL
	}
	if cmd.Flag(flagCertificateAuthority).Changed {
		m.StaticConfig.CertificateAuthority = m.CertificateAuthority
	}
	if cmd.Flag(flagDisableMultiCluster).Changed && m.DisableMultiCluster {
		m.StaticConfig.ClusterProviderStrategy = config.ClusterProviderDisabled
	}
}

func (m *MCPServerOptions) initializeLogging() {
	flagSet := flag.NewFlagSet("klog", flag.ContinueOnError)
	klog.InitFlags(flagSet)
	if m.StaticConfig.Port == "" {
		// disable klog output for stdio mode
		// this is needed to avoid klog writing to stderr and breaking the protocol
		_ = flagSet.Parse([]string{"-logtostderr=false", "-alsologtostderr=false", "-stderrthreshold=FATAL"})
		return
	}
	loggerOptions := []textlogger.ConfigOption{textlogger.Output(m.Out)}
	if m.StaticConfig.LogLevel >= 0 {
		loggerOptions = append(loggerOptions, textlogger.Verbosity(m.StaticConfig.LogLevel))
		_ = flagSet.Parse([]string{"--v", strconv.Itoa(m.StaticConfig.LogLevel)})
	}
	logger := textlogger.NewLogger(textlogger.NewConfig(loggerOptions...))
	klog.SetLoggerWithOptions(logger)
}

func (m *MCPServerOptions) Validate() error {
	if m.Port != "" && (m.SSEPort > 0 || m.HttpPort > 0) {
		return fmt.Errorf("--port is mutually exclusive with deprecated --http-port and --sse-port flags")
	}
	if output.FromString(m.StaticConfig.ListOutput) == nil {
		return fmt.Errorf("invalid output name: %s, valid names are: %s", m.StaticConfig.ListOutput, strings.Join(output.Names, ", "))
	}
	if err := toolsets.Validate(m.StaticConfig.Toolsets); err != nil {
		return err
	}
	if !m.StaticConfig.RequireOAuth && (m.StaticConfig.ValidateToken || m.StaticConfig.OAuthAudience != "" || m.StaticConfig.AuthorizationURL != "" || m.StaticConfig.ServerURL != "" || m.StaticConfig.CertificateAuthority != "") {
		return fmt.Errorf("validate-token, oauth-audience, authorization-url, server-url and certificate-authority are only valid if require-oauth is enabled. Missing --port may implicitly set require-oauth to false")
	}
	if m.StaticConfig.AuthorizationURL != "" {
		u, err := url.Parse(m.StaticConfig.AuthorizationURL)
		if err != nil {
			return err
		}
		if u.Scheme != "https" && u.Scheme != "http" {
			return fmt.Errorf("--authorization-url must be a valid URL")
		}
		if u.Scheme == "http" {
			klog.Warningf("authorization-url is using http://, this is not recommended production use")
		}
	}
	return nil
}

func (m *MCPServerOptions) Run() error {
	klog.V(1).Info("Starting kubernetes-mcp-server")
	klog.V(1).Infof(" - Config: %s", m.ConfigPath)
	klog.V(1).Infof(" - Toolsets: %s", strings.Join(m.StaticConfig.Toolsets, ", "))
	klog.V(1).Infof(" - ListOutput: %s", m.StaticConfig.ListOutput)
	klog.V(1).Infof(" - Read-only mode: %t", m.StaticConfig.ReadOnly)
	klog.V(1).Infof(" - Disable destructive tools: %t", m.StaticConfig.DisableDestructive)

	strategy := m.StaticConfig.ClusterProviderStrategy
	if strategy == "" {
		strategy = "auto-detect (it is recommended to set this explicitly in your Config)"
	}

	klog.V(1).Infof(" - ClusterProviderStrategy: %s", strategy)

	if m.Version {
		_, _ = fmt.Fprintf(m.Out, "%s\n", version.Version)
		return nil
	}

	var oidcProvider *oidc.Provider
	var httpClient *http.Client
	if m.StaticConfig.AuthorizationURL != "" {
		ctx := context.Background()
		if m.StaticConfig.CertificateAuthority != "" {
			httpClient = &http.Client{}
			caCert, err := os.ReadFile(m.StaticConfig.CertificateAuthority)
			if err != nil {
				return fmt.Errorf("failed to read CA certificate from %s: %w", m.StaticConfig.CertificateAuthority, err)
			}
			caCertPool := x509.NewCertPool()
			if !caCertPool.AppendCertsFromPEM(caCert) {
				return fmt.Errorf("failed to append CA certificate from %s to pool", m.StaticConfig.CertificateAuthority)
			}

			if caCertPool.Equal(x509.NewCertPool()) {
				caCertPool = nil
			}

			transport := &http.Transport{
				TLSClientConfig: &tls.Config{
					RootCAs: caCertPool,
				},
			}
			httpClient.Transport = transport
			ctx = oidc.ClientContext(ctx, httpClient)
		}
		provider, err := oidc.NewProvider(ctx, m.StaticConfig.AuthorizationURL)
		if err != nil {
			return fmt.Errorf("unable to setup OIDC provider: %w", err)
		}
		oidcProvider = provider
	}

	mcpServer, err := mcp.NewServer(mcp.Configuration{StaticConfig: m.StaticConfig})
	if err != nil {
		return fmt.Errorf("failed to initialize MCP server: %w", err)
	}
	defer mcpServer.Close()

	if m.StaticConfig.Port != "" {
		ctx := context.Background()
		return internalhttp.Serve(ctx, mcpServer, m.StaticConfig, oidcProvider, httpClient)
	}

	if err := mcpServer.ServeStdio(); err != nil && !errors.Is(err, context.Canceled) {
		return err
	}

	return nil
}

```

--------------------------------------------------------------------------------
/pkg/mcp/common_test.go:
--------------------------------------------------------------------------------

```go
package mcp

import (
	"bytes"
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"net/http/httptest"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"testing"
	"time"

	"github.com/mark3labs/mcp-go/client"
	"github.com/mark3labs/mcp-go/client/transport"
	"github.com/mark3labs/mcp-go/mcp"
	"github.com/mark3labs/mcp-go/server"
	"github.com/pkg/errors"
	"github.com/spf13/afero"
	"github.com/stretchr/testify/suite"
	"golang.org/x/sync/errgroup"
	corev1 "k8s.io/api/core/v1"
	rbacv1 "k8s.io/api/rbac/v1"
	apiextensionsv1spec "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/watch"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
	toolswatch "k8s.io/client-go/tools/watch"
	"k8s.io/klog/v2"
	"k8s.io/klog/v2/textlogger"
	"k8s.io/utils/ptr"
	"sigs.k8s.io/controller-runtime/pkg/envtest"
	"sigs.k8s.io/controller-runtime/tools/setup-envtest/env"
	"sigs.k8s.io/controller-runtime/tools/setup-envtest/remote"
	"sigs.k8s.io/controller-runtime/tools/setup-envtest/store"
	"sigs.k8s.io/controller-runtime/tools/setup-envtest/versions"
	"sigs.k8s.io/controller-runtime/tools/setup-envtest/workflows"

	"github.com/containers/kubernetes-mcp-server/internal/test"
	"github.com/containers/kubernetes-mcp-server/pkg/config"
	"github.com/containers/kubernetes-mcp-server/pkg/output"
)

// envTest has an expensive setup, so we only want to do it once per entire test run.
var envTest *envtest.Environment
var envTestRestConfig *rest.Config
var envTestUser = envtest.User{Name: "test-user", Groups: []string{"test:users"}}

func TestMain(m *testing.M) {
	// Set up
	_ = os.Setenv("KUBECONFIG", "/dev/null")     // Avoid interference from existing kubeconfig
	_ = os.Setenv("KUBERNETES_SERVICE_HOST", "") // Avoid interference from in-cluster config
	_ = os.Setenv("KUBERNETES_SERVICE_PORT", "") // Avoid interference from in-cluster config
	envTestDir, err := store.DefaultStoreDir()
	if err != nil {
		panic(err)
	}
	envTestEnv := &env.Env{
		FS:  afero.Afero{Fs: afero.NewOsFs()},
		Out: os.Stdout,
		Client: &remote.HTTPClient{
			IndexURL: remote.DefaultIndexURL,
		},
		Platform: versions.PlatformItem{
			Platform: versions.Platform{
				OS:   runtime.GOOS,
				Arch: runtime.GOARCH,
			},
		},
		Version: versions.AnyVersion,
		Store:   store.NewAt(envTestDir),
	}
	envTestEnv.CheckCoherence()
	workflows.Use{}.Do(envTestEnv)
	versionDir := envTestEnv.Platform.BaseName(*envTestEnv.Version.AsConcrete())
	envTest = &envtest.Environment{
		BinaryAssetsDirectory: filepath.Join(envTestDir, "k8s", versionDir),
	}
	adminSystemMasterBaseConfig, _ := envTest.Start()
	au := test.Must(envTest.AddUser(envTestUser, adminSystemMasterBaseConfig))
	envTestRestConfig = au.Config()
	envTest.KubeConfig = test.Must(au.KubeConfig())

	//Create test data as administrator
	ctx := context.Background()
	restoreAuth(ctx)
	createTestData(ctx)

	// Test!
	code := m.Run()

	// Tear down
	if envTest != nil {
		_ = envTest.Stop()
	}
	os.Exit(code)
}

type mcpContext struct {
	toolsets   []string
	listOutput output.Output
	logLevel   int

	staticConfig  *config.StaticConfig
	clientOptions []transport.ClientOption
	before        func(*mcpContext)
	after         func(*mcpContext)
	ctx           context.Context
	tempDir       string
	cancel        context.CancelFunc
	mcpServer     *Server
	mcpHttpServer *httptest.Server
	mcpClient     *client.Client
	klogState     klog.State
	logBuffer     bytes.Buffer
}

func (c *mcpContext) beforeEach(t *testing.T) {
	var err error
	c.ctx, c.cancel = context.WithCancel(t.Context())
	c.tempDir = t.TempDir()
	c.withKubeConfig(nil)
	if c.staticConfig == nil {
		c.staticConfig = config.Default()
		// Default to use YAML output for lists (previously the default)
		c.staticConfig.ListOutput = "yaml"
	}
	if c.toolsets != nil {
		c.staticConfig.Toolsets = c.toolsets

	}
	if c.listOutput != nil {
		c.staticConfig.ListOutput = c.listOutput.GetName()
	}
	if c.before != nil {
		c.before(c)
	}
	// Set up logging
	c.klogState = klog.CaptureState()
	flags := flag.NewFlagSet("test", flag.ContinueOnError)
	klog.InitFlags(flags)
	_ = flags.Set("v", strconv.Itoa(c.logLevel))
	klog.SetLogger(textlogger.NewLogger(textlogger.NewConfig(textlogger.Verbosity(c.logLevel), textlogger.Output(&c.logBuffer))))
	// MCP Server
	if c.mcpServer, err = NewServer(Configuration{StaticConfig: c.staticConfig}); err != nil {
		t.Fatal(err)
		return
	}
	c.mcpHttpServer = server.NewTestServer(c.mcpServer.server, server.WithSSEContextFunc(contextFunc))
	if c.mcpClient, err = client.NewSSEMCPClient(c.mcpHttpServer.URL+"/sse", c.clientOptions...); err != nil {
		t.Fatal(err)
		return
	}
	// MCP Client
	if err = c.mcpClient.Start(c.ctx); err != nil {
		t.Fatal(err)
		return
	}
	initRequest := mcp.InitializeRequest{}
	initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
	initRequest.Params.ClientInfo = mcp.Implementation{Name: "test", Version: "1.33.7"}
	_, err = c.mcpClient.Initialize(c.ctx, initRequest)
	if err != nil {
		t.Fatal(err)
		return
	}
}

func (c *mcpContext) afterEach() {
	if c.after != nil {
		c.after(c)
	}
	c.cancel()
	c.mcpServer.Close()
	_ = c.mcpClient.Close()
	c.mcpHttpServer.Close()
	c.klogState.Restore()
}

func testCase(t *testing.T, test func(c *mcpContext)) {
	testCaseWithContext(t, &mcpContext{}, test)
}

func testCaseWithContext(t *testing.T, mcpCtx *mcpContext, test func(c *mcpContext)) {
	mcpCtx.beforeEach(t)
	defer mcpCtx.afterEach()
	test(mcpCtx)
}

// withKubeConfig sets up a fake kubeconfig in the temp directory based on the provided rest.Config
func (c *mcpContext) withKubeConfig(rc *rest.Config) *clientcmdapi.Config {
	fakeConfig := clientcmdapi.NewConfig()
	fakeConfig.Clusters["fake"] = clientcmdapi.NewCluster()
	fakeConfig.Clusters["fake"].Server = "https://127.0.0.1:6443"
	fakeConfig.Clusters["additional-cluster"] = clientcmdapi.NewCluster()
	fakeConfig.AuthInfos["fake"] = clientcmdapi.NewAuthInfo()
	fakeConfig.AuthInfos["additional-auth"] = clientcmdapi.NewAuthInfo()
	if rc != nil {
		fakeConfig.Clusters["fake"].Server = rc.Host
		fakeConfig.Clusters["fake"].CertificateAuthorityData = rc.CAData
		fakeConfig.AuthInfos["fake"].ClientKeyData = rc.KeyData
		fakeConfig.AuthInfos["fake"].ClientCertificateData = rc.CertData
	}
	fakeConfig.Contexts["fake-context"] = clientcmdapi.NewContext()
	fakeConfig.Contexts["fake-context"].Cluster = "fake"
	fakeConfig.Contexts["fake-context"].AuthInfo = "fake"
	fakeConfig.Contexts["additional-context"] = clientcmdapi.NewContext()
	fakeConfig.Contexts["additional-context"].Cluster = "additional-cluster"
	fakeConfig.Contexts["additional-context"].AuthInfo = "additional-auth"
	fakeConfig.CurrentContext = "fake-context"
	kubeConfig := filepath.Join(c.tempDir, "config")
	_ = clientcmd.WriteToFile(*fakeConfig, kubeConfig)
	_ = os.Setenv("KUBECONFIG", kubeConfig)
	if c.mcpServer != nil {
		if err := c.mcpServer.reloadKubernetesClusterProvider(); err != nil {
			panic(err)
		}
	}
	return fakeConfig
}

// withEnvTest sets up the environment for kubeconfig to be used with envTest
func (c *mcpContext) withEnvTest() {
	c.withKubeConfig(envTestRestConfig)
}

// inOpenShift sets up the kubernetes environment to seem to be running OpenShift
func inOpenShift(c *mcpContext) {
	c.withEnvTest()
	crdTemplate := `
          {
            "apiVersion": "apiextensions.k8s.io/v1",
            "kind": "CustomResourceDefinition",
            "metadata": {"name": "%s"},
            "spec": {
              "group": "%s",
              "versions": [{
                "name": "v1","served": true,"storage": true,
                "schema": {"openAPIV3Schema": {"type": "object","x-kubernetes-preserve-unknown-fields": true}}
              }],
              "scope": "%s",
              "names": {"plural": "%s","singular": "%s","kind": "%s"}
            }
          }`
	tasks, _ := errgroup.WithContext(c.ctx)
	tasks.Go(func() error {
		return c.crdApply(fmt.Sprintf(crdTemplate, "projects.project.openshift.io", "project.openshift.io",
			"Cluster", "projects", "project", "Project"))
	})
	tasks.Go(func() error {
		return c.crdApply(fmt.Sprintf(crdTemplate, "routes.route.openshift.io", "route.openshift.io",
			"Namespaced", "routes", "route", "Route"))
	})
	if err := tasks.Wait(); err != nil {
		panic(err)
	}
}

// inOpenShiftClear clears the kubernetes environment so it no longer seems to be running OpenShift
func inOpenShiftClear(c *mcpContext) {
	tasks, _ := errgroup.WithContext(c.ctx)
	tasks.Go(func() error { return c.crdDelete("projects.project.openshift.io") })
	tasks.Go(func() error { return c.crdDelete("routes.route.openshift.io") })
	if err := tasks.Wait(); err != nil {
		panic(err)
	}
}

// newKubernetesClient creates a new Kubernetes client with the envTest kubeconfig
func (c *mcpContext) newKubernetesClient() *kubernetes.Clientset {
	return kubernetes.NewForConfigOrDie(envTestRestConfig)
}

// newApiExtensionsClient creates a new ApiExtensions client with the envTest kubeconfig
func (c *mcpContext) newApiExtensionsClient() *apiextensionsv1.ApiextensionsV1Client {
	return apiextensionsv1.NewForConfigOrDie(envTestRestConfig)
}

// crdApply creates a CRD from the provided resource string and waits for it to be established
func (c *mcpContext) crdApply(resource string) error {
	apiExtensionsV1Client := c.newApiExtensionsClient()
	var crd = &apiextensionsv1spec.CustomResourceDefinition{}
	err := json.Unmarshal([]byte(resource), crd)
	if err != nil {
		return fmt.Errorf("failed to create CRD %v", err)
	}
	_, err = apiExtensionsV1Client.CustomResourceDefinitions().Create(c.ctx, crd, metav1.CreateOptions{})
	if err != nil {
		return fmt.Errorf("failed to create CRD %v", err)
	}
	c.crdWaitUntilReady(crd.Name)
	return nil
}

// crdDelete deletes a CRD by name and waits for it to be removed
func (c *mcpContext) crdDelete(name string) error {
	apiExtensionsV1Client := c.newApiExtensionsClient()
	err := apiExtensionsV1Client.CustomResourceDefinitions().Delete(c.ctx, name, metav1.DeleteOptions{
		GracePeriodSeconds: ptr.To(int64(0)),
	})
	iteration := 0
	for iteration < 100 {
		if _, derr := apiExtensionsV1Client.CustomResourceDefinitions().Get(c.ctx, name, metav1.GetOptions{}); derr != nil {
			break
		}
		time.Sleep(5 * time.Millisecond)
		iteration++
	}
	if err != nil {
		return errors.Wrap(err, "failed to delete CRD")
	}
	return nil
}

// crdWaitUntilReady waits for a CRD to be established
func (c *mcpContext) crdWaitUntilReady(name string) {
	watcher, err := c.newApiExtensionsClient().CustomResourceDefinitions().Watch(c.ctx, metav1.ListOptions{
		FieldSelector: "metadata.name=" + name,
	})
	if err != nil {
		panic(fmt.Errorf("failed to watch CRD %v", err))
	}
	_, err = toolswatch.UntilWithoutRetry(c.ctx, watcher, func(event watch.Event) (bool, error) {
		for _, c := range event.Object.(*apiextensionsv1spec.CustomResourceDefinition).Status.Conditions {
			if c.Type == apiextensionsv1spec.Established && c.Status == apiextensionsv1spec.ConditionTrue {
				return true, nil
			}
		}
		return false, nil
	})
	if err != nil {
		panic(fmt.Errorf("failed to wait for CRD %v", err))
	}
}

// callTool helper function to call a tool by name with arguments
func (c *mcpContext) callTool(name string, args map[string]interface{}) (*mcp.CallToolResult, error) {
	callToolRequest := mcp.CallToolRequest{}
	callToolRequest.Params.Name = name
	callToolRequest.Params.Arguments = args
	return c.mcpClient.CallTool(c.ctx, callToolRequest)
}

func restoreAuth(ctx context.Context) {
	kubernetesAdmin := kubernetes.NewForConfigOrDie(envTest.Config)
	// Authorization
	_, _ = kubernetesAdmin.RbacV1().ClusterRoles().Update(ctx, &rbacv1.ClusterRole{
		ObjectMeta: metav1.ObjectMeta{Name: "allow-all"},
		Rules: []rbacv1.PolicyRule{{
			Verbs:     []string{"*"},
			APIGroups: []string{"*"},
			Resources: []string{"*"},
		}},
	}, metav1.UpdateOptions{})
	_, _ = kubernetesAdmin.RbacV1().ClusterRoleBindings().Update(ctx, &rbacv1.ClusterRoleBinding{
		ObjectMeta: metav1.ObjectMeta{Name: "allow-all"},
		Subjects:   []rbacv1.Subject{{Kind: "Group", Name: envTestUser.Groups[0]}},
		RoleRef:    rbacv1.RoleRef{Kind: "ClusterRole", Name: "allow-all"},
	}, metav1.UpdateOptions{})
}

func createTestData(ctx context.Context) {
	kubernetesAdmin := kubernetes.NewForConfigOrDie(envTestRestConfig)
	// Namespaces
	_, _ = kubernetesAdmin.CoreV1().Namespaces().
		Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "ns-1"}}, metav1.CreateOptions{})
	_, _ = kubernetesAdmin.CoreV1().Namespaces().
		Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "ns-2"}}, metav1.CreateOptions{})
	_, _ = kubernetesAdmin.CoreV1().Namespaces().
		Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "ns-to-delete"}}, metav1.CreateOptions{})
	_, _ = kubernetesAdmin.CoreV1().Pods("default").Create(ctx, &corev1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:   "a-pod-in-default",
			Labels: map[string]string{"app": "nginx"},
		},
		Spec: corev1.PodSpec{
			Containers: []corev1.Container{
				{
					Name:  "nginx",
					Image: "nginx",
				},
			},
		},
	}, metav1.CreateOptions{})
	// Pods for listing
	_, _ = kubernetesAdmin.CoreV1().Pods("ns-1").Create(ctx, &corev1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name: "a-pod-in-ns-1",
		},
		Spec: corev1.PodSpec{
			Containers: []corev1.Container{
				{
					Name:  "nginx",
					Image: "nginx",
				},
			},
		},
	}, metav1.CreateOptions{})
	_, _ = kubernetesAdmin.CoreV1().Pods("ns-2").Create(ctx, &corev1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name: "a-pod-in-ns-2",
		},
		Spec: corev1.PodSpec{
			Containers: []corev1.Container{
				{
					Name:  "nginx",
					Image: "nginx",
				},
			},
		},
	}, metav1.CreateOptions{})
	_, _ = kubernetesAdmin.CoreV1().ConfigMaps("default").
		Create(ctx, &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "a-configmap-to-delete"}}, metav1.CreateOptions{})
}

type BaseMcpSuite struct {
	suite.Suite
	*test.McpClient
	mcpServer *Server
	Cfg       *config.StaticConfig
}

func (s *BaseMcpSuite) SetupTest() {
	s.Cfg = config.Default()
	s.Cfg.ListOutput = "yaml"
	s.Cfg.KubeConfig = filepath.Join(s.T().TempDir(), "config")
	s.Require().NoError(os.WriteFile(s.Cfg.KubeConfig, envTest.KubeConfig, 0600), "Expected to write kubeconfig")
}

func (s *BaseMcpSuite) TearDownTest() {
	if s.McpClient != nil {
		s.Close()
	}
	if s.mcpServer != nil {
		s.mcpServer.Close()
	}
}

func (s *BaseMcpSuite) InitMcpClient() {
	var err error
	s.mcpServer, err = NewServer(Configuration{StaticConfig: s.Cfg})
	s.Require().NoError(err, "Expected no error creating MCP server")
	s.McpClient = test.NewMcpClient(s.T(), s.mcpServer.ServeHTTP(nil))
}

```

--------------------------------------------------------------------------------
/pkg/mcp/testdata/toolsets-core-tools.json:
--------------------------------------------------------------------------------

```json
[
  {
    "annotations": {
      "title": "Events: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes events in the current cluster from all namespaces",
    "inputSchema": {
      "type": "object",
      "properties": {
        "namespace": {
          "description": "Optional Namespace to retrieve the events from. If not provided, will list events from all namespaces",
          "type": "string"
        }
      }
    },
    "name": "events_list"
  },
  {
    "annotations": {
      "title": "Namespaces: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes namespaces in the current cluster",
    "inputSchema": {
      "type": "object"
    },
    "name": "namespaces_list"
  },
  {
    "annotations": {
      "title": "Node: Log",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get logs from a Kubernetes node (kubelet, kube-proxy, or other system logs). This accesses node logs through the Kubernetes API proxy to the kubelet",
    "inputSchema": {
      "type": "object",
      "properties": {
        "log_path": {
          "default": "kubelet.log",
          "description": "Path to the log file on the node (e.g. 'kubelet.log', 'kube-proxy.log'). Default is 'kubelet.log'",
          "type": "string"
        },
        "name": {
          "description": "Name of the node to get logs from",
          "type": "string"
        },
        "tail": {
          "default": 100,
          "description": "Number of lines to retrieve from the end of the logs (Optional, 0 means all logs)",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "nodes_log"
  },
  {
    "annotations": {
      "title": "Pods: Delete",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Delete a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {
          "description": "Name of the Pod to delete",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to delete the Pod from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_delete"
  },
  {
    "annotations": {
      "title": "Pods: Exec",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Execute a command in a Kubernetes Pod in the current or provided namespace with the provided name and command",
    "inputSchema": {
      "type": "object",
      "properties": {
        "command": {
          "description": "Command to execute in the Pod container. The first item is the command to be run, and the rest are the arguments to that command. Example: [\"ls\", \"-l\", \"/tmp\"]",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "container": {
          "description": "Name of the Pod container where the command will be executed (Optional)",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod where the command will be executed",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace of the Pod where the command will be executed",
          "type": "string"
        }
      },
      "required": [
        "name",
        "command"
      ]
    },
    "name": "pods_exec"
  },
  {
    "annotations": {
      "title": "Pods: Get",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {
          "description": "Name of the Pod",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pod from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_get"
  },
  {
    "annotations": {
      "title": "Pods: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes pods in the current cluster from all namespaces",
    "inputSchema": {
      "type": "object",
      "properties": {
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        }
      }
    },
    "name": "pods_list"
  },
  {
    "annotations": {
      "title": "Pods: List in Namespace",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes pods in the specified namespace in the current cluster",
    "inputSchema": {
      "type": "object",
      "properties": {
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to list pods from",
          "type": "string"
        }
      },
      "required": [
        "namespace"
      ]
    },
    "name": "pods_list_in_namespace"
  },
  {
    "annotations": {
      "title": "Pods: Log",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get the logs of a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "container": {
          "description": "Name of the Pod container to get the logs from (Optional)",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod to get the logs from",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pod logs from",
          "type": "string"
        },
        "previous": {
          "description": "Return previous terminated container logs (Optional)",
          "type": "boolean"
        },
        "tail": {
          "default": 100,
          "description": "Number of lines to retrieve from the end of the logs (Optional, default: 100)",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_log"
  },
  {
    "annotations": {
      "title": "Pods: Run",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Run a Kubernetes Pod in the current or provided namespace with the provided container image and optional name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "image": {
          "description": "Container Image to run in the Pod",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod (Optional, random name if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to run the Pod in",
          "type": "string"
        },
        "port": {
          "description": "TCP/IP port to expose from the Pod container (Optional, no port exposed if not provided)",
          "type": "number"
        }
      },
      "required": [
        "image"
      ]
    },
    "name": "pods_run"
  },
  {
    "annotations": {
      "title": "Pods: Top",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "List the resource consumption (CPU and memory) as recorded by the Kubernetes Metrics Server for the specified Kubernetes Pods in the all namespaces, the provided namespace, or the current namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "all_namespaces": {
          "default": true,
          "description": "If true, list the resource consumption for all Pods in all namespaces. If false, list the resource consumption for Pods in the provided namespace or the current namespace",
          "type": "boolean"
        },
        "label_selector": {
          "description": "Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label (Optional, only applicable when name is not provided)",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod to get the resource consumption from (Optional, all Pods in the namespace if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pods resource consumption from (Optional, current namespace if not provided and all_namespaces is false)",
          "type": "string"
        }
      }
    },
    "name": "pods_top"
  },
  {
    "annotations": {
      "title": "Resources: Create or Update",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Create or update a Kubernetes resource in the current cluster by providing a YAML or JSON representation of the resource\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "resource": {
          "description": "A JSON or YAML containing a representation of the Kubernetes resource. Should include top-level fields such as apiVersion,kind,metadata, and spec",
          "type": "string"
        }
      },
      "required": [
        "resource"
      ]
    },
    "name": "resources_create_or_update"
  },
  {
    "annotations": {
      "title": "Resources: Delete",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Delete a Kubernetes resource in the current cluster by providing its apiVersion, kind, optionally the namespace, and its name\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to delete the namespaced resource from (ignored in case of cluster scoped resources). If not provided, will delete resource from configured namespace",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_delete"
  },
  {
    "annotations": {
      "title": "Resources: Get",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get a Kubernetes resource in the current cluster by providing its apiVersion, kind, optionally the namespace, and its name\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to retrieve the namespaced resource from (ignored in case of cluster scoped resources). If not provided, will get resource from configured namespace",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_get"
  },
  {
    "annotations": {
      "title": "Resources: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List Kubernetes resources and objects in the current cluster by providing their apiVersion and kind and optionally the namespace and label selector\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resources (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resources (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to retrieve the namespaced resources from (ignored in case of cluster scoped resources). If not provided, will list resources from all namespaces",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind"
      ]
    },
    "name": "resources_list"
  }
]

```

--------------------------------------------------------------------------------
/pkg/toolsets/core/pods.go:
--------------------------------------------------------------------------------

```go
package core

import (
	"bytes"
	"errors"
	"fmt"

	"github.com/google/jsonschema-go/jsonschema"
	"k8s.io/kubectl/pkg/metricsutil"
	"k8s.io/utils/ptr"

	"github.com/containers/kubernetes-mcp-server/pkg/api"
	"github.com/containers/kubernetes-mcp-server/pkg/kubernetes"
	"github.com/containers/kubernetes-mcp-server/pkg/output"
)

func initPods() []api.ServerTool {
	return []api.ServerTool{
		{Tool: api.Tool{
			Name:        "pods_list",
			Description: "List all the Kubernetes pods in the current cluster from all namespaces",
			InputSchema: &jsonschema.Schema{
				Type: "object",
				Properties: map[string]*jsonschema.Schema{
					"labelSelector": {
						Type:        "string",
						Description: "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
						Pattern:     "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
					},
				},
			},
			Annotations: api.ToolAnnotations{
				Title:           "Pods: List",
				ReadOnlyHint:    ptr.To(true),
				DestructiveHint: ptr.To(false),
				IdempotentHint:  ptr.To(false),
				OpenWorldHint:   ptr.To(true),
			},
		}, Handler: podsListInAllNamespaces},
		{Tool: api.Tool{
			Name:        "pods_list_in_namespace",
			Description: "List all the Kubernetes pods in the specified namespace in the current cluster",
			InputSchema: &jsonschema.Schema{
				Type: "object",
				Properties: map[string]*jsonschema.Schema{
					"namespace": {
						Type:        "string",
						Description: "Namespace to list pods from",
					},
					"labelSelector": {
						Type:        "string",
						Description: "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
						Pattern:     "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
					},
				},
				Required: []string{"namespace"},
			},
			Annotations: api.ToolAnnotations{
				Title:           "Pods: List in Namespace",
				ReadOnlyHint:    ptr.To(true),
				DestructiveHint: ptr.To(false),
				IdempotentHint:  ptr.To(false),
				OpenWorldHint:   ptr.To(true),
			},
		}, Handler: podsListInNamespace},
		{Tool: api.Tool{
			Name:        "pods_get",
			Description: "Get a Kubernetes Pod in the current or provided namespace with the provided name",
			InputSchema: &jsonschema.Schema{
				Type: "object",
				Properties: map[string]*jsonschema.Schema{
					"namespace": {
						Type:        "string",
						Description: "Namespace to get the Pod from",
					},
					"name": {
						Type:        "string",
						Description: "Name of the Pod",
					},
				},
				Required: []string{"name"},
			},
			Annotations: api.ToolAnnotations{
				Title:           "Pods: Get",
				ReadOnlyHint:    ptr.To(true),
				DestructiveHint: ptr.To(false),
				IdempotentHint:  ptr.To(false),
				OpenWorldHint:   ptr.To(true),
			},
		}, Handler: podsGet},
		{Tool: api.Tool{
			Name:        "pods_delete",
			Description: "Delete a Kubernetes Pod in the current or provided namespace with the provided name",
			InputSchema: &jsonschema.Schema{
				Type: "object",
				Properties: map[string]*jsonschema.Schema{
					"namespace": {
						Type:        "string",
						Description: "Namespace to delete the Pod from",
					},
					"name": {
						Type:        "string",
						Description: "Name of the Pod to delete",
					},
				},
				Required: []string{"name"},
			},
			Annotations: api.ToolAnnotations{
				Title:           "Pods: Delete",
				ReadOnlyHint:    ptr.To(false),
				DestructiveHint: ptr.To(true),
				IdempotentHint:  ptr.To(true),
				OpenWorldHint:   ptr.To(true),
			},
		}, Handler: podsDelete},
		{Tool: api.Tool{
			Name:        "pods_top",
			Description: "List the resource consumption (CPU and memory) as recorded by the Kubernetes Metrics Server for the specified Kubernetes Pods in the all namespaces, the provided namespace, or the current namespace",
			InputSchema: &jsonschema.Schema{
				Type: "object",
				Properties: map[string]*jsonschema.Schema{
					"all_namespaces": {
						Type:        "boolean",
						Description: "If true, list the resource consumption for all Pods in all namespaces. If false, list the resource consumption for Pods in the provided namespace or the current namespace",
						Default:     api.ToRawMessage(true),
					},
					"namespace": {
						Type:        "string",
						Description: "Namespace to get the Pods resource consumption from (Optional, current namespace if not provided and all_namespaces is false)",
					},
					"name": {
						Type:        "string",
						Description: "Name of the Pod to get the resource consumption from (Optional, all Pods in the namespace if not provided)",
					},
					"label_selector": {
						Type:        "string",
						Description: "Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label (Optional, only applicable when name is not provided)",
						Pattern:     "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
					},
				},
			},
			Annotations: api.ToolAnnotations{
				Title:           "Pods: Top",
				ReadOnlyHint:    ptr.To(true),
				DestructiveHint: ptr.To(false),
				IdempotentHint:  ptr.To(true),
				OpenWorldHint:   ptr.To(true),
			},
		}, Handler: podsTop},
		{Tool: api.Tool{
			Name:        "pods_exec",
			Description: "Execute a command in a Kubernetes Pod in the current or provided namespace with the provided name and command",
			InputSchema: &jsonschema.Schema{
				Type: "object",
				Properties: map[string]*jsonschema.Schema{
					"namespace": {
						Type:        "string",
						Description: "Namespace of the Pod where the command will be executed",
					},
					"name": {
						Type:        "string",
						Description: "Name of the Pod where the command will be executed",
					},
					"command": {
						Type:        "array",
						Description: "Command to execute in the Pod container. The first item is the command to be run, and the rest are the arguments to that command. Example: [\"ls\", \"-l\", \"/tmp\"]",
						Items: &jsonschema.Schema{
							Type: "string",
						},
					},
					"container": {
						Type:        "string",
						Description: "Name of the Pod container where the command will be executed (Optional)",
					},
				},
				Required: []string{"name", "command"},
			},
			Annotations: api.ToolAnnotations{
				Title:           "Pods: Exec",
				ReadOnlyHint:    ptr.To(false),
				DestructiveHint: ptr.To(true), // Depending on the Pod's entrypoint, executing certain commands may kill the Pod
				IdempotentHint:  ptr.To(false),
				OpenWorldHint:   ptr.To(true),
			},
		}, Handler: podsExec},
		{Tool: api.Tool{
			Name:        "pods_log",
			Description: "Get the logs of a Kubernetes Pod in the current or provided namespace with the provided name",
			InputSchema: &jsonschema.Schema{
				Type: "object",
				Properties: map[string]*jsonschema.Schema{
					"namespace": {
						Type:        "string",
						Description: "Namespace to get the Pod logs from",
					},
					"name": {
						Type:        "string",
						Description: "Name of the Pod to get the logs from",
					},
					"container": {
						Type:        "string",
						Description: "Name of the Pod container to get the logs from (Optional)",
					},
					"tail": {
						Type:        "integer",
						Description: "Number of lines to retrieve from the end of the logs (Optional, default: 100)",
						Default:     api.ToRawMessage(kubernetes.DefaultTailLines),
						Minimum:     ptr.To(float64(0)),
					},
					"previous": {
						Type:        "boolean",
						Description: "Return previous terminated container logs (Optional)",
					},
				},
				Required: []string{"name"},
			},
			Annotations: api.ToolAnnotations{
				Title:           "Pods: Log",
				ReadOnlyHint:    ptr.To(true),
				DestructiveHint: ptr.To(false),
				IdempotentHint:  ptr.To(false),
				OpenWorldHint:   ptr.To(true),
			},
		}, Handler: podsLog},
		{Tool: api.Tool{
			Name:        "pods_run",
			Description: "Run a Kubernetes Pod in the current or provided namespace with the provided container image and optional name",
			InputSchema: &jsonschema.Schema{
				Type: "object",
				Properties: map[string]*jsonschema.Schema{
					"namespace": {
						Type:        "string",
						Description: "Namespace to run the Pod in",
					},
					"name": {
						Type:        "string",
						Description: "Name of the Pod (Optional, random name if not provided)",
					},
					"image": {
						Type:        "string",
						Description: "Container Image to run in the Pod",
					},
					"port": {
						Type:        "number",
						Description: "TCP/IP port to expose from the Pod container (Optional, no port exposed if not provided)",
					},
				},
				Required: []string{"image"},
			},
			Annotations: api.ToolAnnotations{
				Title:           "Pods: Run",
				ReadOnlyHint:    ptr.To(false),
				DestructiveHint: ptr.To(false),
				IdempotentHint:  ptr.To(false),
				OpenWorldHint:   ptr.To(true),
			},
		}, Handler: podsRun},
	}
}

func podsListInAllNamespaces(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
	labelSelector := params.GetArguments()["labelSelector"]
	resourceListOptions := kubernetes.ResourceListOptions{
		AsTable: params.ListOutput.AsTable(),
	}
	if labelSelector != nil {
		resourceListOptions.LabelSelector = labelSelector.(string)
	}
	ret, err := params.PodsListInAllNamespaces(params, resourceListOptions)
	if err != nil {
		return api.NewToolCallResult("", fmt.Errorf("failed to list pods in all namespaces: %v", err)), nil
	}
	return api.NewToolCallResult(params.ListOutput.PrintObj(ret)), nil
}

func podsListInNamespace(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
	ns := params.GetArguments()["namespace"]
	if ns == nil {
		return api.NewToolCallResult("", errors.New("failed to list pods in namespace, missing argument namespace")), nil
	}
	resourceListOptions := kubernetes.ResourceListOptions{
		AsTable: params.ListOutput.AsTable(),
	}
	labelSelector := params.GetArguments()["labelSelector"]
	if labelSelector != nil {
		resourceListOptions.LabelSelector = labelSelector.(string)
	}
	ret, err := params.PodsListInNamespace(params, ns.(string), resourceListOptions)
	if err != nil {
		return api.NewToolCallResult("", fmt.Errorf("failed to list pods in namespace %s: %v", ns, err)), nil
	}
	return api.NewToolCallResult(params.ListOutput.PrintObj(ret)), nil
}

func podsGet(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
	ns := params.GetArguments()["namespace"]
	if ns == nil {
		ns = ""
	}
	name := params.GetArguments()["name"]
	if name == nil {
		return api.NewToolCallResult("", errors.New("failed to get pod, missing argument name")), nil
	}
	ret, err := params.PodsGet(params, ns.(string), name.(string))
	if err != nil {
		return api.NewToolCallResult("", fmt.Errorf("failed to get pod %s in namespace %s: %v", name, ns, err)), nil
	}
	return api.NewToolCallResult(output.MarshalYaml(ret)), nil
}

func podsDelete(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
	ns := params.GetArguments()["namespace"]
	if ns == nil {
		ns = ""
	}
	name := params.GetArguments()["name"]
	if name == nil {
		return api.NewToolCallResult("", errors.New("failed to delete pod, missing argument name")), nil
	}
	ret, err := params.PodsDelete(params, ns.(string), name.(string))
	if err != nil {
		return api.NewToolCallResult("", fmt.Errorf("failed to delete pod %s in namespace %s: %v", name, ns, err)), nil
	}
	return api.NewToolCallResult(ret, err), nil
}

func podsTop(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
	podsTopOptions := kubernetes.PodsTopOptions{AllNamespaces: true}
	if v, ok := params.GetArguments()["namespace"].(string); ok {
		podsTopOptions.Namespace = v
	}
	if v, ok := params.GetArguments()["all_namespaces"].(bool); ok {
		podsTopOptions.AllNamespaces = v
	}
	if v, ok := params.GetArguments()["name"].(string); ok {
		podsTopOptions.Name = v
	}
	if v, ok := params.GetArguments()["label_selector"].(string); ok {
		podsTopOptions.LabelSelector = v
	}
	ret, err := params.PodsTop(params, podsTopOptions)
	if err != nil {
		return api.NewToolCallResult("", fmt.Errorf("failed to get pods top: %v", err)), nil
	}
	buf := new(bytes.Buffer)
	printer := metricsutil.NewTopCmdPrinter(buf, true)
	err = printer.PrintPodMetrics(ret.Items, true, true, false, "", true)
	if err != nil {
		return api.NewToolCallResult("", fmt.Errorf("failed to get pods top: %v", err)), nil
	}
	return api.NewToolCallResult(buf.String(), nil), nil
}

func podsExec(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
	ns := params.GetArguments()["namespace"]
	if ns == nil {
		ns = ""
	}
	name := params.GetArguments()["name"]
	if name == nil {
		return api.NewToolCallResult("", errors.New("failed to exec in pod, missing argument name")), nil
	}
	container := params.GetArguments()["container"]
	if container == nil {
		container = ""
	}
	commandArg := params.GetArguments()["command"]
	command := make([]string, 0)
	if _, ok := commandArg.([]interface{}); ok {
		for _, cmd := range commandArg.([]interface{}) {
			if _, ok := cmd.(string); ok {
				command = append(command, cmd.(string))
			}
		}
	} else {
		return api.NewToolCallResult("", errors.New("failed to exec in pod, invalid command argument")), nil
	}
	ret, err := params.PodsExec(params, ns.(string), name.(string), container.(string), command)
	if err != nil {
		return api.NewToolCallResult("", fmt.Errorf("failed to exec in pod %s in namespace %s: %v", name, ns, err)), nil
	} else if ret == "" {
		ret = fmt.Sprintf("The executed command in pod %s in namespace %s has not produced any output", name, ns)
	}
	return api.NewToolCallResult(ret, err), nil
}

func podsLog(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
	ns := params.GetArguments()["namespace"]
	if ns == nil {
		ns = ""
	}
	name := params.GetArguments()["name"]
	if name == nil {
		return api.NewToolCallResult("", errors.New("failed to get pod log, missing argument name")), nil
	}
	container := params.GetArguments()["container"]
	if container == nil {
		container = ""
	}
	previous := params.GetArguments()["previous"]
	var previousBool bool
	if previous != nil {
		previousBool = previous.(bool)
	}
	// Extract tailLines parameter
	tail := params.GetArguments()["tail"]
	var tailInt int64
	if tail != nil {
		// Convert to int64 - safely handle both float64 (JSON number) and int types
		switch v := tail.(type) {
		case float64:
			tailInt = int64(v)
		case int:
			tailInt = int64(v)
		case int64:
			tailInt = v
		default:
			return api.NewToolCallResult("", fmt.Errorf("failed to parse tail parameter: expected integer, got %T", tail)), nil
		}
	}

	ret, err := params.PodsLog(params.Context, ns.(string), name.(string), container.(string), previousBool, tailInt)
	if err != nil {
		return api.NewToolCallResult("", fmt.Errorf("failed to get pod %s log in namespace %s: %v", name, ns, err)), nil
	} else if ret == "" {
		ret = fmt.Sprintf("The pod %s in namespace %s has not logged any message yet", name, ns)
	}
	return api.NewToolCallResult(ret, err), nil
}

func podsRun(params api.ToolHandlerParams) (*api.ToolCallResult, error) {
	ns := params.GetArguments()["namespace"]
	if ns == nil {
		ns = ""
	}
	name := params.GetArguments()["name"]
	if name == nil {
		name = ""
	}
	image := params.GetArguments()["image"]
	if image == nil {
		return api.NewToolCallResult("", errors.New("failed to run pod, missing argument image")), nil
	}
	port := params.GetArguments()["port"]
	if port == nil {
		port = float64(0)
	}
	resources, err := params.PodsRun(params, ns.(string), name.(string), image.(string), int32(port.(float64)))
	if err != nil {
		return api.NewToolCallResult("", fmt.Errorf("failed to run pod %s in namespace %s: %v", name, ns, err)), nil
	}
	marshalledYaml, err := output.MarshalYaml(resources)
	if err != nil {
		err = fmt.Errorf("failed to run pod: %v", err)
	}
	return api.NewToolCallResult("# The following resources (YAML) have been created or updated successfully\n"+marshalledYaml, err), nil
}

```

--------------------------------------------------------------------------------
/pkg/mcp/testdata/toolsets-full-tools.json:
--------------------------------------------------------------------------------

```json
[
  {
    "annotations": {
      "title": "Configuration: View",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get the current Kubernetes configuration content as a kubeconfig YAML",
    "inputSchema": {
      "type": "object",
      "properties": {
        "minified": {
          "description": "Return a minified version of the configuration. If set to true, keeps only the current-context and the relevant pieces of the configuration for that context. If set to false, all contexts, clusters, auth-infos, and users are returned in the configuration. (Optional, default true)",
          "type": "boolean"
        }
      }
    },
    "name": "configuration_view"
  },
  {
    "annotations": {
      "title": "Events: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes events in the current cluster from all namespaces",
    "inputSchema": {
      "type": "object",
      "properties": {
        "namespace": {
          "description": "Optional Namespace to retrieve the events from. If not provided, will list events from all namespaces",
          "type": "string"
        }
      }
    },
    "name": "events_list"
  },
  {
    "annotations": {
      "title": "Helm: Install",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Install a Helm chart in the current or provided namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "chart": {
          "description": "Chart reference to install (for example: stable/grafana, oci://ghcr.io/nginxinc/charts/nginx-ingress)",
          "type": "string"
        },
        "name": {
          "description": "Name of the Helm release (Optional, random name if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to install the Helm chart in (Optional, current namespace if not provided)",
          "type": "string"
        },
        "values": {
          "description": "Values to pass to the Helm chart (Optional)",
          "type": "object"
        }
      },
      "required": [
        "chart"
      ]
    },
    "name": "helm_install"
  },
  {
    "annotations": {
      "title": "Helm: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Helm releases in the current or provided namespace (or in all namespaces if specified)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "all_namespaces": {
          "description": "If true, lists all Helm releases in all namespaces ignoring the namespace argument (Optional)",
          "type": "boolean"
        },
        "namespace": {
          "description": "Namespace to list Helm releases from (Optional, all namespaces if not provided)",
          "type": "string"
        }
      }
    },
    "name": "helm_list"
  },
  {
    "annotations": {
      "title": "Helm: Uninstall",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Uninstall a Helm release in the current or provided namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {
          "description": "Name of the Helm release to uninstall",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to uninstall the Helm release from (Optional, current namespace if not provided)",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "helm_uninstall"
  },
  {
    "annotations": {
      "title": "Namespaces: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes namespaces in the current cluster",
    "inputSchema": {
      "type": "object"
    },
    "name": "namespaces_list"
  },
  {
    "annotations": {
      "title": "Node: Log",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get logs from a Kubernetes node (kubelet, kube-proxy, or other system logs). This accesses node logs through the Kubernetes API proxy to the kubelet",
    "inputSchema": {
      "type": "object",
      "properties": {
        "log_path": {
          "default": "kubelet.log",
          "description": "Path to the log file on the node (e.g. 'kubelet.log', 'kube-proxy.log'). Default is 'kubelet.log'",
          "type": "string"
        },
        "name": {
          "description": "Name of the node to get logs from",
          "type": "string"
        },
        "tail": {
          "default": 100,
          "description": "Number of lines to retrieve from the end of the logs (Optional, 0 means all logs)",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "nodes_log"
  },
  {
    "annotations": {
      "title": "Pods: Delete",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Delete a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {
          "description": "Name of the Pod to delete",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to delete the Pod from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_delete"
  },
  {
    "annotations": {
      "title": "Pods: Exec",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Execute a command in a Kubernetes Pod in the current or provided namespace with the provided name and command",
    "inputSchema": {
      "type": "object",
      "properties": {
        "command": {
          "description": "Command to execute in the Pod container. The first item is the command to be run, and the rest are the arguments to that command. Example: [\"ls\", \"-l\", \"/tmp\"]",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "container": {
          "description": "Name of the Pod container where the command will be executed (Optional)",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod where the command will be executed",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace of the Pod where the command will be executed",
          "type": "string"
        }
      },
      "required": [
        "name",
        "command"
      ]
    },
    "name": "pods_exec"
  },
  {
    "annotations": {
      "title": "Pods: Get",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {
          "description": "Name of the Pod",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pod from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_get"
  },
  {
    "annotations": {
      "title": "Pods: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes pods in the current cluster from all namespaces",
    "inputSchema": {
      "type": "object",
      "properties": {
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        }
      }
    },
    "name": "pods_list"
  },
  {
    "annotations": {
      "title": "Pods: List in Namespace",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes pods in the specified namespace in the current cluster",
    "inputSchema": {
      "type": "object",
      "properties": {
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to list pods from",
          "type": "string"
        }
      },
      "required": [
        "namespace"
      ]
    },
    "name": "pods_list_in_namespace"
  },
  {
    "annotations": {
      "title": "Pods: Log",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get the logs of a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "container": {
          "description": "Name of the Pod container to get the logs from (Optional)",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod to get the logs from",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pod logs from",
          "type": "string"
        },
        "previous": {
          "description": "Return previous terminated container logs (Optional)",
          "type": "boolean"
        },
        "tail": {
          "default": 100,
          "description": "Number of lines to retrieve from the end of the logs (Optional, default: 100)",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_log"
  },
  {
    "annotations": {
      "title": "Pods: Run",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Run a Kubernetes Pod in the current or provided namespace with the provided container image and optional name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "image": {
          "description": "Container Image to run in the Pod",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod (Optional, random name if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to run the Pod in",
          "type": "string"
        },
        "port": {
          "description": "TCP/IP port to expose from the Pod container (Optional, no port exposed if not provided)",
          "type": "number"
        }
      },
      "required": [
        "image"
      ]
    },
    "name": "pods_run"
  },
  {
    "annotations": {
      "title": "Pods: Top",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "List the resource consumption (CPU and memory) as recorded by the Kubernetes Metrics Server for the specified Kubernetes Pods in the all namespaces, the provided namespace, or the current namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "all_namespaces": {
          "default": true,
          "description": "If true, list the resource consumption for all Pods in all namespaces. If false, list the resource consumption for Pods in the provided namespace or the current namespace",
          "type": "boolean"
        },
        "label_selector": {
          "description": "Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label (Optional, only applicable when name is not provided)",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod to get the resource consumption from (Optional, all Pods in the namespace if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pods resource consumption from (Optional, current namespace if not provided and all_namespaces is false)",
          "type": "string"
        }
      }
    },
    "name": "pods_top"
  },
  {
    "annotations": {
      "title": "Resources: Create or Update",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Create or update a Kubernetes resource in the current cluster by providing a YAML or JSON representation of the resource\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "resource": {
          "description": "A JSON or YAML containing a representation of the Kubernetes resource. Should include top-level fields such as apiVersion,kind,metadata, and spec",
          "type": "string"
        }
      },
      "required": [
        "resource"
      ]
    },
    "name": "resources_create_or_update"
  },
  {
    "annotations": {
      "title": "Resources: Delete",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Delete a Kubernetes resource in the current cluster by providing its apiVersion, kind, optionally the namespace, and its name\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to delete the namespaced resource from (ignored in case of cluster scoped resources). If not provided, will delete resource from configured namespace",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_delete"
  },
  {
    "annotations": {
      "title": "Resources: Get",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get a Kubernetes resource in the current cluster by providing its apiVersion, kind, optionally the namespace, and its name\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to retrieve the namespaced resource from (ignored in case of cluster scoped resources). If not provided, will get resource from configured namespace",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_get"
  },
  {
    "annotations": {
      "title": "Resources: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List Kubernetes resources and objects in the current cluster by providing their apiVersion and kind and optionally the namespace and label selector\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resources (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resources (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to retrieve the namespaced resources from (ignored in case of cluster scoped resources). If not provided, will list resources from all namespaces",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind"
      ]
    },
    "name": "resources_list"
  }
]

```

--------------------------------------------------------------------------------
/pkg/mcp/testdata/toolsets-full-tools-openshift.json:
--------------------------------------------------------------------------------

```json
[
  {
    "annotations": {
      "title": "Configuration: View",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get the current Kubernetes configuration content as a kubeconfig YAML",
    "inputSchema": {
      "type": "object",
      "properties": {
        "minified": {
          "description": "Return a minified version of the configuration. If set to true, keeps only the current-context and the relevant pieces of the configuration for that context. If set to false, all contexts, clusters, auth-infos, and users are returned in the configuration. (Optional, default true)",
          "type": "boolean"
        }
      }
    },
    "name": "configuration_view"
  },
  {
    "annotations": {
      "title": "Events: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes events in the current cluster from all namespaces",
    "inputSchema": {
      "type": "object",
      "properties": {
        "namespace": {
          "description": "Optional Namespace to retrieve the events from. If not provided, will list events from all namespaces",
          "type": "string"
        }
      }
    },
    "name": "events_list"
  },
  {
    "annotations": {
      "title": "Helm: Install",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Install a Helm chart in the current or provided namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "chart": {
          "description": "Chart reference to install (for example: stable/grafana, oci://ghcr.io/nginxinc/charts/nginx-ingress)",
          "type": "string"
        },
        "name": {
          "description": "Name of the Helm release (Optional, random name if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to install the Helm chart in (Optional, current namespace if not provided)",
          "type": "string"
        },
        "values": {
          "description": "Values to pass to the Helm chart (Optional)",
          "type": "object"
        }
      },
      "required": [
        "chart"
      ]
    },
    "name": "helm_install"
  },
  {
    "annotations": {
      "title": "Helm: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Helm releases in the current or provided namespace (or in all namespaces if specified)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "all_namespaces": {
          "description": "If true, lists all Helm releases in all namespaces ignoring the namespace argument (Optional)",
          "type": "boolean"
        },
        "namespace": {
          "description": "Namespace to list Helm releases from (Optional, all namespaces if not provided)",
          "type": "string"
        }
      }
    },
    "name": "helm_list"
  },
  {
    "annotations": {
      "title": "Helm: Uninstall",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Uninstall a Helm release in the current or provided namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {
          "description": "Name of the Helm release to uninstall",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to uninstall the Helm release from (Optional, current namespace if not provided)",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "helm_uninstall"
  },
  {
    "annotations": {
      "title": "Namespaces: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes namespaces in the current cluster",
    "inputSchema": {
      "type": "object"
    },
    "name": "namespaces_list"
  },
  {
    "annotations": {
      "title": "Node: Log",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get logs from a Kubernetes node (kubelet, kube-proxy, or other system logs). This accesses node logs through the Kubernetes API proxy to the kubelet",
    "inputSchema": {
      "type": "object",
      "properties": {
        "log_path": {
          "default": "kubelet.log",
          "description": "Path to the log file on the node (e.g. 'kubelet.log', 'kube-proxy.log'). Default is 'kubelet.log'",
          "type": "string"
        },
        "name": {
          "description": "Name of the node to get logs from",
          "type": "string"
        },
        "tail": {
          "default": 100,
          "description": "Number of lines to retrieve from the end of the logs (Optional, 0 means all logs)",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "nodes_log"
  },
  {
    "annotations": {
      "title": "Pods: Delete",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Delete a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {
          "description": "Name of the Pod to delete",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to delete the Pod from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_delete"
  },
  {
    "annotations": {
      "title": "Pods: Exec",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Execute a command in a Kubernetes Pod in the current or provided namespace with the provided name and command",
    "inputSchema": {
      "type": "object",
      "properties": {
        "command": {
          "description": "Command to execute in the Pod container. The first item is the command to be run, and the rest are the arguments to that command. Example: [\"ls\", \"-l\", \"/tmp\"]",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "container": {
          "description": "Name of the Pod container where the command will be executed (Optional)",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod where the command will be executed",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace of the Pod where the command will be executed",
          "type": "string"
        }
      },
      "required": [
        "name",
        "command"
      ]
    },
    "name": "pods_exec"
  },
  {
    "annotations": {
      "title": "Pods: Get",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {
          "description": "Name of the Pod",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pod from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_get"
  },
  {
    "annotations": {
      "title": "Pods: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes pods in the current cluster from all namespaces",
    "inputSchema": {
      "type": "object",
      "properties": {
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        }
      }
    },
    "name": "pods_list"
  },
  {
    "annotations": {
      "title": "Pods: List in Namespace",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes pods in the specified namespace in the current cluster",
    "inputSchema": {
      "type": "object",
      "properties": {
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to list pods from",
          "type": "string"
        }
      },
      "required": [
        "namespace"
      ]
    },
    "name": "pods_list_in_namespace"
  },
  {
    "annotations": {
      "title": "Pods: Log",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get the logs of a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "container": {
          "description": "Name of the Pod container to get the logs from (Optional)",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod to get the logs from",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pod logs from",
          "type": "string"
        },
        "previous": {
          "description": "Return previous terminated container logs (Optional)",
          "type": "boolean"
        },
        "tail": {
          "default": 100,
          "description": "Number of lines to retrieve from the end of the logs (Optional, default: 100)",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_log"
  },
  {
    "annotations": {
      "title": "Pods: Run",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Run a Kubernetes Pod in the current or provided namespace with the provided container image and optional name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "image": {
          "description": "Container Image to run in the Pod",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod (Optional, random name if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to run the Pod in",
          "type": "string"
        },
        "port": {
          "description": "TCP/IP port to expose from the Pod container (Optional, no port exposed if not provided)",
          "type": "number"
        }
      },
      "required": [
        "image"
      ]
    },
    "name": "pods_run"
  },
  {
    "annotations": {
      "title": "Pods: Top",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "List the resource consumption (CPU and memory) as recorded by the Kubernetes Metrics Server for the specified Kubernetes Pods in the all namespaces, the provided namespace, or the current namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "all_namespaces": {
          "default": true,
          "description": "If true, list the resource consumption for all Pods in all namespaces. If false, list the resource consumption for Pods in the provided namespace or the current namespace",
          "type": "boolean"
        },
        "label_selector": {
          "description": "Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label (Optional, only applicable when name is not provided)",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod to get the resource consumption from (Optional, all Pods in the namespace if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pods resource consumption from (Optional, current namespace if not provided and all_namespaces is false)",
          "type": "string"
        }
      }
    },
    "name": "pods_top"
  },
  {
    "annotations": {
      "title": "Projects: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the OpenShift projects in the current cluster",
    "inputSchema": {
      "type": "object"
    },
    "name": "projects_list"
  },
  {
    "annotations": {
      "title": "Resources: Create or Update",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Create or update a Kubernetes resource in the current cluster by providing a YAML or JSON representation of the resource\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress, route.openshift.io/v1 Route)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "resource": {
          "description": "A JSON or YAML containing a representation of the Kubernetes resource. Should include top-level fields such as apiVersion,kind,metadata, and spec",
          "type": "string"
        }
      },
      "required": [
        "resource"
      ]
    },
    "name": "resources_create_or_update"
  },
  {
    "annotations": {
      "title": "Resources: Delete",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Delete a Kubernetes resource in the current cluster by providing its apiVersion, kind, optionally the namespace, and its name\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress, route.openshift.io/v1 Route)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to delete the namespaced resource from (ignored in case of cluster scoped resources). If not provided, will delete resource from configured namespace",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_delete"
  },
  {
    "annotations": {
      "title": "Resources: Get",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get a Kubernetes resource in the current cluster by providing its apiVersion, kind, optionally the namespace, and its name\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress, route.openshift.io/v1 Route)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to retrieve the namespaced resource from (ignored in case of cluster scoped resources). If not provided, will get resource from configured namespace",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_get"
  },
  {
    "annotations": {
      "title": "Resources: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List Kubernetes resources and objects in the current cluster by providing their apiVersion and kind and optionally the namespace and label selector\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress, route.openshift.io/v1 Route)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resources (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resources (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to retrieve the namespaced resources from (ignored in case of cluster scoped resources). If not provided, will list resources from all namespaces",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind"
      ]
    },
    "name": "resources_list"
  }
]

```

--------------------------------------------------------------------------------
/pkg/mcp/testdata/toolsets-full-tools-multicluster.json:
--------------------------------------------------------------------------------

```json
[
  {
    "annotations": {
      "title": "Configuration: Contexts List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": false
    },
    "description": "List all available context names and associated server urls from the kubeconfig file",
    "inputSchema": {
      "type": "object"
    },
    "name": "configuration_contexts_list"
  },
  {
    "annotations": {
      "title": "Configuration: View",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get the current Kubernetes configuration content as a kubeconfig YAML",
    "inputSchema": {
      "type": "object",
      "properties": {
        "minified": {
          "description": "Return a minified version of the configuration. If set to true, keeps only the current-context and the relevant pieces of the configuration for that context. If set to false, all contexts, clusters, auth-infos, and users are returned in the configuration. (Optional, default true)",
          "type": "boolean"
        }
      }
    },
    "name": "configuration_view"
  },
  {
    "annotations": {
      "title": "Events: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes events in the current cluster from all namespaces",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to retrieve the events from. If not provided, will list events from all namespaces",
          "type": "string"
        }
      }
    },
    "name": "events_list"
  },
  {
    "annotations": {
      "title": "Helm: Install",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Install a Helm chart in the current or provided namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "chart": {
          "description": "Chart reference to install (for example: stable/grafana, oci://ghcr.io/nginxinc/charts/nginx-ingress)",
          "type": "string"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "name": {
          "description": "Name of the Helm release (Optional, random name if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to install the Helm chart in (Optional, current namespace if not provided)",
          "type": "string"
        },
        "values": {
          "description": "Values to pass to the Helm chart (Optional)",
          "type": "object"
        }
      },
      "required": [
        "chart"
      ]
    },
    "name": "helm_install"
  },
  {
    "annotations": {
      "title": "Helm: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Helm releases in the current or provided namespace (or in all namespaces if specified)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "all_namespaces": {
          "description": "If true, lists all Helm releases in all namespaces ignoring the namespace argument (Optional)",
          "type": "boolean"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to list Helm releases from (Optional, all namespaces if not provided)",
          "type": "string"
        }
      }
    },
    "name": "helm_list"
  },
  {
    "annotations": {
      "title": "Helm: Uninstall",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Uninstall a Helm release in the current or provided namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "name": {
          "description": "Name of the Helm release to uninstall",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to uninstall the Helm release from (Optional, current namespace if not provided)",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "helm_uninstall"
  },
  {
    "annotations": {
      "title": "Namespaces: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes namespaces in the current cluster",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        }
      }
    },
    "name": "namespaces_list"
  },
  {
    "annotations": {
      "title": "Node: Log",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get logs from a Kubernetes node (kubelet, kube-proxy, or other system logs). This accesses node logs through the Kubernetes API proxy to the kubelet",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "log_path": {
          "default": "kubelet.log",
          "description": "Path to the log file on the node (e.g. 'kubelet.log', 'kube-proxy.log'). Default is 'kubelet.log'",
          "type": "string"
        },
        "name": {
          "description": "Name of the node to get logs from",
          "type": "string"
        },
        "tail": {
          "default": 100,
          "description": "Number of lines to retrieve from the end of the logs (Optional, 0 means all logs)",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "nodes_log"
  },
  {
    "annotations": {
      "title": "Pods: Delete",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Delete a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod to delete",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to delete the Pod from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_delete"
  },
  {
    "annotations": {
      "title": "Pods: Exec",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Execute a command in a Kubernetes Pod in the current or provided namespace with the provided name and command",
    "inputSchema": {
      "type": "object",
      "properties": {
        "command": {
          "description": "Command to execute in the Pod container. The first item is the command to be run, and the rest are the arguments to that command. Example: [\"ls\", \"-l\", \"/tmp\"]",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "container": {
          "description": "Name of the Pod container where the command will be executed (Optional)",
          "type": "string"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod where the command will be executed",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace of the Pod where the command will be executed",
          "type": "string"
        }
      },
      "required": [
        "name",
        "command"
      ]
    },
    "name": "pods_exec"
  },
  {
    "annotations": {
      "title": "Pods: Get",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pod from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_get"
  },
  {
    "annotations": {
      "title": "Pods: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes pods in the current cluster from all namespaces",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        }
      }
    },
    "name": "pods_list"
  },
  {
    "annotations": {
      "title": "Pods: List in Namespace",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes pods in the specified namespace in the current cluster",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to list pods from",
          "type": "string"
        }
      },
      "required": [
        "namespace"
      ]
    },
    "name": "pods_list_in_namespace"
  },
  {
    "annotations": {
      "title": "Pods: Log",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get the logs of a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "container": {
          "description": "Name of the Pod container to get the logs from (Optional)",
          "type": "string"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod to get the logs from",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pod logs from",
          "type": "string"
        },
        "previous": {
          "description": "Return previous terminated container logs (Optional)",
          "type": "boolean"
        },
        "tail": {
          "default": 100,
          "description": "Number of lines to retrieve from the end of the logs (Optional, default: 100)",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_log"
  },
  {
    "annotations": {
      "title": "Pods: Run",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Run a Kubernetes Pod in the current or provided namespace with the provided container image and optional name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "image": {
          "description": "Container Image to run in the Pod",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod (Optional, random name if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to run the Pod in",
          "type": "string"
        },
        "port": {
          "description": "TCP/IP port to expose from the Pod container (Optional, no port exposed if not provided)",
          "type": "number"
        }
      },
      "required": [
        "image"
      ]
    },
    "name": "pods_run"
  },
  {
    "annotations": {
      "title": "Pods: Top",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "List the resource consumption (CPU and memory) as recorded by the Kubernetes Metrics Server for the specified Kubernetes Pods in the all namespaces, the provided namespace, or the current namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "all_namespaces": {
          "default": true,
          "description": "If true, list the resource consumption for all Pods in all namespaces. If false, list the resource consumption for Pods in the provided namespace or the current namespace",
          "type": "boolean"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "label_selector": {
          "description": "Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label (Optional, only applicable when name is not provided)",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod to get the resource consumption from (Optional, all Pods in the namespace if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pods resource consumption from (Optional, current namespace if not provided and all_namespaces is false)",
          "type": "string"
        }
      }
    },
    "name": "pods_top"
  },
  {
    "annotations": {
      "title": "Resources: Create or Update",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Create or update a Kubernetes resource in the current cluster by providing a YAML or JSON representation of the resource\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "resource": {
          "description": "A JSON or YAML containing a representation of the Kubernetes resource. Should include top-level fields such as apiVersion,kind,metadata, and spec",
          "type": "string"
        }
      },
      "required": [
        "resource"
      ]
    },
    "name": "resources_create_or_update"
  },
  {
    "annotations": {
      "title": "Resources: Delete",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Delete a Kubernetes resource in the current cluster by providing its apiVersion, kind, optionally the namespace, and its name\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to delete the namespaced resource from (ignored in case of cluster scoped resources). If not provided, will delete resource from configured namespace",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_delete"
  },
  {
    "annotations": {
      "title": "Resources: Get",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get a Kubernetes resource in the current cluster by providing its apiVersion, kind, optionally the namespace, and its name\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to retrieve the namespaced resource from (ignored in case of cluster scoped resources). If not provided, will get resource from configured namespace",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_get"
  },
  {
    "annotations": {
      "title": "Resources: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List Kubernetes resources and objects in the current cluster by providing their apiVersion and kind and optionally the namespace and label selector\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resources (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resources (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to retrieve the namespaced resources from (ignored in case of cluster scoped resources). If not provided, will list resources from all namespaces",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind"
      ]
    },
    "name": "resources_list"
  }
]

```

--------------------------------------------------------------------------------
/pkg/mcp/testdata/toolsets-full-tools-multicluster-enum.json:
--------------------------------------------------------------------------------

```json
[
  {
    "annotations": {
      "title": "Configuration: Contexts List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": false
    },
    "description": "List all available context names and associated server urls from the kubeconfig file",
    "inputSchema": {
      "type": "object"
    },
    "name": "configuration_contexts_list"
  },
  {
    "annotations": {
      "title": "Configuration: View",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get the current Kubernetes configuration content as a kubeconfig YAML",
    "inputSchema": {
      "type": "object",
      "properties": {
        "minified": {
          "description": "Return a minified version of the configuration. If set to true, keeps only the current-context and the relevant pieces of the configuration for that context. If set to false, all contexts, clusters, auth-infos, and users are returned in the configuration. (Optional, default true)",
          "type": "boolean"
        }
      }
    },
    "name": "configuration_view"
  },
  {
    "annotations": {
      "title": "Events: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes events in the current cluster from all namespaces",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to retrieve the events from. If not provided, will list events from all namespaces",
          "type": "string"
        }
      }
    },
    "name": "events_list"
  },
  {
    "annotations": {
      "title": "Helm: Install",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Install a Helm chart in the current or provided namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "chart": {
          "description": "Chart reference to install (for example: stable/grafana, oci://ghcr.io/nginxinc/charts/nginx-ingress)",
          "type": "string"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "name": {
          "description": "Name of the Helm release (Optional, random name if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to install the Helm chart in (Optional, current namespace if not provided)",
          "type": "string"
        },
        "values": {
          "description": "Values to pass to the Helm chart (Optional)",
          "type": "object"
        }
      },
      "required": [
        "chart"
      ]
    },
    "name": "helm_install"
  },
  {
    "annotations": {
      "title": "Helm: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Helm releases in the current or provided namespace (or in all namespaces if specified)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "all_namespaces": {
          "description": "If true, lists all Helm releases in all namespaces ignoring the namespace argument (Optional)",
          "type": "boolean"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to list Helm releases from (Optional, all namespaces if not provided)",
          "type": "string"
        }
      }
    },
    "name": "helm_list"
  },
  {
    "annotations": {
      "title": "Helm: Uninstall",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Uninstall a Helm release in the current or provided namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "name": {
          "description": "Name of the Helm release to uninstall",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to uninstall the Helm release from (Optional, current namespace if not provided)",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "helm_uninstall"
  },
  {
    "annotations": {
      "title": "Namespaces: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes namespaces in the current cluster",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        }
      }
    },
    "name": "namespaces_list"
  },
  {
    "annotations": {
      "title": "Node: Log",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get logs from a Kubernetes node (kubelet, kube-proxy, or other system logs). This accesses node logs through the Kubernetes API proxy to the kubelet",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "log_path": {
          "default": "kubelet.log",
          "description": "Path to the log file on the node (e.g. 'kubelet.log', 'kube-proxy.log'). Default is 'kubelet.log'",
          "type": "string"
        },
        "name": {
          "description": "Name of the node to get logs from",
          "type": "string"
        },
        "tail": {
          "default": 100,
          "description": "Number of lines to retrieve from the end of the logs (Optional, 0 means all logs)",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "nodes_log"
  },
  {
    "annotations": {
      "title": "Pods: Delete",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Delete a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod to delete",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to delete the Pod from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_delete"
  },
  {
    "annotations": {
      "title": "Pods: Exec",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Execute a command in a Kubernetes Pod in the current or provided namespace with the provided name and command",
    "inputSchema": {
      "type": "object",
      "properties": {
        "command": {
          "description": "Command to execute in the Pod container. The first item is the command to be run, and the rest are the arguments to that command. Example: [\"ls\", \"-l\", \"/tmp\"]",
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        "container": {
          "description": "Name of the Pod container where the command will be executed (Optional)",
          "type": "string"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod where the command will be executed",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace of the Pod where the command will be executed",
          "type": "string"
        }
      },
      "required": [
        "name",
        "command"
      ]
    },
    "name": "pods_exec"
  },
  {
    "annotations": {
      "title": "Pods: Get",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pod from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_get"
  },
  {
    "annotations": {
      "title": "Pods: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes pods in the current cluster from all namespaces",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        }
      }
    },
    "name": "pods_list"
  },
  {
    "annotations": {
      "title": "Pods: List in Namespace",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List all the Kubernetes pods in the specified namespace in the current cluster",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to list pods from",
          "type": "string"
        }
      },
      "required": [
        "namespace"
      ]
    },
    "name": "pods_list_in_namespace"
  },
  {
    "annotations": {
      "title": "Pods: Log",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get the logs of a Kubernetes Pod in the current or provided namespace with the provided name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "container": {
          "description": "Name of the Pod container to get the logs from (Optional)",
          "type": "string"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod to get the logs from",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pod logs from",
          "type": "string"
        },
        "previous": {
          "description": "Return previous terminated container logs (Optional)",
          "type": "boolean"
        },
        "tail": {
          "default": 100,
          "description": "Number of lines to retrieve from the end of the logs (Optional, default: 100)",
          "minimum": 0,
          "type": "integer"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "pods_log"
  },
  {
    "annotations": {
      "title": "Pods: Run",
      "readOnlyHint": false,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Run a Kubernetes Pod in the current or provided namespace with the provided container image and optional name",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "image": {
          "description": "Container Image to run in the Pod",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod (Optional, random name if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to run the Pod in",
          "type": "string"
        },
        "port": {
          "description": "TCP/IP port to expose from the Pod container (Optional, no port exposed if not provided)",
          "type": "number"
        }
      },
      "required": [
        "image"
      ]
    },
    "name": "pods_run"
  },
  {
    "annotations": {
      "title": "Pods: Top",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "List the resource consumption (CPU and memory) as recorded by the Kubernetes Metrics Server for the specified Kubernetes Pods in the all namespaces, the provided namespace, or the current namespace",
    "inputSchema": {
      "type": "object",
      "properties": {
        "all_namespaces": {
          "default": true,
          "description": "If true, list the resource consumption for all Pods in all namespaces. If false, list the resource consumption for Pods in the provided namespace or the current namespace",
          "type": "boolean"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "label_selector": {
          "description": "Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label (Optional, only applicable when name is not provided)",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "name": {
          "description": "Name of the Pod to get the resource consumption from (Optional, all Pods in the namespace if not provided)",
          "type": "string"
        },
        "namespace": {
          "description": "Namespace to get the Pods resource consumption from (Optional, current namespace if not provided and all_namespaces is false)",
          "type": "string"
        }
      }
    },
    "name": "pods_top"
  },
  {
    "annotations": {
      "title": "Resources: Create or Update",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Create or update a Kubernetes resource in the current cluster by providing a YAML or JSON representation of the resource\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "resource": {
          "description": "A JSON or YAML containing a representation of the Kubernetes resource. Should include top-level fields such as apiVersion,kind,metadata, and spec",
          "type": "string"
        }
      },
      "required": [
        "resource"
      ]
    },
    "name": "resources_create_or_update"
  },
  {
    "annotations": {
      "title": "Resources: Delete",
      "readOnlyHint": false,
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Delete a Kubernetes resource in the current cluster by providing its apiVersion, kind, optionally the namespace, and its name\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to delete the namespaced resource from (ignored in case of cluster scoped resources). If not provided, will delete resource from configured namespace",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_delete"
  },
  {
    "annotations": {
      "title": "Resources: Get",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "Get a Kubernetes resource in the current cluster by providing its apiVersion, kind, optionally the namespace, and its name\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to retrieve the namespaced resource from (ignored in case of cluster scoped resources). If not provided, will get resource from configured namespace",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_get"
  },
  {
    "annotations": {
      "title": "Resources: List",
      "readOnlyHint": true,
      "destructiveHint": false,
      "idempotentHint": false,
      "openWorldHint": true
    },
    "description": "List Kubernetes resources and objects in the current cluster by providing their apiVersion and kind and optionally the namespace and label selector\n(common apiVersion and kind include: v1 Pod, v1 Service, v1 Node, apps/v1 Deployment, networking.k8s.io/v1 Ingress)",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resources (examples of valid apiVersion are: v1, apps/v1, networking.k8s.io/v1)",
          "type": "string"
        },
        "context": {
          "description": "Optional parameter selecting which context to run the tool in. Defaults to fake-context if not set",
          "enum": [
            "extra-cluster",
            "fake-context"
          ],
          "type": "string"
        },
        "kind": {
          "description": "kind of the resources (examples of valid kind are: Pod, Service, Deployment, Ingress)",
          "type": "string"
        },
        "labelSelector": {
          "description": "Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label",
          "pattern": "([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to retrieve the namespaced resources from (ignored in case of cluster scoped resources). If not provided, will list resources from all namespaces",
          "type": "string"
        }
      },
      "required": [
        "apiVersion",
        "kind"
      ]
    },
    "name": "resources_list"
  }
]

```
Page 3/4FirstPrevNextLast