Repo for Kubernetes Manifest Generator using MCP Server
K8s Manifest Generator — MCP Server
An MCP server that generates production-ready Kubernetes manifests from a simple service description. Built with FastMCP and Pydantic for automatic schema generation and input validation.
Given a service name, container image, and ports, it produces up to 8 fully-configured Kubernetes resources with security hardening, health probes, resource limits, and availability guarantees — ready to kubectl apply.
Architecture
User request → server.py (FastMCP + Pydantic) → generators.py (K8s logic) → YAML output
| File | Purpose |
|------|---------|
| server.py | MCP protocol layer — tool registration, input validation via Pydantic models |
| generators.py | Business logic — builds K8s manifests as Python dicts, converts to YAML |
Setup
cd mcp-server
uv sync
This installs all dependencies into a .venv managed by uv. Dependencies are defined in pyproject.toml.
Prerequisites
- Python 3.11+
- uv — install with
curl -LsSf https://astral.sh/uv/install.sh | sh
Usage
With Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"k8s-generator": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/mcp-server", "python", "server.py"]
}
}
}
With Claude Code
claude mcp add k8s-generator -- uv run --directory /absolute/path/to/mcp-server python server.py
Direct Test
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | uv run python server.py
Run the Server
uv run python server.py
Standalone (without MCP)
uv run python -c "
from generators import generate_all
result = generate_all({
'name': 'sock-shop-front-end',
'image': 'weaveworksdemos/front-end:0.3.12',
'ports': [{'port': 8079, 'name': 'http'}],
'namespace': 'sock-shop',
'access_level': 'public',
'autoscaling': {'min': 2, 'max': 10, 'cpu_target': 70},
'ingress': {'host': 'shop.example.com', 'tls': True},
})
print(result['manifests'])
print(result['security_summary'])
"
All examples below use real Docker images from the Weaveworks Sock Shop — a polyglot e-commerce microservices demo you can deploy and test immediately.
Tool: generate_k8s_manifests
Required Fields
| Field | Type | Example |
|-------|------|---------|
| name | string | "sock-shop-orders" |
| image | string | "weaveworksdemos/orders:0.4.7" |
| ports | list | [{"name": "http", "port": 8080}] |
Optional Fields
| Field | Default | Description |
|-------|---------|-------------|
| replicas | 2 | Number of pod replicas |
| namespace | "default" | Kubernetes namespace |
| rollout_strategy | "RollingUpdate" | "RollingUpdate" or "Recreate" |
| max_surge | "25%" | Max surge during rolling update |
| max_unavailable | "0" | Max unavailable during rolling update |
| access_level | "internal" | "internal", "public", or "restricted" |
| autoscaling | none | {"min": 2, "max": 10, "cpu_target": 70} |
| cpu_request | "100m" | CPU request |
| cpu_limit | "500m" | CPU limit |
| memory_request | "128Mi" | Memory request |
| memory_limit | "512Mi" | Memory limit |
| env_vars | none | {"LOG_LEVEL": "info"} |
| health_path | "/healthz" | Health check endpoint |
| health_port | first port | Health check port |
Ingress Configuration
| Field | Default | Description |
|-------|---------|-------------|
| ingress.host | required | Hostname (e.g. "api.example.com") |
| ingress.tls | true | Enable TLS with auto-generated secret name |
| ingress.ingress_class | "nginx" | Ingress controller class |
| ingress.path | "/" | URL path |
| ingress.path_type | "Prefix" | "Prefix" or "Exact" |
PodDisruptionBudget Configuration
| Field | Default | Description |
|-------|---------|-------------|
| pdb.min_available | "50%" | Minimum available pods (e.g. "50%" or "1") |
PDB is auto-generated when replicas >= 2. Skipped for single-replica deployments.
Security Configuration
| Field | Default | Description |
|-------|---------|-------------|
| service_account_token | false | Automount ServiceAccount token |
| read_only_fs | true | readOnlyRootFilesystem (writable /tmp provided via emptyDir) |
| run_as_user | 65534 | Container UID (null to omit) |
| run_as_non_root | true | Enforce non-root (false for images like nginx/httpd) |
| drop_capabilities | ["ALL"] | Linux capabilities to drop |
| add_capabilities | none | Capabilities to add back (e.g. ["CHOWN", "SETUID", "SETGID"]) |
Generated Resources
| Resource | Condition | Name Pattern |
|----------|-----------|-------------|
| Namespace | namespace != "default" | {namespace} |
| ServiceAccount | Always | {name}-sa |
| Deployment | Always | {name} |
| Service | Always | {name} |
| HorizontalPodAutoscaler | autoscaling provided | {name} |
| PodDisruptionBudget | replicas >= 2 | {name}-pdb |
| NetworkPolicy | Always | {name}-netpol |
| Ingress | ingress provided | {name}-ingress |
Generation Order
Namespace → ServiceAccount → Deployment → Service → HPA → PDB → NetworkPolicy → Ingress
Security Defaults
- Dedicated ServiceAccount per workload (
automountServiceAccountToken: false) runAsNonRoot: true,runAsUser: 65534(nobody)readOnlyRootFilesystem: truewith writable/tmpvia emptyDirallowPrivilegeEscalation: falsecapabilities: drop: ["ALL"]seccompProfile: RuntimeDefault- NetworkPolicy scoped by access level
Examples
All examples use real Docker images from the Weaveworks Sock Shop e-commerce demo.
Storefront — public-facing with autoscaling and ingress
generate_all({
"name": "sock-shop-front-end",
"image": "weaveworksdemos/front-end:0.3.12",
"ports": [{"port": 8079, "name": "http"}],
"namespace": "sock-shop",
"access_level": "public",
"replicas": 3,
"health_path": "/",
"autoscaling": {"min": 2, "max": 10, "cpu_target": 70},
"ingress": {"host": "shop.example.com", "tls": True},
"read_only_fs": False,
"run_as_non_root": False,
"run_as_user": None,
"add_capabilities": ["CHOWN", "SETUID", "SETGID", "NET_BIND_SERVICE"],
})
# Generates all 8 resources: Namespace, ServiceAccount, Deployment, Service, HPA, PDB, NetworkPolicy, Ingress
Orders API — internal microservice
generate_all({
"name": "sock-shop-orders",
"image": "weaveworksdemos/orders:0.4.7",
"ports": [{"port": 80, "name": "http"}],
"namespace": "sock-shop",
"access_level": "internal",
"replicas": 2,
"health_path": "/health",
"env_vars": {"JAVA_OPTS": "-Xms64m -Xmx128m"},
"read_only_fs": False,
"run_as_non_root": False,
"run_as_user": None,
"add_capabilities": ["CHOWN", "SETUID", "SETGID", "NET_BIND_SERVICE"],
})
Catalogue — lightweight Go service (hardened defaults)
generate_all({
"name": "sock-shop-catalogue",
"image": "weaveworksdemos/catalogue:0.3.5",
"ports": [{"port": 80, "name": "http"}],
"namespace": "sock-shop",
"health_path": "/health",
"replicas": 2,
})
# Uses all security defaults: non-root, read-only FS, drop ALL capabilities
Shipping worker — single replica, no ingress
generate_all({
"name": "sock-shop-shipping",
"image": "weaveworksdemos/shipping:0.4.8",
"ports": [{"port": 80, "name": "http"}],
"namespace": "sock-shop",
"replicas": 1,
"health_path": "/health",
"read_only_fs": False,
"run_as_non_root": False,
"run_as_user": None,
"add_capabilities": ["CHOWN", "SETUID", "SETGID", "NET_BIND_SERVICE"],
})
# Generates: Namespace, ServiceAccount, Deployment, Service, NetworkPolicy
# Skips: HPA (no autoscaling), PDB (single replica), Ingress (no config)
Payment — restricted access, strict security
generate_all({
"name": "sock-shop-payment",
"image": "weaveworksdemos/payment:0.4.3",
"ports": [{"port": 80, "name": "http"}],
"namespace": "sock-shop",
"access_level": "restricted",
"replicas": 3,
"health_path": "/health",
"pdb": {"min_available": "2"},
})
# NetworkPolicy denies all ingress by default — add explicit allow rules after deployment
License
MIT