Skip to main content
Glama

k8s-pilot-ci

The Central Pilot for Your Kubernetes Fleets ✈️✈️

k8s_pilot is a lightweight, centralized control plane server for managing multiple Kubernetes clusters at once.
With powerful tools and intuitive APIs, you can observe and control all your clusters from one cockpit.


πŸš€ Overview

  • πŸ”„ Supports multi-cluster context switching

  • πŸ”§ Enables CRUD operations on most common Kubernetes resources

  • πŸ”’ Readonly mode for safe cluster inspection

  • βš™οΈ Powered by MCP for Claude AI and beyond

  • 🌐 Streamable HTTP transport support for remote access

  • πŸ€– MCP Prompts for guided operations

  • πŸ“ Context-aware logging for write operations


Related MCP server: Multi-Cluster MCP Server

🧰 Prerequisites

  • Python 3.13 or higher

  • uv package manager

  • Access to Kubernetes clusters (~/.kube/config or in-cluster config)

# Install uv (if not installed)

# For MacOS
brew install uv

# For Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

Installation

# Clone the repository
git clone https://github.com/bourbonkk/k8s-pilot.git
cd k8s-pilot

# Launch with uv + MCP
uv run --with "mcp[cli]>=1.28.0,<2" python k8s_pilot.py

πŸ†• What's New in v2.0

  • Streamable HTTP Transport: Remote cluster management via HTTP (in addition to stdio)

  • MCP Prompts: Built-in prompt templates for common K8s operations

  • Context-aware Logging: Write operations now report progress via MCP context

  • Bug Fixes: Fixed missing API clients for Ingress and RBAC resources

  • Security: Added readonly checks for node modification operations

  • Dockerfile: Modernized with uv package manager for faster builds

Usage

Normal Mode (Full Access)

# Start with full read/write access
uv run --with "mcp[cli]>=1.28.0,<2" python k8s_pilot.py

Readonly Mode (Safe Inspection)

# Start in readonly mode - only read operations allowed
uv run --with "mcp[cli]>=1.28.0,<2" python k8s_pilot.py --readonly

Streamable HTTP Mode (Remote Access)

# Start with Streamable HTTP transport for remote access
uv run --with "mcp[cli]>=1.28.0,<2" python k8s_pilot.py --transport streamable-http

Command Line Options

# Show help
uv run --with "mcp[cli]>=1.28.0,<2" python k8s_pilot.py --help

Run via Docker

You can run k8s-pilot directly using the published Docker image without installing uv locally. Make sure to mount your ~/.kube/config so the container can access your clusters.

docker run -i --rm \
  -v ~/.kube/config:/root/.kube/config \
  ghcr.io/bourbonkk/k8s-pilot:latest

Readonly Mode

The --readonly flag enables a safety mode that prevents any write operations to your Kubernetes clusters. This is perfect for:

  • Cluster inspection without risk of accidental changes

  • Audit scenarios where you need to view but not modify

  • Learning environments where you want to explore safely

  • Production monitoring with zero risk of modifications

Protected Operations (Blocked in Readonly Mode)

  • pod_create, pod_update, pod_delete

  • deployment_create, deployment_update, deployment_delete

  • service_create, service_update, service_delete

  • configmap_create, configmap_update, configmap_delete

  • secret_create, secret_update, secret_delete

  • namespace_create, namespace_delete

  • All other create/update/delete operations

Allowed Operations (Always Available)

  • pod_list, pod_detail, pod_logs

  • deployment_list, deployment_get

  • service_list, service_get

  • configmap_list, configmap_get

  • secret_list, secret_get

  • namespace_list, namespace_get

  • All other list/get operations

MCP Prompts

k8s-pilot includes built-in prompt templates for common operations:

Prompt

Description

troubleshoot_pod

Step-by-step pod troubleshooting guide

deployment_guide

Guided application deployment workflow

cluster_health_check

Comprehensive cluster health assessment

namespace_cleanup

Safe namespace cleanup procedure

Usage with Claude Desktop

Use this config to run k8s_pilot MCP server from within Claude:

{
  "mcpServers": {
    "k8s_pilot": {
      "command": "uv",
      "args": [
        "--directory",
        "<path-to-cloned-repo>/k8s-pilot",
        "run",
        "--with",
        "mcp[cli]>=1.28.0,<2",
        "python",
        "k8s_pilot.py"
      ]
    }
  }
}

For readonly mode, use this configuration:

{
  "mcpServers": {
    "k8s_pilot_readonly": {
      "command": "uv",
      "args": [
        "--directory",
        "<path-to-cloned-repo>/k8s-pilot",
        "run",
        "--with",
        "mcp[cli]>=1.28.0,<2",
        "python",
        "k8s_pilot.py",
        "--readonly"
      ]
    }
  }
}

For Docker, use this configuration (replace YOUR_USERNAME with your actual Mac user name):

{
  "mcpServers": {
    "k8s_pilot_docker": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-v",
        "/Users/YOUR_USERNAME/.kube/config:/root/.kube/config",
        "ghcr.io/bourbonkk/k8s-pilot:latest"
      ]
    }
  }
}

Replace <path-to-cloned-repo> with the actual directory where you cloned the repo.

Scenario

Create a Deployment using the nginx:latest image in the pypy namespace, and also create a Service that connects to it. deployα„‹α…ͺ ᄉα…₯바스ᄉᅒᆼᄉα…₯α†Ό(α„‹α…§α†Όα„‹α…₯

Key Features

Multi-Cluster Management

  • Seamlessly interact with multiple Kubernetes clusters

  • Perform context-aware operations

  • Easily switch between clusters via MCP prompts

Resource Control

  • View, create, update, delete:

    • Deployments, Services, Pods

    • ConfigMaps, Secrets, Ingresses

    • StatefulSets, DaemonSets

    • Roles, ClusterRoles

    • PersistentVolumes & Claims

Namespace Operations

  • Create/delete namespaces

  • List all resources in a namespace

  • Manage labels and resource quotas

Node Management

  • View node details and conditions

  • Cordon/uncordon, label/taint nodes

  • List pods per node

License

This project is licensed under the MIT License. See the LICENSE file for details.

Available Tools

57 tools
add_namespace_labelB

Add or update a label on a namespace.

Args: context_name: The Kubernetes context name namespace: The name of the namespace label_key: The label key to add label_value: The label value to set

Returns: JSON string containing the updated namespace labels

Inputs: label_key (required), namespace (required), label_value (required), context_name (required).

add_node_labelB

Add or update a label to a node.

Args: context_name: The Kubernetes context name node_name: The name of the node to modify label_key: The label key to add label_value: The label value to set

Returns: JSON string containing the updated node labels

Inputs: label_key (required), node_name (required), label_value (required), context_name (required).

clusterrole_createC

Create a ClusterRole in the cluster.

Args: context_name: The Kubernetes context name name: The ClusterRole name rules: List of policy rules

Returns: Status of the creation operation

Inputs: name (required), rules (required), context_name (required).

clusterrole_deleteB

Delete a ClusterRole from the cluster.

Args: context_name: The Kubernetes context name name: The ClusterRole name

Returns: Status of the deletion operation

Inputs: name (required), context_name (required).

clusterrole_getC

Get details of a specific ClusterRole.

Args: context_name: The Kubernetes context name name: The ClusterRole name

Returns: Detailed information about the ClusterRole

Inputs: name (required), context_name (required).

clusterrole_listC

List all ClusterRoles in the cluster.

Args: context_name: The Kubernetes context name

Returns: List of ClusterRole basic information

Inputs: context_name (required).

configmap_createB

Create a ConfigMap in the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The ConfigMap name data: The data to store in the ConfigMap

Returns: Status of the creation operation

Inputs: data (required), name (required), namespace (required), context_name (required).

configmap_deleteB

Delete a ConfigMap from the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The ConfigMap name

Returns: Status of the deletion operation

Inputs: name (required), namespace (required), context_name (required).

configmap_getB

Get details of a specific ConfigMap.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The ConfigMap name

Returns: Detailed information about the ConfigMap

Inputs: name (required), namespace (required), context_name (required).

configmap_listB

List all ConfigMaps in a given namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace

Returns: List of ConfigMap basic information

Inputs: namespace (required), context_name (required).

configmap_updateB

Update an existing ConfigMap in the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The ConfigMap name data: The new data to update in the ConfigMap

Returns: Status of the update operation

Inputs: data (required), name (required), namespace (required), context_name (required).

create_namespaceB

Create a new namespace.

Args: context_name: The Kubernetes context name namespace: The name for the new namespace labels: Optional dictionary of labels to apply to the namespace

Returns: JSON string containing information about the created namespace

Inputs: namespace (required), context_name (required), labels.

daemonset_updateC

Update an existing DaemonSet in the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The DaemonSet name image: The new container image to update

Returns: Status of the update operation

Inputs: name (required), image (required), namespace (required), context_name (required).

delete_namespaceB

Delete a namespace and all resources within it.

Args: context_name: The Kubernetes context name namespace: The name of the namespace to delete

Returns: JSON string containing the result of the operation

Inputs: namespace (required), context_name (required).

deployment_deleteB

Delete a Deployment from the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Deployment name

Returns: Status of the deletion operation

Inputs: name (required), namespace (required), context_name (required).

deployment_listB

List all Deployments in a given namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace

Returns: List of Deployment basic information

Inputs: namespace (required), context_name (required).

deployment_updateB

Update an existing Deployment in the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Deployment name image: The new container image to update replicas: The new number of replicas

Returns: Status of the update operation

Inputs: name (required), image (required), replicas (required), namespace (required), +1 more.

get_clustersC

Get all clusters from the kubeconfig file. :return:

Inputs: no named parameters.

get_current_clusterC

Get the current cluster from the kubeconfig file. :return:

Inputs: no named parameters.

get_namespace_detailsC

Get detailed information about a specific namespace.

Args: context_name: The Kubernetes context name namespace: The name of the namespace to get details for

Returns: JSON string containing detailed information about the namespace

Inputs: namespace (required), context_name (required).

get_node_detailsC

Get detailed information about a specific node.

Args: context_name: The Kubernetes context name node_name: The name of the node to get details for

Returns: JSON string containing detailed information about the node

Inputs: node_name (required), context_name (required).

ingress_createB

Create an Ingress in the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Ingress name host: The host for the Ingress service_name: The backend service name service_port: The backend service port

Returns: Status of the creation operation

Inputs: host (required), name (required), namespace (required), context_name (required), +2 more.

ingress_deleteB

Delete an Ingress from the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Ingress name

Returns: Status of the deletion operation

Inputs: name (required), namespace (required), context_name (required).

ingress_getC

Get details of a specific Ingress.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Ingress name

Returns: Detailed information about the Ingress

Inputs: name (required), namespace (required), context_name (required).

ingress_listB

List all Ingresses in a given namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace

Returns: List of Ingress basic information

Inputs: namespace (required), context_name (required).

ingress_updateB

Update an existing Ingress in the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Ingress name host: The new host for the Ingress service_name: The new backend service name service_port: The new backend service port

Returns: Status of the update operation

Inputs: host (required), name (required), namespace (required), context_name (required), +2 more.

list_namespacesB

List all namespaces in the Kubernetes cluster.

Args: context_name: The Kubernetes context name

Returns: JSON string containing basic information about all namespaces

Inputs: context_name (required).

list_nodesB

List all nodes in the Kubernetes cluster.

Args: context_name: The Kubernetes context name

Returns: JSON string containing basic information about all nodes

Inputs: context_name (required).

pod_detailC

Get details of a specific pod.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The pod name

Returns: Detailed information about the pod

Inputs: name (required), namespace (required), context_name (required).

pod_logsB

Get logs from a pod or a specific container within the pod.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The pod name container: Optional container name (if pod has multiple containers) tail_lines: Number of lines to retrieve from the end of the logs previous: Whether to get logs from a previous instance of the container

Returns: Pod logs

Inputs: name (required), namespace (required), context_name (required), previous, +2 more.

pod_updateB

Update an existing pod's metadata (only labels can be updated for an existing pod).

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The pod name labels: New labels to apply to the pod

Returns: Information about the updated pod

Inputs: name (required), namespace (required), context_name (required), labels.

pvc_deleteB

Delete a PersistentVolumeClaim from the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The PersistentVolumeClaim name

Returns: Status of the deletion operation

Inputs: name (required), namespace (required), context_name (required).

pvc_getC

Get details of a specific PersistentVolumeClaim.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The PersistentVolumeClaim name

Returns: Detailed information about the PersistentVolumeClaim

Inputs: name (required), namespace (required), context_name (required).

pvc_listB

List all PersistentVolumeClaims in a given namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace

Returns: List of PersistentVolumeClaim basic information

Inputs: namespace (required), context_name (required).

pv_createB

Create a PersistentVolume in the cluster.

Args: context_name: The Kubernetes context name name: The PersistentVolume name capacity: The storage capacity (e.g., "10Gi") access_modes: List of access modes (e.g., ["ReadWriteOnce"]) storage_class: The storage class name host_path: The host path for the volume

Returns: Status of the creation operation

Inputs: name (required), capacity (required), host_path (required), access_modes (required), +2 more.

pv_deleteC

Delete a PersistentVolume from the cluster.

Args: context_name: The Kubernetes context name name: The PersistentVolume name

Returns: Status of the deletion operation

Inputs: name (required), context_name (required).

pv_updateC

Update an existing PersistentVolume's metadata (e.g., labels).

Args: context_name: The Kubernetes context name name: The PersistentVolume name labels: New labels to apply to the PersistentVolume

Returns: Status of the update operation

Inputs: name (required), labels (required), context_name (required).

remove_namespace_labelC

Remove a label from a namespace.

Args: context_name: The Kubernetes context name namespace: The name of the namespace label_key: The label key to remove

Returns: JSON string containing the updated namespace labels

Inputs: label_key (required), namespace (required), context_name (required).

remove_node_labelC

Remove a label from a node.

Args: context_name: The Kubernetes context name node_name: The name of the node to modify label_key: The label key to remove

Returns: JSON string containing the updated node labels

Inputs: label_key (required), node_name (required), context_name (required).

remove_node_taintB

Remove a taint from a node.

Args: context_name: The Kubernetes context name node_name: The name of the node to modify taint_key: The taint key to remove

Returns: JSON string containing the updated node taints

Inputs: node_name (required), taint_key (required), context_name (required).

replicaset_createB

Create a ReplicaSet in the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The ReplicaSet name image: The container image to use replicas: Number of replicas labels: Labels to apply to the ReplicaSet

Returns: Status of the creation operation

Inputs: name (required), image (required), labels (required), replicas (required), +2 more.

replicaset_getC

Get details of a specific ReplicaSet.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The ReplicaSet name

Returns: Detailed information about the ReplicaSet

Inputs: name (required), namespace (required), context_name (required).

replicaset_listB

List all ReplicaSets in a given namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace

Returns: List of ReplicaSet basic information

Inputs: namespace (required), context_name (required).

role_createB

Create a Role in the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Role name rules: List of policy rules

Returns: Status of the creation operation

Inputs: name (required), rules (required), namespace (required), context_name (required).

role_deleteB

Delete a Role from the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Role name

Returns: Status of the deletion operation

Inputs: name (required), namespace (required), context_name (required).

role_getB

Get details of a specific Role.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Role name

Returns: Detailed information about the Role

Inputs: name (required), namespace (required), context_name (required).

role_listC

List all Roles in a given namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace

Returns: List of Role basic information

Inputs: namespace (required), context_name (required).

secret_createB

Create a Secret in the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Secret name data: A dictionary of key-value pairs (values will be base64 encoded) secret_type: The type of the Secret (default is "Opaque")

Returns: Status of the creation operation

Inputs: data (required), name (required), namespace (required), context_name (required), +1 more.

secret_deleteA

Delete a Secret from the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Secret name

Returns: Status of the deletion operation

Inputs: name (required), namespace (required), context_name (required).

secret_listC

List all Secrets in a given namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace

Returns: List of Secret basic information

Inputs: namespace (required), context_name (required).

serviceaccount_listC

List all ServiceAccounts in a given namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace

Returns: List of ServiceAccount basic information

Inputs: namespace (required), context_name (required).

service_createB

Create a Service in the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Service name selector: A dictionary of labels to select the target pods ports: A list of ports (e.g., [{"port": 80, "target_port": 8080}]) service_type: The type of the Service (default is "ClusterIP")

Returns: Status of the creation operation

Inputs: name (required), ports (required), selector (required), namespace (required), +2 more.

service_deleteC

Delete a Service from the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Service name

Returns: Status of the deletion operation

Inputs: name (required), namespace (required), context_name (required).

service_updateC

Update an existing Service's metadata (e.g., labels).

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The Service name labels: New labels to apply to the Service

Returns: Status of the update operation

Inputs: name (required), labels (required), namespace (required), context_name (required).

statefulset_createC

Create a StatefulSet in the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The StatefulSet name image: The container image to use replicas: Number of replicas labels: Labels to apply to the StatefulSet

Returns: Status of the creation operation

Inputs: name (required), image (required), labels (required), replicas (required), +2 more.

statefulset_deleteB

Delete a StatefulSet from the specified namespace.

Args: context_name: The Kubernetes context name namespace: The Kubernetes namespace name: The StatefulSet name

Returns: Status of the deletion operation

Inputs: name (required), namespace (required), context_name (required).

uncordon_nodeC

Uncordon a node (mark as schedulable).

Args: context_name: The Kubernetes context name node_name: The name of the node to uncordon

Returns: JSON string containing the result of the operation

Inputs: node_name (required), context_name (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.9/5.0

    Scored across 57 tools

    Disambiguation5/5

    Each tool targets a distinct Kubernetes resource or operation (e.g., clusterrole_create vs clusterrole_delete, pod_logs vs pod_detail). There is no ambiguity between tools as they clearly differentiate by resource and action.

    Naming Consistency2/5

    Tool names mix styles: some use verb_noun (e.g., create_namespace), others use noun_verb (e.g., configmap_create). Additionally, there are inconsistencies like plural vs singular (list_namespaces vs clusterrole_list). This makes naming unpredictable.

    Tool Count3/5

    57 tools is high for a Kubernetes MCP server. While the scope is broad, many tools are redundant or could be combined (e.g., separate add/remove label tools for namespaces and nodes). The count exceeds typical ranges, but it is still manageable.

    Completeness2/5

    The server covers various resources but has notable gaps: missing deployment_create and deployment_get, no pod creation, no support for common resources like HPA, NetworkPolicy, or RBAC bindings. This limits its ability to perform complete workflows.

    Maintenance

    ActivityStale
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      A Model Context Protocol server that enables AI assistants to interact with Kubernetes clusters through natural language, supporting core Kubernetes operations, monitoring, security, and diagnostics.
      169 npm
      972
      MIT
    • F
      license
      B
      quality
      D
      maintenance
      A gateway for Generative AI systems to interact with multiple Kubernetes clusters through Model Context Protocol, enabling comprehensive Kubernetes resource operations and multi-cluster management.
      4
      54 npm
      5
      -
    • F
      license
      Not graded
      quality
      D
      maintenance
      An MCP server that enables interaction with multiple Kubernetes clusters simultaneously, providing comprehensive tools for cluster management, resource operations, and diagnostics across different environments.
      -
    • A
      license
      Not graded
      quality
      D
      maintenance
      A Model Context Protocol server that lets AI assistants query multiple Kubernetes clusters simultaneously using natural language.
      3
      MIT