BetaMCPG is in public beta. Join the waitlist for managed cloud + early-access features.
MCPG
beta
All guides
Production8 min

Kubernetes install with Helm

Run an HA MCPG fleet on Kubernetes with the operator + Helm chart. NATS or Redis for shared state.

This guide installs MCPG on Kubernetes for production use: the operator, an HA gateway deployment, and shared state via NATS (or Redis). Target audience: SREs and platform teams.

Prerequisites

  • Kubernetes 1.26 or newer
  • Helm 3.x
  • A namespace to deploy into (we'll use mcpg)
  • Either NATS or Redis available in-cluster (we'll deploy NATS as a chart dependency)

1. Install the operator

The operator watches MCPGGateway, MCPGPlugin, MCPGPluginSet, and MCPGRevocationList CRDs cluster-wide.

bash
kubectl create namespace mcpg
helm repo add mcpg https://charts.mcpg.dev
helm repo update

helm install mcpg-operator mcpg/mcpg-operator -n mcpg \
  --set rbac.create=true \
  --set webhook.enabled=true

Verify:

bash
kubectl -n mcpg get pods
# mcpg-operator-7d8c4b9b8-xj2pq   1/1   Running

2. Install the control plane

The control plane is optional for single-instance deployments but required for fleets.

bash
helm install mcpg-cp mcpg/mcpg-cp -n mcpg \
  --set replicaCount=3 \
  --set postgres.enabled=true \
  --set postgres.auth.password=$(openssl rand -hex 16) \
  --set ingress.enabled=true \
  --set ingress.host=mcpg-cp.example.com

This deploys 3 cp-server replicas with Postgres for state, an Ingress at the configured host, and the embedded dashboard. Login uses OIDC (configure in oidc.* values) or local admin credentials.

3. Install a gateway fleet

bash
helm install gw mcpg/mcpg -n mcpg \
  --set replicaCount=3 \
  --set autoscaling.enabled=true \
  --set autoscaling.minReplicas=3 \
  --set autoscaling.maxReplicas=10 \
  --set podDisruptionBudget.enabled=true \
  --set nats.enabled=true \
  --set controlPlane.url=https://mcpg-cp.example.com \
  --set controlPlane.enrollmentToken=$(mcpg-ctl token --once)

Each gateway replica registers itself with the control plane on startup using the single-use enrollment token. The CP hands back an instance JWT and starts pushing config.

4. Verify the fleet

In the dashboard:

  1. Navigate to Instances.
  2. You should see 3 instances in Active state.
  3. Click one to drill into per-instance status, plugins, and tool calls.

CLI verification:

bash
mcpg-ctl gateway status
# 3 instances · 0 quarantined · 0 dirty

5. Bind a plugin set

Create the plugin set as a CRD:

yaml
apiVersion: mcpg.dev/v1
kind: MCPGPluginSet
metadata:
  name: production
  namespace: mcpg
spec:
  plugins:
    - id: identity.oidc
      version: "1.0.0"
    - id: policy.cedar
      version: "1.0.0"
      config:
        bundle: ./policies/
    - id: reliability.rate-limit
      version: "1.0.0"
      config:
        default_rps: 100

Apply:

bash
kubectl apply -f plugin-set.yaml

Bind to the gateway:

bash
kubectl patch mcpggateway gw -n mcpg --type=merge \
  -p '{"spec":{"pluginSetRef":{"name":"production"}}}'

The operator reconciles, the CP pushes a ConfigUpdate, and each gateway replica reloads without dropping connections.

6. Connect upstream tools

The same bindings: config from the quickstart guide works unchanged. Mount it as a ConfigMap and reference it in the MCPGGateway spec.

Cluster state options

BackendPick when
NATS JetStream (nats.enabled=true)You don't already run Redis. JetStream gives KV + pub/sub + leases in one component.
Redis (redis.enabled=true)You already run Redis. Lower operational overhead.
Built-in single-nodeSingle-instance only. Don't use this for HA.

See the cluster backends article for the trade-offs.

What's next