Skip to content

[feat][MCP] Make public routing mode explicit - #391

Merged
arnold-retool merged 7 commits into
mainfrom
arnold/mcp-routing-mode
Oct 21, 2026
Merged

arnold-retool merged 7 commits into
mainfrom
arnold/mcp-routing-mode

Conversation

@arnold-retool

@arnold-retool arnold-retool commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #390 (arnold/mcp-helm-public-url-test). Review this PR against that branch; it contains only the routing change and its tests.

Summary

Adds public MCP routing choices for older Retool versions (direct) and Retool 4.0.7+ (backendRelay).

For recent versions, backendRelay lets MCP and OAuth discovery requests use the main Retool Service instead of dedicated public MCP routes. The public route must cover those URLs; the backend then relays /mcp to the MCP Service.

In more detail:

  • Adds mcp.routing.mode with direct as the compatibility default. This preserves the dedicated routes used by older Retool servers and also works with the tested recent server image.
  • Retool 4.0.7 and later can explicitly select backendRelay to route MCP and OAuth discovery requests through the main Retool Service; its backend relays /mcp to the MCP Service using MCP_SERVICE_INGRESS_DOMAIN.
Public path direct target
/.well-known/oauth-authorization-server (ImplementationSpecific Ingress; Exact HTTPRoute) Backend API Service, port 3001
/.well-known/oauth-protected-resource (ImplementationSpecific Ingress; Exact HTTPRoute) MCP Service, port 4010
/mcp (prefix) MCP Service, port 4010
/ (ImplementationSpecific Ingress default; PathPrefix HTTPRoute) Main Retool Service, port 3000

In backendRelay, the chart renders no dedicated MCP Ingress or HTTPRoute rules; a public / route must match the MCP URLs and target the main Retool Service. The chart does not parse image.tag to choose a mode. Unknown modes and non-boolean legacy enable flags fail rendering when a chart-managed Ingress or HTTPRoute renders. The alternate ingress.hostName branch renders an explicit / main path. No server code changed.

Migration

  • Retool before 4.0.7 requires direct. It remains the default and also works on newer versions. On Retool 4.0.7+, opt into backendRelay with mcp.routing.mode: backendRelay.
  • When switching to backendRelay, remove any old mcp.ingress.enabled: true or mcp.httpRoute.enabled: true overrides, or set them to false. These flags now default to null, which adds dedicated routes only in direct mode when MCP is enabled. If MCP is enabled and the chart renders an Ingress or HTTPRoute, an explicit true conflicts with backendRelay and fails rendering.
  • Ensure the public host routes /mcp and both OAuth discovery URLs to the main Retool Service on port 3000. The default HTTPRoute rule and an Ingress using ingress.hostName provide a / route. Check each ingress.hosts[*].paths entry, custom httpRoute.rules, and externally managed routes separately. An Ingress path with pathType: Exact and path: / does not cover /mcp. External operators can use the direct-mode routing table above.
  • For chart upgrades, use helm upgrade --reset-then-reuse-values to load the new defaults while retaining saved overrides. Plain --reuse-values can leave mcp.routing.mode absent. If MCP is enabled and the chart renders its Ingress or HTTPRoute, that produces a migration error. If your Helm version lacks the flag, pass your custom values file with -f and omit --reuse-values.
  • To check the public routes after upgrading, set mcp.test.publicUrl to your Retool origin and run helm test. The test pod must be able to reach that host.

Implementation notes

ingress-nginx with strict path validation rejects dots in Exact and Prefix paths, so direct Ingress discovery paths use ImplementationSpecific. Check path matching with your Ingress controller; Gateway API discovery rules remain Exact.

Routing and migration guidance sits above mcp.routing.mode in both synchronized values files. This stacked PR targets chart version 6.12.5; #390 targets 6.12.4, following the current main release at 6.12.3.

Validation

  • python3 .github/test_mcp_routing.py: 15 render checks passed for both modes, Ingress and HTTPRoute, MCP disabled, explicit overrides, conflicts, and invalid modes.
  • Stacked python3 .github/test_mcp_helm_test.py: 16 checks passed.
  • helm lint with CI installation and MCP values: passed.
  • Repository .github/kubeconform.sh against Kubernetes v1.31.6 across its CI value combinations: passed.
  • Values-file sync and git diff --check: passed.
  • All 22 locally available on-prem source tags from onprem-4.0.7-f08359f through onprem-4.47.0-92b3bae retain the MCP /mcp, MCP protected-resource discovery, and backend authorization-server discovery route definitions targeted by direct.
  • On the AWS sandbox's pr-4.68.0-15a4b64 image, direct requests to the MCP and backend API Services with the public Host and forwarded HTTPS scheme passed: /mcp returned a 401 Bearer challenge with public resource_metadata; protected-resource discovery returned valid public resource JSON; authorization-server discovery returned valid public OAuth JSON.
  • Upgraded the AWS sandbox release to revision 8 with this chart. Its computed mode is direct, all four deployments are ready, and helm test retool passed. The sandbox disables chart-managed Ingress and HTTPRoute, so its external ALB normally keeps a catch-all main-Service route.
  • Temporarily added exact public-host ALB path rules matching direct: /mcp and protected-resource discovery to the MCP pod on 4010, authorization-server discovery to backend API pods on 3001, with ALB-only security-group access. Both the public probe and in-cluster helm test passed through those direct rules. Removed the temporary rules, target groups, and access afterward; independently verified the original catch-all rule and port-3000-only access remained, and the public probe still passed.
  • The local source tags are a sample of releases; source inspection and live testing on one recent image do not prove every later build.

@greptile-apps

greptile-apps Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new actionable issues remain.

Reviews (2) · Last reviewed commit: "Clarify MCP routing setup guidance" · Reviewed by Greptile

Comment thread charts/retool/values.yaml Outdated
Comment thread charts/retool/templates/_helpers.tpl Outdated
Comment thread README.md Outdated
Comment on lines +1 to +2
{{- /* Run mode and migration validation even when neither public route is enabled. */ -}}
{{- $mode := include "retool.mcp.routingMode" . -}}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait why do we still need to run the validation helper if neither the ingress nor httproute are enabled?

@arnold-retool
arnold-retool force-pushed the arnold/mcp-routing-mode branch 2 times, most recently from 6853746 to 9f1f24d Compare October 20, 2026 20:51
@arnold-retool
arnold-retool force-pushed the arnold/mcp-routing-mode branch from 9f1f24d to 0ac6245 Compare October 20, 2026 23:32
Base automatically changed from arnold/mcp-helm-public-url-test to main October 21, 2026 21:42
@arnold-retool
arnold-retool force-pushed the arnold/mcp-routing-mode branch from 0ac6245 to 358d14c Compare October 21, 2026 21:47

Copy link
Copy Markdown
Contributor Author

@arnold-retool
arnold-retool merged commit 941053a into main Oct 21, 2026
16 checks passed
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