diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b343ea9..6f950ec 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,12 +1,13 @@ name: goreleaser -on: +on: push: tags: - "*" permissions: contents: write + packages: write jobs: goreleaser: @@ -16,16 +17,29 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Set up Go uses: actions/setup-go@v5 with: go-version-file: "go.mod" + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Run Goreleaser uses: goreleaser/goreleaser-action@v6 with: - # either 'goreleaser' or 'goreleaser-pro' distribution: goreleaser - # 'latest', 'nightly' or a semver version like 'v2.0.0' version: "~> v2" args: release --clean workdir: . diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 201c8ce..5365708 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -13,8 +13,45 @@ builds: - linux - windows - darwin + goarch: + - amd64 + - arm64 main: ./cmd/kai +dockers: + - image_templates: + - "ghcr.io/basebandit/kai:{{ .Tag }}-amd64" + dockerfile: Dockerfile.goreleaser + use: buildx + build_flag_templates: + - "--platform=linux/amd64" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Version }}" + - "--label=org.opencontainers.image.source={{ .GitURL }}" + goarch: amd64 + + - image_templates: + - "ghcr.io/basebandit/kai:{{ .Tag }}-arm64" + dockerfile: Dockerfile.goreleaser + use: buildx + build_flag_templates: + - "--platform=linux/arm64" + - "--label=org.opencontainers.image.title={{ .ProjectName }}" + - "--label=org.opencontainers.image.version={{ .Version }}" + - "--label=org.opencontainers.image.source={{ .GitURL }}" + goarch: arm64 + +docker_manifests: + - name_template: "ghcr.io/basebandit/kai:{{ .Tag }}" + image_templates: + - "ghcr.io/basebandit/kai:{{ .Tag }}-amd64" + - "ghcr.io/basebandit/kai:{{ .Tag }}-arm64" + + - name_template: "ghcr.io/basebandit/kai:latest" + image_templates: + - "ghcr.io/basebandit/kai:{{ .Tag }}-amd64" + - "ghcr.io/basebandit/kai:{{ .Tag }}-arm64" + archives: - formats: tar.gz name_template: >- diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..cdfd0b0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +# Build stage +FROM golang:1.24-alpine AS builder + +WORKDIR /app + +# Install git for go mod download +RUN apk add --no-cache git + +# Download dependencies first (better caching) +COPY go.mod go.sum ./ +RUN go mod download + +# Copy source code +COPY . . + +# Build the binary +RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o kai ./cmd/kai + +# Runtime stage +FROM alpine:3.19 + +RUN apk --no-cache add ca-certificates + +COPY --from=builder /app/kai /usr/local/bin/kai + +ENTRYPOINT ["kai"] diff --git a/Dockerfile.goreleaser b/Dockerfile.goreleaser new file mode 100644 index 0000000..f69bb67 --- /dev/null +++ b/Dockerfile.goreleaser @@ -0,0 +1,7 @@ +FROM alpine:3.19 + +RUN apk --no-cache add ca-certificates + +COPY kai /usr/local/bin/kai + +ENTRYPOINT ["kai"] diff --git a/README.md b/README.md index 8bcf467..560649d 100644 --- a/README.md +++ b/README.md @@ -1,140 +1,248 @@

- Kai Logo + Kai Logo

-# Kai - Kubernetes MCP Server +

Kai

-A Model Context Protocol (MCP) server for managing Kubernetes clusters through LLM clients like Claude and Ollama. +

+ Talk to your Kubernetes cluster using natural language +

-## Overview +

+ CI Status + Go Report Card + Release + License +

-Kai provides a bridge between large language models (LLMs) and your Kubernetes clusters, enabling natural language interaction with Kubernetes resources. The server exposes a comprehensive set of tools for managing clusters, namespaces, pods, deployments, services, and other Kubernetes resources. +

+ Quick Start • + Installation • + What Can I Do? • + Configuration • + Production +

+ +--- -## Features +Kai is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that lets you manage Kubernetes clusters through AI assistants like Claude, Cursor, and VS Code Copilot. -### Core Workloads -- [x] **Pods** - Create, list, get, delete, and stream logs -- [x] **Deployments** - Create, list, describe, and update -- [x] **Jobs** - Batch workload management (create, get, list, delete) -- [x] **CronJobs** - Scheduled batch workloads (create, get, list, delete) +Instead of memorizing kubectl commands, just ask: -### Networking -- [x] **Services** - Create, get, list, and delete -- [x] **Ingress** - HTTP/HTTPS routing, TLS configuration (create, get, list, update, delete) +> "List all pods in the production namespace" +> "Scale the api deployment to 5 replicas" +> "Show me the logs for the failing pod" -### Configuration -- [x] **ConfigMaps** - Configuration management (create, get, list, update, delete) -- [x] **Secrets** - Secret management (create, get, list, update, delete) -- [x] **Namespaces** - Namespace management (create, get, list, delete) +--- + +## Quick Start + +### 1. Install Kai -### Cluster Operations -- [x] **Context Management** - Switch contexts, list contexts, rename, delete -- [ ] **Nodes** - Node monitoring, cordoning, and draining -- [ ] **Cluster Health** - Cluster status and resource metrics +```bash +go install github.com/basebandit/kai/cmd/kai@latest +``` -### Storage -- [ ] **Persistent Volumes** - PV and PVC management -- [ ] **Storage Classes** - Storage class operations +### 2. Add to Claude Desktop -### Security -- [ ] **RBAC** - Roles, RoleBindings, and ServiceAccounts +Edit your config file: -### Utilities -- [x] **Port Forwarding** - Forward ports to pods and services (start, stop, list sessions) +- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` +- **Linux**: `~/.config/Claude/claude_desktop_config.json` +- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` + +```json +{ + "mcpServers": { + "kubernetes": { + "command": "kai" + } + } +} +``` -### Advanced -- [ ] **Custom Resources** - CRD and custom resource operations -- [ ] **Events** - Event streaming and filtering -- [ ] **API Discovery** - API resource exploration +### 3. Restart Claude Desktop -## Requirements +That's it! Start asking questions about your cluster. -The server connects to your current kubectl context by default. Ensure you have access to a Kubernetes cluster configured for kubectl (e.g., minikube, Rancher Desktop, kind, EKS, GKE, AKS). +--- ## Installation -```sh +### Using Go (Recommended) + +```bash go install github.com/basebandit/kai/cmd/kai@latest ``` -## CLI Options +### Download Binary -``` -kai [options] +Download from the [releases page](https://github.com/basebandit/kai/releases): -Options: - -kubeconfig string Path to kubeconfig file (default "~/.kube/config") - -context string Name for the loaded context (default "local") - -transport string Transport mode: stdio (default) or sse - -sse-addr string Address for SSE server (default ":8080") - -log-format string Log format: json (default) or text - -log-level string Log level: debug, info, warn, error (default "info") - -version Show version information +**macOS (Apple Silicon)** +```bash +curl -LO https://github.com/basebandit/kai/releases/latest/download/kai_Darwin_arm64.tar.gz +tar -xzf kai_Darwin_arm64.tar.gz +sudo mv kai /usr/local/bin/ ``` -Logs are written to stderr in structured JSON format by default, making them easy to parse: +**macOS (Intel)** +```bash +curl -LO https://github.com/basebandit/kai/releases/latest/download/kai_Darwin_x86_64.tar.gz +tar -xzf kai_Darwin_x86_64.tar.gz +sudo mv kai /usr/local/bin/ +``` -```json -{"time":"2024-01-15T10:30:00Z","level":"INFO","msg":"kubeconfig loaded","path":"/home/user/.kube/config","context":"local"} -{"time":"2024-01-15T10:30:00Z","level":"INFO","msg":"starting server","transport":"stdio"} +**Linux** +```bash +curl -LO https://github.com/basebandit/kai/releases/latest/download/kai_Linux_x86_64.tar.gz +tar -xzf kai_Linux_x86_64.tar.gz +sudo mv kai /usr/local/bin/ ``` -## Configuration +**Windows (PowerShell)** +```powershell +Invoke-WebRequest -Uri https://github.com/basebandit/kai/releases/latest/download/kai_Windows_x86_64.zip -OutFile kai.zip +Expand-Archive kai.zip -DestinationPath . +Move-Item kai.exe C:\Windows\System32\ +``` -### Claude Desktop +### Build from Source -Edit your Claude Desktop configuration: +```bash +git clone https://github.com/basebandit/kai.git +cd kai +go build -o kai ./cmd/kai +sudo mv kai /usr/local/bin/ +``` -```sh -# macOS -code ~/Library/Application\ Support/Claude/claude_desktop_config.json +### Verify Installation -# Linux -code ~/.config/Claude/claude_desktop_config.json +```bash +kai -version ``` -Add the server configuration: +--- + +## What Can I Do? + +Here are some things you can ask your AI assistant once Kai is configured: + +### Managing Pods +- "List all pods in the default namespace" +- "Show me pods that aren't running" +- "Get the logs from pod nginx-abc123" +- "Delete the crashed pod in staging" + +### Working with Deployments +- "Create a deployment named api with 3 replicas using nginx:latest" +- "Scale the frontend deployment to 10 replicas" +- "Roll back the api deployment" +- "What's the status of all deployments?" + +### Services & Networking +- "Create a service for the nginx deployment" +- "List all services in the production namespace" +- "Set up an ingress for api.example.com" + +### Configuration +- "Create a configmap from these key-value pairs" +- "Show me all secrets in the default namespace" +- "Update the database configmap" + +### Jobs & Scheduled Tasks +- "Create a job that runs the backup script" +- "Show me all cronjobs" +- "Suspend the nightly-cleanup cronjob" + +### Debugging +- "Port forward the postgres service to localhost:5432" +- "Stream logs from all api pods" +- "Why is my pod failing?" + +--- + +## Configuration + +### Supported MCP Clients + +
+Claude Desktop + +Edit your config file: +- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` +- **Linux**: `~/.config/Claude/claude_desktop_config.json` +- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` ```json { "mcpServers": { "kubernetes": { - "command": "/path/to/kai" + "command": "kai" } } } ``` +
-With custom kubeconfig: +
+Claude Code (VS Code Extension) + +Run in terminal: +```bash +claude mcp add kubernetes -- kai +``` +Or edit `~/.claude/settings.json`: ```json { "mcpServers": { "kubernetes": { - "command": "/path/to/kai", - "args": ["-kubeconfig", "/path/to/custom/kubeconfig"] + "command": "kai" } } } ``` +
-### Cursor +
+Cursor -Add to your Cursor MCP settings: +Add to Cursor's MCP settings (Settings → MCP): ```json { "mcpServers": { "kubernetes": { - "command": "/path/to/kai" + "command": "kai" } } } ``` +
-### Continue +
+VS Code (GitHub Copilot) -Add to your Continue configuration (`~/.continue/config.json`): +Add to your VS Code `settings.json`: + +```json +{ + "mcp": { + "servers": { + "kubernetes": { + "command": "kai" + } + } + } +} +``` +
+ +
+Continue + +Add to `~/.continue/config.json`: ```json { @@ -143,52 +251,256 @@ Add to your Continue configuration (`~/.continue/config.json`): { "transport": { "type": "stdio", - "command": "/path/to/kai" + "command": "kai" } } ] } } ``` +
-### SSE Mode (Web Clients) +### Custom Kubeconfig -For web-based clients or custom integrations, run in SSE mode: +By default, Kai uses `~/.kube/config`. To use a different config: -```sh +```json +{ + "mcpServers": { + "kubernetes": { + "command": "kai", + "args": ["-kubeconfig", "/path/to/kubeconfig"] + } + } +} +``` + +### Multiple Clusters + +Set up different kai instances for each cluster in Claude Desktop: + +```json +{ + "mcpServers": { + "k8s-prod": { + "command": "kai", + "args": ["-kubeconfig", "/Users/you/.kube/prod-config", "-context", "production"] + }, + "k8s-staging": { + "command": "kai", + "args": ["-kubeconfig", "/Users/you/.kube/staging-config", "-context", "staging"] + } + } +} +``` + +> **Note**: Use absolute paths (not `~`) for kubeconfig files in MCP configurations. + +--- + +## CLI Options + +``` +kai [options] + +Options: + -kubeconfig string Path to kubeconfig file (default "~/.kube/config") + -context string Context name (default "local") + -transport string Transport mode: stdio or sse (default "stdio") + -sse-addr string SSE server address (default ":8080") + -tls-cert string TLS certificate file (for HTTPS) + -tls-key string TLS private key file (for HTTPS) + -request-timeout API request timeout (default 30s) + -metrics Enable Prometheus metrics (default true) + -log-format string Log format: json or text (default "json") + -log-level string Log level: debug, info, warn, error (default "info") + -version Show version +``` + +--- + +## Supported Resources + +| Category | Resources | Operations | +|----------|-----------|------------| +| **Workloads** | Pods, Deployments, Jobs, CronJobs | Create, Read, Update, Delete, Scale, Logs | +| **Networking** | Services, Ingress | Create, Read, Update, Delete | +| **Config** | ConfigMaps, Secrets, Namespaces | Create, Read, Update, Delete | +| **Operations** | Contexts, Port Forwarding | Switch, List, Forward | + +--- + +## Production Deployment + +For production use cases, Kai supports SSE transport with TLS, health endpoints, and Prometheus metrics. + +### SSE Mode (for web clients) + +```bash kai -transport=sse -sse-addr=:8080 ``` -Then connect to `http://localhost:8080/sse`. +With TLS: +```bash +kai -transport=sse -sse-addr=:8443 -tls-cert=cert.pem -tls-key=key.pem +``` -### Custom Kubeconfig +### Health Endpoints + +| Endpoint | Description | +|----------|-------------| +| `GET /healthz` | Liveness probe | +| `GET /readyz` | Readiness probe | +| `GET /metrics` | Prometheus metrics | + +### Prometheus Metrics + +| Metric | Type | Description | +|--------|------|-------------| +| `kai_requests_total` | Counter | Total requests by tool and status | +| `kai_request_duration_seconds` | Histogram | Request latency | +| `kai_active_connections` | Gauge | Active SSE connections | + +### Kubernetes Deployment + +
+Click to expand Kubernetes manifests + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kai +spec: + replicas: 1 + selector: + matchLabels: + app: kai + template: + metadata: + labels: + app: kai + spec: + serviceAccountName: kai + containers: + - name: kai + image: ghcr.io/basebandit/kai:latest + args: ["-transport=sse", "-sse-addr=:8080"] + ports: + - containerPort: 8080 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + readinessProbe: + httpGet: + path: /readyz + port: 8080 +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kai +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kai +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin # Scope down for production! +subjects: + - kind: ServiceAccount + name: kai + namespace: default +``` +
-By default, Kai uses `~/.kube/config`. You can specify a different kubeconfig: +### Docker -```sh -kai -kubeconfig=/path/to/custom/kubeconfig -context=my-cluster +```bash +docker run -v ~/.kube/config:/root/.kube/config:ro \ + ghcr.io/basebandit/kai:latest -transport=sse ``` -## Usage Examples +--- -Once configured, you can interact with your cluster using natural language: +## Viewing Logs -- "List all pods in the default namespace" -- "Create a deployment named nginx with 3 replicas using the nginx:latest image" -- "Show me the logs for pod my-app" -- "Delete the service named backend" -- "Create a cronjob that runs every 5 minutes" -- "Create an ingress for my-app with TLS enabled" -- "Port forward service nginx on port 8080:80" +Kai outputs structured JSON logs to stderr. + +**Claude Desktop logs location:** +- macOS: `~/Library/Logs/Claude/mcp-server-kubernetes.log` +- Linux: `~/.config/Claude/logs/mcp-server-kubernetes.log` + +```bash +# Watch logs in real-time +tail -f ~/Library/Logs/Claude/mcp-server-kubernetes.log +``` + +--- + +## Troubleshooting + +**Kai command not found** +```bash +# Check if kai is in your PATH +which kai + +# If using go install, ensure GOPATH/bin is in PATH +export PATH=$PATH:$(go env GOPATH)/bin +``` + +**Can't connect to cluster** +```bash +# Verify kubectl works +kubectl cluster-info +kubectl get nodes +``` + +**MCP client not seeing Kai** +1. Restart the MCP client after config changes +2. Check the config file syntax (valid JSON) +3. Verify the kai path is correct + +**Enable debug logging** +```json +{ + "mcpServers": { + "kubernetes": { + "command": "kai", + "args": ["-log-level", "debug"] + } + } +} +``` + +--- ## Contributing -Contributions are welcome! Please see our contributing guidelines for more information. +Contributions are welcome! See our [contributing guidelines](CONTRIBUTING.md). + +```bash +git clone https://github.com/basebandit/kai.git +cd kai +go test ./... +go build -o kai ./cmd/kai +``` + +--- ## License -This project is licensed under the MIT License. +MIT License - see [LICENSE](LICENSE) for details. --- -![Kubernetes MCP Server](./claude_desktop.png) \ No newline at end of file +

+ Kai in Claude Desktop +

+ +

+ Listed on MCP Servers +