Skip to content

ClickHouse MCP Server + Agentgateway Integration

ClickHouse MCP Server + Agentgateway Integration

Section titled “ClickHouse MCP Server + Agentgateway Integration”

Status: Design (pre-plan) Bead: hl-a44o Date: 2026-06-09

Deploy the ClickHouse MCP server (ghcr.io/clickhouse/mcp-clickhouse:0.4) in-cluster with two instances (read-only + read-write-no-drop), route both through the existing agentgateway at mcp-gw.fzymgc.house, and expose raw ClickHouse ports through Traefik for direct human access.

┌──────────────────────────────────────┐
│ agentgateway Gateway │
│ mcp-gw.fzymgc.house (MetalLB) │
│ │
Claude Code ──VK──► │ /mcp/clickhouse-ro ──token──► ro │
│ /mcp/clickhouse-rw ──token──► rw │
└──────────────────────────────────────┘
│ cluster-internal
┌──────────────────────────────────────┐
│ clickhouse-mcp namespace │
│ │
│ deploy/clickhouse-mcp-ro :8000 │
│ deploy/clickhouse-mcp-rw :8000 │
│ │
│ CLICKHOUSE_HOST=clickhouse. │
│ clickstack.svc:8123 │
│ CLICKHOUSE_USER=mcp_readonly/rw │
│ CLICKHOUSE_ALLOW_WRITE= true/false │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│ clickstack namespace │
│ │
- │ chi-cs-clickhouse-0-0 :8123 (HTTP) │
- │ chi-cs-clickhouse-0-0 :9000 (native) │
+ │ svc/clickhouse-headless :8123 (HTTP) │
+ │ svc/clickhouse-headless :9000 (native)│
│ │
│ Traefik IngressRoute │
- │ ch.fzymgc.house → svc:8123 │
- │ ch-native.fzymgc.house → svc:9000 │
+ │ ch.fzymgc.house → headless:8123 │
+ │ ch-native.fzymgc.house → headless:9000│
└──────────────────────────────────────┘

-Traefik terminates TLS at the edge (existing *.fzymgc.house wildcard cert), -forwards plain protocol internally: +Traefik terminates TLS at the edge, forwards plain protocol internally to the +ClickHouse headless service cs-clickstack-clickhouse-clickhouse-headless:

-HostnameTraefik Route TypeBackend PortProtocolClient Example
-ch.fzymgc.houseIngressRoute8123HTTPcurl, Tabix, DBeaver HTTP
-ch-native.fzymgc.houseIngressRouteTCP9000Native TCPclickhouse-client --host ch-native.fzymgc.house --port 443 --secure
+HostnameTraefik Route TypeBackendPortClient Example
+------------------------------------------------------------
+ch.fzymgc.houseIngressRoutecs-clickstack-clickhouse-clickhouse-headless8123curl, Tabix, DBeaver HTTP
+ch-native.fzymgc.houseIngressRouteTCPcs-clickstack-clickhouse-clickhouse-headless9000clickhouse-client --host ch-native.fzymgc.house --port 443 --secure

No new DNS entries needed — both hostnames are covered by the existing -*.fzymgc.house wildcard. No new cert-manager certificates needed. +*.fzymgc.house wildcard. + +TLS certificate: A new cert-manager Certificate resource is needed in the +clickstack namespace (secretName: ch-tls, DNS names: ch.fzymgc.house + +ch-native.fzymgc.house, issuer: cloudflare-acme-issuer ClusterIssuer). +Wildcard certs are namespace-scoped — the existing one lives in traefik only. +The IngressRoute and IngressRouteTCP both reference ch-tls.

Two dedicated users provisioned via a one-shot PostSync Job:

UserGrantsUsed by
mcp_readonlySELECT ON *.*clickhouse-mcp-ro
mcp_readwriteSELECT, INSERT, ALTER, CREATE ON *.* (no DROP/TRUNCATE)clickhouse-mcp-rw

Passwords stored in Vault at fzymgc-house/cluster/clickstack:

  • mcp_readonly_password

  • mcp_readwrite_password

    The provisioning Job is an ArgoCD PostSync hook in the clickstack namespace (ensures ClickHouse exists before user creation).

Image: ghcr.io/clickhouse/mcp-clickhouse:0.4 (multi-arch)

New ArgoCD Application: clickhouse-mcp → namespace clickhouse-mcp

Two Deployment+Service pairs, identical except for user and write flag:

Settingclickhouse-mcp-roclickhouse-mcp-rw
CLICKHOUSE_USERmcp_readonlymcp_readwrite
CLICKHOUSE_ALLOW_WRITE_ACCESSfalsetrue
CLICKHOUSE_ALLOW_DROPfalsefalse

Shared settings (both instances):

  • CLICKHOUSE_HOST: clickhouse.clickstack.svc.cluster.local

  • CLICKHOUSE_PORT: 8123

  • CLICKHOUSE_SECURE: false (cluster-internal, plain HTTP)

  • CLICKHOUSE_MCP_SERVER_TRANSPORT: http

  • CLICKHOUSE_MCP_BIND_HOST: 0.0.0.0

  • CLICKHOUSE_MCP_BIND_PORT: 8000

  • CLICKHOUSE_MCP_AUTH_TOKEN: sourced from clickhouse-mcp-auth ExternalSecret

    ExternalSecrets in clickhouse-mcp namespace:

  • clickhouse-mcp-creds → sources mcp_readonly_password + mcp_readwrite_password from fzymgc-house/cluster/clickstack

  • clickhouse-mcp-auth → sources clickhouse_mcp_auth_token from fzymgc-house/cluster/agentgateway

    NetworkPolicy: Allow ingress from agentgateway namespace on port 8000.

    App config path: argocd/app-configs/clickhouse-mcp/ (kustomize) Cluster app path: argocd/cluster-app/templates/clickhouse-mcp.yaml

New file: argocd/app-configs/agentgateway/mcp-clickhouse.yaml

For each of ro and rw:

  1. AgentgatewayBackend → cluster-local Service (clickhouse-mcp-{ro,rw}.clickhouse-mcp.svc.cluster.local:8000)

  2. HTTPRoute at /mcp/clickhouse-ro and /mcp/clickhouse-rw on the mcp-gw listener

  3. AgentgatewayPolicy apiKeyAuthentication — VK gating, mode: Strict

  4. AgentgatewayPolicy backend.auth.secretRef — injects Authorization: Bearer <token> upstream (same token for both instances)

    Modified files:

  • argocd/app-configs/agentgateway/kustomization.yaml — add mcp-clickhouse.yaml
  • argocd/app-configs/agentgateway/secrets.yaml:
    • New ExternalSecret agentgateway-mcp-clickhouse → templates clickhouse_mcp_auth_token as Authorization: Bearer <token>
    • agentgateway-vkeys — add clickhouse-ro and clickhouse-rw entries

fzymgc-house/cluster/clickstack — two new properties:

Terminal window
vault kv patch fzymgc-house/cluster/clickstack \
mcp_readonly_password="$(openssl rand -base64 24)" \
mcp_readwrite_password="$(openssl rand -base64 24)"

fzymgc-house/cluster/agentgateway — three new properties:

Terminal window
vault kv patch fzymgc-house/cluster/agentgateway \
clickhouse_mcp_auth_token="$(openssl rand -base64 32)" \
vk_clickhouse_ro="vk-ro-$(openssl rand -hex 16)" \
vk_clickhouse_rw="vk-rw-$(openssl rand -hex 16)"
{
"mcp-clickhouse-ro": {
"type": "http",
"url": "https://mcp-gw.fzymgc.house/mcp/clickhouse-ro",
"headers": { "Authorization": "Bearer <vk_clickhouse_ro>" }
},
"mcp-clickhouse-rw": {
"type": "http",
"url": "https://mcp-gw.fzymgc.house/mcp/clickhouse-rw",
"headers": { "Authorization": "Bearer <vk_clickhouse_rw>" }
}
}
  • docs/engineering/specs/2026-06-09-clickhouse-mcp-agentgateway-design.md
  • argocd/app-configs/clickhouse-mcp/namespace.yaml
  • argocd/app-configs/clickhouse-mcp/deployment.yaml
  • argocd/app-configs/clickhouse-mcp/service.yaml
  • argocd/app-configs/clickhouse-mcp/external-secret.yaml
  • argocd/app-configs/clickhouse-mcp/networkpolicy.yaml
  • argocd/app-configs/clickhouse-mcp/kustomization.yaml
  • argocd/cluster-app/templates/clickhouse-mcp.yaml
  • argocd/app-configs/agentgateway/mcp-clickhouse.yaml
  • argocd/app-configs/clickstack/ingressroute-ch-http.yaml
  • argocd/app-configs/clickstack/ingressroute-ch-native.yaml +- argocd/app-configs/clickstack/certificate-ch.yaml
  • argocd/app-configs/clickstack/user-provisioning-job.yaml (PostSync hook)
  • argocd/app-configs/agentgateway/kustomization.yaml
  • argocd/app-configs/agentgateway/secrets.yaml
  • argocd/app-configs/clickstack/kustomization.yaml +- argocd/app-configs/velero/backup-schedule.yaml — add clickhouse-mcp to excludedNamespaces (stateless, Git-recreatable)