Overview
Deploy the MCP Server with LangGraph using Helm for simplified Kubernetes deployment management. The Helm chart includes all dependencies (Keycloak, Redis, OpenFGA, PostgreSQL) with production-ready defaults.v2.8.0 Helm chart includes Keycloak SSO, Redis sessions, OpenFGA authorization, and comprehensive observability.
Quick Start
Copy
Ask AI
## Add Helm repository (future - when published)
## helm repo add langgraph https://your-org.github.io/helm-charts
## helm repo update
## For now, use local chart
cd deployments/helm
## Install with default values
helm install mcp-server-langgraph ./mcp-server-langgraph \
--namespace mcp-server-langgraph \
--create-namespace \
--set image.repository=gcr.io/your-project/mcp-server-langgraph \
--set image.tag=v2.8.0 \
--set secrets.anthropicApiKey="${ANTHROPIC_API_KEY}"
## Check deployment status
helm status mcp-server-langgraph -n mcp-server-langgraph
## Get service URL
kubectl get ingress -n mcp-server-langgraph
Prerequisites
Install Helm
Copy
Ask AI
# Install Helm 3
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Verify installation
helm version
Container Image
Build and push your container image:
Copy
Ask AI
docker build -t gcr.io/your-project/mcp-server-langgraph:v2.8.0 .
docker push gcr.io/your-project/mcp-server-langgraph:v2.8.0
Chart Structure
Copy
Ask AI
deployments/helm/mcp-server-langgraph/
├── Chart.yaml # Chart metadata
├── values.yaml # Default configuration
├── values-production.yaml # Production overrides
├── templates/
│ ├── deployment.yaml # Main application
│ ├── service.yaml # Kubernetes Service
│ ├── ingress.yaml # Ingress configuration
│ ├── configmap.yaml # Configuration
│ ├── secret.yaml # Secrets
│ ├── serviceaccount.yaml # Service account
│ ├── hpa.yaml # Autoscaling
│ ├── pdb.yaml # Pod disruption budget
│ └── _helpers.tpl # Template helpers
└── README.md
Installation
Basic Installation
Copy
Ask AI
helm install mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
--namespace mcp-server-langgraph \
--create-namespace \
--set image.repository=gcr.io/your-project/mcp-server-langgraph \
--set image.tag=v2.8.0 \
--set secrets.anthropicApiKey="${ANTHROPIC_API_KEY}" \
--set secrets.googleApiKey="${GOOGLE_API_KEY}" \
--set ingress.enabled=true \
--set ingress.hosts[0].host=api.yourdomain.com
With Custom Values File
- Create values-production.yaml
- Install
Copy
Ask AI
# values-production.yaml
replicaCount: 5
image:
repository: gcr.io/your-project/mcp-server-langgraph
tag: "v2.8.0"
pullPolicy: IfNotPresent
# Ingress
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
hosts:
- host: api.yourdomain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: mcp-server-langgraph-tls
hosts:
- api.yourdomain.com
# Autoscaling
autoscaling:
enabled: true
minReplicas: 5
maxReplicas: 20
targetCPUUtilizationPercentage: 70
# Resources
resources:
requests:
cpu: 1000m
memory: 1Gi
limits:
cpu: 4000m
memory: 4Gi
# Application config
config:
llmProvider: "anthropic"
modelName: "claude-sonnet-4-5-20250929"
authProvider: "keycloak"
authMode: "session"
enableTracing: true
enableMetrics: true
# Keycloak SSO
keycloak:
enabled: true
replicaCount: 2
postgresql:
enabled: true
ingress:
enabled: true
hostname: sso.yourdomain.com
# Redis Sessions
redis:
enabled: true
architecture: replication
master:
persistence:
enabled: true
size: 20Gi
replica:
replicaCount: 2
persistence:
enabled: true
# OpenFGA
openfga:
enabled: true
replicaCount: 2
# PostgreSQL (for Keycloak & OpenFGA)
postgresql:
enabled: true
primary:
persistence:
enabled: true
size: 50Gi
Copy
Ask AI
helm install mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
--namespace mcp-server-langgraph \
--create-namespace \
--values values-production.yaml \
--set secrets.anthropicApiKey="${ANTHROPIC_API_KEY}" \
--set secrets.googleApiKey="${GOOGLE_API_KEY}" \
--set secrets.jwtSecretKey="$(openssl rand -base64 32)" \
--set secrets.redisPassword="$(openssl rand -base64 32)"
Cloud-Specific Installations
- Google Cloud (GKE)
- AWS (EKS)
- Azure (AKS)
Copy
Ask AI
# values-gke.yaml
image:
repository: gcr.io/your-project/mcp-server-langgraph
serviceAccount:
create: true
annotations:
iam.gke.io/gcp-service-account: mcp-server-langgraph@your-project.iam.gserviceaccount.com
ingress:
enabled: true
className: "gce"
annotations:
kubernetes.io/ingress.global-static-ip-name: "mcp-server-langgraph-ip"
networking.gke.io/managed-certificates: "mcp-server-langgraph-cert"
keycloak:
ingress:
className: "gce"
postgresql:
primary:
persistence:
storageClass: "standard-rwo"
redis:
master:
persistence:
storageClass: "standard-rwo"
Copy
Ask AI
# Create static IP
gcloud compute addresses create mcp-server-langgraph-ip --global
# Install chart
helm install mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
-n mcp-server-langgraph --create-namespace \
-f values-gke.yaml
Copy
Ask AI
# values-eks.yaml
image:
repository: 123456789012.dkr.ecr.us-east-1.amazonaws.com/mcp-server-langgraph
serviceAccount:
create: true
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/mcp-server-langgraph-role
ingress:
enabled: true
className: "alb"
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:...
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
postgresql:
primary:
persistence:
storageClass: "gp3"
redis:
master:
persistence:
storageClass: "gp3"
Copy
Ask AI
helm install mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
-n mcp-server-langgraph --create-namespace \
-f values-eks.yaml
Copy
Ask AI
# values-aks.yaml
image:
repository: yourregistry.azurecr.io/mcp-server-langgraph
serviceAccount:
create: true
annotations:
azure.workload.identity/client-id: "your-client-id"
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
postgresql:
primary:
persistence:
storageClass: "managed-premium"
redis:
master:
persistence:
storageClass: "managed-premium"
Copy
Ask AI
helm install mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
-n mcp-server-langgraph --create-namespace \
-f values-aks.yaml
Configuration
Application Configuration
Copy
Ask AI
## In values.yaml
config:
# Service
environment: "production"
logLevel: "INFO"
# LLM Provider
llmProvider: "anthropic" # google, anthropic, openai, azure
modelName: "claude-sonnet-4-5-20250929"
modelTemperature: "0.7"
modelMaxTokens: "4096"
enableFallback: true
# Agent
maxIterations: 10
enableCheckpointing: true
# Authentication
authProvider: "keycloak" # inmemory, keycloak
authMode: "session" # token, session
# Keycloak
keycloakServerUrl: "http://keycloak:8080"
keycloakRealm: "mcp-server-langgraph"
keycloakClientId: "langgraph-client"
keycloakVerifySsl: true
# Sessions
sessionBackend: "redis"
redisUrl: "redis://redis-session:6379/0"
sessionTtlSeconds: 86400
sessionSlidingWindow: true
sessionMaxConcurrent: 5
# OpenFGA
openfgaApiUrl: "http://openfga:8080"
# Observability
enableTracing: true
enableMetrics: true
observabilityBackend: "opentelemetry"
otlpEndpoint: "http://otel-collector:4317"
Secrets Configuration
Never commit secrets to Git! Use
--set flags, external secret managers, or Kubernetes secrets.Copy
Ask AI
## In values.yaml (DO NOT commit actual values!)
secrets:
# LLM API Keys
anthropicApiKey: ""
googleApiKey: ""
openaiApiKey: ""
# Authentication
jwtSecretKey: ""
keycloakClientSecret: ""
# Session Store
redisPassword: ""
# OpenFGA
openfgaStoreId: ""
openfgaModelId: ""
# Observability (optional)
langsmithApiKey: ""
# Secrets Management (optional)
infisicalClientId: ""
infisicalClientSecret: ""
infisicalProjectId: ""
Copy
Ask AI
helm install mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
--set secrets.anthropicApiKey="${ANTHROPIC_API_KEY}" \
--set secrets.googleApiKey="${GOOGLE_API_KEY}" \
--set secrets.jwtSecretKey="$(openssl rand -base64 32)" \
--set secrets.keycloakClientSecret="${KEYCLOAK_CLIENT_SECRET}" \
--set secrets.redisPassword="$(openssl rand -base64 32)"
Dependencies Configuration
- Keycloak
- Redis
- OpenFGA
- PostgreSQL
Copy
Ask AI
keycloak:
enabled: true
replicaCount: 2
auth:
adminUser: admin
adminPassword: "" # Set via --set
postgresql:
enabled: true
auth:
password: "" # Auto-generated
ingress:
enabled: true
hostname: sso.yourdomain.com
ingressClassName: nginx
tls: true
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 2Gi
Copy
Ask AI
redis:
enabled: true
architecture: replication # standalone, replication
auth:
password: "" # Set via --set
master:
persistence:
enabled: true
size: 10Gi
storageClass: "standard"
replica:
replicaCount: 2
persistence:
enabled: true
size: 10Gi
sentinel:
enabled: true
metrics:
enabled: true
serviceMonitor:
enabled: true
Copy
Ask AI
openfga:
enabled: true
replicaCount: 2
datastore:
engine: postgres
# Uses postgresql dependency
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 1000m
memory: 1Gi
Copy
Ask AI
postgresql:
enabled: true
auth:
postgresPassword: "" # Auto-generated
database: keycloak
primary:
persistence:
enabled: true
size: 50Gi
storageClass: "standard"
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
metrics:
enabled: true
serviceMonitor:
enabled: true
Upgrading
Minor Version Upgrade
Copy
Ask AI
## Update values if needed
vim values-production.yaml
## Upgrade release
helm upgrade mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
--namespace mcp-server-langgraph \
--values values-production.yaml \
--set image.tag=v2.8.0
## Check rollout
kubectl rollout status deployment/mcp-server-langgraph -n mcp-server-langgraph
Major Version Upgrade
Copy
Ask AI
## Check for breaking changes
helm show notes ./deployments/helm/mcp-server-langgraph
## Backup current values
helm get values mcp-server-langgraph -n mcp-server-langgraph > current-values.yaml
## Perform upgrade
helm upgrade mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
--namespace mcp-server-langgraph \
--values current-values.yaml \
--set image.tag=v3.0.0 \
--reuse-values
## Verify
helm list -n mcp-server-langgraph
kubectl get pods -n mcp-server-langgraph
Rollback
Copy
Ask AI
## List release history
helm history mcp-server-langgraph -n mcp-server-langgraph
## Rollback to previous version
helm rollback mcp-server-langgraph -n mcp-server-langgraph
## Or rollback to specific revision
helm rollback mcp-server-langgraph 3 -n mcp-server-langgraph
Uninstallation
Copy
Ask AI
## Uninstall release
helm uninstall mcp-server-langgraph -n mcp-server-langgraph
## Delete namespace (if desired)
kubectl delete namespace mcp-server-langgraph
## Note: PVCs are not deleted by default
## List PVCs
kubectl get pvc -n mcp-server-langgraph
## Delete PVCs (WARNING: Deletes data!)
kubectl delete pvc --all -n mcp-server-langgraph
Customization
Custom Init Containers
Copy
Ask AI
## values.yaml
initContainers:
- name: wait-for-database
image: busybox:1.36
command: ['sh', '-c']
args:
- |
until nc -z postgresql 5432; do
echo "Waiting for PostgreSQL..."
sleep 2
done
Custom Sidecars
Copy
Ask AI
## values.yaml
sidecars:
- name: cloud-sql-proxy
image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.8.0
args:
- "--structured-logs"
- "--port=5432"
- "your-project:us-central1:your-instance"
securityContext:
runAsNonRoot: true
resources:
requests:
memory: "256Mi"
cpu: "100m"
Custom Volumes
Copy
Ask AI
## values.yaml
extraVolumes:
- name: model-cache
persistentVolumeClaim:
claimName: model-cache-pvc
extraVolumeMounts:
- name: model-cache
mountPath: /app/.cache/models
Environment Variables
Copy
Ask AI
## values.yaml
extraEnv:
- name: CUSTOM_VAR
value: "custom-value"
- name: SECRET_VAR
valueFrom:
secretKeyRef:
name: external-secret
key: secret-key
Monitoring
Prometheus Integration
Copy
Ask AI
## values.yaml
metrics:
enabled: true
serviceMonitor:
enabled: true
interval: 30s
labels:
release: prometheus
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8000"
prometheus.io/path: "/metrics/prometheus"
Grafana Dashboards
Copy
Ask AI
## Import dashboards from configmap
kubectl create configmap langgraph-dashboards \
--from-file=dashboards/ \
--namespace=observability
## Label for Grafana sidecar
kubectl label configmap langgraph-dashboards \
grafana_dashboard=1 \
--namespace=observability
Troubleshooting
Helm install fails
Helm install fails
Copy
Ask AI
# Check for syntax errors
helm lint ./deployments/helm/mcp-server-langgraph
# Dry-run to see rendered manifests
helm install mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
--dry-run --debug \
--namespace mcp-server-langgraph
# Check dependencies
helm dependency update ./deployments/helm/mcp-server-langgraph
Dependencies not deploying
Dependencies not deploying
Copy
Ask AI
# Update dependencies
cd deployments/helm/mcp-server-langgraph
helm dependency update
# Check Chart.yaml dependencies
cat Chart.yaml
# Install with dependency conditions
helm install mcp-server-langgraph . \
--set keycloak.enabled=true \
--set redis.enabled=true \
--set openfga.enabled=true
Values not applying
Values not applying
Copy
Ask AI
# Check current values
helm get values mcp-server-langgraph -n mcp-server-langgraph
# Check all values (including defaults)
helm get values mcp-server-langgraph -n mcp-server-langgraph --all
# Verify rendered templates
helm template mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
--values values-production.yaml \
--debug
Upgrade fails
Upgrade fails
Copy
Ask AI
# Check what will change
helm diff upgrade mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
--values values-production.yaml
# Force upgrade
helm upgrade mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
--force \
--cleanup-on-fail
# If stuck, delete and reinstall
helm uninstall mcp-server-langgraph -n mcp-server-langgraph
helm install mcp-server-langgraph ./deployments/helm/mcp-server-langgraph \
--values values-production.yaml
Best Practices
Version Control
Version Control
- Commit values files to Git (without secrets)
- Tag releases with Helm chart version
- Use semantic versioning for Chart.yaml
- Document breaking changes in Chart notes
Secret Management
Secret Management
- Never commit secrets to values files
- Use external secret operators (External Secrets Operator, Sealed Secrets)
- Rotate secrets regularly
- Use cloud secret managers (GCP Secret Manager, AWS Secrets Manager)
Testing
Testing
- Test with helm lint before deployment
- Use —dry-run to preview changes
- Deploy to staging first
- Validate with smoke tests after deployment
Production Readiness
Production Readiness
- Enable autoscaling for production
- Set resource limits appropriately
- Enable PodDisruptionBudget for HA
- Use persistent volumes for stateful components
- Enable monitoring and alerting
Next Steps
Kubernetes Deployment
Manual Kubernetes deployment guide
Production Checklist
Pre-deployment verification
Scaling Guide
Auto-scaling configuration
Monitoring
Observability setup
Simplified Deployment: Helm charts make Kubernetes deployment easy with one command!