MCP CAPI Server
A Model Context Protocol (MCP) server for Cluster API (CAPI), enabling seamless integration between Large Language Models (LLMs) and Kubernetes cluster management through CAPI.
Overview
The MCP CAPI Server provides a bridge between AI assistants (like Claude, GPT, etc.) and Cluster API, allowing natural language interactions for managing Kubernetes clusters across multiple infrastructure providers.
Features
- Cluster Management: Create, update, scale, and delete Kubernetes clusters
- Multi-Provider Support: Works with AWS, Azure, GCP, vSphere, and more
- Machine Operations: Manage control plane and worker nodes
- Real-time Monitoring: Watch cluster status changes and events
- Resource Discovery: Browse CAPI resources through MCP resources
- Guided Workflows: Interactive prompts for complex operations
- Multi-Transport Support: Connect via stdio, Server-Sent Events (SSE), or Streamable HTTP
- Enhanced CLI: Version management, self-update capability, and comprehensive help system
- Backwards Compatible: Maintains compatibility with existing configurations and scripts
Architecture
The MCP CAPI Server is built using:
Quick Start
Prerequisites
- Go 1.24.4 or later
- Access to a CAPI management cluster
- Kubeconfig configured for the management cluster
Installation
# Clone the repository
git clone https://github.com/giantswarm/mcp-capi.git
cd mcp-capi
# Build the server
make build
# Run the server
make run
Self-Update
The server includes a built-in self-update mechanism:
mcp-capi self-update
Usage
CLI Commands
The MCP server provides several commands:
$ mcp-capi --help
mcp-capi is a Model Context Protocol (MCP) server that provides
tools for interacting with Cluster API (CAPI) clusters. It offers various capabilities
including cluster management, machine operations, scaling, and infrastructure
provider management.
When run without subcommands, it starts the MCP server (equivalent to 'mcp-capi serve').
Usage:
mcp-capi [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command
self-update Update mcp-capi to the latest version
serve Start the MCP CAPI server
version Print the version number of mcp-capi
Flags:
-h, --help help for mcp-capi
-v, --version version for mcp-capi
Use "mcp-capi [command] --help" for more information about a command.
Basic Usage (Backwards Compatible)
Start the MCP server with default settings using stdio transport:
# Both commands are equivalent and start the server
mcp-capi
mcp-capi serve
Multi-Transport Support
The server supports three transport types for different deployment scenarios:
Standard I/O (Default)
Best for MCP client integrations and development:
mcp-capi serve --transport stdio
Server-Sent Events (SSE)
Ideal for web applications and browser-based clients:
mcp-capi serve --transport sse --http-addr :8080
Streamable HTTP
Perfect for HTTP-based integrations and REST-like interactions:
mcp-capi serve --transport streamable-http --http-addr :8080
Advanced Configuration Examples
# Run with SSE transport on custom port with custom endpoints
mcp-capi serve \
--transport sse \
--http-addr :9090 \
--sse-endpoint /events \
--message-endpoint /messages
# Run with streamable HTTP transport
mcp-capi serve \
--transport streamable-http \
--http-addr :8080 \
--http-endpoint /api/mcp
Authentication and the caller's identity
With --enable-oauth (sse and streamable-http transports) mcp-capi is an
OAuth 2.1 resource server built on
mcp-oauth. Two kinds of bearer are
accepted on the MCP endpoint:
- an OIDC ID token forwarded by an aggregator such as
muster (
forwardToken: true), when
its audience is listed in OAUTH_TRUSTED_AUDIENCES — single sign-on;
- an access token issued by mcp-capi's own authorization server after an
interactive login at the configured identity provider (Dex or Google).
With --downstream-oauth mcp-capi acts as the caller: every Kubernetes API
call authenticates with the person's ID token, the API server's OIDC
authenticator resolves the person, and the person's RBAC governs every CAPI
operation. The server holds no kubeconfig credentials and no ServiceAccount
token; a request without an identity token is refused instead of falling back
to a service identity.
export MCP_OAUTH_ISSUER=https://mcp-capi.example.com
export OAUTH_REDIRECT_URL=https://mcp-capi.example.com/oauth/callback
export DEX_ISSUER_URL=https://dex.example.com
export DEX_CLIENT_ID=mcp-capi
export DEX_CLIENT_SECRET=...
export DEX_K8S_AUTHENTICATOR_CLIENT_ID=dex-k8s-authenticator # audience the apiserver trusts
export OAUTH_TRUSTED_AUDIENCES=muster-client,dex-k8s-authenticator
mcp-capi serve --transport streamable-http --enable-oauth --downstream-oauth
All settings are environment variables; mcp-capi serve --help lists them.
The Helm chart exposes them under oauth.* (see helm/mcp-capi/README.md);
oauth.downstream.enabled (default on) mounts no ServiceAccount token and the
chart renders no RBAC.
Write policy: read-only and the GitOps guard
Two switches decide what an agent may change, a third what it may take away.
--read-only and --gitops-guard are on by default, --expose-kubeconfig
is off, in the CLI and in the Helm chart (readOnly, gitopsGuard,
exposeKubeconfig).
--read-only registers only the tools that read (list, get, status,
health, backup, provider lookups). The create, scale, upgrade,
pause, resume, update, move, delete, remediate, rollout, drain and cordon
tools are not offered at all, and every mutating Kubernetes call is refused
should one be reached anyway. Pass --read-only=false to offer them; the
person's RBAC still applies to each call. Every tool carries the MCP
annotations of its class: the reads (and capi_get_kubeconfig) are
readOnlyHint: true, the writes readOnlyHint: false with
destructiveHint: true unless they only create (capi_create_cluster,
capi_create_machinedeployment), so an aggregator's read-only toolset
(muster's preset:read-only) selects exactly the reads.
--gitops-guard refuses a write to an object that a GitOps controller or a
Helm release owns. Such an object is recognised by its markers:
kustomize.toolkit.fluxcd.io/name and helm.toolkit.fluxcd.io/name (Flux),
argocd.argoproj.io/instance or the argocd.argoproj.io/tracking-id
annotation (Argo CD), meta.helm.sh/release-name or
app.kubernetes.io/managed-by=Helm (Helm). On a Giant Swarm management
cluster every workload cluster is rendered by a cluster chart from an App or
HelmRelease in Git, so a direct change would be reverted on the next
reconciliation; the error names the owner and where the change belongs.
Creating new objects is not guarded (there is nothing to inspect); with the
guard off, writes go through. Only meaningful with --read-only=false.
--expose-kubeconfig offers capi_get_kubeconfig and lets
capi_backup_cluster honour include_secrets. Both hand out the workload
cluster's admin credentials from its kubeconfig Secret: reading a Secret is
not a write, but the kubeconfig is the power to do anything to that cluster,
so the export is a class of its own. Without the switch the tool is not
registered, whatever --read-only says, and the client refuses the export
(ErrCredentialExport) should it be reached anyway; a backup never carries
Secret data. On a Giant Swarm management cluster this stays off.
Independently of all three switches, an object labelled
giantswarm.io/prevent-deletion is never deleted.
# operator use against a cluster you manage by hand
mcp-capi serve --read-only=false
# operator use on a GitOps-managed management cluster: writes only to unmanaged objects
mcp-capi serve --read-only=false --gitops-guard
# a local operator who wants the workload cluster kubeconfig through the agent
mcp-capi serve --expose-kubeconfig
The pod logs Write policy readOnly=… gitopsGuard=… exposeKubeconfig=… at
startup; that line, not the arguments, is what to check.
Version Management
# Check current version
mcp-capi version
mcp-capi --version
# Update to latest version
mcp-capi self-update
Integration with AI Assistants
This MCP server can be integrated with various AI assistants that support the Model Context Protocol:
- Cursor: The server can be integrated with Cursor for AI-powered development
- VSCode Insiders: Compatible with VSCode Insiders for enhanced coding assistance
- Claude Desktop: Add the server to your Claude Desktop configuration
- Custom MCP Clients: Use any MCP-compatible client to connect
Example MCP Client Configuration
Standard I/O Transport (Recommended)
{
"servers": {
"capi": {
"command": "/path/to/mcp-capi",
"env": {
"KUBECONFIG": "/path/to/kubeconfig"
}
}
}
}
SSE Transport
{
"servers": {
"capi": {
"url": "http://localhost:8080/sse",
"transport": "sse"
}
}
}
Streamable HTTP Transport
{
"servers": {
"capi": {
"url": "http://localhost:8080/mcp",
"transport": "http"
}
}
}
Every tool returns its result as one JSON document in the text content, so
aggregators (muster), UIs and LLM clients parse it instead of scraping prose.
List tools follow the mcp-toolkit paginated result
convention:
{ "items": [ { "name": "my-cluster", "namespace": "org-example", "phase": "Provisioned", "ready": true, "provider": "aws", "version": "v1.31.0", "totalMachines": 6, "readyMachines": 6 } ] }
nextCursor is omitted because the tools return all matches in one page;
server-side pagination (limit/cursor arguments) is a follow-up. Read tools
return the object digest directly (for example capi_get_cluster returns the
cluster, capi_node_status the node); action tools return the identifiers they
acted on plus a message. Errors stay plain-text MCP tool errors (isError).
Tools marked (write) change resources. They are hidden when the server runs
--read-only (the default) and subject to the GitOps guard otherwise. The tool
marked (credentials) hands out a workload cluster's admin kubeconfig; it is
hidden unless the server runs --expose-kubeconfig, whatever --read-only
says. See Write policy.
Cluster Management
capi_create_cluster (write) - Create a new CAPI cluster
capi_list_clusters - List all clusters
capi_get_cluster - Get cluster details
capi_cluster_status - Detailed cluster status
capi_cluster_health - Cluster health summary
capi_get_kubeconfig (credentials) - Retrieve the cluster's admin kubeconfig
capi_backup_cluster - Export the cluster resources as YAML or JSON; include_secrets needs --expose-kubeconfig
capi_delete_cluster (write) - Delete a cluster
capi_scale_cluster (write) - Scale cluster nodes
capi_upgrade_cluster (write) - Upgrade the Kubernetes version
capi_update_cluster (write) - Update labels and annotations
capi_pause_cluster (write) - Pause reconciliation
capi_resume_cluster (write) - Resume reconciliation
capi_move_cluster (write) - Prepare a move to another management cluster
Machine Management
capi_list_machines - List machines
capi_get_machine - Get machine details
capi_delete_machine (write) - Delete a specific machine
capi_remediate_machine (write) - Trigger machine health check remediation
MachineDeployment Operations
capi_create_machinedeployment (write) - Create new worker node pool
capi_list_machinedeployments - List machine deployments
capi_scale_machinedeployment (write) - Scale worker nodes
capi_update_machinedeployment (write) - Update MachineDeployment configuration
capi_rollout_machinedeployment (write) - Trigger rolling update
MachineSet Operations
capi_list_machinesets - List machine sets
capi_get_machineset - Get machine set details
Node Operations
capi_drain_node (write) - Safely drain a node
capi_cordon_node (write) - Cordon/uncordon nodes
capi_node_status - Get node status from workload cluster
Generic
capi_list_infrastructure_providers - List available providers
capi_get_provider_config - Get provider configuration requirements
AWS
capi_aws_list_clusters - List AWS clusters
capi_aws_get_cluster - Get AWS cluster details
capi_aws_create_cluster - Create AWS cluster (placeholder)
capi_aws_update_vpc - Update VPC configuration (placeholder)
capi_aws_manage_security_groups - Manage security groups (placeholder)
capi_aws_get_machine_template - Get/list AWS machine templates
Azure
capi_azure_list_clusters - List Azure clusters
capi_azure_get_cluster - Get Azure cluster details
capi_azure_manage_resource_group - Manage resource groups (placeholder)
capi_azure_network_config - Configure Azure networking (placeholder)
GCP
capi_gcp_list_clusters - List GCP clusters
capi_gcp_get_cluster - Get GCP cluster details
capi_gcp_manage_network - Manage GCP networks (placeholder)
vSphere
capi_vsphere_list_clusters - List vSphere clusters
capi_vsphere_get_cluster - Get vSphere cluster details
capi_vsphere_manage_vms - Manage vSphere VMs (placeholder)
Resources
The server exposes CAPI data through MCP resources:
capi://clusters - List of all clusters
capi://clusters/{name} - Specific cluster details
capi://machines - List of all machines
capi://providers - Available infrastructure providers
Configuration
The server can be configured through environment variables:
KUBECONFIG - Path to kubeconfig file
LOG_LEVEL - Logging level (debug, info, warn, error)
Deployment
Docker
You can run the server in a Docker container:
FROM golang:1.24.4-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o mcp-capi
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/mcp-capi .
EXPOSE 8080
CMD ["./mcp-capi", "serve", "--transport", "sse", "--http-addr", ":8080"]
Systemd Service
Create a systemd service for automatic startup:
[Unit]
Description=MCP CAPI Server
After=network.target
[Service]
Type=simple
User=capi
ExecStart=/usr/local/bin/mcp-capi serve
Environment=KUBECONFIG=/etc/kubernetes/admin.conf
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Development
Project Structure
mcp-capi/
├── cmd/ # Command implementations
│ ├── root.go # Root Cobra command
│ ├── serve.go # Server command with multi-transport support
│ ├── version.go # Version command
│ ├── selfupdate.go # Self-update command
│ ├── doc.go # Package documentation
│ └── *.go # Tool handlers and server logic
├── pkg/ # Public packages
│ ├── capi/ # CAPI client and utilities
│ ├── tools/ # MCP tool implementations
│ ├── resources/ # MCP resource handlers
│ └── prompts/ # MCP prompt definitions
├── internal/ # Private packages
├── docs/ # Documentation
└── examples/ # Usage examples
Building
# Build for current platform
make build
# Build for multiple platforms
make release
# Run tests
make test
# Run with coverage
make test-coverage
Downloading CRDs
The project includes make targets to download Custom Resource Definitions (CRDs) from upstream CAPI providers:
# Download all CRDs from all providers
make download-crds
# Download CRDs for specific providers
make download-capi-crds # Core CAPI CRDs
make download-capa-crds # AWS provider CRDs
make download-capz-crds # Azure provider CRDs
make download-capv-crds # vSphere provider CRDs
make download-capvcd-crds # Cloud Director provider CRDs
make download-capg-crds # GCP provider CRDs
You can override the default versions by setting environment variables:
# Example: Download CAPI CRDs for a specific version
CAPI_VERSION=v1.11.2 make download-capi-crds
Contributing
Please see CONTRIBUTING.md for guidelines on how to contribute to this project.
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Issues and Support
Roadmap
See our GitHub Issues for the complete roadmap and planned features.