A Model Context Protocol (MCP) server for Kubernetes app deployment orchestration
Project description
Kubernetes App Deployment Orchestration MCP Server
A production-ready Model Context Protocol (MCP) server that empowers LLMs to dynamically orchestrate containerized application deployments to a Kubernetes cluster.
It handles configuration validation, interactive storage resolution, multi-resource manifest generation (Namespace, PersistentVolumeClaim, Deployment, Service), dry-run plan reviews, actual apply actions, and service endpoints extraction optimized for cloudflared tunnel routing.
Architecture Overview
For a detailed view of the system design and interaction flow, see the approved Implementation Plan.
Features
- Interactive Storage Resolution: Dynamically checks whether to create a new PVC, bind to an existing PV, or prompt the user for more details depending on whether the StorageClass matches the cluster's default NFS setup.
- Strict Input Validation: Enforces RFC 1123 compliant naming for apps, namespaces, and StorageClasses, validates port ranges, replicas, image tags, and Kubernetes storage sizes (e.g.
10Gi). - Dry-run Planning & Actual Applying: Exposes separate planning (
plan_deployment) and apply (apply_deployment) stages. Planning runs a Kubernetes server-side dry-run to catch configuration errors before changes are committed. - Enforced Review Step: The
apply_deploymenttool requires an explicitapproved=Trueparameter to enforce user verification of planned changes. - Tunnel Mapping Helpers: Auto-formats endpoints to seamlessly configure public subdomains with
cloudflaredtunnels.
Prerequisites
- Python: Version 3.10 or higher.
- Kubernetes Cluster: Access to a running cluster (e.g., k3s, minikube, GKE, EKS) with cluster credentials.
- Credentials: A valid kubeconfig file (defaults to
~/.kube/config).
Installation & Setup
-
Clone or navigate to the workspace:
cd /home/prod-server-2/mcp-k8s-deployer
-
Create a virtual environment and install dependencies:
python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt
-
Verify the installation by running the test suite:
python3 -m pytest -v
Configuration
The server supports configuration through environment variables or a YAML configuration file.
Environment Variables
| Variable | Description | Default |
|---|---|---|
MCP_K8S_LOG_LEVEL |
Logging level (DEBUG, INFO, WARNING, ERROR) |
INFO |
MCP_K8S_DEFAULT_NFS_STORAGE_CLASS |
StorageClass name treated as default NFS-backed storage | nfs |
MCP_K8S_ALLOWED_NAMESPACES |
Comma-separated list of allowed namespaces. If empty, all are allowed. | "" |
KUBECONFIG or MCP_K8S_KUBECONFIG_PATH |
Path to the active cluster kubeconfig file | ~/.kube/config |
MCP_K8S_DEFAULT_REPLICAS |
Default pod replicas count if unspecified | 1 |
MCP_K8S_DEFAULT_PORT |
Default service port if unspecified | 80 |
MCP_K8S_DEFAULT_STORAGE_SIZE |
Default persistent volume size | 10Gi |
YAML Configuration File
Create a config.yaml file in the root of the project (or store it in /etc/mcp-k8s/config.yaml). See config.yaml.example for template fields.
logging:
level: "INFO"
kubernetes:
kubeconfig_path: "" # Empty uses default ~/.kube/config
default_nfs_storage_class: "nfs"
allowed_namespaces: []
defaults:
replicas: 1
container_port: 80
storage_size: "10Gi"
Exposed MCP Tools
The server exposes the following tools to MCP-enabled clients:
1. choose_storage_option_tool
Assesses storage configuration based on StorageClass and PV requirements.
- Arguments:
storage_class(str, required): The target storage class name (e.g.nfs,local-path).has_existing_pv(bool, required): Whether the user has an existing PersistentVolume (PV) created.existing_pv_name(str, optional): The name of the existing PV to bind statically.storage_size(str, optional): Desired disk size (e.g.5Gi).default_nfs_class(str, optional): Override the default NFS storage class config.
- Returns: A JSON dictionary advising on PVC generation, PV binding, or actions required.
2. deploy_app_tool
Gathers configurations, validates inputs, and generates Kubernetes manifests in YAML format.
- Arguments:
app_name(str, required)image(str, required)container_port(int, required)replicas(int, optional)namespace(str, optional)use_persistence(bool, optional)storage_class(str, optional)storage_size(str, optional)existing_pv_name(str, optional)env_vars(dict, optional)hostname(str, optional)
- Returns: Generates a multi-document YAML string representing the Namespace, PVC, Deployment, and Service.
3. plan_deployment_tool
Validates inputs, generates manifests, and runs a server-side dry-run apply against the cluster. Shows the exact plan of actions.
- Arguments: Same as
deploy_app_tool. - Returns: The generated manifests, dry-run actions list (e.g.,
Created,Patched), and validation status.
4. apply_deployment_tool
Applies approved manifests to the Kubernetes cluster.
- Arguments:
manifests(str, required): The generated YAML manifests.approved(bool, required): Enforces safety. Must be set toTrue.
- Returns: Success status and array of resources created or patched.
5. create_namespace_tool
Creates a namespace if requested and it doesn't already exist.
- Arguments:
namespace(str, required): The namespace to create.dry_run(bool, optional): Runs dry-run check ifTrue.
6. get_service_endpoint_tool
Computes the internal cluster Service DNS endpoint.
- Arguments:
app_name(str),namespace(str),container_port(int). - Returns: The service URL (e.g.
http://app.namespace.svc.cluster.local:80).
7. build_cloudflared_target_tool
Generates the exact target service string to paste into a cloudflared tunnel mapping configuration.
- Arguments:
app_name(str),namespace(str),container_port(int).
Claude Desktop Integration
To configure this server to run in Claude Desktop, add the following entry to your configuration file (usually located at ~/.config/Claude/claude_desktop_config.json on Linux):
{
"mcpServers": {
"kubernetes-deployer": {
"command": "/home/prod-server-2/mcp-k8s-deployer/.venv/bin/python3",
"args": [
"/home/prod-server-2/mcp-k8s-deployer/src/server.py"
],
"env": {
"MCP_K8S_DEFAULT_NFS_STORAGE_CLASS": "nfs",
"MCP_K8S_LOG_LEVEL": "INFO"
}
}
}
}
Transport Selection (Stdio vs SSE)
By default, the server runs over standard input/output (stdio) transport, which is suitable for local integrations like Claude Desktop.
If you are publishing the server as a web service or registering it with public HTTP gateways (like Smithery HTTP endpoints), you can run the server using SSE (Server-Sent Events) transport.
Running over Stdio (Default)
python3 src/server.py --transport stdio
Running over SSE (HTTP Web Server)
python3 src/server.py --transport sse --host 0.0.0.0 --port 8000
Or use environment variables:
export MCP_TRANSPORT=sse
export MCP_PORT=8000
python3 src/server.py
This starts a web server listening on port 8000. The MCP endpoint will be accessible at http://<your-host>:8000/sse.
Typical Execution Flow
- User Request: "I want to deploy my Node.js application
auth-serviceusingnode:18in thedevnamespace. It needs 5Gi of gp2 storage." - Storage Decision: The LLM calls
choose_storage_option_tool(storage_class="gp2", has_existing_pv=False, storage_size="5Gi"). - Storage Advice: The server returns that
gp2is non-default, advising that a PVC will be generated but will rely on dynamic provisioning unless a PV is provided. The LLM presents this choice to the user. - Planning: The user confirms. The LLM calls
plan_deployment_tool(...)which returns the planned resources and dry-run apply status. - Confirmation: The LLM shows the YAML manifests to the user.
- Execution: The user confirms. The LLM calls
apply_deployment_tool(manifests="...", approved=True). - Mapping: The LLM calls
build_cloudflared_target_tool(...)and prints the final Cloudflare Tunnel ingress target (e.g.,http://auth-service.dev.svc.cluster.local:80).
Publishing & Distribution
This project includes all necessary configurations to publish and package the MCP server.
1. Build and Publish on PyPI
Compile the server into a standard pip package and upload it to PyPI:
# Install builder and twine
pip install --upgrade build twine
# Build package artifacts
python3 -m build
# Upload package to PyPI
python3 -m twine upload dist/*
Once published, users can install it via pip install mcp-k8s-deployer and run the executable mcp-k8s-deployer.
2. Package as a Docker Container
Build and distribute a lightweight, secure Docker image:
# Build the container image
docker build -t your-dockerhub-username/mcp-k8s-deployer:latest .
# Push the container image to Docker Hub
docker push your-dockerhub-username/mcp-k8s-deployer:latest
3. Deploy with Docker Compose & Cloudflare Tunnel
For a ready-to-run setup that exposes the MCP server over HTTP using a Cloudflare Tunnel:
- Create a
.envfile in the same directory asdocker-compose.yamlto hold your Cloudflare token:CLOUDFLARE_TUNNEL_TOKEN=your_cloudflare_tunnel_token_here
- Start the services:
docker compose up -d
- In your Cloudflare Zero Trust Dashboard, set up a Public Hostname for your tunnel:
- Subdomain/Domain:
mcp.yourdomain.com - Service Type:
HTTP - URL:
mcp-server:8000(orlocalhost:8000if using host network mode)
- Subdomain/Domain:
Your MCP server is now securely routed at https://mcp.yourdomain.com/sse.
4. Share on GitHub
To share the codebase on GitHub, initialize git, register origin, and push:
git init
git add .
git commit -m "Initial commit of MCP Kubernetes deployer"
git remote add origin https://github.com/yourusername/mcp-k8s-deployer.git
git branch -M main
git push -u origin main
Note: A .gitignore file has been preconfigured to exclude environment files and build caches.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_k8s_deployer-1.0.0.tar.gz.
File metadata
- Download URL: mcp_k8s_deployer-1.0.0.tar.gz
- Upload date:
- Size: 21.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad5133e465803fd9830500d1aa3d7c716bb36e26439bcaf9e2a989c80db1e9d1
|
|
| MD5 |
ffc36745e31bfb4028327704be769706
|
|
| BLAKE2b-256 |
1db4641db60f8972891562c3f5f9f82141faeafab9da3a211842655ddb76abf6
|
Provenance
The following attestation bundles were made for mcp_k8s_deployer-1.0.0.tar.gz:
Publisher:
publish.yml on stwins60/mcp-k8s-deployer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_k8s_deployer-1.0.0.tar.gz -
Subject digest:
ad5133e465803fd9830500d1aa3d7c716bb36e26439bcaf9e2a989c80db1e9d1 - Sigstore transparency entry: 1984464153
- Sigstore integration time:
-
Permalink:
stwins60/mcp-k8s-deployer@4d7069edce573571cd08060200776bde28ae1447 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/stwins60
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4d7069edce573571cd08060200776bde28ae1447 -
Trigger Event:
release
-
Statement type:
File details
Details for the file mcp_k8s_deployer-1.0.0-py3-none-any.whl.
File metadata
- Download URL: mcp_k8s_deployer-1.0.0-py3-none-any.whl
- Upload date:
- Size: 17.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2439769cab2ca24f1a4ec0afaa21bcc4965097296e2ead55ab8b385969af430
|
|
| MD5 |
c66420b665beabe34e68c34919643afb
|
|
| BLAKE2b-256 |
cd56a67d430b4ed6cc8ac5a6aba63a8d9a0d5b897921481b3469a93cd98e9a2d
|
Provenance
The following attestation bundles were made for mcp_k8s_deployer-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on stwins60/mcp-k8s-deployer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_k8s_deployer-1.0.0-py3-none-any.whl -
Subject digest:
e2439769cab2ca24f1a4ec0afaa21bcc4965097296e2ead55ab8b385969af430 - Sigstore transparency entry: 1984464258
- Sigstore integration time:
-
Permalink:
stwins60/mcp-k8s-deployer@4d7069edce573571cd08060200776bde28ae1447 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/stwins60
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4d7069edce573571cd08060200776bde28ae1447 -
Trigger Event:
release
-
Statement type: