MCP server for managing Deckhouse Kubernetes Platform (Community Edition).
Supports dual transport:
- stdio (default): local process, newline-delimited JSON on stdin/stdout.
- SSE (HTTP): set
LISTEN_ADDR=:8080(or use-listen :8080) to serve viamcp.NewSSEHandler.
Authenticates to Kubernetes using in-cluster config (when running inside a Pod) or ~/.kube/config / KUBECONFIG (for local execution).
Diagnostics (read-only, 11 tools)
deckhouse_GetClusterStatus— aggregated cluster health: nodes, modules, releases, unhealthy podsdeckhouse_ListNodes— cluster nodes with filtering by group, status, roledeckhouse_ListNodeGroups— NodeGroup resources with status and conditionsdeckhouse_ListStaticInstances— StaticInstance resources with filtering by group and phasedeckhouse_ListUnhealthyPods— pods not in Running/Succeeded statedeckhouse_GetNode— detailed node info with conditions, capacity, eventsdeckhouse_GetNodeGroup— full NodeGroup spec with member node namesdeckhouse_GetDeckhouseLogs— Deckhouse controller pod logs with grep/tail/sincedeckhouse_GetNodeEvents— Kubernetes Events for a specific nodedeckhouse_GetStaticInstance— detailed StaticInstance infodeckhouse_GetPodLogs— logs for a specific pod and container
Modules (7 tools)
deckhouse_ListModuleConfigs— ModuleConfig resources with enabled/disabled filterdeckhouse_GetModuleConfig— full spec and status of a single ModuleConfigdeckhouse_EnableModule/deckhouse_DisableModule— toggle module enabled statedeckhouse_ListModules— runtime Module resourcesdeckhouse_UpdateModuleSettings— RFC 7396 JSON Merge Patch on module settingsdeckhouse_SetModuleMaintenance— toggle module maintenance mode
Releases (3 tools)
deckhouse_ListDeckhouseReleases— DeckhouseRelease resources with phase filterdeckhouse_GetDeckhouseRelease— full release details with requirementsdeckhouse_ApproveRelease— approve a pending release
Nodes (13 tools, write)
deckhouse_CreateSSHCredentials/deckhouse_DeleteSSHCredentialsdeckhouse_CreateStaticInstance/deckhouse_DeleteStaticInstancedeckhouse_AddWorkerNode— composite: SSHCredentials → StaticInstance → wait for Runningdeckhouse_RemoveNode— composite: drain → delete StaticInstancedeckhouse_CreateNodeGroup/deckhouse_DeleteNodeGroupdeckhouse_WaitNodeReady— poll StaticInstance until Running or timeoutdeckhouse_CordonNode/deckhouse_UncordonNodedeckhouse_DrainNode— cordon + eviction loop with PDB awarenessdeckhouse_CreateNodeGroupConfiguration— bash script bound to NodeGroups
Config (3 tools)
deckhouse_GetClusterConfiguration— read ClusterConfiguration YAMLdeckhouse_GetStaticClusterConfiguration— read StaticClusterConfiguration YAMLdeckhouse_UpdateKubernetesVersion— patch kubernetesVersion with retry-on-conflict
Sources (6 tools)
deckhouse_ListModuleSources/deckhouse_CreateModuleSource/deckhouse_DeleteModuleSourcedeckhouse_ListModuleUpdatePolicies/deckhouse_CreateModuleUpdatePolicydeckhouse_ListModuleReleases— module releases with phase filter
- Go 1.26 with MCP Go SDK (stdio + SSE transports)
- Protobuf + protoc-gen-mcp — proto-first tool generation
- EasyP — proto linting, codegen, dependency management
- client-go — typed client for core resources, dynamic client for Deckhouse CRDs
- Go 1.26+
- EasyP (
brew install easyp-tech/tap/easyp) - go-task (
brew install go-task) - A Kubernetes cluster with Deckhouse CE installed
~/.kube/configorKUBECONFIGenv pointing to the cluster
# Generate protobuf code
task generate
# Build
go build -o deckhouse-harness ./cmd/deckhouse-harness
# Run tests
task test
# Run the server (connects to cluster via kubeconfig)
./deckhouse-harnessThe server supports two transport modes, selectable via the TRANSPORT env var or CLI flags:
Local process mode — newline-delimited JSON on stdin/stdout. Used by MCP clients like Claude Desktop, Cursor, and mcp CLI. Logs go to stderr.
./deckhouse-harness # stdio mode (default)
TRANSPORT=stdio ./deckhouse-harness # explicitSSE transport for in-cluster deployment or remote access. Uses mcp.NewSSEHandler + http.Server with graceful shutdown. Multiple clients can connect concurrently.
TRANSPORT=sse ./deckhouse-harness # SSE on :8080
TRANSPORT=sse LISTEN_ADDR=:9090 ./deckhouse-harness # SSE on :9090
./deckhouse-harness -listen :8080 # via CLI flagDocker image and Kubernetes manifests are provided for deploying the server inside a cluster (e.g. in the d8-system namespace alongside Deckhouse):
# Build and load into Kind
task docker:build
task docker:load
# Deploy
kubectl apply -f deploy/rbac.yaml -f deploy/deployment.yaml -f deploy/service.yaml
# Port-forward for local testing
kubectl port-forward svc/deckhouse-mcp 8080:8080 -n d8-systemThe Deployment sets TRANSPORT=sse and uses in-cluster config for Kubernetes auth. See deploy/ for manifests (Deployment, Service, RBAC).
By default the server uses stdio transport. Configure your MCP client to launch the binary.
SSE / HTTP mode: Start the server with -listen :8080 (or LISTEN_ADDR=:8080 env). The binary uses urfave/cli/v3 so --help shows associated env vars. Configure MCP clients that support HTTP/SSE to the base URL.
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"deckhouse": {
"command": "/path/to/deckhouse-harness",
"env": {
"KUBECONFIG": "/Users/you/.kube/config",
"LOG_LEVEL": "INFO"
}
}
}
}{
"mcpServers": {
"deckhouse": {
"command": "/path/to/deckhouse-harness"
}
}
}echo '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | ./deckhouse-harness| Variable | Default | Description |
|---|---|---|
TRANSPORT |
stdio |
Transport mode: stdio (local) or sse (HTTP in-cluster). If empty, auto-selects based on LISTEN_ADDR. |
LISTEN_ADDR |
:8080 |
SSE listen address (only when TRANSPORT=sse or LISTEN_ADDR is set) |
KUBECONFIG |
~/.kube/config |
Path to kubeconfig file (or in-cluster config when running inside a Pod) |
LOG_LEVEL |
INFO |
Log verbosity: DEBUG, INFO, WARN, ERROR |
LOG_OUTPUT |
stderr |
Log destination: stderr, file, discard |
LOG_FILE |
— | Log file path (required when LOG_OUTPUT=file) |
Stdio mode: stdout is reserved for the MCP protocol (logs never go there).
SSE mode: the server listens on the given address and serves MCP over HTTP/SSE. Multiple clients can connect concurrently.
task generate # easyp mod download + easyp generate
task lint # easyp lint
task build # go build -o deckhouse-harness ./cmd/deckhouse-harness
task test # go test ./...
task docker:build # build Docker image (deckhouse-mcp:local)
task docker:load # load Docker image into Kind cluster
task integration # full integration test cycle (requires Kind)
All MCP tools are defined in .proto files under proto/deckhouse/v1/:
| File | Service | Purpose |
|---|---|---|
diagnostics.proto |
DiagnosticsAPI |
Read-only cluster status, nodes, pods, logs, events |
modules.proto |
ModulesAPI |
ModuleConfig management, enable/disable, settings |
releases.proto |
ReleasesAPI |
DeckhouseRelease listing and approval |
nodes.proto |
NodesAPI |
Node provisioning, drain/cordon, NodeGroup |
config.proto |
ConfigAPI |
Cluster configuration, Kubernetes version |
sources.proto |
SourcesAPI |
ModuleSource, ModuleUpdatePolicy, ModuleRelease |
After editing .proto files, regenerate:
task generateEach handler implements a generated *ToolHandler interface:
type DiagnosticsAPIToolHandler interface {
GetClusterStatus(ctx context.Context, req *emptypb.Empty) (*GetClusterStatusResponse, error)
ListNodes(ctx context.Context, req *ListNodesRequest) (*ListNodesResponse, error)
// ...
}Handlers live in internal/handler/ and receive a k8s.Client interface for all Kubernetes operations.
task test # unit tests (mock k8s.Client, no cluster needed)Tests use a mock k8s.Client with function fields — no external mock libraries.
proto/deckhouse/v1/ # .proto files — single source of truth
├── diagnostics.proto # DiagnosticsAPI (11 RPCs)
├── modules.proto # ModulesAPI (7 RPCs)
├── releases.proto # ReleasesAPI (3 RPCs)
├── nodes.proto # NodesAPI (13 RPCs)
├── config.proto # ConfigAPI (3 RPCs)
└── sources.proto # SourcesAPI (6 RPCs)
cmd/deckhouse-harness/main.go # dual-mode entrypoint (stdio default, SSE via TRANSPORT/LISTEN_ADDR)
internal/handler/ # Tool handler implementations
internal/k8s/client.go # Kubernetes client interface
deploy/ # Kubernetes manifests (Deployment, Service, RBAC)
Dockerfile # Multi-stage build (golang:1.26 → distroless)
tests/integration/ # Integration tests (Kind + Deckhouse CE, dual transport)
Taskfile.yml # Build tasks (go-task)
easyp.yaml # Proto config