π Deploying the MCP Gateway Stack with Helm¶
This guide walks you through installing, upgrading, and removing the full MCP Gateway Stack using Helm. The stack includes:
- π§ MCP Context Forge (the gateway)
- π PostgreSQL database
- β‘ Redis cache
- π§π» PgAdmin UI (optional)
- π§° Redis Commander UI (optional)
Everything is deployable via Helm on any Kubernetes cluster (Minikube, kind, EKS, AKS, GKE, OpenShift, etc.).
π¦ Helm chart location: https://github.com/IBM/mcp-context-forge/tree/main/charts/mcp-stack
π§ Architecture¶
flowchart TD
subgraph Ingress Layer
ingress[NGINX Ingress Controller]
end
subgraph Application Layer
mcp[MCP Context Forge]
pgadmin[PgAdmin UI<br/>optional]
rediscommander[Redis Commander UI<br/>optional]
end
subgraph Data Layer
postgres[(PostgreSQL)]
redis[(Redis)]
end
ingress --> mcp
ingress --> pgadmin
ingress --> rediscommander
mcp --> postgres
mcp --> redis
pgadmin --> postgres
rediscommander --> redis
π Prerequisites¶
Requirement | Notes |
---|---|
Kubernetes β₯ 1.23 | Local (Minikube/kind) or managed (EKS, AKS, GKE, etc.) |
Helm 3 | Used for installing and managing releases |
kubectl | Configured to talk to your target cluster |
Ingress Controller | NGINX, Traefik, or cloud-native (or disable via values.yaml) |
StorageClass (RWX) | Required for PostgreSQL PVC unless persistence is disabled |
β Pre-flight Checklist (Run Before Deploying)
Ensure these checks pass before installing the stack.
Verify you're pointing to the intended cluster context.
kubectl auth can-i create namespace
kubectl auth can-i create deployment -n default
kubectl auth can-i create clusterrolebinding
Confirm you have adequate access (or switch to a namespace where you do).
Must be v1.23
or higher. Some Helm charts and features depend on it.
π Install Helm & kubectl
You'll need both Helm and kubectl installed to deploy the stack.
# Helm
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# kubectl
curl -LO "https://dl.k8s.io/release/$(curl -sSL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin
Installs latest stable versions directly from official sources.
Requires Chocolatey to be installed first.
π¦ Clone and inspect the chart
β RBAC test (if enabled)
Confirm the service account created by the chart can access resources as expected.
π Prepare the Namespace (Recommended)
It's best practice to isolate the stack in its own namespace, with labels and policies for security and clarity.
You can use a different name (e.g. mcp
, prod-gateway
) as long as you reference it consistently in your Helm commands.
kubectl label namespace mcp-private environment=prod --overwrite
kubectl annotate namespace mcp-private "config.kubernetes.io/owner=mcp" --overwrite
Labels and annotations can help with GitOps sync, audit, and tracking tools.
cat <<'EOF' | kubectl apply -n mcp-private -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-by-default
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
EOF
This restricts all traffic by default. You'll need to define allowed communication between components separately, or use service mesh policies.
π§Ύ Customize values¶
π§Ύ Customize values.yaml
Copy and edit the default values file to tailor the deployment to your environment.
This gives you a working copy of the Helm chart and lets you customize settings safely.
mcpContextForge:
image:
repository: ghcr.io/ibm/mcp-context-forge
tag: v1.0.0
ingress:
enabled: true
host: gateway.local # Change this to your actual DNS
className: nginx
envFrom:
- secretRef:
name: mcp-gateway-secret
- configMapRef:
name: mcp-gateway-config
postgres:
credentials:
user: admin
password: S3cuReP@ss # Avoid hardcoding in production
persistence:
size: 10Gi
pgadmin:
enabled: false
redisCommander:
enabled: false
rbac:
create: true
This configures image version, ingress host, secrets, storage, and RBAC. In production, prefer secrets over inline passwords.
π Install / Upgrade the stack¶
π Install or Upgrade the Stack
Install the MCP Gateway Stack into your Kubernetes cluster using Helm. This will deploy all components defined in your my-values.yaml
.
helm upgrade --install mcp-stack . \
--namespace mcp-private \
--create-namespace=false \
-f my-values.yaml \
--wait --timeout 30m --debug
This installs or upgrades the stack in the mcp-private
namespace, using your custom values file. Set --create-namespace=true
if the namespace hasn't been created yet.
- MCP Context Forge (API Gateway)
- PostgreSQL with optional persistence
- Redis cache
- (Optional) PgAdmin & Redis Commander
- Ingress configuration (if enabled)
- NetworkPolicy and RBAC (if configured)
Helm upgrades are idempotent. You can run the same command again safely after making changes to my-values.yaml
.
β Verify deployment¶
β Verify Deployment
After installation completes, confirm that all resources are running and healthy.
This should show running pods, services, deployments, and Helm release status.
You should see a 200 OK
response or similar from the health endpoint.
Port-forwarding gives you local access to the service when Ingress is disabled or not ready.
π Upgrade & Rollback¶
π Upgrade & Rollback
You can upgrade to a new image version, preview changes before applying, or roll back to a previous release.
Updates only the image tag (or any specific value you override) while preserving existing resources.
helm plugin install https://github.com/databus23/helm-diff
helm diff upgrade mcp-stack . -n mcp-private -f my-values.yaml
Shows what will change without applying anything. Requires the helm-diff plugin.
π§Ή Uninstall¶
π§Ή Uninstall the Stack
This removes all components deployed by the Helm chart.
Removes deployments, services, and related resources created by the chart.
Use this if you want to fully clean up everything, including secrets, configmaps, and PVCs.
# Uninstall the Helm release
helm uninstall mcp-stack -n mcp-private
# Delete PVCs if you're not keeping data
kubectl delete pvc --all -n mcp-private
# Delete the namespace
kubectl delete namespace mcp-private
# Reinstall from scratch (if desired)
helm upgrade --install mcp-stack . \
--namespace mcp-private \
-f my-values.yaml \
--wait --timeout 15m --debug
Use this flow when you need to wipe the environment and redeploy fresh.
π§ͺ CI/CD: Packaging & OCI Push¶
π§ͺ CI/CD: Packaging & OCI Push
Package your Helm chart and push it to an OCI-compliant registry for use in GitOps workflows (e.g., Argo CD, Flux).
This validates your chart and creates a .tgz
package in the dist/
directory.
Replace <your-org>
with your GitHub container registry org. Make sure HELM_EXPERIMENTAL_OCI=1
is set if using older Helm versions.
- Works with private registries
- Easily versioned and managed
- Supported by Argo CD and Flux natively
π§― Troubleshooting¶
π§― Troubleshooting Common Issues
Quick fixes and diagnostic tips for common deployment problems.
- Cause: Image not found or access denied
- Fix:
- Check
image:
field invalues.yaml
- Ensure the image tag exists and is publicly accessible (or add a pull secret)
- Cause: Ingress host mismatch or controller not ready
- Fix:
- Make sure the ingress hostname matches DNS or
/etc/hosts
- Confirm an Ingress Controller is deployed and available
- Fix:
Check logs for configuration or secret injection issues.
- Cause: Secret or ConfigMap not mounted
- Fix: Confirm
envFrom
is configured in yourmy-values.yaml
and the resources exist:
π§Ύ values.yaml - Common Keys¶
π§Ύ values.yaml - Common Keys Reference
Most frequently used keys in values.yaml
and what they control.
Key | Default | Description |
---|---|---|
mcpContextForge.image.tag | latest | Image version for MCP Context Forge |
mcpContextForge.ingress.enabled | true | Enables ingress resource creation |
mcpContextForge.ingress.host | gateway.local | Hostname used in Ingress (change in production) |
mcpContextForge.service.type | ClusterIP | Use LoadBalancer if running in cloud |
mcpContextForge.envFrom | [] | Allows mounting Secrets/ConfigMaps as env vars |
postgres.credentials.user | admin | Default DB username (use secret in prod) |
postgres.credentials.password | test123 | Default DB password (avoid hardcoding) |
postgres.persistence.enabled | true | Enables persistent volume claim for PostgreSQL |
postgres.persistence.size | 10Gi | Size of the PostgreSQL volume |
pgadmin.enabled | false | Enable PgAdmin for DB UI |
redisCommander.enabled | false | Enable Redis Commander for Redis UI |
rbac.create | true | Automatically create Role/RoleBinding |
π For all possible options, see the full values.yaml
file in the chart repository.
See full annotations in values.yaml
.
π Further Reading¶
π Further Reading & References
Useful links to understand Helm, Kubernetes, and GitOps tools used with the MCP stack.
- π Helm Documentation
- π§ Helm Diff Plugin
- π¦ Helm OCI Registry Docs
- π Kubernetes Ingress
- πΎ Persistent Volumes
- π Kubernetes Secrets
- π Network Policies
β You now have a production-ready Helm workflow for MCP Context Forge. It's CI-friendly, customizable, and tested across Kubernetes distributions.