An MCP (Model Context Protocol) server that provides powerful tools to interact with OpenShift/Kubernetes clusters using the openshift-python-wrapper library.
- Python 3.8+
- Access to an OpenShift/Kubernetes cluster
- Valid kubeconfig file
# Install with uv (recommended)
uv tool install openshift-python-wrapper
# Or install with pip
pip install openshift-python-wrapperOnce installed, you can run the MCP server with:
# Run the MCP server
openshift-mcp-serverFor development or running from source:
# Clone and install in development mode
git clone https://github.com/RedHatQE/openshift-python-wrapper.git
cd openshift-python-wrapper
# Or run directly
uv run mcp_server/server.pyList Kubernetes/OpenShift resources with filtering capabilities.
Parameters:
resource_type(required): Type of resource (e.g., "pod", "deployment")namespace(optional): Namespace to search inlabel_selector(optional): Filter by labels (e.g., "app=nginx")field_selector(optional): Filter by fieldslimit(optional): Maximum number of results
Example:
# List all pods in the default namespace
list_resources(resource_type="pod", namespace="default")
# List deployments with specific label
list_resources(resource_type="deployment", label_selector="app=frontend")Get detailed information about a specific resource.
Parameters:
resource_type(required): Type of resourcename(required): Resource namenamespace(optional): Namespace (required for namespaced resources)output_format(optional): Format - "info", "yaml", "json", "wide" (default: "info")
Example:
# Get pod details in YAML format
get_resource(resource_type="pod", name="nginx", namespace="default", output_format="yaml")Create a new resource from YAML or specifications.
Parameters:
resource_type(required): Type of resourcename(required): Resource namenamespace(optional): Namespace for namespaced resourcesyaml_content(optional): Complete YAML definitionspec(optional): Resource specification as dictlabels(optional): Labels to applyannotations(optional): Annotations to applywait(optional): Wait for resource to be ready
Example:
# Create a namespace
create_resource(resource_type="namespace", name="test-ns", spec={})
# Create from YAML
yaml = """
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:latest
"""
create_resource(resource_type="pod", name="nginx", yaml_content=yaml)Update an existing resource using patch operations.
Parameters:
resource_type(required): Type of resourcename(required): Resource namenamespace(optional): Namespacepatch(required): Patch data as dictpatch_type(optional): "merge", "strategic", "json" (default: "merge")
Example:
# Scale a deployment
update_resource(
resource_type="deployment",
name="my-app",
namespace="default",
patch={"spec": {"replicas": 3}}
)Delete a resource.
Parameters:
resource_type(required): Type of resourcename(required): Resource namenamespace(optional): Namespacewait(optional): Wait for deletion to complete (default: true)timeout(optional): Deletion timeout in seconds (default: 60)
Example:
delete_resource(resource_type="pod", name="nginx", namespace="default")Apply YAML manifests containing one or more resources.
Parameters:
yaml_content(required): YAML content with one or more resourcesnamespace(optional): Default namespace for resources without namespace
Example:
yaml_content = """
---
apiVersion: v1
kind: Namespace
metadata:
name: test-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: test-app
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
"""
apply_yaml(yaml_content=yaml_content)Retrieve logs from pod containers.
Parameters:
name(required): Pod namenamespace(required): Namespacecontainer(optional): Container name (for multi-container pods)tail_lines(optional): Number of lines from endsince_seconds(optional): Logs since N seconds agoprevious(optional): Get logs from previous container instance
Example:
# Get last 100 lines of logs
get_pod_logs(name="my-app-abc123", namespace="production", tail_lines=100)
# Get logs from last hour
get_pod_logs(name="my-app-abc123", namespace="production", since_seconds=3600)Execute commands inside pod containers.
Parameters:
name(required): Pod namenamespace(required): Namespacecommand(required): Command to execute as listcontainer(optional): Container name
Example:
# Check nginx config
exec_in_pod(
name="nginx-pod",
namespace="default",
command=["nginx", "-t"]
)
# List files
exec_in_pod(
name="my-app",
namespace="default",
command=["ls", "-la", "/app"]
)Get Kubernetes events related to a resource.
Parameters:
resource_type(required): Type of resourcename(required): Resource namenamespace(optional): Namespacelimit(optional): Maximum events to return (default: 10)
Example:
# Get pod events
get_resource_events(resource_type="pod", name="crashloop-pod", namespace="default")Get all available resource types.
Parameters:
random_string(required): Any string (required by MCP protocol)
Example:
get_resource_types(random_string="x")Add to your Cursor settings (~/.cursor/mcp.json):
{
"mcpServers": {
"openshift-python-wrapper": {
"command": "openshift-mcp-server"
}
}
}Then use in Cursor with @openshift-python-wrapper.
Add to Claude Desktop config:
{
"mcpServers": {
"openshift-python-wrapper": {
"command": "openshift-mcp-server"
}
}
}If you need to specify a custom kubeconfig location:
{
"mcpServers": {
"openshift-python-wrapper": {
"command": "openshift-mcp-server",
"env": {
"KUBECONFIG": "/home/user/.kube/config"
}
}
}
}# Check pod status
pod = get_resource("pod", "failing-app", "production")
# Get recent events
events = get_resource_events("pod", "failing-app", "production")
# Check logs
logs = get_pod_logs("failing-app", "production", tail_lines=200)
# Execute diagnostic command
exec_in_pod("failing-app", "production", ["cat", "/etc/app/config.yaml"])# Apply all resources at once
yaml = """
---
apiVersion: v1
kind: Namespace
metadata:
name: my-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: my-app
spec:
replicas: 3
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: api
image: myapp/backend:v1.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: backend
namespace: my-app
spec:
selector:
app: backend
ports:
- port: 80
targetPort: 8080
"""
apply_yaml(yaml)# List nodes
nodes = list_resources("node")
# Check for pod issues
problem_pods = list_resources("pod", field_selector="status.phase!=Running,status.phase!=Succeeded")
# Review recent events
events = list_resources("event", limit=50)# Check CNV version
csv = list_resources("clusterserviceversion", namespace="openshift-cnv")
# List VMs
vms = list_resources("virtualmachine", namespace="my-vms")
# Check VM status
vm = get_resource("virtualmachine", "rhel9-vm", "my-vms")The server dynamically discovers all available resource types from your cluster. Common types include:
pod,service,deployment,replicaset,daemonsetconfigmap,secret,persistentvolume,persistentvolumeclaimnamespace,node,event,endpointserviceaccount,role,rolebinding,clusterrole,clusterrolebinding
route,project,imagestream,buildconfig,deploymentconfiguser,group,oauth,securitycontextconstraints
virtualmachine,virtualmachineinstance,datavolumehyperconverged,kubevirt,cdi
clusterserviceversion,subscription,installplan,operatorgroupcatalogsource,packagemanifest
- RBAC: Ensure your kubeconfig has appropriate permissions
- Namespaces: Use namespace isolation for multi-tenant environments
- Resource Limits: Set appropriate limits when listing resources
- Sensitive Data: Be careful with secrets and configmaps
# Test cluster connectivity
kubectl cluster-info
# Check kubeconfig
echo $KUBECONFIG
kubectl config current-context# Check your permissions
kubectl auth can-i --list# Run in debug mode
SIMPLE_LOGGER_LEVEL=DEBUG python mcp_server/server.py
# Check logs
tail -f /tmp/mcp_server_debug.log- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Submit a pull request
New resource types are automatically discovered from the cluster. To ensure proper support:
- Add the resource module to
ocp_resources/ - Ensure it has
api_groupandapi_versionattributes - Test with the MCP server
This project is licensed under the Apache License 2.0.