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

# Directory Structure

```
├── .github
│   ├── dependabot.yml
│   └── workflows
│       ├── build.yaml
│       ├── gevals.yaml
│       ├── release-helm.yaml
│       ├── release-image.yml
│       └── release.yaml
├── .gitignore
├── AGENTS.md
├── build
│   ├── gevals.mk
│   ├── helm.mk
│   ├── keycloak.mk
│   ├── kind.mk
│   ├── node.mk
│   ├── python.mk
│   └── tools.mk
├── charts
│   └── kubernetes-mcp-server
│       ├── .helmignore
│       ├── Chart.yaml
│       ├── README.md
│       ├── README.md.gotmpl
│       ├── templates
│       │   ├── _helpers.tpl
│       │   ├── configmap.yaml
│       │   ├── deployment.yaml
│       │   ├── ingress.yaml
│       │   ├── service.yaml
│       │   └── serviceaccount.yaml
│       └── values.yaml
├── 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
│   ├── GETTING_STARTED_CLAUDE_CODE.md
│   ├── GETTING_STARTED_KUBERNETES.md
│   ├── images
│   │   ├── keycloak-login-page.png
│   │   ├── keycloak-mcp-inspector-connect.png
│   │   ├── keycloak-mcp-inspector-results.png
│   │   ├── kubernetes-mcp-server-github-copilot.jpg
│   │   └── vibe-coding.jpg
│   ├── KEYCLOAK_OIDC_SETUP.md
│   ├── KIALI.md
│   ├── PROMPTS.md
│   └── README.md
├── evals
│   ├── claude-code
│   │   ├── agent.yaml
│   │   ├── eval-inline.yaml
│   │   └── eval.yaml
│   ├── mcp-config.yaml
│   ├── openai-agent
│   │   ├── agent.yaml
│   │   ├── eval-inline.yaml
│   │   └── eval.yaml
│   ├── README.md
│   └── tasks
│       ├── create-canary-deployment
│       │   ├── artifacts
│       │   │   ├── deployment-v1.yaml
│       │   │   └── service.yaml
│       │   ├── cleanup.sh
│       │   ├── create-canary-deployment.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── create-network-policy
│       │   ├── artifacts
│       │   │   └── desired-policy.yaml
│       │   ├── cleanup.sh
│       │   ├── create-network-policy.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── create-pod
│       │   ├── cleanup.sh
│       │   ├── create-pod.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── create-pod-mount-configmaps
│       │   ├── cleanup.sh
│       │   ├── create-pod-mount-configmaps.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── create-pod-resources-limits
│       │   ├── cleanup.sh
│       │   ├── create-pod-resources-limits.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── create-simple-rbac
│       │   ├── cleanup.sh
│       │   ├── create-simple-rbac.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── debug-app-logs
│       │   ├── artifacts
│       │   │   ├── calc-app-pod.yaml
│       │   │   └── calc-app.py
│       │   ├── cleanup.sh
│       │   ├── debug-app-logs.yaml
│       │   └── setup.sh
│       ├── deployment-traffic-switch
│       │   ├── artifacts
│       │   │   ├── blue-deployment.yaml
│       │   │   ├── green-deployment.yaml
│       │   │   └── service.yaml
│       │   ├── cleanup.sh
│       │   ├── deployment-traffix-switch.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── fix-crashloop
│       │   ├── cleanup.sh
│       │   ├── fix-crashloop.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── fix-image-pull
│       │   ├── cleanup.sh
│       │   ├── fix-image-pull.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── fix-pending-pod
│       │   ├── artifacts
│       │   │   ├── homepage-pod.yaml
│       │   │   └── homepage-pvc.yaml
│       │   ├── cleanup.sh
│       │   ├── fix-pending-pod.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── fix-probes
│       │   ├── cleanup.sh
│       │   ├── fix-probes.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── fix-rbac-wrong-resource
│       │   ├── cleanup.sh
│       │   ├── fix-rbac-wrong-resource.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── fix-service-routing
│       │   ├── cleanup.sh
│       │   ├── fix-service-routing.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── fix-service-with-no-endpoints
│       │   ├── artifacts
│       │   │   ├── deployment.yaml
│       │   │   └── service.yaml
│       │   ├── cleanup.sh
│       │   ├── fix-service-with-no-endpoints.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── horizontal-pod-autoscaler
│       │   ├── cleanup.sh
│       │   ├── horizontal-pod-autoscaler.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── list-images-for-pods
│       │   ├── artifacts
│       │   │   └── manifest.yaml
│       │   ├── cleanup.sh
│       │   ├── list-images-for-pods.yaml
│       │   └── setup.sh
│       ├── multi-container-pod-communication
│       │   ├── cleanup.sh
│       │   ├── multi-container-pod-communication.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── resize-pvc
│       │   ├── artifacts
│       │   │   ├── storage-pod.yaml
│       │   │   └── storage-pvc.yaml
│       │   ├── cleanup.sh
│       │   ├── resize-pvc.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── rolling-update-deployment
│       │   ├── cleanup.sh
│       │   ├── rolling-update-deployment.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── scale-deployment
│       │   ├── cleanup.sh
│       │   ├── scale-deployment.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── scale-down-deployment
│       │   ├── cleanup.sh
│       │   ├── scale-down-deployment.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       ├── setup-dev-cluster
│       │   ├── cleanup.sh
│       │   ├── setup-dev-cluster.md
│       │   ├── setup-dev-cluster.yaml
│       │   ├── setup.sh
│       │   └── verify.sh
│       └── statefulset-lifecycle
│           ├── cleanup.sh
│           ├── setup.sh
│           ├── statefulset-lifecycle.yaml
│           └── verify.sh
├── go.mod
├── go.sum
├── hack
│   └── generate-placeholder-ca.sh
├── internal
│   ├── test
│   │   ├── env.go
│   │   ├── kubernetes.go
│   │   ├── mcp.go
│   │   ├── mock_server.go
│   │   ├── test.go
│   │   ├── unstructured_test.go
│   │   └── unstructured.go
│   └── tools
│       └── update-readme
│           └── main.go
├── LICENSE
├── Makefile
├── npm
│   └── kubernetes-mcp-server
│       └── bin
│           └── index.js
├── pkg
│   ├── api
│   │   ├── config.go
│   │   ├── imports_test.go
│   │   ├── kubernetes.go
│   │   ├── params_test.go
│   │   ├── params.go
│   │   ├── prompt_serialization_test.go
│   │   ├── prompts_test.go
│   │   ├── prompts.go
│   │   ├── toolsets_test.go
│   │   └── toolsets.go
│   ├── config
│   │   ├── config_default_overrides.go
│   │   ├── config_default.go
│   │   ├── config_test.go
│   │   ├── config.go
│   │   ├── context.go
│   │   ├── extended.go
│   │   ├── provider_config_test.go
│   │   ├── provider_config.go
│   │   ├── toolset_config_test.go
│   │   └── toolset_config.go
│   ├── helm
│   │   └── helm.go
│   ├── http
│   │   ├── authorization_test.go
│   │   ├── authorization.go
│   │   ├── http_authorization_test.go
│   │   ├── http_mcp_test.go
│   │   ├── http_test.go
│   │   ├── http.go
│   │   ├── middleware.go
│   │   ├── sts_test.go
│   │   ├── sts.go
│   │   └── wellknown.go
│   ├── kiali
│   │   ├── config_test.go
│   │   ├── config.go
│   │   ├── defaults.go
│   │   ├── endpoints.go
│   │   ├── get_mesh_graph.go
│   │   ├── graph.go
│   │   ├── health_calculation.go
│   │   ├── health.go
│   │   ├── istio.go
│   │   ├── kiali_test.go
│   │   ├── kiali.go
│   │   ├── logs.go
│   │   ├── mesh.go
│   │   ├── namespaces.go
│   │   ├── services.go
│   │   ├── traces.go
│   │   ├── types.go
│   │   ├── validations.go
│   │   └── workloads.go
│   ├── kubernetes
│   │   ├── accesscontrol_round_tripper_test.go
│   │   ├── accesscontrol_round_tripper.go
│   │   ├── common_test.go
│   │   ├── configuration.go
│   │   ├── core.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_watch_test.go
│   │   ├── provider.go
│   │   ├── resources.go
│   │   ├── token.go
│   │   └── watcher
│   │       ├── cluster_test.go
│   │       ├── cluster.go
│   │       ├── kubeconfig_test.go
│   │       ├── kubeconfig.go
│   │       └── watcher.go
│   ├── kubernetes-mcp-server
│   │   └── cmd
│   │       ├── root_sighup_test.go
│   │       ├── root_test.go
│   │       ├── root.go
│   │       └── testdata
│   │           ├── empty-config.toml
│   │           └── valid-config.toml
│   ├── kubevirt
│   │   ├── resources_test.go
│   │   ├── resources.go
│   │   ├── testing
│   │   │   └── helpers.go
│   │   ├── vm_test.go
│   │   └── vm.go
│   ├── mcp
│   │   ├── common_crd_test.go
│   │   ├── common_test.go
│   │   ├── configuration_test.go
│   │   ├── events_test.go
│   │   ├── gosdk.go
│   │   ├── helm_test.go
│   │   ├── kiali_test.go
│   │   ├── kubevirt_test.go
│   │   ├── mcp_middleware_test.go
│   │   ├── mcp_prompts_test.go
│   │   ├── mcp_reload_test.go
│   │   ├── mcp_test.go
│   │   ├── mcp_tools_test.go
│   │   ├── mcp_toolset_prompts_test.go
│   │   ├── mcp_watch_test.go
│   │   ├── mcp.go
│   │   ├── middleware.go
│   │   ├── modules.go
│   │   ├── namespaces_test.go
│   │   ├── nodes_test.go
│   │   ├── nodes_top_test.go
│   │   ├── pods_exec_test.go
│   │   ├── pods_run_test.go
│   │   ├── pods_test.go
│   │   ├── pods_top_test.go
│   │   ├── prompts_config_test.go
│   │   ├── prompts_gosdk_test.go
│   │   ├── prompts_gosdk.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
│   │   │   ├── toolsets-kiali-tools.json
│   │   │   └── toolsets-kubevirt-tools.json
│   │   ├── tool_filter_test.go
│   │   ├── tool_filter.go
│   │   ├── tool_mutator_test.go
│   │   ├── tool_mutator.go
│   │   └── toolsets_test.go
│   ├── openshift
│   │   └── openshift.go
│   ├── output
│   │   ├── output_test.go
│   │   └── output.go
│   ├── prompts
│   │   ├── prompts_test.go
│   │   └── prompts.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
│   │   ├── kiali
│   │   │   ├── internal
│   │   │   │   └── defaults
│   │   │   │       ├── defaults_override.go
│   │   │   │       └── defaults.go
│   │   │   ├── tools
│   │   │   │   ├── get_mesh_graph.go
│   │   │   │   ├── get_metrics.go
│   │   │   │   ├── get_resource_details.go
│   │   │   │   ├── get_traces.go
│   │   │   │   ├── helpers_test.go
│   │   │   │   ├── helpers.go
│   │   │   │   ├── logs.go
│   │   │   │   └── manage_istio_config.go
│   │   │   └── toolset.go
│   │   ├── kubevirt
│   │   │   ├── toolset.go
│   │   │   └── vm
│   │   │       ├── create
│   │   │       │   ├── tool.go
│   │   │       │   └── vm.yaml.tmpl
│   │   │       └── lifecycle
│   │   │           └── tool.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/testdata/toolsets-core-tools.json:
--------------------------------------------------------------------------------

```json
[
  {
    "annotations": {
      "title": "Events: List",
      "readOnlyHint": true,
      "destructiveHint": 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,
      "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,
      "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": {
        "name": {
          "description": "Name of the node to get logs from",
          "type": "string"
        },
        "query": {
          "description": "query specifies services(s) or files from which to return logs (required). Example: \"kubelet\" to fetch kubelet logs, \"/\u003clog-file-name\u003e\" to fetch a specific log file from the node (e.g., \"/var/log/kubelet.log\" or \"/var/log/kube-proxy.log\")",
          "type": "string"
        },
        "tailLines": {
          "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",
        "query"
      ]
    },
    "name": "nodes_log"
  },
  {
    "annotations": {
      "title": "Node: Stats Summary",
      "readOnlyHint": true,
      "destructiveHint": false,
      "openWorldHint": true
    },
    "description": "Get detailed resource usage statistics from a Kubernetes node via the kubelet's Summary API. Provides comprehensive metrics including CPU, memory, filesystem, and network usage at the node, pod, and container levels. On systems with cgroup v2 and kernel 4.20+, also includes PSI (Pressure Stall Information) metrics that show resource pressure for CPU, memory, and I/O. See https://kubernetes.io/docs/reference/instrumentation/understand-psi-metrics/ for details on PSI metrics",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {
          "description": "Name of the node to get stats from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "nodes_stats_summary"
  },
  {
    "annotations": {
      "title": "Nodes: 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 Nodes or all nodes in the cluster",
    "inputSchema": {
      "type": "object",
      "properties": {
        "label_selector": {
          "description": "Kubernetes label selector (e.g. 'node-role.kubernetes.io/worker=') to filter nodes 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 Node to get the resource consumption from (Optional, all Nodes if not provided)",
          "type": "string"
        }
      }
    },
    "name": "nodes_top"
  },
  {
    "annotations": {
      "title": "Pods: Delete",
      "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",
      "destructiveHint": true,
      "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,
      "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,
      "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,
      "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,
      "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",
      "destructiveHint": 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",
      "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",
      "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,
      "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,
      "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"
  },
  {
    "annotations": {
      "title": "Resources: Scale",
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Get or update the scale of a Kubernetes resource in the current cluster by providing its apiVersion, kind, name, and optionally the namespace. If the scale is set in the tool call, the scale will be updated to that value. Always returns the current scale of the resource",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are apps/v1)",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: StatefulSet, Deployment)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to get/update the namespaced resource scale from (ignored in case of cluster scoped resources). If not provided, will get/update resource scale from configured namespace",
          "type": "string"
        },
        "scale": {
          "description": "Optional scale to update the resources scale to. If not provided, will return the current scale of the resource, and not update it",
          "type": "integer"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_scale"
  }
]

```

--------------------------------------------------------------------------------
/pkg/http/http_authorization_test.go:
--------------------------------------------------------------------------------

```go
package http

import (
	"bytes"
	"flag"
	"fmt"
	"net/http"
	"strconv"
	"strings"
	"testing"
	"time"

	"github.com/containers/kubernetes-mcp-server/internal/test"
	"github.com/coreos/go-oidc/v3/oidc"
	"github.com/coreos/go-oidc/v3/oidc/oidctest"
	"github.com/mark3labs/mcp-go/client"
	"github.com/mark3labs/mcp-go/client/transport"
	"github.com/stretchr/testify/suite"
	"k8s.io/klog/v2"
	"k8s.io/klog/v2/textlogger"
)

type AuthorizationSuite struct {
	BaseHttpSuite
	mcpClient *client.Client
	klogState klog.State
	logBuffer bytes.Buffer
}

func (s *AuthorizationSuite) SetupTest() {
	s.BaseHttpSuite.SetupTest()

	// Capture logs
	s.logBuffer.Reset()
	s.klogState = klog.CaptureState()
	flags := flag.NewFlagSet("test", flag.ContinueOnError)
	klog.InitFlags(flags)
	_ = flags.Set("v", "5")
	klog.SetLogger(textlogger.NewLogger(textlogger.NewConfig(textlogger.Verbosity(5), textlogger.Output(&s.logBuffer))))

	// Default Auth settings (overridden in tests as needed)
	s.OidcProvider = nil
	s.StaticConfig.RequireOAuth = true
	s.StaticConfig.ValidateToken = true
	s.StaticConfig.OAuthAudience = ""
	s.StaticConfig.StsClientId = ""
	s.StaticConfig.StsClientSecret = ""
	s.StaticConfig.StsAudience = ""
	s.StaticConfig.StsScopes = []string{}
}

func (s *AuthorizationSuite) TearDownTest() {
	s.BaseHttpSuite.TearDownTest()
	s.klogState.Restore()

	if s.mcpClient != nil {
		_ = s.mcpClient.Close()
	}
}

func (s *AuthorizationSuite) StartClient(options ...transport.StreamableHTTPCOption) {
	var err error
	s.mcpClient, err = client.NewStreamableHttpClient(fmt.Sprintf("http://127.0.0.1:%s/mcp", s.StaticConfig.Port), options...)
	s.Require().NoError(err, "Expected no error creating Streamable HTTP MCP client")
	err = s.mcpClient.Start(s.T().Context())
	s.Require().NoError(err, "Expected no error starting Streamable HTTP MCP client")
}

func (s *AuthorizationSuite) HttpGet(authHeader string) *http.Response {
	req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://127.0.0.1:%s/mcp", s.StaticConfig.Port), nil)
	s.Require().NoError(err, "Failed to create request")
	if authHeader != "" {
		req.Header.Set("Authorization", authHeader)
	}
	resp, err := http.DefaultClient.Do(req)
	s.Require().NoError(err, "Failed to get protected endpoint")
	return resp
}

func (s *AuthorizationSuite) TestAuthorizationUnauthorizedMissingHeader() {
	// Missing Authorization header
	s.StartServer()
	s.StartClient()

	s.Run("Initialize returns error for MISSING Authorization header", func() {
		_, err := s.mcpClient.Initialize(s.T().Context(), test.McpInitRequest())
		s.Require().Error(err, "Expected error creating initial request")
		s.ErrorContains(err, "transport error: request failed with status 401: Unauthorized: Bearer token required")
	})

	s.Run("Protected resource with MISSING Authorization header", func() {
		resp := s.HttpGet("")
		s.T().Cleanup(func() { _ = resp.Body.Close })

		s.Run("returns 401 - Unauthorized status", func() {
			s.Equal(401, resp.StatusCode, "Expected HTTP 401 for MISSING Authorization header")
		})
		s.Run("returns WWW-Authenticate header", func() {
			authHeader := resp.Header.Get("WWW-Authenticate")
			expected := `Bearer realm="Kubernetes MCP Server", error="missing_token"`
			s.Equal(expected, authHeader, "Expected WWW-Authenticate header to match")
		})
		s.Run("logs error", func() {
			s.Contains(s.logBuffer.String(), "Authentication failed - missing or invalid bearer token", "Expected log entry for missing or invalid bearer token")
		})
	})
}

func (s *AuthorizationSuite) TestAuthorizationUnauthorizedHeaderIncompatible() {
	// Authorization header without Bearer prefix
	s.StartServer()
	s.StartClient(transport.WithHTTPHeaders(map[string]string{
		"Authorization": "Basic YWxhZGRpbjpvcGVuc2VzYW1l",
	}))

	s.Run("Initialize returns error for INCOMPATIBLE Authorization header", func() {
		_, err := s.mcpClient.Initialize(s.T().Context(), test.McpInitRequest())
		s.Require().Error(err, "Expected error creating initial request")
		s.ErrorContains(err, "transport error: request failed with status 401: Unauthorized: Bearer token required")
	})

	s.Run("Protected resource with INCOMPATIBLE Authorization header", func() {
		resp := s.HttpGet("Basic YWxhZGRpbjpvcGVuc2VzYW1l")
		s.T().Cleanup(func() { _ = resp.Body.Close })

		s.Run("returns 401 - Unauthorized status", func() {
			s.Equal(401, resp.StatusCode, "Expected HTTP 401 for INCOMPATIBLE Authorization header")
		})
		s.Run("returns WWW-Authenticate header", func() {
			authHeader := resp.Header.Get("WWW-Authenticate")
			expected := `Bearer realm="Kubernetes MCP Server", error="missing_token"`
			s.Equal(expected, authHeader, "Expected WWW-Authenticate header to match")
		})
		s.Run("logs error", func() {
			s.Contains(s.logBuffer.String(), "Authentication failed - missing or invalid bearer token", "Expected log entry for missing or invalid bearer token")
		})
	})
}

func (s *AuthorizationSuite) TestAuthorizationUnauthorizedHeaderInvalid() {
	// Invalid Authorization header
	s.StartServer()
	s.StartClient(transport.WithHTTPHeaders(map[string]string{
		"Authorization": "Bearer " + strings.ReplaceAll(tokenBasicNotExpired, ".", ".invalid"),
	}))

	s.Run("Initialize returns error for INVALID Authorization header", func() {
		_, err := s.mcpClient.Initialize(s.T().Context(), test.McpInitRequest())
		s.Require().Error(err, "Expected error creating initial request")
		s.ErrorContains(err, "transport error: request failed with status 401: Unauthorized: Invalid token")
	})

	s.Run("Protected resource with INVALID Authorization header", func() {
		resp := s.HttpGet("Bearer " + strings.ReplaceAll(tokenBasicNotExpired, ".", ".invalid"))
		s.T().Cleanup(func() { _ = resp.Body.Close })

		s.Run("returns 401 - Unauthorized status", func() {
			s.Equal(401, resp.StatusCode, "Expected HTTP 401 for INVALID Authorization header")
		})
		s.Run("returns WWW-Authenticate header", func() {
			authHeader := resp.Header.Get("WWW-Authenticate")
			expected := `Bearer realm="Kubernetes MCP Server", error="invalid_token"`
			s.Equal(expected, authHeader, "Expected WWW-Authenticate header to match")
		})
		s.Run("logs error", func() {
			s.Contains(s.logBuffer.String(), "Authentication failed - JWT validation error", "Expected log entry for JWT validation error")
			s.Contains(s.logBuffer.String(), "error: failed to parse JWT token: illegal base64 data", "Expected log entry for JWT validation error details")
		})
	})
}

func (s *AuthorizationSuite) TestAuthorizationUnauthorizedHeaderExpired() {
	// Expired Authorization Bearer token
	s.StartServer()
	s.StartClient(transport.WithHTTPHeaders(map[string]string{
		"Authorization": "Bearer " + tokenBasicExpired,
	}))

	s.Run("Initialize returns error for EXPIRED Authorization header", func() {
		_, err := s.mcpClient.Initialize(s.T().Context(), test.McpInitRequest())
		s.Require().Error(err, "Expected error creating initial request")
		s.ErrorContains(err, "transport error: request failed with status 401: Unauthorized: Invalid token")
	})

	s.Run("Protected resource with EXPIRED Authorization header", func() {
		resp := s.HttpGet("Bearer " + tokenBasicExpired)
		s.T().Cleanup(func() { _ = resp.Body.Close })

		s.Run("returns 401 - Unauthorized status", func() {
			s.Equal(401, resp.StatusCode, "Expected HTTP 401 for EXPIRED Authorization header")
		})
		s.Run("returns WWW-Authenticate header", func() {
			authHeader := resp.Header.Get("WWW-Authenticate")
			expected := `Bearer realm="Kubernetes MCP Server", error="invalid_token"`
			s.Equal(expected, authHeader, "Expected WWW-Authenticate header to match")
		})
		s.Run("logs error", func() {
			s.Contains(s.logBuffer.String(), "Authentication failed - JWT validation error", "Expected log entry for JWT validation error")
			s.Contains(s.logBuffer.String(), "validation failed, token is expired (exp)", "Expected log entry for JWT validation error details")
		})
	})
}

func (s *AuthorizationSuite) TestAuthorizationUnauthorizedHeaderInvalidAudience() {
	// Invalid audience claim Bearer token
	s.StaticConfig.OAuthAudience = "expected-audience"
	s.StartServer()
	s.StartClient(transport.WithHTTPHeaders(map[string]string{
		"Authorization": "Bearer " + tokenBasicNotExpired,
	}))

	s.Run("Initialize returns error for INVALID AUDIENCE Authorization header", func() {
		_, err := s.mcpClient.Initialize(s.T().Context(), test.McpInitRequest())
		s.Require().Error(err, "Expected error creating initial request")
		s.ErrorContains(err, "transport error: request failed with status 401: Unauthorized: Invalid token")
	})

	s.Run("Protected resource with INVALID AUDIENCE Authorization header", func() {
		resp := s.HttpGet("Bearer " + tokenBasicNotExpired)
		s.T().Cleanup(func() { _ = resp.Body.Close })

		s.Run("returns 401 - Unauthorized status", func() {
			s.Equal(401, resp.StatusCode, "Expected HTTP 401 for INVALID AUDIENCE Authorization header")
		})
		s.Run("returns WWW-Authenticate header", func() {
			authHeader := resp.Header.Get("WWW-Authenticate")
			expected := `Bearer realm="Kubernetes MCP Server", audience="expected-audience", error="invalid_token"`
			s.Equal(expected, authHeader, "Expected WWW-Authenticate header to match")
		})
		s.Run("logs error", func() {
			s.Contains(s.logBuffer.String(), "Authentication failed - JWT validation error", "Expected log entry for JWT validation error")
			s.Contains(s.logBuffer.String(), "invalid audience claim (aud)", "Expected log entry for JWT validation error details")
		})
	})
}

func (s *AuthorizationSuite) TestAuthorizationUnauthorizedOidcValidation() {
	// Failed OIDC validation
	s.StaticConfig.OAuthAudience = "mcp-server"
	oidcTestServer := NewOidcTestServer(s.T())
	s.T().Cleanup(oidcTestServer.Close)
	s.OidcProvider = oidcTestServer.Provider
	s.StartServer()
	s.StartClient(transport.WithHTTPHeaders(map[string]string{
		"Authorization": "Bearer " + tokenBasicNotExpired,
	}))

	s.Run("Initialize returns error for INVALID OIDC Authorization header", func() {
		_, err := s.mcpClient.Initialize(s.T().Context(), test.McpInitRequest())
		s.Require().Error(err, "Expected error creating initial request")
		s.ErrorContains(err, "transport error: request failed with status 401: Unauthorized: Invalid token")
	})

	s.Run("Protected resource with INVALID OIDC Authorization header", func() {
		resp := s.HttpGet("Bearer " + tokenBasicNotExpired)
		s.T().Cleanup(func() { _ = resp.Body.Close })

		s.Run("returns 401 - Unauthorized status", func() {
			s.Equal(401, resp.StatusCode, "Expected HTTP 401 for INVALID OIDC Authorization header")
		})
		s.Run("returns WWW-Authenticate header", func() {
			authHeader := resp.Header.Get("WWW-Authenticate")
			expected := `Bearer realm="Kubernetes MCP Server", audience="mcp-server", error="invalid_token"`
			s.Equal(expected, authHeader, "Expected WWW-Authenticate header to match")
		})
		s.Run("logs error", func() {
			s.Contains(s.logBuffer.String(), "Authentication failed - JWT validation error", "Expected log entry for JWT validation error")
			s.Contains(s.logBuffer.String(), "OIDC token validation error: failed to verify signature", "Expected log entry for OIDC validation error details")
		})
	})
}

func (s *AuthorizationSuite) TestAuthorizationUnauthorizedKubernetesValidation() {
	// Failed Kubernetes TokenReview
	s.StaticConfig.OAuthAudience = "mcp-server"
	oidcTestServer := NewOidcTestServer(s.T())
	s.T().Cleanup(oidcTestServer.Close)
	rawClaims := `{
		"iss": "` + oidcTestServer.URL + `",
		"exp": ` + strconv.FormatInt(time.Now().Add(time.Hour).Unix(), 10) + `,
		"aud": "mcp-server"
	}`
	validOidcToken := oidctest.SignIDToken(oidcTestServer.PrivateKey, "test-oidc-key-id", oidc.RS256, rawClaims)
	s.OidcProvider = oidcTestServer.Provider
	s.StartServer()
	s.StartClient(transport.WithHTTPHeaders(map[string]string{
		"Authorization": "Bearer " + validOidcToken,
	}))

	s.Run("Initialize returns error for INVALID KUBERNETES Authorization header", func() {
		_, err := s.mcpClient.Initialize(s.T().Context(), test.McpInitRequest())
		s.Require().Error(err, "Expected error creating initial request")
		s.ErrorContains(err, "transport error: request failed with status 401: Unauthorized: Invalid token")
	})

	s.Run("Protected resource with INVALID KUBERNETES Authorization header", func() {
		resp := s.HttpGet("Bearer " + validOidcToken)
		s.T().Cleanup(func() { _ = resp.Body.Close })

		s.Run("returns 401 - Unauthorized status", func() {
			s.Equal(401, resp.StatusCode, "Expected HTTP 401 for INVALID KUBERNETES Authorization header")
		})
		s.Run("returns WWW-Authenticate header", func() {
			authHeader := resp.Header.Get("WWW-Authenticate")
			expected := `Bearer realm="Kubernetes MCP Server", audience="mcp-server", error="invalid_token"`
			s.Equal(expected, authHeader, "Expected WWW-Authenticate header to match")
		})
		s.Run("logs error", func() {
			s.Contains(s.logBuffer.String(), "Authentication failed - JWT validation error", "Expected log entry for JWT validation error")
			s.Contains(s.logBuffer.String(), "kubernetes API token validation error: failed to create token review", "Expected log entry for Kubernetes TokenReview error details")
		})
	})
}

func (s *AuthorizationSuite) TestAuthorizationRequireOAuthFalse() {
	s.StaticConfig.RequireOAuth = false
	s.StartServer()
	s.StartClient()

	s.Run("Initialize returns OK for MISSING Authorization header", func() {
		result, err := s.mcpClient.Initialize(s.T().Context(), test.McpInitRequest())
		s.Require().NoError(err, "Expected no error creating initial request")
		s.Require().NotNil(result, "Expected initial request to not be nil")
	})
}

func (s *AuthorizationSuite) TestAuthorizationRawToken() {
	s.MockServer.ResetHandlers()
	tokenReviewHandler := test.NewTokenReviewHandler()
	s.MockServer.Handle(tokenReviewHandler)

	cases := []struct {
		audience      string
		validateToken bool
	}{
		{"", false},           // No audience, no validation
		{"", true},            // No audience, validation enabled
		{"mcp-server", false}, // Audience set, no validation
		{"mcp-server", true},  // Audience set, validation enabled
	}
	for _, c := range cases {
		s.StaticConfig.OAuthAudience = c.audience
		s.StaticConfig.ValidateToken = c.validateToken
		s.logBuffer.Reset()
		s.StartServer()
		s.StartClient(transport.WithHTTPHeaders(map[string]string{
			"Authorization": "Bearer " + tokenBasicNotExpired,
		}))
		tokenReviewHandler.TokenReviewed = false

		s.Run(fmt.Sprintf("Protected resource with audience = '%s' and validate-token = '%t'", c.audience, c.validateToken), func() {
			s.Run("Initialize returns OK for VALID Authorization header", func() {
				result, err := s.mcpClient.Initialize(s.T().Context(), test.McpInitRequest())
				s.Require().NoError(err, "Expected no error creating initial request")
				s.Require().NotNil(result, "Expected initial request to not be nil")
			})

			s.Run("Performs token validation accordingly", func() {
				if tokenReviewHandler.TokenReviewed == true && !c.validateToken {
					s.Fail("Expected token review to be skipped when validate-token is false, but it was performed")
				}
				if tokenReviewHandler.TokenReviewed == false && c.validateToken {
					s.Fail("Expected token review to be performed when validate-token is true, but it was skipped")
				}
			})
		})
		_ = s.mcpClient.Close()
		s.mcpClient = nil
		s.StopServer()
		s.Require().NoError(s.WaitForShutdown())
	}
}

func (s *AuthorizationSuite) TestAuthorizationOidcToken() {
	s.MockServer.ResetHandlers()
	tokenReviewHandler := test.NewTokenReviewHandler()
	s.MockServer.Handle(tokenReviewHandler)

	oidcTestServer := NewOidcTestServer(s.T())
	s.T().Cleanup(oidcTestServer.Close)
	rawClaims := `{
		"iss": "` + oidcTestServer.URL + `",
		"exp": ` + strconv.FormatInt(time.Now().Add(time.Hour).Unix(), 10) + `,
		"aud": "mcp-server"
	}`
	validOidcToken := oidctest.SignIDToken(oidcTestServer.PrivateKey, "test-oidc-key-id", oidc.RS256, rawClaims)

	cases := []bool{false, true}
	for _, validateToken := range cases {
		s.OidcProvider = oidcTestServer.Provider
		s.StaticConfig.OAuthAudience = "mcp-server"
		s.StaticConfig.ValidateToken = validateToken
		s.StartServer()
		s.StartClient(transport.WithHTTPHeaders(map[string]string{
			"Authorization": "Bearer " + validOidcToken,
		}))
		tokenReviewHandler.TokenReviewed = false

		s.Run(fmt.Sprintf("Protected resource with validate-token = '%t'", validateToken), func() {
			s.Run("Initialize returns OK for VALID OIDC Authorization header", func() {
				result, err := s.mcpClient.Initialize(s.T().Context(), test.McpInitRequest())
				s.Require().NoError(err, "Expected no error creating initial request")
				s.Require().NotNil(result, "Expected initial request to not be nil")
			})

			s.Run("Performs token validation accordingly for VALID OIDC Authorization header", func() {
				if tokenReviewHandler.TokenReviewed == true && !validateToken {
					s.Fail("Expected token review to be skipped when validate-token is false, but it was performed")
				}
				if tokenReviewHandler.TokenReviewed == false && validateToken {
					s.Fail("Expected token review to be performed when validate-token is true, but it was skipped")
				}
			})
		})
		_ = s.mcpClient.Close()
		s.mcpClient = nil
		s.StopServer()
		s.Require().NoError(s.WaitForShutdown())
	}
}

func (s *AuthorizationSuite) TestAuthorizationOidcTokenExchange() {
	s.MockServer.ResetHandlers()
	tokenReviewHandler := test.NewTokenReviewHandler()
	s.MockServer.Handle(tokenReviewHandler)

	oidcTestServer := NewOidcTestServer(s.T())
	s.T().Cleanup(oidcTestServer.Close)
	rawClaims := `{
		"iss": "` + oidcTestServer.URL + `",
		"exp": ` + strconv.FormatInt(time.Now().Add(time.Hour).Unix(), 10) + `,
		"aud": "%s"
	}`
	validOidcClientToken := oidctest.SignIDToken(oidcTestServer.PrivateKey, "test-oidc-key-id", oidc.RS256,
		fmt.Sprintf(rawClaims, "mcp-server"))
	validOidcBackendToken := oidctest.SignIDToken(oidcTestServer.PrivateKey, "test-oidc-key-id", oidc.RS256,
		fmt.Sprintf(rawClaims, "backend-audience"))
	oidcTestServer.TokenEndpointHandler = func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintf(w, `{"access_token":"%s","token_type":"Bearer","expires_in":253402297199}`, validOidcBackendToken)
	}

	cases := []bool{false, true}
	for _, validateToken := range cases {
		s.OidcProvider = oidcTestServer.Provider
		s.StaticConfig.OAuthAudience = "mcp-server"
		s.StaticConfig.ValidateToken = validateToken
		s.StaticConfig.StsClientId = "test-sts-client-id"
		s.StaticConfig.StsClientSecret = "test-sts-client-secret"
		s.StaticConfig.StsAudience = "backend-audience"
		s.StaticConfig.StsScopes = []string{"backend-scope"}
		s.logBuffer.Reset()
		s.StartServer()
		s.StartClient(transport.WithHTTPHeaders(map[string]string{
			"Authorization": "Bearer " + validOidcClientToken,
		}))
		tokenReviewHandler.TokenReviewed = false

		s.Run(fmt.Sprintf("Protected resource with validate-token='%t'", validateToken), func() {
			s.Run("Initialize returns OK for VALID OIDC EXCHANGE Authorization header", func() {
				result, err := s.mcpClient.Initialize(s.T().Context(), test.McpInitRequest())
				s.Require().NoError(err, "Expected no error creating initial request")
				s.Require().NotNil(result, "Expected initial request to not be nil")
			})

			s.Run("Performs token validation accordingly for VALID OIDC EXCHANGE Authorization header", func() {
				if tokenReviewHandler.TokenReviewed == true && !validateToken {
					s.Fail("Expected token review to be skipped when validate-token is false, but it was performed")
				}
				if tokenReviewHandler.TokenReviewed == false && validateToken {
					s.Fail("Expected token review to be performed when validate-token is true, but it was skipped")
				}
			})
		})
		_ = s.mcpClient.Close()
		s.mcpClient = nil
		s.StopServer()
		s.Require().NoError(s.WaitForShutdown())
	}
}

func TestAuthorization(t *testing.T) {
	suite.Run(t, new(AuthorizationSuite))
}

```

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

```json
[
  {
    "annotations": {
      "title": "Configuration: View",
      "readOnlyHint": true,
      "destructiveHint": 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,
      "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",
      "destructiveHint": 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,
      "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",
      "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,
      "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,
      "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": {
        "name": {
          "description": "Name of the node to get logs from",
          "type": "string"
        },
        "query": {
          "description": "query specifies services(s) or files from which to return logs (required). Example: \"kubelet\" to fetch kubelet logs, \"/\u003clog-file-name\u003e\" to fetch a specific log file from the node (e.g., \"/var/log/kubelet.log\" or \"/var/log/kube-proxy.log\")",
          "type": "string"
        },
        "tailLines": {
          "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",
        "query"
      ]
    },
    "name": "nodes_log"
  },
  {
    "annotations": {
      "title": "Node: Stats Summary",
      "readOnlyHint": true,
      "destructiveHint": false,
      "openWorldHint": true
    },
    "description": "Get detailed resource usage statistics from a Kubernetes node via the kubelet's Summary API. Provides comprehensive metrics including CPU, memory, filesystem, and network usage at the node, pod, and container levels. On systems with cgroup v2 and kernel 4.20+, also includes PSI (Pressure Stall Information) metrics that show resource pressure for CPU, memory, and I/O. See https://kubernetes.io/docs/reference/instrumentation/understand-psi-metrics/ for details on PSI metrics",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {
          "description": "Name of the node to get stats from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "nodes_stats_summary"
  },
  {
    "annotations": {
      "title": "Nodes: 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 Nodes or all nodes in the cluster",
    "inputSchema": {
      "type": "object",
      "properties": {
        "label_selector": {
          "description": "Kubernetes label selector (e.g. 'node-role.kubernetes.io/worker=') to filter nodes 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 Node to get the resource consumption from (Optional, all Nodes if not provided)",
          "type": "string"
        }
      }
    },
    "name": "nodes_top"
  },
  {
    "annotations": {
      "title": "Pods: Delete",
      "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",
      "destructiveHint": true,
      "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,
      "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,
      "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,
      "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,
      "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",
      "destructiveHint": 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",
      "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",
      "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,
      "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,
      "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"
  },
  {
    "annotations": {
      "title": "Resources: Scale",
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Get or update the scale of a Kubernetes resource in the current cluster by providing its apiVersion, kind, name, and optionally the namespace. If the scale is set in the tool call, the scale will be updated to that value. Always returns the current scale of the resource",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are apps/v1)",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: StatefulSet, Deployment)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to get/update the namespaced resource scale from (ignored in case of cluster scoped resources). If not provided, will get/update resource scale from configured namespace",
          "type": "string"
        },
        "scale": {
          "description": "Optional scale to update the resources scale to. If not provided, will return the current scale of the resource, and not update it",
          "type": "integer"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_scale"
  }
]

```

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

```json
[
  {
    "annotations": {
      "title": "Configuration: View",
      "readOnlyHint": true,
      "destructiveHint": 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,
      "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",
      "destructiveHint": 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,
      "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",
      "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,
      "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,
      "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": {
        "name": {
          "description": "Name of the node to get logs from",
          "type": "string"
        },
        "query": {
          "description": "query specifies services(s) or files from which to return logs (required). Example: \"kubelet\" to fetch kubelet logs, \"/\u003clog-file-name\u003e\" to fetch a specific log file from the node (e.g., \"/var/log/kubelet.log\" or \"/var/log/kube-proxy.log\")",
          "type": "string"
        },
        "tailLines": {
          "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",
        "query"
      ]
    },
    "name": "nodes_log"
  },
  {
    "annotations": {
      "title": "Node: Stats Summary",
      "readOnlyHint": true,
      "destructiveHint": false,
      "openWorldHint": true
    },
    "description": "Get detailed resource usage statistics from a Kubernetes node via the kubelet's Summary API. Provides comprehensive metrics including CPU, memory, filesystem, and network usage at the node, pod, and container levels. On systems with cgroup v2 and kernel 4.20+, also includes PSI (Pressure Stall Information) metrics that show resource pressure for CPU, memory, and I/O. See https://kubernetes.io/docs/reference/instrumentation/understand-psi-metrics/ for details on PSI metrics",
    "inputSchema": {
      "type": "object",
      "properties": {
        "name": {
          "description": "Name of the node to get stats from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "nodes_stats_summary"
  },
  {
    "annotations": {
      "title": "Nodes: 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 Nodes or all nodes in the cluster",
    "inputSchema": {
      "type": "object",
      "properties": {
        "label_selector": {
          "description": "Kubernetes label selector (e.g. 'node-role.kubernetes.io/worker=') to filter nodes 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 Node to get the resource consumption from (Optional, all Nodes if not provided)",
          "type": "string"
        }
      }
    },
    "name": "nodes_top"
  },
  {
    "annotations": {
      "title": "Pods: Delete",
      "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",
      "destructiveHint": true,
      "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,
      "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,
      "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,
      "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,
      "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",
      "destructiveHint": 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,
      "openWorldHint": true
    },
    "description": "List all the OpenShift projects in the current cluster",
    "inputSchema": {
      "type": "object"
    },
    "name": "projects_list"
  },
  {
    "annotations": {
      "title": "Resources: Create or Update",
      "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",
      "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,
      "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,
      "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"
  },
  {
    "annotations": {
      "title": "Resources: Scale",
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Get or update the scale of a Kubernetes resource in the current cluster by providing its apiVersion, kind, name, and optionally the namespace. If the scale is set in the tool call, the scale will be updated to that value. Always returns the current scale of the resource",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are apps/v1)",
          "type": "string"
        },
        "kind": {
          "description": "kind of the resource (examples of valid kind are: StatefulSet, Deployment)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to get/update the namespaced resource scale from (ignored in case of cluster scoped resources). If not provided, will get/update resource scale from configured namespace",
          "type": "string"
        },
        "scale": {
          "description": "Optional scale to update the resources scale to. If not provided, will return the current scale of the resource, and not update it",
          "type": "integer"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_scale"
  }
]

```

--------------------------------------------------------------------------------
/pkg/http/http_test.go:
--------------------------------------------------------------------------------

```go
package http

import (
	"bytes"
	"context"
	"crypto/rand"
	"crypto/rsa"
	"flag"
	"fmt"
	"io"
	"net"
	"net/http"
	"net/http/httptest"
	"os"
	"regexp"
	"strconv"
	"strings"
	"testing"
	"time"

	"github.com/containers/kubernetes-mcp-server/internal/test"
	"github.com/containers/kubernetes-mcp-server/pkg/api"
	"github.com/coreos/go-oidc/v3/oidc"
	"github.com/coreos/go-oidc/v3/oidc/oidctest"
	"github.com/stretchr/testify/suite"
	"golang.org/x/sync/errgroup"
	"k8s.io/klog/v2"
	"k8s.io/klog/v2/textlogger"

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

type BaseHttpSuite struct {
	suite.Suite
	MockServer      *test.MockServer
	StaticConfig    *config.StaticConfig
	mcpServer       *mcp.Server
	OidcProvider    *oidc.Provider
	timeoutCancel   context.CancelFunc
	StopServer      context.CancelFunc
	WaitForShutdown func() error
}

func (s *BaseHttpSuite) SetupTest() {
	http.DefaultClient.Timeout = 10 * time.Second
	s.MockServer = test.NewMockServer()
	s.MockServer.Handle(&test.DiscoveryClientHandler{})
	s.StaticConfig = config.Default()
	s.StaticConfig.KubeConfig = s.MockServer.KubeconfigFile(s.T())
}

func (s *BaseHttpSuite) StartServer() {

	tcpAddr, err := test.RandomPortAddress()
	s.Require().NoError(err, "Expected no error getting random port address")
	s.StaticConfig.Port = strconv.Itoa(tcpAddr.Port)

	s.mcpServer, err = mcp.NewServer(mcp.Configuration{StaticConfig: s.StaticConfig})
	s.Require().NoError(err, "Expected no error creating MCP server")
	s.Require().NotNil(s.mcpServer, "MCP server should not be nil")
	var timeoutCtx, cancelCtx context.Context
	timeoutCtx, s.timeoutCancel = context.WithTimeout(s.T().Context(), 10*time.Second)
	group, gc := errgroup.WithContext(timeoutCtx)
	cancelCtx, s.StopServer = context.WithCancel(gc)
	group.Go(func() error { return Serve(cancelCtx, s.mcpServer, s.StaticConfig, s.OidcProvider, nil) })
	s.WaitForShutdown = group.Wait
	s.Require().NoError(test.WaitForServer(tcpAddr), "HTTP server did not start in time")
	s.Require().NoError(test.WaitForHealthz(tcpAddr), "HTTP server /healthz endpoint did not respond with non-404 in time")
}

func (s *BaseHttpSuite) TearDownTest() {
	s.MockServer.Close()
	if s.mcpServer != nil {
		s.mcpServer.Close()
	}
	s.StopServer()
	s.Require().NoError(s.WaitForShutdown(), "HTTP server did not shut down gracefully")
	s.timeoutCancel()
}

type httpContext struct {
	klogState       klog.State
	mockServer      *test.MockServer
	LogBuffer       bytes.Buffer
	HttpAddress     string             // HTTP server address
	timeoutCancel   context.CancelFunc // Release resources if test completes before the timeout
	StopServer      context.CancelFunc
	WaitForShutdown func() error
	StaticConfig    *config.StaticConfig
	OidcProvider    *oidc.Provider
}

func (c *httpContext) beforeEach(t *testing.T) {
	t.Helper()
	http.DefaultClient.Timeout = 10 * time.Second
	if c.StaticConfig == nil {
		c.StaticConfig = config.Default()
	}
	c.mockServer = test.NewMockServer()
	// Fake Kubernetes configuration
	c.StaticConfig.KubeConfig = c.mockServer.KubeconfigFile(t)
	// Capture logging
	c.klogState = klog.CaptureState()
	flags := flag.NewFlagSet("test", flag.ContinueOnError)
	klog.InitFlags(flags)
	_ = flags.Set("v", "5")
	klog.SetLogger(textlogger.NewLogger(textlogger.NewConfig(textlogger.Verbosity(5), textlogger.Output(&c.LogBuffer))))
	// Start server in random port
	ln, err := net.Listen("tcp", "0.0.0.0:0")
	if err != nil {
		t.Fatalf("Failed to find random port for HTTP server: %v", err)
	}
	c.HttpAddress = ln.Addr().String()
	if randomPortErr := ln.Close(); randomPortErr != nil {
		t.Fatalf("Failed to close random port listener: %v", randomPortErr)
	}
	c.StaticConfig.Port = fmt.Sprintf("%d", ln.Addr().(*net.TCPAddr).Port)
	mcpServer, err := mcp.NewServer(mcp.Configuration{StaticConfig: c.StaticConfig})
	if err != nil {
		t.Fatalf("Failed to create MCP server: %v", err)
	}
	var timeoutCtx, cancelCtx context.Context
	timeoutCtx, c.timeoutCancel = context.WithTimeout(t.Context(), 10*time.Second)
	group, gc := errgroup.WithContext(timeoutCtx)
	cancelCtx, c.StopServer = context.WithCancel(gc)
	group.Go(func() error { return Serve(cancelCtx, mcpServer, c.StaticConfig, c.OidcProvider, nil) })
	c.WaitForShutdown = group.Wait
	// Wait for HTTP server to start (using net)
	for i := 0; i < 10; i++ {
		conn, err := net.Dial("tcp", c.HttpAddress)
		if err == nil {
			_ = conn.Close()
			break
		}
		time.Sleep(50 * time.Millisecond) // Wait before retrying
	}
}

func (c *httpContext) afterEach(t *testing.T) {
	t.Helper()
	c.mockServer.Close()
	c.StopServer()
	err := c.WaitForShutdown()
	if err != nil {
		t.Errorf("HTTP server did not shut down gracefully: %v", err)
	}
	c.timeoutCancel()
	c.klogState.Restore()
	_ = os.Setenv("KUBECONFIG", "")
}

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

func testCaseWithContext(t *testing.T, httpCtx *httpContext, test func(c *httpContext)) {
	httpCtx.beforeEach(t)
	t.Cleanup(func() { httpCtx.afterEach(t) })
	test(httpCtx)
}

type OidcTestServer struct {
	*rsa.PrivateKey
	*oidc.Provider
	*httptest.Server
	TokenEndpointHandler http.HandlerFunc
}

func NewOidcTestServer(t *testing.T) (oidcTestServer *OidcTestServer) {
	t.Helper()
	var err error
	oidcTestServer = &OidcTestServer{}
	oidcTestServer.PrivateKey, err = rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		t.Fatalf("failed to generate private key for oidc: %v", err)
	}
	oidcServer := &oidctest.Server{
		Algorithms: []string{oidc.RS256, oidc.ES256},
		PublicKeys: []oidctest.PublicKey{
			{
				PublicKey: oidcTestServer.Public(),
				KeyID:     "test-oidc-key-id",
				Algorithm: oidc.RS256,
			},
		},
	}
	oidcTestServer.Server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/token" && oidcTestServer.TokenEndpointHandler != nil {
			oidcTestServer.TokenEndpointHandler.ServeHTTP(w, r)
			return
		}
		oidcServer.ServeHTTP(w, r)
	}))
	oidcServer.SetIssuer(oidcTestServer.URL)
	oidcTestServer.Provider, err = oidc.NewProvider(t.Context(), oidcTestServer.URL)
	if err != nil {
		t.Fatalf("failed to create OIDC provider: %v", err)
	}
	return
}

func TestGracefulShutdown(t *testing.T) {
	testCase(t, func(ctx *httpContext) {
		ctx.StopServer()
		err := ctx.WaitForShutdown()
		t.Run("Stops gracefully", func(t *testing.T) {
			if err != nil {
				t.Errorf("Expected graceful shutdown, but got error: %v", err)
			}
		})
		t.Run("Stops on context cancel", func(t *testing.T) {
			if !strings.Contains(ctx.LogBuffer.String(), "Context cancelled, initiating graceful shutdown") {
				t.Errorf("Context cancelled, initiating graceful shutdown, got: %s", ctx.LogBuffer.String())
			}
		})
		t.Run("Starts server shutdown", func(t *testing.T) {
			if !strings.Contains(ctx.LogBuffer.String(), "Shutting down HTTP server gracefully") {
				t.Errorf("Expected graceful shutdown log, got: %s", ctx.LogBuffer.String())
			}
		})
		t.Run("Server shutdown completes", func(t *testing.T) {
			if !strings.Contains(ctx.LogBuffer.String(), "HTTP server shutdown complete") {
				t.Errorf("Expected HTTP server shutdown completed log, got: %s", ctx.LogBuffer.String())
			}
		})
	})
}

func TestHealthCheck(t *testing.T) {
	testCase(t, func(ctx *httpContext) {
		t.Run("Exposes health check endpoint at /healthz", func(t *testing.T) {
			resp, err := http.Get(fmt.Sprintf("http://%s/healthz", ctx.HttpAddress))
			if err != nil {
				t.Fatalf("Failed to get health check endpoint: %v", err)
			}
			t.Cleanup(func() { _ = resp.Body.Close })
			if resp.StatusCode != http.StatusOK {
				t.Errorf("Expected HTTP 200 OK, got %d", resp.StatusCode)
			}
		})
	})
	// Health exposed even when require Authorization
	testCaseWithContext(t, &httpContext{StaticConfig: &config.StaticConfig{RequireOAuth: true, ValidateToken: true, ClusterProviderStrategy: api.ClusterProviderKubeConfig}}, func(ctx *httpContext) {
		resp, err := http.Get(fmt.Sprintf("http://%s/healthz", ctx.HttpAddress))
		if err != nil {
			t.Fatalf("Failed to get health check endpoint with OAuth: %v", err)
		}
		t.Cleanup(func() { _ = resp.Body.Close() })
		t.Run("Health check with OAuth returns HTTP 200 OK", func(t *testing.T) {
			if resp.StatusCode != http.StatusOK {
				t.Errorf("Expected HTTP 200 OK, got %d", resp.StatusCode)
			}
		})
	})
}

func TestWellKnownReverseProxy(t *testing.T) {
	cases := []string{
		".well-known/oauth-authorization-server",
		".well-known/oauth-protected-resource",
		".well-known/openid-configuration",
	}
	// With No Authorization URL configured
	testCaseWithContext(t, &httpContext{StaticConfig: &config.StaticConfig{RequireOAuth: true, ValidateToken: true, ClusterProviderStrategy: api.ClusterProviderKubeConfig}}, func(ctx *httpContext) {
		for _, path := range cases {
			resp, err := http.Get(fmt.Sprintf("http://%s/%s", ctx.HttpAddress, path))
			t.Cleanup(func() { _ = resp.Body.Close() })
			t.Run("Protected resource '"+path+"' without Authorization URL returns 404 - Not Found", func(t *testing.T) {
				if err != nil {
					t.Fatalf("Failed to get %s endpoint: %v", path, err)
				}
				if resp.StatusCode != http.StatusNotFound {
					t.Errorf("Expected HTTP 404 Not Found, got %d", resp.StatusCode)
				}
			})
		}
	})
	// With Authorization URL configured but invalid payload
	invalidPayloadServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		_, _ = w.Write([]byte(`NOT A JSON PAYLOAD`))
	}))
	t.Cleanup(invalidPayloadServer.Close)
	invalidPayloadConfig := &config.StaticConfig{
		AuthorizationURL:        invalidPayloadServer.URL,
		RequireOAuth:            true,
		ValidateToken:           true,
		ClusterProviderStrategy: api.ClusterProviderKubeConfig,
	}
	testCaseWithContext(t, &httpContext{StaticConfig: invalidPayloadConfig}, func(ctx *httpContext) {
		for _, path := range cases {
			resp, err := http.Get(fmt.Sprintf("http://%s/%s", ctx.HttpAddress, path))
			t.Cleanup(func() { _ = resp.Body.Close() })
			t.Run("Protected resource '"+path+"' with invalid Authorization URL payload returns 500 - Internal Server Error", func(t *testing.T) {
				if err != nil {
					t.Fatalf("Failed to get %s endpoint: %v", path, err)
				}
				if resp.StatusCode != http.StatusInternalServerError {
					t.Errorf("Expected HTTP 500 Internal Server Error, got %d", resp.StatusCode)
				}
			})
		}
	})
	// With Authorization URL configured and valid payload
	testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if !strings.HasPrefix(r.URL.EscapedPath(), "/.well-known/") {
			http.NotFound(w, r)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		_, _ = w.Write([]byte(`{"issuer": "https://example.com","scopes_supported":["mcp-server"]}`))
	}))
	t.Cleanup(testServer.Close)
	staticConfig := &config.StaticConfig{
		AuthorizationURL:        testServer.URL,
		RequireOAuth:            true,
		ValidateToken:           true,
		ClusterProviderStrategy: api.ClusterProviderKubeConfig,
	}
	testCaseWithContext(t, &httpContext{StaticConfig: staticConfig}, func(ctx *httpContext) {
		for _, path := range cases {
			resp, err := http.Get(fmt.Sprintf("http://%s/%s", ctx.HttpAddress, path))
			t.Cleanup(func() { _ = resp.Body.Close() })
			t.Run("Exposes "+path+" endpoint", func(t *testing.T) {
				if err != nil {
					t.Fatalf("Failed to get %s endpoint: %v", path, err)
				}
				if resp.StatusCode != http.StatusOK {
					t.Errorf("Expected HTTP 200 OK, got %d", resp.StatusCode)
				}
			})
			t.Run(path+" returns application/json content type", func(t *testing.T) {
				if resp.Header.Get("Content-Type") != "application/json" {
					t.Errorf("Expected Content-Type application/json, got %s", resp.Header.Get("Content-Type"))
				}
			})
		}
	})
}

func TestWellKnownHeaderPropagation(t *testing.T) {
	cases := []string{
		".well-known/oauth-authorization-server",
		".well-known/oauth-protected-resource",
		".well-known/openid-configuration",
	}
	var receivedRequestHeaders http.Header
	testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if !strings.HasPrefix(r.URL.EscapedPath(), "/.well-known/") {
			http.NotFound(w, r)
			return
		}
		// Capture headers received from the proxy
		receivedRequestHeaders = r.Header.Clone()
		// Set response headers that should be propagated back
		w.Header().Set("Content-Type", "application/json")
		w.Header().Set("Access-Control-Allow-Origin", "https://example.com")
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
		w.Header().Set("Cache-Control", "no-cache")
		w.Header().Set("X-Custom-Backend-Header", "backend-value")
		_, _ = w.Write([]byte(`{"issuer": "https://example.com"}`))
	}))
	t.Cleanup(testServer.Close)
	staticConfig := &config.StaticConfig{
		AuthorizationURL:        testServer.URL,
		RequireOAuth:            true,
		ValidateToken:           true,
		ClusterProviderStrategy: api.ClusterProviderKubeConfig,
	}
	testCaseWithContext(t, &httpContext{StaticConfig: staticConfig}, func(ctx *httpContext) {
		for _, path := range cases {
			receivedRequestHeaders = nil
			req, err := http.NewRequest("GET", fmt.Sprintf("http://%s/%s", ctx.HttpAddress, path), nil)
			if err != nil {
				t.Fatalf("Failed to create request: %v", err)
			}
			// Add various headers to test propagation
			req.Header.Set("Origin", "https://example.com")
			req.Header.Set("User-Agent", "Test-Agent/1.0")
			req.Header.Set("Accept", "application/json")
			req.Header.Set("Accept-Language", "en-US")
			req.Header.Set("X-Custom-Header", "custom-value")
			req.Header.Set("Referer", "https://example.com/page")

			resp, err := http.DefaultClient.Do(req)
			if err != nil {
				t.Fatalf("Failed to get %s endpoint: %v", path, err)
			}
			t.Cleanup(func() { _ = resp.Body.Close() })

			t.Run("Well-known proxy propagates Origin header to backend for "+path, func(t *testing.T) {
				if receivedRequestHeaders == nil {
					t.Fatal("Backend did not receive any headers")
				}
				if receivedRequestHeaders.Get("Origin") != "https://example.com" {
					t.Errorf("Expected Origin header 'https://example.com', got '%s'", receivedRequestHeaders.Get("Origin"))
				}
			})

			t.Run("Well-known proxy propagates User-Agent header to backend for "+path, func(t *testing.T) {
				if receivedRequestHeaders.Get("User-Agent") != "Test-Agent/1.0" {
					t.Errorf("Expected User-Agent header 'Test-Agent/1.0', got '%s'", receivedRequestHeaders.Get("User-Agent"))
				}
			})

			t.Run("Well-known proxy propagates Accept header to backend for "+path, func(t *testing.T) {
				if receivedRequestHeaders.Get("Accept") != "application/json" {
					t.Errorf("Expected Accept header 'application/json', got '%s'", receivedRequestHeaders.Get("Accept"))
				}
			})

			t.Run("Well-known proxy propagates Accept-Language header to backend for "+path, func(t *testing.T) {
				if receivedRequestHeaders.Get("Accept-Language") != "en-US" {
					t.Errorf("Expected Accept-Language header 'en-US', got '%s'", receivedRequestHeaders.Get("Accept-Language"))
				}
			})

			t.Run("Well-known proxy propagates custom headers to backend for "+path, func(t *testing.T) {
				if receivedRequestHeaders.Get("X-Custom-Header") != "custom-value" {
					t.Errorf("Expected X-Custom-Header 'custom-value', got '%s'", receivedRequestHeaders.Get("X-Custom-Header"))
				}
			})

			t.Run("Well-known proxy propagates Referer header to backend for "+path, func(t *testing.T) {
				if receivedRequestHeaders.Get("Referer") != "https://example.com/page" {
					t.Errorf("Expected Referer header 'https://example.com/page', got '%s'", receivedRequestHeaders.Get("Referer"))
				}
			})

			t.Run("Well-known proxy returns Access-Control-Allow-Origin from backend for "+path, func(t *testing.T) {
				if resp.Header.Get("Access-Control-Allow-Origin") != "https://example.com" {
					t.Errorf("Expected Access-Control-Allow-Origin header 'https://example.com', got '%s'", resp.Header.Get("Access-Control-Allow-Origin"))
				}
			})

			t.Run("Well-known proxy returns Access-Control-Allow-Methods from backend for "+path, func(t *testing.T) {
				if resp.Header.Get("Access-Control-Allow-Methods") != "GET, POST, OPTIONS" {
					t.Errorf("Expected Access-Control-Allow-Methods header 'GET, POST, OPTIONS', got '%s'", resp.Header.Get("Access-Control-Allow-Methods"))
				}
			})

			t.Run("Well-known proxy returns Cache-Control from backend for "+path, func(t *testing.T) {
				if resp.Header.Get("Cache-Control") != "no-cache" {
					t.Errorf("Expected Cache-Control header 'no-cache', got '%s'", resp.Header.Get("Cache-Control"))
				}
			})

			t.Run("Well-known proxy returns custom response headers from backend for "+path, func(t *testing.T) {
				if resp.Header.Get("X-Custom-Backend-Header") != "backend-value" {
					t.Errorf("Expected X-Custom-Backend-Header 'backend-value', got '%s'", resp.Header.Get("X-Custom-Backend-Header"))
				}
			})
		}
	})
}

func TestWellKnownOverrides(t *testing.T) {
	cases := []string{
		".well-known/oauth-authorization-server",
		".well-known/oauth-protected-resource",
		".well-known/openid-configuration",
	}
	testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if !strings.HasPrefix(r.URL.EscapedPath(), "/.well-known/") {
			http.NotFound(w, r)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		_, _ = w.Write([]byte(`
			{
				"issuer": "https://localhost",
				"registration_endpoint": "https://localhost/clients-registrations/openid-connect",
				"require_request_uri_registration": true,
				"scopes_supported":["scope-1", "scope-2"]
			}`))
	}))
	t.Cleanup(testServer.Close)
	baseConfig := config.StaticConfig{
		AuthorizationURL:        testServer.URL,
		RequireOAuth:            true,
		ValidateToken:           true,
		ClusterProviderStrategy: api.ClusterProviderKubeConfig,
	}
	// With Dynamic Client Registration disabled
	disableDynamicRegistrationConfig := baseConfig
	disableDynamicRegistrationConfig.DisableDynamicClientRegistration = true
	testCaseWithContext(t, &httpContext{StaticConfig: &disableDynamicRegistrationConfig}, func(ctx *httpContext) {
		for _, path := range cases {
			resp, _ := http.Get(fmt.Sprintf("http://%s/%s", ctx.HttpAddress, path))
			t.Cleanup(func() { _ = resp.Body.Close() })
			body, err := io.ReadAll(resp.Body)
			if err != nil {
				t.Fatalf("Failed to read response body: %v", err)
			}
			t.Run("DisableDynamicClientRegistration removes registration_endpoint field", func(t *testing.T) {
				if strings.Contains(string(body), "registration_endpoint") {
					t.Error("Expected registration_endpoint to be removed, but it was found in the response")
				}
			})
			t.Run("DisableDynamicClientRegistration sets require_request_uri_registration = false", func(t *testing.T) {
				if !strings.Contains(string(body), `"require_request_uri_registration":false`) {
					t.Error("Expected require_request_uri_registration to be false, but it was not found in the response")
				}
			})
			t.Run("DisableDynamicClientRegistration includes/preserves scopes_supported", func(t *testing.T) {
				if !strings.Contains(string(body), `"scopes_supported":["scope-1","scope-2"]`) {
					t.Error("Expected scopes_supported to be present, but it was not found in the response")
				}
			})
		}
	})
	// With overrides for OAuth scopes (client/frontend)
	oAuthScopesConfig := baseConfig
	oAuthScopesConfig.OAuthScopes = []string{"openid", "mcp-server"}
	testCaseWithContext(t, &httpContext{StaticConfig: &oAuthScopesConfig}, func(ctx *httpContext) {
		for _, path := range cases {
			resp, _ := http.Get(fmt.Sprintf("http://%s/%s", ctx.HttpAddress, path))
			t.Cleanup(func() { _ = resp.Body.Close() })
			body, err := io.ReadAll(resp.Body)
			if err != nil {
				t.Fatalf("Failed to read response body: %v", err)
			}
			t.Run("OAuthScopes overrides scopes_supported", func(t *testing.T) {
				if !strings.Contains(string(body), `"scopes_supported":["openid","mcp-server"]`) {
					t.Errorf("Expected scopes_supported to be overridden, but original was preserved, response: %s", string(body))
				}
			})
			t.Run("OAuthScopes preserves other fields", func(t *testing.T) {
				if !strings.Contains(string(body), `"issuer":"https://localhost"`) {
					t.Errorf("Expected issuer to be preserved, but got: %s", string(body))
				}
				if !strings.Contains(string(body), `"registration_endpoint":"https://localhost`) {
					t.Errorf("Expected registration_endpoint to be preserved, but got: %s", string(body))
				}
				if !strings.Contains(string(body), `"require_request_uri_registration":true`) {
					t.Error("Expected require_request_uri_registration to be true, but it was not found in the response")
				}
			})
		}
	})
}

func TestMiddlewareLogging(t *testing.T) {
	testCase(t, func(ctx *httpContext) {
		_, _ = http.Get(fmt.Sprintf("http://%s/.well-known/oauth-protected-resource", ctx.HttpAddress))
		t.Run("Logs HTTP requests and responses", func(t *testing.T) {
			if !strings.Contains(ctx.LogBuffer.String(), "GET /.well-known/oauth-protected-resource 404") {
				t.Errorf("Expected log entry for GET /.well-known/oauth-protected-resource, got: %s", ctx.LogBuffer.String())
			}
		})
		t.Run("Logs HTTP request duration", func(t *testing.T) {
			expected := `"GET /.well-known/oauth-protected-resource 404 (.+)"`
			m := regexp.MustCompile(expected).FindStringSubmatch(ctx.LogBuffer.String())
			if len(m) != 2 {
				t.Fatalf("Expected log entry to contain duration, got %s", ctx.LogBuffer.String())
			}
			duration, err := time.ParseDuration(m[1])
			if err != nil {
				t.Fatalf("Failed to parse duration from log entry: %v", err)
			}
			if duration < 0 {
				t.Errorf("Expected duration to be non-negative, got %v", duration)
			}
		})
	})
}

```

--------------------------------------------------------------------------------
/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,
      "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,
      "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",
      "destructiveHint": 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,
      "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",
      "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,
      "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,
      "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"
        },
        "name": {
          "description": "Name of the node to get logs from",
          "type": "string"
        },
        "query": {
          "description": "query specifies services(s) or files from which to return logs (required). Example: \"kubelet\" to fetch kubelet logs, \"/\u003clog-file-name\u003e\" to fetch a specific log file from the node (e.g., \"/var/log/kubelet.log\" or \"/var/log/kube-proxy.log\")",
          "type": "string"
        },
        "tailLines": {
          "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",
        "query"
      ]
    },
    "name": "nodes_log"
  },
  {
    "annotations": {
      "title": "Node: Stats Summary",
      "readOnlyHint": true,
      "destructiveHint": false,
      "openWorldHint": true
    },
    "description": "Get detailed resource usage statistics from a Kubernetes node via the kubelet's Summary API. Provides comprehensive metrics including CPU, memory, filesystem, and network usage at the node, pod, and container levels. On systems with cgroup v2 and kernel 4.20+, also includes PSI (Pressure Stall Information) metrics that show resource pressure for CPU, memory, and I/O. See https://kubernetes.io/docs/reference/instrumentation/understand-psi-metrics/ for details on PSI metrics",
    "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 node to get stats from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "nodes_stats_summary"
  },
  {
    "annotations": {
      "title": "Nodes: 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 Nodes or all nodes in the 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"
        },
        "label_selector": {
          "description": "Kubernetes label selector (e.g. 'node-role.kubernetes.io/worker=') to filter nodes 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 Node to get the resource consumption from (Optional, all Nodes if not provided)",
          "type": "string"
        }
      }
    },
    "name": "nodes_top"
  },
  {
    "annotations": {
      "title": "Pods: Delete",
      "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",
      "destructiveHint": true,
      "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,
      "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,
      "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,
      "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,
      "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",
      "destructiveHint": 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",
      "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",
      "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,
      "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,
      "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"
  },
  {
    "annotations": {
      "title": "Resources: Scale",
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Get or update the scale of a Kubernetes resource in the current cluster by providing its apiVersion, kind, name, and optionally the namespace. If the scale is set in the tool call, the scale will be updated to that value. Always returns the current scale of the resource",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are apps/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: StatefulSet, Deployment)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to get/update the namespaced resource scale from (ignored in case of cluster scoped resources). If not provided, will get/update resource scale from configured namespace",
          "type": "string"
        },
        "scale": {
          "description": "Optional scale to update the resources scale to. If not provided, will return the current scale of the resource, and not update it",
          "type": "integer"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_scale"
  }
]

```

--------------------------------------------------------------------------------
/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,
      "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,
      "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",
      "destructiveHint": 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,
      "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",
      "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,
      "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,
      "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"
        },
        "name": {
          "description": "Name of the node to get logs from",
          "type": "string"
        },
        "query": {
          "description": "query specifies services(s) or files from which to return logs (required). Example: \"kubelet\" to fetch kubelet logs, \"/\u003clog-file-name\u003e\" to fetch a specific log file from the node (e.g., \"/var/log/kubelet.log\" or \"/var/log/kube-proxy.log\")",
          "type": "string"
        },
        "tailLines": {
          "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",
        "query"
      ]
    },
    "name": "nodes_log"
  },
  {
    "annotations": {
      "title": "Node: Stats Summary",
      "readOnlyHint": true,
      "destructiveHint": false,
      "openWorldHint": true
    },
    "description": "Get detailed resource usage statistics from a Kubernetes node via the kubelet's Summary API. Provides comprehensive metrics including CPU, memory, filesystem, and network usage at the node, pod, and container levels. On systems with cgroup v2 and kernel 4.20+, also includes PSI (Pressure Stall Information) metrics that show resource pressure for CPU, memory, and I/O. See https://kubernetes.io/docs/reference/instrumentation/understand-psi-metrics/ for details on PSI metrics",
    "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 node to get stats from",
          "type": "string"
        }
      },
      "required": [
        "name"
      ]
    },
    "name": "nodes_stats_summary"
  },
  {
    "annotations": {
      "title": "Nodes: 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 Nodes or all nodes in the 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"
        },
        "label_selector": {
          "description": "Kubernetes label selector (e.g. 'node-role.kubernetes.io/worker=') to filter nodes 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 Node to get the resource consumption from (Optional, all Nodes if not provided)",
          "type": "string"
        }
      }
    },
    "name": "nodes_top"
  },
  {
    "annotations": {
      "title": "Pods: Delete",
      "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",
      "destructiveHint": true,
      "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,
      "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,
      "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,
      "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,
      "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",
      "destructiveHint": 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",
      "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",
      "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,
      "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,
      "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"
  },
  {
    "annotations": {
      "title": "Resources: Scale",
      "destructiveHint": true,
      "idempotentHint": true,
      "openWorldHint": true
    },
    "description": "Get or update the scale of a Kubernetes resource in the current cluster by providing its apiVersion, kind, name, and optionally the namespace. If the scale is set in the tool call, the scale will be updated to that value. Always returns the current scale of the resource",
    "inputSchema": {
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "apiVersion of the resource (examples of valid apiVersion are apps/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: StatefulSet, Deployment)",
          "type": "string"
        },
        "name": {
          "description": "Name of the resource",
          "type": "string"
        },
        "namespace": {
          "description": "Optional Namespace to get/update the namespaced resource scale from (ignored in case of cluster scoped resources). If not provided, will get/update resource scale from configured namespace",
          "type": "string"
        },
        "scale": {
          "description": "Optional scale to update the resources scale to. If not provided, will return the current scale of the resource, and not update it",
          "type": "integer"
        }
      },
      "required": [
        "apiVersion",
        "kind",
        "name"
      ]
    },
    "name": "resources_scale"
  }
]

```
Page 7/8FirstPrevNextLast