crossplane-mcp-server

module
v0.1.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 13, 2026 License: Apache-2.0

README

crossplane-mcp-server

CI Release CodeQL GitHub release golangci-lint Go version Crossplane Downloads License

A Model Context Protocol server that lets AI assistants understand a Crossplane control plane.

Ask your assistant "how many managed resources do I have and is anything broken?" and it will answer from your actual control plane, with the reason for every failure, instead of guessing.

> Why is the app-db claim not ready?

  crossplane_diagnose(kind="PostgreSQLInstance", name="app-db")

  PostgreSQLInstance app-db is NOT READY.

  Verdict: Instance/app-db-rds is the deepest failure: InvalidParameterValue:
  the instance class db.t2.mega does not exist

  Root causes (deepest failing resources):
  KIND       NAME          READY   SYNCED   REASON          DETAIL
  Instance   app-db-rds    False   False    ApplyFailure    InvalidParameterValue...

  Control plane checks:
  CHECK         STATE   DETAIL
  composition   OK      Composition "postgres-aws" exists.
  providers     OK      all 3 provider(s) are Installed and Healthy

  Fix the instanceClass field in your Composition and the claim will reconcile.

Every tool is read-only. This server cannot create, update or delete anything on your control plane.

Contents

Why not a generic Kubernetes MCP server?

A general purpose Kubernetes MCP server can already reach every object on a Crossplane control plane: Crossplane resources are Kubernetes resources, and a generic resources_list with an apiVersion and a kind will happily return your XRDs. Access was never the problem.

The problem is that it does not know what any of it means, and it will happily delete it.

Generic Kubernetes MCP This server
Reach Crossplane CRDs Yes Yes
Follow a claim to the infrastructure it created No. It returns objects; the model has to guess which field to follow at each hop crossplane_resource_tree walks resourceRefs for you
Say which resource is actually at fault No crossplane_diagnose finds the deepest failure, not the symptom at the top
Notice infrastructure changed outside Crossplane No. It can return spec and status but has no idea they are meant to match crossplane_drift_detect diffs desired against observed
Explain why a delete is hanging No crossplane_deleting_resources names the Usage, finalizer or provider holding it
Say what a delete would destroy first No crossplane_impact reports the blast radius before you act
Simulate a change without touching the cluster No crossplane_composition_render runs the function pipeline offline
Write to your cluster Yes: create, update, delete, exec Never. There is no code path that mutates anything

That last row matters more here than it does for ordinary Kubernetes work. On a Crossplane control plane a deleted object is not a pod that a ReplicaSet will recreate, it is a production database. A tool surface that cannot mutate is one you can point at your production control plane without a change review.

Underneath, the Crossplane knowledge this server encodes is:

  • It discovers resources by Crossplane category (managed, composite, claim), so it works with every provider without being taught about any of them.
  • It reads Ready/Synced on resources and Installed/Healthy on packages, and explains the difference to the model.
  • It walks resourceRefs to build the composition tree, the same view as crossplane beta trace.
  • It knows that drift on a paused or Observe-only resource is never corrected, which is the difference between a warning and a non-event.
  • It supports both Crossplane v1 and v2 layouts, including namespaced composite resources and the spec.crossplane reference location.

Quick start

go install github.com/ravibagri5/crossplane-mcp-server/cmd/crossplane-mcp-server@latest

# See what this build exposes
crossplane-mcp-server tools

# Check it can reach your control plane
crossplane-mcp-server call crossplane_status

Then add it to your MCP client (see Client configuration) and ask it about your control plane.

Installation

Requirements
  • Go 1.26 or newer, if you install from source or with go install. The pre-built binaries and the container image have no such requirement.
  • Access to a Kubernetes cluster with Crossplane installed. Any version of Crossplane v1 or v2 works.
  • Optional: the crossplane CLI and a container runtime, used only by crossplane_composition_render. Rendering executes the composition function pipeline, which cannot be done through the Kubernetes API. Every other tool needs nothing beyond API access, and crossplane_composition_validate covers most of the same ground without a container runtime.
Go install
go install github.com/ravibagri5/crossplane-mcp-server/cmd/crossplane-mcp-server@latest
Container image
docker run --rm -i \
  -v "${HOME}/.kube:/home/nonroot/.kube:ro" \
  ghcr.io/ravibagri5/crossplane-mcp-server:latest
Binaries

Pre-built binaries for Linux, macOS and Windows are attached to every release. These are the easiest option if you do not have a recent Go toolchain.

From source
git clone https://github.com/ravibagri5/crossplane-mcp-server.git
cd crossplane-mcp-server
make build
./bin/crossplane-mcp-server tools
Registries

This server is listed in:

  • Official MCP Registry as io.github.ravibagri5/crossplane-mcp-server, which is where MCP clients look it up.
  • Smithery, which also offers one-click installation into a client.
  • pkg.go.dev for the Go package documentation.

Client configuration

Claude Desktop, Claude Code, Cursor, Windsurf
{
  "mcpServers": {
    "crossplane": {
      "command": "crossplane-mcp-server",
      "args": ["--clusters", "staging,production", "--context", "staging"],
      "env": {
        "PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin",
        "HOME": "/Users/you"
      }
    }
  }
}

PATH and HOME matter whenever a kubeconfig context authenticates through an exec plugin such as kubelogin or aws. Desktop applications launch servers with a near-empty environment, so without them the plugin is either not found or cannot read its token cache.

Goose

In ~/.config/goose/config.yaml:

extensions:
  crossplane:
    enabled: true
    type: stdio
    cmd: /path/to/crossplane-mcp-server
    args: ["--clusters", "staging,production", "--context", "staging"]
    envs:
      PATH: /opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin
      HOME: /Users/you
    timeout: 300
VS Code

Add to .vscode/mcp.json in your workspace:

{
  "servers": {
    "crossplane": {
      "type": "stdio",
      "command": "crossplane-mcp-server",
      "args": ["--clusters", "staging,production"]
    }
  }
}
Container based clients
{
  "mcpServers": {
    "crossplane": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-v", "${HOME}/.kube:/home/nonroot/.kube:ro",
        "ghcr.io/ravibagri5/crossplane-mcp-server:latest"
      ]
    }
  }
}

Tools

Run crossplane-mcp-server tools to print this list from your build.

resources

Managed resources, composite resources and claims.

Tool What it answers
crossplane_managed_resources_summary How many managed resources exist, by kind, and how many are Ready and Synced
crossplane_managed_resources_list Which managed resources exist, optionally only the failing ones
crossplane_composite_resources_list Which composite resources (XRs) exist and which Composition each selected
crossplane_claims_list Which claims exist and which composite each is bound to
crossplane_resource_get Everything about one resource: conditions, external name, events, manifest
crossplane_resource_tree The composition tree below a claim or composite, with per-resource status
crossplane_resource_events The events Crossplane recorded against one resource
crossplane_diagnose Why a resource is not Ready, and which resource is actually at fault
crossplane_drift_detect Which infrastructure no longer matches its declared spec, and whether that will be corrected
packages
Tool What it answers
crossplane_providers_list Which providers are installed and healthy
crossplane_functions_list Which composition functions are installed and healthy
crossplane_configurations_list Which configurations are installed and healthy
crossplane_package_get One package plus its revisions, where image pull and dependency errors appear
compositions
Tool What it answers
crossplane_xrds_list Which platform APIs this control plane offers
crossplane_xrd_schema The fields a platform API takes, with a ready-to-edit example manifest
crossplane_compositions_list Which Compositions exist and what pipeline they run
crossplane_composition_get The full definition of one Composition
crossplane_composition_validate Why a Composition does not work, without running anything
crossplane_composition_render What a Composition would actually create, as a dry run
config

How the control plane itself is configured.

Tool What it answers
crossplane_environment_configs_list Which EnvironmentConfigs exist and what data they hold
crossplane_deployment_runtime_configs_list Which runtime configs exist and which packages use them
crossplane_managed_resource_definitions_list Which managed resource kinds are Active, on Crossplane v2
crossplane_managed_resource_activation_policies_list Which policies activate those definitions
diagnostics
Tool What it answers
crossplane_clusters_list Which control planes this server can reach
crossplane_status The overall health of the control plane in one call
crossplane_unhealthy_resources Everything that is currently failing, and why
crossplane_deleting_resources What is stuck deleting, and what is holding it up
crossplane_usages_list What is protected from deletion, and what needs it
crossplane_impact What a deletion would destroy, and whether it would be blocked
crossplane_api_resources The Crossplane API surface, to find exact kinds and groups

Expose a subset with --toolsets:

crossplane-mcp-server --toolsets diagnostics,packages

Prompts

Tools tell a model what it can do. Prompts tell it the order an experienced operator would do things in, so it does not have to rediscover on every conversation that diagnosing a claim starts at the claim and not at the managed resource that looks angriest.

Most clients surface these as slash commands or a prompt picker.

Prompt What it does
diagnose_resource Walks a failing resource down to the provider error and proposes the fix
control_plane_review Produces a health report ordered by what needs attention first
explain_platform_api Explains what a platform API offers and how to ask for one
assess_deletion Works out the blast radius of a deletion before anyone runs it

Calling a tool directly

call runs one tool and prints what it returns, without an MCP client in the way. Use it to check the server can reach your cluster, and to see what a tool really returns rather than what a model says it returned.

# No arguments
crossplane-mcp-server call crossplane_status

# Arguments are the same JSON an MCP client would send
crossplane-mcp-server call crossplane_managed_resources_list '{"status":"not-ready"}'
crossplane-mcp-server call crossplane_diagnose '{"kind":"Bucket","name":"app-data"}'

# The structured payload the model receives, instead of the text rendering
crossplane-mcp-server call crossplane_status --json

# Against another control plane
crossplane-mcp-server call crossplane_status --context prod

Run crossplane-mcp-server tools --json to see the exact arguments a tool accepts.

Configuration

Flag Default Description
--kubeconfig $KUBECONFIG, then ~/.kube/config, then in-cluster Path to a kubeconfig file
--context current context Kubeconfig context used when a tool does not name a cluster
--clusters every context Comma separated contexts to expose as targets
--namespace context namespace, else default Default namespace for namespaced resources
--toolsets all Comma separated toolsets to expose
--http-address (unset) Serve streamable HTTP on this address instead of stdio
--log-level info debug, info, warn or error. Logs always go to stderr
--tool-timeout 2m Maximum time a single tool call may run. 0 disables
--version Print the version and exit

Multiple control planes

One server can talk to several control planes. Every tool takes an optional cluster argument naming one of them, and crossplane_clusters_list tells a model which are available.

crossplane-mcp-server --clusters staging,production --context staging

Ask your assistant "is anything failing in production?" and it passes cluster: "production"; omit the cluster and it uses --context.

Use --clusters. Without it every context in your kubeconfig becomes a target, which on a machine with a few hundred contexts means an assistant could reach a production cluster when you meant a sandbox. Naming the handful you work with is both faster and safer.

Clients are created lazily and cached, so an unreachable cluster does not stop the others from working, and listing clusters costs nothing.

Credentials
Source How it works
Kubeconfig context Used as-is, including contexts that authenticate through an exec plugin
Cloud identity (AKS, EKS, GKE) Works through the exec plugin the kubeconfig already declares, such as kubelogin or aws
Service account Used automatically when there is no kubeconfig, which is the case for the in-cluster deployment

Exec plugins are ordinary executables, so a server launched by a desktop application needs PATH to include them, and HOME so they can find their own token cache. Most MCP clients start servers with a near-empty environment, which is the usual reason a cluster works in a terminal but not in the client:

{
  "command": "crossplane-mcp-server",
  "args": ["--clusters", "staging,production"],
  "env": {
    "PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin",
    "HOME": "/Users/you"
  }
}

Running in a cluster

Serve the streamable HTTP transport when the server runs inside the control plane it inspects:

crossplane-mcp-server --http-address :8080

The MCP endpoint is /mcp and a liveness endpoint is served at /healthz. The server uses the pod's service account when no kubeconfig is present. Manifests are in deploy/.

The HTTP transport has no built-in authentication. Put it behind an authenticating proxy, or keep it on a private network. See SECURITY.md.

Required RBAC

The server only ever reads. A cluster role that covers every tool:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: crossplane-mcp-server
rules:
  # Discovery, so the server can find managed and composite resource kinds.
  - apiGroups: ["apiextensions.k8s.io"]
    resources: ["customresourcedefinitions"]
    verbs: ["get", "list"]
  # Everything Crossplane owns.
  - apiGroups: ["*.crossplane.io"]
    resources: ["*"]
    verbs: ["get", "list"]
  # Managed resources, which live in provider-specific API groups.
  - apiGroups: ["*"]
    resources: ["*"]
    verbs: ["get", "list"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["get", "list"]
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list"]

If you would rather not grant a cluster-wide read, deploy/rbac-minimal.yaml narrows the permissions at the cost of some tools returning warnings.

Contributing

Contributions are very welcome. Start with CONTRIBUTING.md, which covers the development workflow, how to add a tool, and the sign-off requirement. Good first issues are labelled good first issue.

This project follows the Crossplane Code of Conduct and is governed as described in GOVERNANCE.md.

Security

Please report vulnerabilities privately. See SECURITY.md.

License

Apache License 2.0. See LICENSE.

crossplane-mcp-server is a community project and is not an official Crossplane or CNCF project. Crossplane is a registered trademark of The Linux Foundation.

Directories

Path Synopsis
cmd
crossplane-mcp-server command
Command crossplane-mcp-server runs a Model Context Protocol server that gives AI assistants read-only access to a Crossplane control plane.
Command crossplane-mcp-server runs a Model Context Protocol server that gives AI assistants read-only access to a Crossplane control plane.
internal
cli
Package cli implements the crossplane-mcp-server command line.
Package cli implements the crossplane-mcp-server command line.
pkg
api
Package api defines the contract between the MCP transport layer and the tools this server exposes.
Package api defines the contract between the MCP transport layer and the tools this server exposes.
crossplane
Package crossplane knows how to talk to a Crossplane control plane.
Package crossplane knows how to talk to a Crossplane control plane.
kube
Package kube deals with locating and loading the Kubernetes client configuration that the MCP server uses to talk to a cluster.
Package kube deals with locating and loading the Kubernetes client configuration that the MCP server uses to talk to a cluster.
mcp
Package mcp adapts this server's tools to the Model Context Protocol.
Package mcp adapts this server's tools to the Model Context Protocol.
toolsets
Package toolsets collects the tool groups this server can expose and lets the command line pick between them.
Package toolsets collects the tool groups this server can expose and lets the command line pick between them.
toolsets/compositions
Package compositions exposes the tools that describe the platform APIs a control plane offers: CompositeResourceDefinitions and Compositions.
Package compositions exposes the tools that describe the platform APIs a control plane offers: CompositeResourceDefinitions and Compositions.
toolsets/config
Package config exposes the tools that describe how a control plane is configured: environment configs, runtime configs, and the Crossplane v2 types that decide which managed resources exist at all.
Package config exposes the tools that describe how a control plane is configured: environment configs, runtime configs, and the Crossplane v2 types that decide which managed resources exist at all.
toolsets/diagnostics
Package diagnostics exposes the tools that give an overall picture of a control plane's health, and that find the things which are broken.
Package diagnostics exposes the tools that give an overall picture of a control plane's health, and that find the things which are broken.
toolsets/packages
Package packages exposes the tools that answer questions about the Crossplane packages installed on a control plane: providers, functions and configurations.
Package packages exposes the tools that answer questions about the Crossplane packages installed on a control plane: providers, functions and configurations.
toolsets/resources
Package resources exposes the tools that answer questions about the resources a Crossplane control plane manages: managed resources, composite resources and claims.
Package resources exposes the tools that answer questions about the resources a Crossplane control plane manages: managed resources, composite resources and claims.
version
Package version exposes build information about the crossplane-mcp-server binary.
Package version exposes build information about the crossplane-mcp-server binary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL