+++ title = 'Installation' weight = 1 +++
This guide describes how to deploy the MCP Server for Strimzi to a Kubernetes cluster. For a local setup or quick evaluation (no build required), see the getting started guide.
Before you begin, ensure you have:
- A Kubernetes cluster with
kubectlconfigured - The Strimzi operator deployed (see Deploy Strimzi)
- An AI assistant that supports MCP (see MCP clients)
If you do not have Strimzi deployed, follow these steps.
The setup script automates the entire deployment process. Run this from the repository root:
./dev/scripts/setup-strimzi.sh deployThis script performs the following steps:
- Deploys the Strimzi operator to the
strimzinamespace - Waits for the operator to be ready
- Creates the
strimzi-kafkanamespace - Deploys a sample Kafka cluster named
mcp-cluster - Waits for the Kafka cluster to be ready
You can pass additional flags to deploy observability infrastructure alongside Strimzi:
# Deploy Strimzi with Prometheus for metrics collection
./dev/scripts/setup-strimzi.sh deploy --prometheus
# Deploy Strimzi with Loki for log collection (OpenShift only)
./dev/scripts/setup-strimzi.sh deploy --loki
# Deploy Strimzi with both
./dev/scripts/setup-strimzi.sh deploy --prometheus --loki
# Deploy Strimzi with KafkaConnect and a sample connector
./dev/scripts/setup-strimzi.sh deploy --connect
# Deploy Strimzi with Jaeger for tracing
./dev/scripts/setup-strimzi.sh deploy --jaeger
# Deploy Strimzi with Drain Cleaner for graceful node drains
./dev/scripts/setup-strimzi.sh deploy --drain-cleaner
# Deploy Strimzi with a secondary Kafka cluster and MirrorMaker2 for cross-cluster replication
./dev/scripts/setup-strimzi.sh deploy --mirror-makerOn OpenShift, add the --ocp flag to use Route listeners instead of NodePort:
./dev/scripts/setup-strimzi.sh deploy --ocpIf you prefer to deploy manually:
# Deploy the Strimzi operator
kubectl apply -k dev/manifests/strimzi/strimzi-operator/
# Wait for the operator to be ready
kubectl wait --for=condition=Available \
deployment/strimzi-cluster-operator \
-n strimzi \
--timeout=120s
# Deploy a Kafka cluster
kubectl apply -k dev/manifests/strimzi/kafka/
# Wait for the cluster to be ready
kubectl wait kafka/mcp-cluster \
--for=condition=Ready \
-n strimzi-kafka \
--timeout=300sCheck that Strimzi is running correctly:
# Check the operator
kubectl get deployment -n strimzi
# Check the Kafka cluster
kubectl get kafka -n strimzi-kafka
# Check the pods
kubectl get pods -n strimzi-kafkaYou should see the operator running and the Kafka cluster in a Ready state.
Build and push the container image to your registry:
cd strimzi-mcp
# Build and push to your registry
../mvnw clean package -DskipTests \
-Dquarkus.container-image.build=true \
-Dquarkus.container-image.push=true \
-Dquarkus.container-image.registry=quay.io \
-Dquarkus.container-image.group=your-org \
-Dquarkus.container-image.name=strimzi-mcp \
-Dquarkus.container-image.tag=latestThe default image location is quay.io/streamshub/strimzi-mcp:latest.
The deployment manifests use Kustomize with a base and environment-specific overlays:
| Overlay | Command | Use case |
|---|---|---|
base |
kubectl apply -k install/strimzi-mcp/base/ |
Minimal deployment with defaults |
overlays/dev |
kubectl apply -k install/strimzi-mcp/overlays/dev/ |
Local development with Kind, minikube, or Docker Desktop. Uses imagePullPolicy: Always. |
overlays/dev-openshift |
kubectl apply -k install/strimzi-mcp/overlays/dev-openshift/ |
Local development on OpenShift (CRC, Red Hat OpenShift Local). Adds a TLS Route for external access. |
overlays/prod |
kubectl apply -k install/strimzi-mcp/overlays/prod/ |
Production Kubernetes. Adds 2 replicas, higher resource limits, ConfigMap/Secret references. |
overlays/prod-openshift |
kubectl apply -k install/strimzi-mcp/overlays/prod-openshift/ |
Production OpenShift. Extends prod with an edge-terminated TLS Route. |
How to choose:
- Use dev or dev-openshift if you are testing locally or developing features.
- Use prod or prod-openshift for any shared or production environment.
- Use the -openshift variants if you are running on OpenShift (they add a Route for external access).
- Use base only if you want a minimal starting point to customize yourself.
The prod overlay adds:
- 2 replicas for high availability
- Higher resource requests and limits
- Optional ConfigMap and Secret references for configuration via
envFrom
The prod-openshift overlay extends prod with an edge-terminated TLS Route for external access.
The dev-openshift overlay extends dev with the same Route configuration, for local development on OpenShift (CRC, Red Hat OpenShift Local). It is deployed automatically by dev-deploy.sh --ocp.
Install directly from a release tag without cloning the repository.
Replace <version> with a tag from the releases page (e.g., v0.1.0):
# Production Kubernetes
kubectl apply -k "https://github.com/streamshub/streamshub-mcp/install/strimzi-mcp/overlays/prod?ref=<version>"
# Production OpenShift
kubectl apply -k "https://github.com/streamshub/streamshub-mcp/install/strimzi-mcp/overlays/prod-openshift?ref=<version>"
# Base (minimal deployment)
kubectl apply -k "https://github.com/streamshub/streamshub-mcp/install/strimzi-mcp/base?ref=<version>"Deploy using the overlay that matches your environment:
# Production Kubernetes
kubectl apply -k install/strimzi-mcp/overlays/prod/
# Production OpenShift
kubectl apply -k install/strimzi-mcp/overlays/prod-openshift/Verify the deployment is healthy:
# Wait for the rollout to complete
kubectl -n streamshub-mcp rollout status deployment/streamshub-mcp-strimzi --timeout=120s
# Check pods are running
kubectl -n streamshub-mcp get pods
# Check health endpoint (requires port-forward if not exposed)
kubectl -n streamshub-mcp port-forward svc/streamshub-mcp-strimzi 8080:8080 &
curl http://localhost:8080/q/healthTo override the image tag or registry:
cd install/strimzi-mcp/base
kustomize edit set image quay.io/streamshub/strimzi-mcp=my-registry.io/my-org/strimzi-mcp:1.0.0
kubectl apply -k ../overlays/prod/The install/strimzi-mcp/base/ directory contains the following resources:
| File | Resource | Purpose |
|---|---|---|
namespace.yaml |
Namespace | Creates the streamshub-mcp namespace |
serviceaccount.yaml |
ServiceAccount | Provides identity for the MCP server |
clusterrole.yaml |
ClusterRole | Grants read-only permissions for non-sensitive resources |
clusterrolebinding.yaml |
ClusterRoleBinding | Binds the ClusterRole to the ServiceAccount |
deployment.yaml |
Deployment | Deploys the MCP server with health probes |
service.yaml |
Service | Exposes the MCP server on port 8080 |
../optional/role-sensitive.yaml |
Role | Optional per-namespace permissions for sensitive resources |
../optional/rolebinding-sensitive.yaml |
RoleBinding | Companion RoleBinding for the sensitive Role |
For the full directory structure and overlay details, see the install README.
The MCP server uses a two-tier RBAC model for security.
ClusterRole (default, non-sensitive resources):
The ClusterRole grants read-only access to:
- Strimzi custom resources --
get,list,watch - Deployments --
get,list,watch - Pods and logs --
get,list - Services and ConfigMaps --
get,list - Routes and Ingresses --
get,list - Leases --
get,list - ValidatingWebhookConfigurations --
get,list
Role (opt-in per namespace, sensitive resources):
The optional Role grants access to:
- Secrets --
get(for certificate metadata only, not secret data) - Pods/proxy --
get(for direct metrics scraping from pods)
Deploy the sensitive Role and its RoleBinding only in namespaces where you need these features:
kubectl apply -f install/strimzi-mcp/optional/role-sensitive.yaml -n kafka-namespace
kubectl apply -f install/strimzi-mcp/optional/rolebinding-sensitive.yaml -n kafka-namespaceWhat happens without the sensitive Role:
If you do not apply the optional sensitive Role, the following features are unavailable:
- Certificate details —
get_kafka_cluster_certificatescannot read TLS certificate metadata from Secrets - Direct metrics scraping — The default
streamshub-pod-scrapingmetrics provider cannot access pod metrics endpoints viapods/proxy. You must use thestreamshub-prometheusprovider instead (see configuration).
All other tools work normally without the sensitive Role.
The MCP Server for Strimzi is designed for platform engineering and SRE teams that already have Kubernetes access. It provides a read-only view of Strimzi-managed resources and relies on Kubernetes RBAC as its sole authorization mechanism.
The MCP server has no built-in authentication or authorization. It inherits the Kubernetes identity of its runtime environment:
- Kubernetes deployment -- The server uses its ServiceAccount token. The ServiceAccount's RBAC rules determine which resources the server can access.
- Local development (
quarkus:dev) -- The server uses the current user's kubeconfig. All tools operate with the user's Kubernetes permissions.
The MCP HTTP endpoint (/mcp) does not require credentials.
Any client that can reach the endpoint can invoke all tools.
Warning: The endpoint is unauthenticated by design and is live as soon as the server starts. Apply at least one of the controls below (a NetworkPolicy is the minimum recommended step) before exposing the server in any shared or production environment. See also the production deployment checklist in the configuration guide.
In production, restrict access to the MCP endpoint using infrastructure-level controls:
- Kubernetes NetworkPolicy -- Limit which pods or namespaces can reach the MCP server
- Authenticating reverse proxy -- Deploy an OAuth2 proxy, mTLS termination, or API gateway in front of the MCP server
- Service mesh -- Use Istio, Linkerd, or similar to enforce mutual TLS and authorization policies
- Ingress authentication -- Configure ingress controller annotations for authentication (e.g.,
nginx.ingress.kubernetes.io/auth-url)
CORS is restricted to localhost origins by default.
Configure quarkus.http.cors.origins to allow other origins (see configuration).
All tools are read-only (readOnlyHint=true, destructiveHint=false).
The server never creates, modifies, or deletes Kubernetes resources.
Sensitive data is protected by multiple layers:
- Credential secrets are never exposed. The server reads Secrets only for certificate metadata (issuer, expiry) -- never for secret data such as passwords, keys, or tokens.
- Log redaction automatically strips sensitive patterns (tokens, passwords, API keys) from log output before returning it to the client.
- Response size limits truncate large responses to prevent excessive data transfer.
- Rate limiting throttles requests per category to prevent resource exhaustion.
The prod overlay references an optional ConfigMap (strimzi-mcp-config) and Secret (strimzi-mcp-secrets) via envFrom.
Create these before deploying to configure the server:
# Create a ConfigMap with your configuration
kubectl -n streamshub-mcp create configmap strimzi-mcp-config \
--from-literal=MCP_LOG_TAIL_LINES=500 \
--from-literal=MCP_METRICS_PROVIDER=streamshub-prometheus \
--from-literal=QUARKUS_REST_CLIENT_PROMETHEUS_URL=http://prometheus.monitoring:9090
# Create a Secret for sensitive values
kubectl -n streamshub-mcp create secret generic strimzi-mcp-secrets \
--from-literal=QUARKUS_REST_CLIENT_PROMETHEUS_USERNAME=your-username \
--from-literal=QUARKUS_REST_CLIENT_PROMETHEUS_PASSWORD=your-passwordBoth are marked as optional so the deployment works without them.
See the configuration guide for all available settings.
Use port-forwarding to access the server from your local machine:
kubectl -n streamshub-mcp port-forward svc/streamshub-mcp-strimzi 8080:8080Configure your MCP client to use http://localhost:8080/mcp.
The prod-openshift and dev-openshift overlays include an edge-terminated Route automatically:
kubectl apply -k install/strimzi-mcp/overlays/prod-openshift/
# Get the Route hostname
ROUTE_HOST=$(oc -n streamshub-mcp get route streamshub-mcp-strimzi -o jsonpath='{.spec.host}')
echo "MCP Server URL: https://${ROUTE_HOST}/mcp"Alternatively, create a Route manually:
oc -n streamshub-mcp create route edge streamshub-mcp-strimzi \
--service=streamshub-mcp-strimzi \
--port=httpConfigure your MCP client with the HTTPS URL: https://<route-hostname>/mcp.
Prerequisites: This example requires an ingress controller (e.g., nginx-ingress) and cert-manager for automatic TLS certificate provisioning. Adjust the annotations if you use a different setup.
Create an Ingress resource for external access on standard Kubernetes:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: streamshub-mcp-strimzi
namespace: streamshub-mcp
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- mcp.example.com
secretName: strimzi-mcp-tls
rules:
- host: mcp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: streamshub-mcp-strimzi
port:
number: 8080Apply the Ingress and configure your MCP client with: https://mcp.example.com/mcp.
Verify the server is healthy:
# Liveness probe
curl http://localhost:8080/q/health/live
# Readiness probe
curl http://localhost:8080/q/health/ready
# Full health check
curl http://localhost:8080/q/healthTest the MCP endpoint directly:
# List available tools
curl -X POST http://localhost:8080/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'You should see a JSON response listing all available MCP tools.
If the server fails to start in Kubernetes:
# Check Kubernetes connectivity
kubectl cluster-info
# Verify Strimzi CRDs exist
kubectl get crd | grep strimzi
# Check server logs
kubectl -n streamshub-mcp logs deployment/streamshub-mcp-strimziIf you see permission errors:
# Verify you have the necessary permissions
kubectl auth can-i list kafkas --all-namespaces
# Check the ServiceAccount exists
kubectl get serviceaccount -n streamshub-mcp
# Check the ClusterRoleBinding exists
kubectl get clusterrolebinding | grep streamshub-mcpIf your AI assistant cannot connect:
- Verify the server is running:
curl http://localhost:8080/q/health - Check firewall rules allow connections on port 8080
- Verify your MCP client configuration has the correct URL
- Check server logs for connection attempts
For more help, see the troubleshooting guide.
- Configuration -- Configure Loki, Prometheus, and other settings
- Tools reference -- Explore available tools and their parameters
- Usage examples -- See practical examples and workflows
- Troubleshooting -- Resolve common issues