Skip to content

Add MCP server support to Retool Helm chart#285

Open
arnold-retool wants to merge 5 commits into
r2from
arnold/mcp-helm-chart
Open

Add MCP server support to Retool Helm chart#285
arnold-retool wants to merge 5 commits into
r2from
arnold/mcp-helm-chart

Conversation

@arnold-retool
Copy link
Copy Markdown

@arnold-retool arnold-retool commented May 7, 2026

Adds optional MCP server support to the Retool Helm chart, disabled by default.

Main changes:

  • Adds a new mcp values block in charts/retool/values.yaml and root values.yaml.
  • Adds a standalone MCP Service, Deployment, and optional PodDisruptionBudget.
  • Runs MCP using the backend image with SERVICE_TYPE=MCP_SERVER.
  • Supports MCP configuration for replicas, resources, env vars, toolsets, transport/session limits, service ports, affinity, node selectors, and tolerations.
  • Routes /mcp and /.well-known/oauth-protected-resource to the MCP service through both Ingress and HTTPRoute.
  • Adds MCP helper labels/naming in _helpers.tpl.
  • Adds CI render coverage via test-mcp-enabled-option.yaml.

Validation performed:

  • Helm template render with MCP disabled
  • Helm template render with MCP enabled
  • Helm lint with MCP enabled
  • kubeconform validation during earlier verification

@arnold-retool
Copy link
Copy Markdown
Author

@codex review this bad boy

@arnold-retool
Copy link
Copy Markdown
Author

Some initial AI review comments:

Full review comments:

  • [P1] Default mcp.config to an empty map — /Users/arnold/retool-helm/charts/retool/values.yaml:582-582
    When users enable MCP with the documented defaults, e.g. --set mcp.enabled=true, this key is null because it contains only comments. The template then dereferences .Values.mcp.config.retoolBackendUrl, so helm
    template fails before rendering; default this to {} or guard the accesses so MCP can be enabled without supplying optional config.
  • [P2] Branch MCP ingress backends for v1beta1 — /Users/arnold/retool-helm/charts/retool/templates/ingress.yaml:54-58
    On Kubernetes versions where this template emits networking.k8s.io/v1beta1 (<1.19), these new MCP paths still render the v1 backend.service.name/port.number fields. The v1beta1 API expects serviceName/servicePo
    rt, so enabling MCP ingress on those clusters produces an Ingress the API rejects; use the same version branch as the main backend path for the MCP backend, including the duplicated hosts block below.

@JatinNanda
Copy link
Copy Markdown
Contributor

main thing: this template is 374 lines, multiplayer is 252, and most of the diff is stuff we don't actually need in v1. ideally this just mirrors deployment_multiplayer_ws.yaml — one optional service + deployment, gated on mcp.enabled. can we cut it down?

stuff i'd drop unless there's a concrete reason:

  • the PodDisruptionBudget block — multiplayer doesn't have one, neither do the other deployments. if we want PDBs everywhere that's a separate chart-wide change
  • the externalSecrets envFrom blocks (both enabled and externalSecretsOperator.enabled variants) — multiplayer reads the same db/jwt/encryption secrets without it, why does mcp need it?
  • the dbconnector env vars (DB_CONNECTOR_HOST/PORT, JAVA_DB_CONNECTOR_*, etc.) — i thought mcp called the backend over http. does it really need to talk to dbconnector directly?
  • google OAuth CLIENT_ID/CLIENT_SECRET — same question, mcp sits behind the backend, why does it need google oauth client creds?
  • the preStopHook lifecycle — multiplayer doesn't have it, skip unless there's a real reason
  • per-deployment affinity/nodeSelector/tolerations override (mcp.affinity | default .Values.affinity, etc.) — multiplayer just inherits top-level. fine for v1, can add later if someone asks
  • mcp.config.retoolUrl falling back to env.BASE_DOMAIN with a kindIs "map" guard — feels fragile, just require the user to set it explicitly

if you cut those, the template lands close to multiplayer in size and shape and they'll be much easier to keep in sync going forward.

couple of bugs worth fixing regardless:

  • the new retool.env helper in _helpers.tpl got wedged between shouldIncludeConfigSecretsEnvVars's doc comment and its define. the doc comment is now orphaned above retool.env and shouldIncludeConfigSecretsEnvVars has no doc. move it next to the other env-rendering helpers
  • retool.env is named generically but only used by mcp — either inline it the way every other deployment does (range $key, $value := .Values.env) or rename so it doesn't look like the canonical helper
  • naming nit: mcp.replicas should be mcp.replicaCount to match multiplayer.replicaCount / codeExecutor.replicaCount / etc.
  • the service's metadata.labels only includes retool.labels, but the deployment includes retool.mcp.selectorLabels + retool.mcp.labels + retool.labels. pick one — probably just match multiplayer (retool.labels + retoolService: selector inline) and drop the two new mcp label helpers entirely

ingress + httproute additions look fine, they match the existing multiplayer pattern.

@arnold-retool arnold-retool force-pushed the arnold/mcp-helm-chart branch from db5e260 to d618c4d Compare May 8, 2026 18:26
Comment thread charts/retool/templates/deployment_mcp.yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants