# K8s Mcp Server

> Manage Your Kubernetes Cluster with k8s mcp-server

- **Type:** MCP server
- **Install:** `agentstack add mcp-reza-gholizade-k8s-mcp-server`
- **Verified:** Pending review
- **Seller:** [reza-gholizade](https://agentstack.voostack.com/s/reza-gholizade)
- **Installs:** 0
- **Category:** [Cloud & Infrastructure](https://agentstack.voostack.com/c/cloud-infrastructure)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [reza-gholizade](https://github.com/reza-gholizade)
- **Source:** https://github.com/reza-gholizade/k8s-mcp-server

## Install

```sh
agentstack add mcp-reza-gholizade-k8s-mcp-server
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Kubernetes MCP Server

A Kubernetes Model Context Protocol (MCP) server that provides tools for interacting with Kubernetes clusters through a standardized interface.

## Hosted deployment

A hosted deployment is available on [Fronteir AI](https://fronteir.ai/mcp/reza-gholizade-k8s-mcp-server).

## Features

- **API Resource Discovery**: Get all available API resources in your Kubernetes cluster.
- **Resource Listing**: List resources of any type with optional namespace and label filtering.
- **Resource Details**: Get detailed information about specific Kubernetes resources.
- **Resource Description**: Get comprehensive descriptions of Kubernetes resources, similar to `kubectl describe`.
- **Pod Logs**: Retrieve logs from specific pods (optionally from a specific container, or all containers if unspecified).
- **Node Metrics**: Get resource usage metrics for specific nodes.
- **Pod Metrics**: Get CPU and Memory metrics for specific pods.
- **Event Listing**: List events within a namespace or for a specific resource.
- **Resource Creation/Updating**: Create new Kubernetes resources or update existing ones from a YAML or JSON manifest.
- **Resource Deletion**: It deletes a resource in the Kubernetes cluster based on the provided namespace and kind.
- **Standardized Interface**: Uses the MCP protocol for consistent tool interaction.
- **Flexible Configuration**: Supports different Kubernetes contexts and resource scopes.
- **Multiple Modes**: Run in `stdio` mode for CLI tools, `sse` mode, or `streamable-http` mode for web applications, and `--readonly` for no change in the cluster.
- **Security**: Runs as non-root user in Docker containers for enhanced security.

## Prerequisites

- Go 1.23 or later
- Access to a Kubernetes cluster
- `kubectl` configured with appropriate cluster access

## Installation

1.  **Clone the repository:**
    ```bash
    git clone https://github.com/reza-gholizade/k8s-mcp-server.git
    cd k8s-mcp-server
    ```

2.  **Install dependencies:**
    ```bash
    go mod download
    ```

3.  **Build the server:**
    ```bash
    go build -o k8s-mcp-server main.go
    ```

## Usage

### Starting the Server

The server can run in three modes, configurable via command-line flags or environment variables.

#### Stdio Mode (for CLI integrations)
This mode uses standard input/output for communication.

```bash
./k8s-mcp-server --mode stdio
```
Or using environment variables:
```bash
SERVER_MODE=stdio ./k8s-mcp-server
```

#### SSE Mode (for web applications)
This mode starts an HTTP server with Server-Sent Events support.

Default (port 8080):
```bash
./k8s-mcp-server --mode sse
```
Specify a port:
```bash
./k8s-mcp-server --mode sse --port 9090
```
Or using environment variables:
```bash
SERVER_MODE=sse SERVER_PORT=9090 ./k8s-mcp-server
```
#### Streamable-HTTP Mode (for web applications)
This mode starts an HTTP server with streamable-http transport support, following the MCP specification.

Default (port 8080):
```bash
./k8s-mcp-server --mode streamable-http
```
Specify a port:
```bash
./k8s-mcp-server --mode streamable-http --port 9090
```
Or using environment variables:
```bash
SERVER_MODE=streamable-http SERVER_PORT=9090 ./k8s-mcp-server
```

The server will be available at `http://localhost:8080/mcp` (or your specified port).

If no mode is specified, it defaults to SSE on port 8080.

### Kubernetes Authentication

The server supports multiple authentication methods, which are tried in the following order of priority:

#### 1. Kubeconfig Content from Environment Variable

You can provide the entire kubeconfig file content via the `KUBECONFIG_DATA` environment variable:

```bash
export KUBECONFIG_DATA="$(cat ~/.kube/config)"
./k8s-mcp-server
```

This is useful when you want to avoid mounting files or when running in environments where file access is restricted.

#### 2. API Server URL and Token

You can authenticate using a Kubernetes API server URL and bearer token:

```bash
export KUBERNETES_SERVER="https://kubernetes.example.com:6443"
export KUBERNETES_TOKEN="your-bearer-token-here"
./k8s-mcp-server
```

Optional environment variables for TLS configuration:
- `KUBERNETES_CA_CERT`: CA certificate content (base64-encoded or PEM format)
- `KUBERNETES_CA_CERT_PATH`: Path to CA certificate file
- `KUBERNETES_INSECURE`: Set to `"true"` to skip TLS verification (not recommended for production)

Example with CA certificate:
```bash
export KUBERNETES_SERVER="https://kubernetes.example.com:6443"
export KUBERNETES_TOKEN="your-bearer-token-here"
export KUBERNETES_CA_CERT_PATH="/path/to/ca.crt"
./k8s-mcp-server
```

#### 3. In-Cluster Authentication (Service Account)

When running inside a Kubernetes cluster, the server automatically detects and uses the service account token from `/var/run/secrets/kubernetes.io/serviceaccount/token`. This is the recommended method for running the server as a pod within a cluster.

**Example Deployment:**

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: k8s-mcp-server-sa
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: k8s-mcp-server-role
rules:
  - apiGroups: [""]
    resources: ["*"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  - apiGroups: ["apps"]
    resources: ["*"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  # Add more rules as needed for your use case
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: k8s-mcp-server-rb
subjects:
  - kind: ServiceAccount
    name: k8s-mcp-server-sa
    namespace: default
roleRef:
  kind: ClusterRole
  name: k8s-mcp-server-role
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8s-mcp-server
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: k8s-mcp-server
  template:
    metadata:
      labels:
        app: k8s-mcp-server
    spec:
      serviceAccountName: k8s-mcp-server-sa
      containers:
        - name: k8s-mcp-server
          image: ginnux/k8s-mcp-server:latest
          ports:
            - containerPort: 8080
          env:
            - name: SERVER_MODE
              value: "sse"
            - name: SERVER_PORT
              value: "8080"
```

#### 4. Kubeconfig File Path (Default)

If none of the above methods are available, the server falls back to using a kubeconfig file:

- Uses the path provided via `--kubeconfig` flag (if implemented) or `KUBECONFIG` environment variable
- Defaults to `~/.kube/config` if neither is specified

```bash
# Using default ~/.kube/config
./k8s-mcp-server

# Using custom kubeconfig path
export KUBECONFIG=/path/to/your/kubeconfig
./k8s-mcp-server
```

**Note:** The server automatically detects which authentication method to use based on the available environment variables and file system. You don't need to explicitly configure the authentication method - it will use the first available method in the priority order listed above.

#### Read-Only Mode

The server supports a read-only mode that disables all write operations, providing a safer way to explore and monitor your Kubernetes cluster without the risk of making changes.

Enable read-only mode with the `--read-only` flag:

```bash
./k8s-mcp-server --read-only
```

You can combine read-only mode with any server mode:

```bash
# Read-only with stdio mode
./k8s-mcp-server --mode stdio --read-only

# Read-only with SSE mode
./k8s-mcp-server --mode sse --read-only

# Read-only with streamable-http mode
./k8s-mcp-server --mode streamable-http --read-only
```

When read-only mode is enabled, the following tools are disabled:
- `createResource` (Kubernetes resource creation/updates)
- `helmInstall` (Helm chart installations)
- `helmUpgrade` (Helm chart upgrades)
- `helmUninstall` (Helm chart uninstallations)
- `helmRollback` (Helm release rollbacks)
- `helmRepoAdd` (Helm repository additions)

All other read-only operations remain available, including listing resources, getting logs, viewing metrics, and inspecting Helm releases.

#### Tool Category Flags
You can selectively disable entire categories of tools using these flags:

**Disable Kubernetes Tools:**
```bash
./k8s-mcp-server --no-k8s
```

**Disable Helm Tools:**
```bash
./k8s-mcp-server --no-helm
```

**Combine with other flags:**
```bash
# Read-only mode with only Kubernetes tools (no Helm)
./k8s-mcp-server --read-only --no-helm

# Read-only mode with only Helm tools (no Kubernetes)
./k8s-mcp-server --read-only --no-k8s

# SSE mode with only Kubernetes tools
./k8s-mcp-server --mode sse --no-helm

```

**Note:** You cannot use both `--no-k8s` and `--no-helm` together, as this would result in no available tools. The server will exit with an error if both flags are provided.

When `--no-k8s` is enabled, all Kubernetes tools are disabled:
- `getAPIResources`, `listResources`, `getResource`, `describeResource`
- `getPodsLogs`, `getNodeMetrics`, `getPodMetrics`, `getEvents`
- `createResource` (if not in read-only mode)

When `--no-helm` is enabled, all Helm tools are disabled:
- `helmList`, `helmGet`, `helmHistory`, `helmRepoList`
- `helmInstall`, `helmUpgrade`, `helmUninstall`, `helmRollback`, `helmRepoAdd` (if not in read-only mode)

### Using the Docker Image

You can also run the server using the pre-built Docker image from Docker Hub.

1.  **Pull the image:**
    ```bash
    docker pull ginnux/k8s-mcp-server:latest
    ```
    You can replace `latest` with a specific version tag (e.g., `1.0.0`).

2.  **Run the container:**

    **Note:** The server supports multiple authentication methods. You can either mount a kubeconfig file (as shown below) or use environment variables for authentication (see [Kubernetes Authentication](#kubernetes-authentication) section above).

    *   **SSE Mode (default behavior of the image):**
        ```bash
        docker run -p 8080:8080 -v ~/.kube/config:/home/appuser/.kube/config:ro ginnux/k8s-mcp-server:latest
        ```
        This maps port 8080 of the container to port 8080 on your host and mounts your Kubernetes config read-only to the non-root user's home directory. The server will be available at `http://localhost:8080`. The image defaults to `sse` mode on port `8080`.

    *   **Streamable-HTTP Mode:**
        ```bash
        docker run -p 8080:8080 -v ~/.kube/config:/home/appuser/.kube/config:ro ginnux/k8s-mcp-server:latest --mode streamable-http
        ```
        This runs the server in streamable-http mode. The server will be available at `http://localhost:8080/mcp`.

    *   **Stdio Mode:**
        ```bash
        docker run -i --rm -v ~/.kube/config:/home/appuser/.kube/config:ro ginnux/k8s-mcp-server:latest --mode stdio
        ```
        The `-i` flag is important for interactive stdio communication. `--rm` cleans up the container after exit.

    *   **Custom Port for SSE Mode:**
        ```bash
        docker run -p 9090:9090 -v ~/.kube/config:/home/appuser/.kube/config:ro ginnux/k8s-mcp-server:latest --mode sse --port 9090
        ```

    *   **Custom Port for Streamable-HTTP Mode:**
        ```bash
        docker run -p 9090:9090 -v ~/.kube/config:/home/appuser/.kube/config:ro ginnux/k8s-mcp-server:latest --mode streamable-http --port 9090
        ```

    *   **Alternative: Mount entire .kube directory:**
        ```bash
        docker run -p 8080:8080 -v ~/.kube:/home/appuser/.kube:ro ginnux/k8s-mcp-server:latest
        ```

    *   **Using environment variables for authentication (no file mounting required):**
        ```bash
        # Using kubeconfig content from environment variable
        docker run -p 8080:8080 \
          -e KUBECONFIG_DATA="$(cat ~/.kube/config)" \
          ginnux/k8s-mcp-server:latest

        # Or using API server URL and token
        docker run -p 8080:8080 \
          -e KUBERNETES_SERVER="https://kubernetes.example.com:6443" \
          -e KUBERNETES_TOKEN="your-token-here" \
          -e KUBERNETES_CA_CERT_PATH="/path/to/ca.crt" \
          -v /path/to/ca.crt:/path/to/ca.crt:ro \
          ginnux/k8s-mcp-server:latest
        ```

#### Using with Docker Compose

Create a `docker-compose.yml` file:

**Option 1: Using kubeconfig file (traditional method):**
```yaml
version: '3.8'
services:
  k8s-mcp-server:
    image: ginnux/k8s-mcp-server:latest # Or a specific version
    container_name: k8s-mcp-server
    ports:
      - "8080:8080" # Host:Container, adjust if using a different SERVER_PORT
    volumes:
      - ~/.kube:/home/appuser/.kube:ro # Mount kubeconfig read-only to non-root user home
    environment:
      - KUBECONFIG=/home/appuser/.kube/config
      - SERVER_MODE=sse # Can be 'stdio', 'sse', or 'streamable-http'
      - SERVER_PORT=8080 # Port for SSE/streamable-http modes
    # command: ["--read-only"] # Uncomment this line to enable read-only mode
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s
```

**Option 2: Using environment variables (no file mounting):**
```yaml
version: '3.8'
services:
  k8s-mcp-server:
    image: ginnux/k8s-mcp-server:latest
    container_name: k8s-mcp-server
    ports:
      - "8080:8080"
    environment:
      - KUBECONFIG_DATA=${KUBECONFIG_DATA} # Set this in your .env file or shell
      # Or use API server and token:
      # - KUBERNETES_SERVER=https://kubernetes.example.com:6443
      # - KUBERNETES_TOKEN=${KUBERNETES_TOKEN}
      - SERVER_MODE=sse
      - SERVER_PORT=8080
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s
```

**Note:** To enable read-only mode, use the `command` override as shown in Option 1. For stdio mode, you might need to adjust 'ports', add 'stdin_open: true' and 'tty: true', and potentially override the command.

Then start with:
```bash
docker compose up -d
```
To see logs: `docker compose logs -f k8s-mcp-server`.

#### Security Considerations

The Docker image runs as a non-root user (`appuser` with UID 1001) for enhanced security:
- The application binary is located at `/usr/local/bin/k8s-mcp-server`
- The kubeconfig should be mounted to `/home/appuser/.kube/config`
- Health checks are enabled to monitor container status
- The container includes minimal dependencies (ca-certificates and curl only)

#### Making API Calls (SSE/Streamable-HTTP Mode)
Once the server is running in SSE or streamable-http mode, you can make JSON-RPC calls to its HTTP endpoint:
```bash
curl -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "getAPIResources",
    "arguments": {
      "includeNamespaceScoped": true,
      "includeClusterScoped": true
    }
  }
}' http://localhost:8080/
```

You can also check the health status:
```bash
curl -f http://localhost:8080/
```

### Available Tools

#### 1. `getAPIResources`

Retrieves all available API resources in the Kubernetes cluster.

**Parameters:**
- `includeNamespaceScoped` (boolean, optional): Whether to include namespace-scoped resources (defaults to true).
- `includeClusterScoped` (boolean, optional): Whether to include cluster-scoped resources (defaults to true).

**Example:**
```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "getAPIResources",
    "arguments": {
      "includeNamespaceScoped": true,
      "includeClusterScoped": true
    }
  }
}
```

#### 2. `listResources`

Lists all instances of a specific resource type.

**Parameters:**
- `Kind` (string, required): The kind of resource to list (e.g., "Pod", "Deployment").
- `namespace` (string, optional): The namespace to list resources from. If omitted, lists across all namespaces for namespaced resources (subject to RBAC).
- `labelSelector` (string, optional): Filter resources by label

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [reza-gholizade](https://github.com/reza-gholizade)
- **Source:** [reza-gholizade/k8s-mcp-server](https://github.com/reza-gholizade/k8s-mcp-server)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: flagged — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-reza-gholizade-k8s-mcp-server
- Seller: https://agentstack.voostack.com/s/reza-gholizade
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
