A community-driven registry for Claude, Cursor, Windsurf, Cline & more. Not affiliated with Anthropic.
Are you the author? Sign in to claim
A read-only Kubernetes MCP server: list resources, get resource details, retrieve pod logs, discover API resources, and
mcp-kubernetes-ro is a Model Context Protocol (MCP) server providing read-only access to Kubernetes clusters for AI assistants. It enables AI models to list resources, get resource details, retrieve pod logs, discover API resources, and perform base64 encoding/decoding operations - all while maintaining security through read-only access.
The server leverages your local kubectl configuration (even when kubectl is not required to be installed) and provides a safe, read-only interface to your Kubernetes clusters, preventing any destructive operations while allowing comprehensive cluster inspection and troubleshooting capabilities.
kubectl: The MCP server uses your local kubectl configuration to connect to your Kubernetes cluster but not the binary, so it works even when kubectl is not installed on your machine.Feel free to grab a pre-built binary from the releases page.
Alternatively, you can use Homebrew in macOS or Linux to install it:
brew install patrickdappollonio/tap/mcp-kubernetes-ro
You can also use it as an NPM package: just make sure the configuration is given to your AI agent:
npx -y @patrickdappollonio/mcp-kubernetes-ro
Finally, Docker users can use the prebuilt image from the GitHub Container Registry:
docker pull ghcr.io/patrickdappollonio/mcp-kubernetes-ro:latest
Add the following configuration to your editor's settings to use mcp-kubernetes-ro:
{
"mcpServers": {
"kubernetes-ro": {
"command": "mcp-kubernetes-ro",
"args": [
// Uncomment and modify as needed:
// "--kubeconfig=/path/to/kubeconfig",
// "--namespace=default",
// "--transport=stdio",
// "--port=8080",
// "--disabled-tools=get_logs,decode_base64",
// "--disabled-resources=secrets",
// "--always-start"
],
"env": {
// Set KUBECONFIG environment variable if needed:
// "KUBECONFIG": "/path/to/kubeconfig",
// Set MCP_KUBERNETES_RO_DISABLED_TOOLS environment variable if needed:
// "MCP_KUBERNETES_RO_DISABLED_TOOLS": "get_logs,decode_base64",
// Or use generic DISABLED_TOOLS environment variable:
// "DISABLED_TOOLS": "get_logs,decode_base64",
// Disable access to specific resource types:
// "MCP_KUBERNETES_RO_DISABLED_RESOURCES": "secrets,configmaps",
// Skip startup connectivity check via environment variable:
// "MCP_KUBERNETES_RO_ALWAYS_START": "true"
}
}
}
}
You can use mcp-kubernetes-ro directly from your $PATH as shown above, or provide the full path to the binary (e.g., /path/to/mcp-kubernetes-ro).
You can also simplify the installation process by using it as an npx package:
{
"mcpServers": {
"kubernetes-ro": {
"command": "npx",
"args": [
"-y",
"@patrickdappollonio/mcp-kubernetes-ro"
// Uncomment and modify as needed:
// "--kubeconfig=/path/to/kubeconfig",
// "--namespace=default",
// "--transport=stdio",
// "--port=8080",
// "--disabled-tools=get_logs,decode_base64",
// "--disabled-resources=secrets"
],
"env": {
// Set KUBECONFIG environment variable if needed:
// "KUBECONFIG": "/path/to/kubeconfig",
// Set MCP_KUBERNETES_RO_DISABLED_TOOLS environment variable if needed:
// "MCP_KUBERNETES_RO_DISABLED_TOOLS": "get_logs,decode_base64",
// Or use generic DISABLED_TOOLS environment variable:
// "DISABLED_TOOLS": "get_logs,decode_base64",
// Disable access to specific resource types:
// "MCP_KUBERNETES_RO_DISABLED_RESOURCES": "secrets,configmaps"
}
}
}
}
And this is how to leverage the Docker image instead:
{
"mcpServers": {
"kubernetes-ro": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e", "KUBECONFIG=/root/.kube/config",
"-v", "/path/to/kubeconfig:/root/.kube/config",
"ghcr.io/patrickdappollonio/mcp-kubernetes-ro"
// Place additional flags here, like:
// "--disabled-tools=get_logs,decode_base64",
// "--disabled-resources=secrets"
],
"env": {
// Set KUBECONFIG environment variable if needed:
// "KUBECONFIG": "/path/to/kubeconfig",
// Set MCP_KUBERNETES_RO_DISABLED_TOOLS environment variable if needed:
// "MCP_KUBERNETES_RO_DISABLED_TOOLS": "get_logs,decode_base64",
// Or use generic DISABLED_TOOLS environment variable:
// "DISABLED_TOOLS": "get_logs,decode_base64",
// Disable access to specific resource types:
// "MCP_KUBERNETES_RO_DISABLED_RESOURCES": "secrets,configmaps"
}
},
}
}
Do note that you'll need to mount your kubeconfig file into the container, and either set the KUBECONFIG environment variable to the path of the mounted file, or use the --kubeconfig flag to set it.
~/.kube/config)get_node_metrics, get_pod_metrics), the metrics-server must be installed in your cluster. If not available, these tools will return an error message.There are 10 tools available by default, plus 3 additional tools when port forwarding is enabled:
list_resources: List any Kubernetes resources by type with optional filtering, sorted newest first. metadata.managedFields is omitted by default unless include_managed_fields=trueget_resource: Get specific resource details. metadata.managedFields is omitted by default unless include_managed_fields=trueget_logs: Get pod logs with advanced filtering options including grep patterns, time filtering, and previous logsget_pod_containers: List containers in a pod for log accesslist_api_resources: List available Kubernetes API resources with their details (similar to kubectl api-resources)list_contexts: List available Kubernetes contexts from the kubeconfig fileget_node_metrics: Get node metrics (CPU and memory usage)get_pod_metrics: Get pod metrics (CPU and memory usage)encode_base64: Encode text data to base64 formatdecode_base64: Decode base64 data to text formatstart_port_forward (opt-in): Start port forwarding to a pod with one or more port mappingsstop_port_forward (opt-in): Stop an active port-forwarding session by IDlist_port_forwards (opt-in): List all active port-forwarding sessionsYou can disable specific tools using the --disabled-tools flag or the MCP_KUBERNETES_RO_DISABLED_TOOLS / DISABLED_TOOLS environment variables. The flag is repeatable and accepts comma-separated values:
# Comma-separated
mcp-kubernetes-ro --disabled-tools=get_logs,decode_base64
# Repeated flags
mcp-kubernetes-ro --disabled-tools=get_logs --disabled-tools=decode_base64
# Using environment variable
export MCP_KUBERNETES_RO_DISABLED_TOOLS=get_logs,decode_base64
mcp-kubernetes-ro
Values from flags and environment variables are merged. If the MCP_KUBERNETES_RO_DISABLED_TOOLS env var is not set, DISABLED_TOOLS is used as a fallback.
When a tool is disabled, it will not be registered with the MCP server and will not appear in the available tools list. A message will be logged to stderr indicating which tools have been skipped.
Available tool names for disabling:
list_resourcesget_resourceget_logsget_pod_containerslist_api_resourceslist_contextsget_node_metricsget_pod_metricsencode_base64decode_base64start_port_forward (only when port forwarding is enabled)stop_port_forward (only when port forwarding is enabled)list_port_forwards (only when port forwarding is enabled)You can prevent AI agents from querying specific Kubernetes resource types using the --disabled-resources flag or the MCP_KUBERNETES_RO_DISABLED_RESOURCES environment variable. This is particularly useful for preventing access to sensitive resources like Secrets.
Resources can be specified by name (singular, plural, kind, or short name) or as a full group/version/resource triple. The core keyword is used as an alias for the Kubernetes core API group. All names are resolved against the cluster's discovery API at startup, so singular names, kind names, and short names are all accepted:
# By resource name (resolved via the cluster's discovery API)
mcp-kubernetes-ro --disabled-resources=secrets
# Singular, kind, and short names all work
mcp-kubernetes-ro --disabled-resources=secret # singular
mcp-kubernetes-ro --disabled-resources=Secret # kind
mcp-kubernetes-ro --disabled-resources=cm # short name for configmaps
# Full group/version/resource format
mcp-kubernetes-ro --disabled-resources=core/v1/secrets
# Multiple resources (comma-separated or repeated flags)
mcp-kubernetes-ro --disabled-resources=secrets,configmaps
mcp-kubernetes-ro --disabled-resources=secrets --disabled-resources=configmaps
# Non-core API groups
mcp-kubernetes-ro --disabled-resources=apps/v1/deployments
# Using environment variable
export MCP_KUBERNETES_RO_DISABLED_RESOURCES=secrets,configmaps
mcp-kubernetes-ro
When a disabled resource is queried via list_resources or get_resource, the server returns a clear error:
access to resource "secrets" (core/v1/secrets) is disabled by configuration and cannot be queried
Disabled resources are also hidden from list_api_resources output, so AI agents won't discover them as available.
If a resource name cannot be resolved against the cluster (e.g., a typo or a CRD that doesn't exist), the server will refuse to start with a descriptive error — ensuring disabled resources always take effect.
By default, mcp-kubernetes-ro runs in stdio mode, which is suitable for integration with editors and other tools that communicate via standard input/output.
mcp-kubernetes-ro
Alternatively, you can run mcp-kubernetes-ro as an HTTP server with SSE support for web-based integrations:
mcp-kubernetes-ro --transport=sse --port=8080
In SSE mode, the server will listen on the specified port (default: 8080) and provide the same MCP tools over HTTP using Server-Sent Events. This is useful for web applications or environments where stdio communication isn't practical.
The following command-line flags are available to configure the MCP server:
--kubeconfig=PATH: Path to kubeconfig file (defaults to KUBECONFIG environment variable, then ~/.kube/config)--namespace=NAME: Default namespace for operations (defaults to current namespace)--transport=TYPE: Transport type: stdio or sse (default: stdio)--port=PORT: Port for SSE server (default: 8080, only used with --transport=sse)--disabled-tools=NAMES: Tool names to disable, repeatable and comma-separated (optional)--disabled-resources=RESOURCES: Resource types to block, repeatable and comma-separated (optional). Accepts resource names (secrets, deploy, cm) or full specs (core/v1/secrets, apps/v1/deployments)MCP_KUBERNETES_RO_DISABLED_TOOLS: Environment variable for disabled tools (merged with flag values, fallback: DISABLED_TOOLS)MCP_KUBERNETES_RO_DISABLED_RESOURCES: Environment variable for disabled resources (merged with flag values)--enable-port-forwarding: Enable port forwarding tools (disabled by default)MCP_KUBERNETES_RO_ENABLE_PORT_FORWARDING: App-specific environment variable (set to true, 1, or yes)ENABLE_PORT_FORWARDING: Generic environment variable (set to true, 1, or yes)The server supports per-command context. This provides more flexibility when working with multiple Kubernetes clusters or contexts within the same $KUBECONFIG file.
Configuration Priority:
context parameter in individual tool callsKubeconfig Resolution Priority:
--kubeconfig parameterKUBECONFIG environment variable~/.kube/configExamples:
{
"resource_type": "pods",
"namespace": "default",
"context": "production-cluster"
}
This approach allows you to:
Lists any Kubernetes resources by type with optional filtering, sorted newest first.
Arguments:
resource_type (required): The type of resource to list - use plural form (e.g., 'pods', 'deployments', 'services')api_version (optional): API version for the resource (e.g., 'v1', 'apps/v1')namespace (optional): Target namespace (leave empty for cluster-scoped resources)context (optional): Kubernetes context to use (defaults to current context from kubeconfig)label_selector (optional): Label selector to filter resources (e.g., 'app=nginx,version=1.0')field_selector (optional): Field selector to filter resources (e.g., 'status.phase=Running')limit (optional): Maximum number of resources to return (defaults to all)continue (optional): Continue token for pagination (from previous response)Example:
{
"resource_type": "pods",
"namespace": "default",
"context": "production",
"label_selector": "app=nginx"
}
Gets specific resource details with complete configuration.
Arguments:
resource_type (required): The type of resource to getname (required): Resource nameapi_version (optional): API version for the resource (e.g., 'v1', 'apps/v1')namespace (optional): Target namespace (required for namespaced resources)context (optional): Kubernetes context to use (defaults to current context from kubeconfig)Example:
{
"resource_type": "deployment",
"name": "nginx-deployment",
"namespace": "default",
"context": "production"
}
Gets pod logs with advanced filtering options including grep patterns, time filtering, and previous logs.
Arguments:
namespace (required): Pod namespacename (required): Pod namecontainer (optional): Container name (required for multi-container pods)context (optional): Kubernetes context to use (defaults to current context from kubeconfig)max_lines (optional): Maximum number of lines to retrievegrep_include (optional): Include only lines matching these patterns (comma-separated). Works like grep - includes lines containing any of these patternsgrep_exclude (optional): Exclude lines matching these patterns (comma-separated). Works like grep -v - excludes lines containing any of these patternsuse_regex (optional): Whether to treat grep patterns as regular expressions instead of literal stringssince (optional): Return logs newer than this time. Supports durations like "5m", "1h", "2h30m", "1d" or absolute times like "2023-01-01T10:00:00Z"previous (optional): Return logs from the previous terminated container instance (like kubectl logs --previous)Example:
{
"namespace": "default",
"name": "nginx-pod-12345",
"container": "nginx",
"context": "production",
"max_lines": "100",
"grep_include": "error,warning",
"since": "5m"
}
Lists containers in a pod for log access.
Arguments:
namespace (required): Pod namespacename (required): Pod namecontext (optional): Kubernetes context to use (defaults to current context from kubeconfig)Example:
{
"namespace": "default",
"name": "nginx-pod-12345",
"context": "production"
}
Lists available Kubernetes API resources with their details (similar to kubectl api-resources).
Arguments:
Example:
{}
Lists available Kubernetes contexts from the kubeconfig file. This is useful for discovering what contexts are available for use with the context parameter in other tools.
Arguments:
Example:
{}
Example Response:
{
"contexts": [
{
"name": "production",
"cluster": "prod-cluster",
"user": "prod-user",
"namespace": "default",
"current": true
},
{
"name": "staging",
"cluster": "staging-cluster",
"user": "staging-user",
"namespace": "staging",
"current": false
}
],
"count": 2
}
Gets node metrics (CPU and memory usage) from the metrics server. Results are sorted by timestamp (newest first) for consistent ordering and pagination, since the built-in metrics server endpoint does not support needle-based pagination.
Arguments:
node_name (optional): Specific node name to get metrics for. If not provided, returns metrics for all nodes.context (optional): Kubernetes context to use (defaults to current context from kubeconfig)limit (optional): Maximum number of node metrics to return. If not provided, returns all available metrics.continue (optional): Continue token for pagination (from previous response).Error Handling:
Example:
{
"node_name": "worker-node-1",
"context": "production",
"limit": 5
}
Example Response (Single Node):
{
"kind": "NodeMetrics",
"apiVersion": "metrics.k8s.io/v1beta1",
"metadata": {
"name": "worker-node-1",
"creationTimestamp": "2023-01-01T12:00:00Z"
},
"timestamp": "2023-01-01T12:00:00Z",
"window": "10.062s",
"usage": {
"cpu": "137m",
"memory": "1368128Ki"
}
}
Example Response (List with Pagination):
{
"kind": "NodeMetricsList",
"apiVersion": "metrics.k8s.io/v1beta1",
"count": 5,
"items": [
{
"kind": "NodeMetrics",
"metadata": { "name": "node-1" },
"timestamp": "2023-01-01T12:00:00Z",
"usage": { "cpu": "137m", "memory": "1368128Ki" }
}
],
"continue": "eyJvZmZzZXQiOjUsInR5cGUiOiJub2RlIiwibmFtZXNwYWNlIjoiIn0="
}
Gets pod metrics (CPU and memory usage) from the metrics server. Results are sorted by timestamp (newest first) for consistent ordering and pagination, since the built-in metrics server endpoint does not support needle-based pagination.
Arguments:
namespace (optional): Namespace to get pod metrics from. If not provided, returns metrics for all pods in all namespaces.pod_name (optional): Specific pod name to get metrics for. Requires namespace if specified.context (optional): Kubernetes context to use (defaults to current context from kubeconfig)limit (optional): Maximum number of pod metrics to return. If not provided, returns all available metrics.continue (optional): Continue token for pagination (from previous response).Error Handling:
namespace is provided when pod_name is specifiedPagination Notes:
Example (Specific Pod):
{
"namespace": "kube-system",
"pod_name": "metrics-server-557ff575fb-9dcl4",
"context": "production"
}
Example (With Pagination):
{
"namespace": "kube-system",
"context": "production",
"limit": 10,
"continue": "eyJvZmZzZXQiOjEwLCJ0eXBlIjoicG9kIiwibmFtZXNwYWNlIjoia3ViZS1zeXN0ZW0ifQ=="
}
Example Response (Single Pod):
{
"kind": "PodMetrics",
"apiVersion": "metrics.k8s.io/v1beta1",
"metadata": {
"name": "metrics-server-557ff575fb-9dcl4",
"namespace": "kube-system",
"creationTimestamp": "2023-01-01T12:00:00Z"
},
"timestamp": "2023-01-01T12:00:00Z",
"window": "18.888s",
"containers": [
{
"name": "metrics-server",
"usage": {
"cpu": "8020419n",
"memory": "48164Ki"
}
}
]
}
Example Response (List with Pagination):
{
"kind": "PodMetricsList",
"apiVersion": "metrics.k8s.io/v1beta1",
"namespace": "kube-system",
"count": 10,
"items": [
{
"kind": "PodMetrics",
"metadata": { "name": "pod-1", "namespace": "kube-system" },
"timestamp": "2023-01-01T12:00:00Z",
"containers": [
{
"name": "container-1",
"usage": { "cpu": "8020419n", "memory": "48164Ki" }
}
]
}
],
"continue": "eyJvZmZzZXQiOjIwLCJ0eXBlIjoicG9kIiwibmFtZXNwYWNlIjoia3ViZS1zeXN0ZW0ifQ=="
}
Encodes text data to base64 format.
Arguments:
data (required): Text data to encodeExample:
{
"data": "username:password"
}
Decodes base64 data to text format.
Arguments:
data (required): Base64 data to decodeExample:
{
"data": "dXNlcm5hbWU6cGFzc3dvcmQ="
}
Port forwarding is disabled by default because it goes beyond read-only operations. While it does not modify any cluster state (no resources are created, updated, or deleted), it establishes active network tunnels from your local machine to pod ports. This means traffic can flow through those tunnels, which could interact with the running application — for example, hitting an HTTP endpoint, connecting to a database, or triggering side effects in the target service. For this reason, port forwarding must be explicitly enabled.
Enable it with the --enable-port-forwarding flag or by setting the MCP_KUBERNETES_RO_ENABLE_PORT_FORWARDING environment variable to true.
[!WARNING] Port forwarding can target any pod in the cluster that your kubeconfig credentials have access to, including infrastructure pods. If the Kubernetes API server itself is running as a pod (e.g., in self-hosted or certain managed setups), an AI agent could theoretically forward to it. While port forwarding alone does not grant additional privileges — you still need valid credentials and RBAC permissions to authenticate against the API server — exposing the API server on a local port could lead to unintended interactions if other local tools or scripts discover it. Always review your RBAC policies and consider using
--disabled-resourcesalongside port forwarding to limit what the AI agent can discover and target.
[!WARNING] When running in SSE mode (
--transport=sse) on a remote server, forwarded ports bind to the server's local interface, not your workstation. This meanslocalhost:<local_port>refers to the machine wheremcp-kubernetes-rois running. To access forwarded services from your workstation, you must expose those ports — for example, via SSH tunneling (ssh -L <local_port>:localhost:<local_port> user@remote-host) or other network configuration. In stdio mode this is not an issue, as the server runs locally alongside your editor.
When enabled, three additional tools become available:
Establishes a port-forwarding session to a Kubernetes pod. Supports forwarding multiple ports in a single session. Each port mapping forwards a local port to a port on the pod. Set local_port to 0 (or omit it) to let the system auto-assign a free local port.
Arguments:
namespace (required): Pod namespacepod (required): Pod nameports (required): Array of port mappings, each with:
pod_port (required): Port on the pod to forward to (1-65535)local_port (optional): Local port to listen on (0 or omit for auto-assign)context (optional): Kubernetes context to use (defaults to current context from kubeconfig)Example (single port, auto-assign):
{
"namespace": "default",
"pod": "my-app-pod-abc123",
"ports": [
{ "pod_port": 8080 }
]
}
Example (multiple ports, explicit local ports):
{
"namespace": "default",
"pod": "my-app-pod-abc123",
"ports": [
{ "pod_port": 8080, "local_port": 18080 },
{ "pod_port": 5432, "local_port": 15432 }
]
}
Example Response:
{
"id": "pf-1",
"namespace": "default",
"pod": "my-app-pod-abc123",
"ports": [
{ "pod_port": 8080, "local_port": 18080 },
{ "pod_port": 5432, "local_port": 15432 }
],
"started_at": "2025-01-15T10:30:00Z"
}
Terminates an active port-forwarding session by its ID.
Arguments:
id (required): Port forward session ID (e.g., "pf-1")Example:
{
"id": "pf-1"
}
Example Response:
{
"id": "pf-1",
"stopped": true
}
Lists all active port-forwarding sessions with their port mappings and metadata. Takes no arguments.
Example:
{}
Example Response:
{
"count": 2,
"port_forwards": [
{
"id": "pf-1",
"namespace": "default",
"pod": "my-app-pod-abc123",
"ports": [
{ "pod_port": 8080, "local_port": 18080 }
],
"started_at": "2025-01-15T10:30:00Z"
},
{
"id": "pf-2",
"namespace": "monitoring",
"pod": "grafana-xyz789",
"ports": [
{ "pod_port": 3000, "local_port": 13000 }
],
"started_at": "2025-01-15T10:35:00Z"
}
]
}
list_port_forwards will no longer show the terminated session.SIGINT or SIGTERM), all active port-forward sessions are terminated.pf-1, pf-2). Use this ID with stop_port_forward to terminate a specific session.{
"mcpServers": {
"kubernetes-ro": {
"command": "mcp-kubernetes-ro",
"args": [
"--enable-port-forwarding"
],
"env": {
// Or use the environment variable instead of the flag:
// "MCP_KUBERNETES_RO_ENABLE_PORT_FORWARDING": "true"
}
}
}
}
# Start with default kubeconfig and context
mcp-kubernetes-ro
# Start with specific kubeconfig
mcp-kubernetes-ro --kubeconfig ~/.kube/config
# Start with KUBECONFIG environment variable
export KUBECONFIG=~/.kube/config
mcp-kubernetes-ro
# Start with specific namespace
mcp-kubernetes-ro --namespace kube-system
# Start in SSE mode
mcp-kubernetes-ro --transport=sse --port=3000
# Start with port forwarding enabled
mcp-kubernetes-ro --enable-port-forwarding
# Start with port forwarding via environment variable
export MCP_KUBERNETES_RO_ENABLE_PORT_FORWARDING=true
mcp-kubernetes-ro
# Production cluster with specific kubeconfig
mcp-kubernetes-ro \
--kubeconfig ~/.kube/prod-config \
--namespace monitoring
# Development setup with SSE mode using environment variable
export KUBECONFIG=~/.kube/dev-config
mcp-kubernetes-ro \
--transport=sse \
--port=8080
# Using per-command context (specify context in tool calls)
# Context is now specified at the tool level, not globally
# Disable specific tools for security or performance reasons
mcp-kubernetes-ro --disabled-tools=get_logs,decode_base64
# Disable metrics tools when metrics server is not available
mcp-kubernetes-ro --disabled-tools=get_node_metrics,get_pod_metrics
# Prevent AI agents from reading Secrets and ConfigMaps
mcp-kubernetes-ro --disabled-resources=secrets --disabled-resources=configmaps
# Lock down a production environment: no logs, no secrets, no base64 decoding
mcp-kubernetes-ro \
--kubeconfig ~/.kube/prod-config \
--disabled-tools=get_logs,decode_base64 \
--disabled-resources=secrets
# Use environment variables for disabled tools and resources
export MCP_KUBERNETES_RO_DISABLED_TOOLS=get_logs,decode_base64
export MCP_KUBERNETES_RO_DISABLED_RESOURCES=secrets
mcp-kubernetes-ro
While this MCP server provides comprehensive tools for Kubernetes cluster inspection, some AI assistants may have limitations or policies that prevent them from using certain tool combinations, even when technically available:
get_resource and decode_base64 tools) due to security policies around credential handlingIf your AI assistant refuses to use available tools for security reasons:
Direct CLI Access: Use kubectl directly for sensitive operations, and just ask the AI to give you the command to run, for example:
kubectl get secret <secret-name> -n <namespace> -o yaml
echo "<base64-data>" | base64 -d
Manual Tool Usage: If using the MCP server programmatically, call the tools directly rather than through an AI assistant
Documentation: Consider the security implications - the AI's refusal might actually be protecting you from inadvertent credential exposure
This behavior reflects different approaches to security:
Both perspectives are valid, and this limitation should be considered when designing workflows that involve sensitive data retrieval.
The MCP server performs an automatic connectivity check on startup to verify that it can successfully connect to your Kubernetes cluster. This check includes:
On successful startup, you'll see output like:
Testing connectivity to Kubernetes cluster...
✓ Successfully connected to Kubernetes cluster (version: v1.28.0)
If the connectivity check fails, you'll see a detailed error message. Common issues include:
The connectivity check has a 10-second timeout to prevent hanging on unresponsive clusters.
--always-start)If your credentials are granted via an OIDC browser-flow or another mechanism where the token is not yet valid when the MCP server process starts, use the --always-start flag (or MCP_KUBERNETES_RO_ALWAYS_START=true environment variable) to skip the startup connectivity check entirely:
mcp-kubernetes-ro --always-start
With --always-start, the server starts immediately without contacting the cluster. The connectivity check is effectively deferred: the first time a tool is called, it will attempt to reach the cluster normally. If the cluster is unreachable or the credentials have expired at that point, the tool will return a structured error message to the AI instructing it not to retry automatically and to prompt you to re-authenticate.
Resource filters configured via --disabled-resources are similarly deferred: name resolution happens on the first tool call rather than at startup, so no cluster connection is required to start the server.
get, list, watch)--disabled-resourcesThe metrics tools (get_node_metrics and get_pod_metrics) include sophisticated error detection for metrics server availability:
metrics-server service not foundmetrics.k8s.io API group unavailableBoth metrics tools implement client-side pagination for consistent results, since the built-in metrics server endpoint does not support needle-based pagination, and also to provide a safe way for AI tools to request just the data they need, especially useful in small context windows.
offset: Current position in the result settype: Resource type ("node" or "pod")namespace: Context namespace (for pod metrics)eyJvZmZzZXQiOjEwLCJ0eXBlIjoicG9kIiwibmFtZXNwYWNlIjoia3ViZS1zeXN0ZW0ifQ==The server provides detailed error messages for common issues:
MCP server integration for DaVinci Resolve Studio
mcp-language-server gives MCP enabled clients access semantic tools like get definition, references, rename, and diagnos
Run Claude Code as an MCP server so any agent can delegate coding tasks to it
Browser automation using accessibility snapshots instead of screenshots