Enable the MCP server
Enable Retool's MCP server on a self-hosted instance so MCP clients can connect and authenticate with OAuth 2.0.
Retool's MCP server lets compatible MCP clients connect to your self-hosted instance over HTTPS and authenticate with OAuth 2.0. On self-hosted instances, the MCP server runs as a separate service that you enable and route to at https://example.retool.com/mcp.
This guide explains how to enable the MCP service, route public traffic to it, and verify the connection. Once you're done, refer to Use Retool's MCP server to learn how to connect a client and which tools are available.
Requirements
Before you enable the MCP server, make sure you have:
- Retool 4.0.0 or later. If you're setting up a new instance, complete the self-hosted quickstart first. If you're upgrading your instance, follow the upgrade guide that applies to you.
- To use the app-generation tools, the new app builder's supporting services: the agent sandbox, Temporal, and a code executor or JS executor. For setup steps, refer to Update Helm configuration. MCP can connect and serve its other tools without these services, but the app-generation tools don't appear in your MCP client's tool list until they're running.
- Your Retool HTTPS URL, reachable by your MCP client and users' browsers, which this guide refers to as
https://example.retool.com. The MCP endpoint and the OAuth endpoints must use this same origin. - Access to change your public routes, whether the Retool Helm chart or your own ingress, gateway, or load balancer manages them.
Kubernetes with Helm is the supported production deployment method for Retool 4.0 and later. Other methods are suitable only for development and testing.
MCP traffic routing
The MCP server runs as its own service. MCP clients connect to /mcp and discover OAuth settings through /.well-known metadata paths. The MCP service serves /mcp and protected-resource metadata. The main Retool backend serves authorization-server metadata and the OAuth API endpoints. All of these are presented under your existing public Retool origin. To configure these routes, refer to Configure public routes. If an SSO gateway protects your origin, also refer to Configure an SSO gateway.
The MCP service also needs a private connection to the Retool backend so it can validate tokens and run tools. Keep this connection on your internal network and keep the MCP service port private.
Enable the MCP service
Complete the following steps to enable the MCP service on your instance.
- Helm
- Non-Helm
Set the public origin
In the values file for your existing Retool instance, enable the MCP service and set the public origin.
mcp:
enabled: true
routing:
mode: direct
config:
mcpServiceExternalUrl: "https://example.retool.com"
direct is the chart's default routing mode. It adds dedicated public routes for the MCP service. For more information, refer to Configure public routes.
Three addresses are involved in an MCP connection:
| Address | Purpose | Helm setting |
|---|---|---|
| Public URL | The origin that users visit and MCP clients connect to. Clients use this URL followed by /mcp. The MCP service also uses it to build the URL that clients upload app imports to. It must not include /mcp. | mcp.config.mcpServiceExternalUrl |
| OAuth hostname | The public Retool hostname that serves OAuth metadata and the /api/oauth2/* endpoints. It's a hostname only, without https://. | mcp.config.oauthMainDomain. Defaults to the plain-text value of env.BASE_DOMAIN. Set this yourself if BASE_DOMAIN comes from a Kubernetes Secret or isn't set. |
| Private backend URL | The internal address the MCP service uses to reach the Retool backend, so it can validate tokens and run tools. | mcp.config.retoolBackendUrl. The chart sets this automatically. |
For example, if users visit https://retool.example.com, the three addresses are:
- Public URL:
https://retool.example.com - OAuth hostname:
retool.example.com - Client endpoint:
https://retool.example.com/mcp
Set secrets
When an MCP client sends a request, the MCP service asks the Retool backend to check the user's access token. The backend and MCP workloads must receive the same introspection token. This token is a secret that only the backend and the MCP service share. It's separate from the access token a client receives after the user signs in.
Let the chart manage the token
When the chart manages your configuration secrets and you don't set a secret name, it generates the token and gives the same value to the backend and MCP workloads. You don't need to do anything.
Manage the token yourself
If you manage secrets separately, store the token in a Kubernetes Secret. The following example creates the secret with a random value:
kubectl create secret generic retool-mcp-oauth \
--from-literal=oauthIntrospectionAuthToken="$(openssl rand -hex 32)"
Then set the secret's name in your values file:
mcp:
config:
oauthIntrospectionAuthTokenSecretName: retool-mcp-oauth
The chart reads the token from this secret and sets it as OAUTH_INTROSPECTION_AUTH_TOKEN on both the backend and MCP workloads, so both receive the same value. If the key in your secret isn't oauthIntrospectionAuthToken, also set mcp.config.oauthIntrospectionAuthTokenSecretKey.
If you set OAUTH_INTROSPECTION_AUTH_TOKEN through mcp.environmentVariables instead, set the same value for the backend through the top-level env, environmentVariables, or environmentSecrets values.
For the full list of settings, refer to the MCP values in the Retool Helm chart.
Apply updated values
Apply the updated values with helm upgrade, then confirm the MCP pod is ready.
helm upgrade my-retool retool/retool -f values.yaml
kubectl get pods
Run the MCP container
Run one additional container from the same Retool backend image version as your main service. Set SERVICE_TYPE=MCP_SERVER and MCP_PORT=4010. Keep port 4010 private.
Set environment variables
Add the following environment variables to the MCP container:
| Variable | Value |
|---|---|
RETOOL_BACKEND_URL | The private URL of the main Retool service, such as http://api:3000. |
OAUTH_MAIN_DOMAIN | The hostname of https://example.retool.com, without https://. |
MCP_SERVICE_EXTERNAL_URL | The public HTTPS origin, such as https://example.retool.com. |
OAUTH_INTROSPECTION_AUTH_TOKEN | A secret value. Supply the same value to both the main backend and the MCP container. |
RETOOL_GIT_SERVER_URL | The private URL of your separate git service. Set this only if the new app builder's git service runs as its own deployment. Otherwise, the MCP service uses RETOOL_BACKEND_URL. |
AGENT_SANDBOX_JWT_PRIVATE_KEY | The signing key your agent sandbox already uses. Set this only if your setup uses an agent sandbox. If you named the key AGENT_EXECUTOR_JWT_PRIVATE_KEY, use that name instead. Pass the value through your secret manager. |
Keep the rest of your new app builder infrastructure in place.
Configure public routes
Public traffic reaches the MCP service through your ingress, gateway, or load balancer. How you route it depends on your deployment method.
- Helm
- Non-Helm
Direct routing mode
With direct routing, your ingress or gateway sends MCP requests straight to the MCP service, which runs separately from the main Retool service. direct is the default routing mode and the only mode available before Retool 4.0.7.
If the Retool Helm chart manages your ingress or Gateway API routes, it adds the MCP routes when MCP is enabled. No further route configuration is required.
If you manage public routes outside the chart, disable the chart's MCP routes:
mcp:
ingress:
enabled: false
httpRoute:
enabled: false
Then add the following routes to your own gateway so that they take precedence over your main Retool route. In systems that evaluate rules in order, such as AWS ALB, list them before the / route:
| Public path | Destination |
|---|---|
/.well-known/oauth-authorization-server | Retool backend metadata service, port 3001 |
/.well-known/oauth-protected-resource | MCP service, port 4010 |
/mcp and paths beneath it | MCP service, port 4010 |
/ and remaining paths, including /api/oauth2/* | Main Retool service, port 3000 |
Preserve the original public Host header and HTTPS protocol in forwarded requests, and allow long-lived streaming responses on /mcp. If your load balancer uses separate path patterns for an exact path and its descendants, add both /mcp and /mcp/*.
Backend relay routing mode
On Retool 4.0.7 and later, the chart also offers backendRelay routing mode. In this mode, public /mcp and OAuth discovery requests reach the main Retool service first, and the backend relays /mcp internally to the MCP service. The MCP service still runs separately. Use this mode to avoid maintaining MCP-specific routes. Set the mode in your values file:
mcp:
routing:
mode: backendRelay
Make sure your existing public / route covers /mcp and both /.well-known URLs and targets the main Retool service on port 3000. Where you configure that route depends on how you manage routing:
- Chart-managed ingress: Keep
path: /underingress.hosts[].paths, and setingress.pathTypetoImplementationSpecific(the default) orPrefix.Exactdoesn't cover/mcpor/.well-known. - Chart-managed Gateway API: Omit
httpRoute.rulesto use the chart's default catch-all rule. If you sethttpRoute.rules, include aPathPrefixmatch on/that targets the main Retool service on port 3000. - Your own gateway or load balancer: Add a
/prefix rule that targets the main Retool service on port 3000.
If you previously set mcp.ingress.enabled or mcp.httpRoute.enabled to true, remove those overrides or set them to false. An explicit true conflicts with backendRelay and causes the chart to fail rendering.
Route /mcp and /.well-known/oauth-protected-resource to the MCP container. Route /.well-known/oauth-authorization-server and /api/oauth2/* to the backend listeners that serve them in your setup.
Make sure these routes take precedence over your main Retool route. Preserve the original public Host header and HTTPS protocol in forwarded requests, and allow long-lived streaming responses on /mcp. If your load balancer uses separate path patterns for an exact path and its descendants, add both /mcp and /mcp/*.
After you configure your routes, verify the public responses described in Verify the connection.
Configure an SSO gateway
If an SSO gateway protects your Retool origin, it must let MCP clients through without a browser SSO session. The user completes initial authentication through the browser and approves the client. On subsequent requests, MCP clients call Retool directly, so they can't complete the gateway's browser login flow on each request. To continue to control access, every MCP call carries an access token that Retool validates, including bearer-token authentication on /mcp.
Allow MCP clients to reach the following paths without a browser SSO session or a login redirect. Forward each request to the destination described in Configure public routes.
| Method | Path | Purpose |
|---|---|---|
GET, POST, DELETE | /mcp | MCP transport and Bearer challenge. |
GET | /.well-known/oauth-protected-resource | Protected-resource discovery. |
GET | /.well-known/oauth-authorization-server | OAuth server discovery. |
POST | /api/oauth2/token | Authorization code exchange and token refresh. |
POST | /api/oauth2/register | Dynamic client registration, when the client uses it. |
Apply the /mcp exception to paths beneath /mcp as well. For full client and tool coverage, also allow:
POST /api/oauth2/revoke, so clients can disconnect.GET /.well-known/oauth-protected-resource/mcp, for path-specific discovery.PUT /mcp/sandbox/:sandboxId/upload, if clients use the prepared import tool.
The first time an MCP client connects, Retool asks the user to approve it. This is the browser consent flow, the OAuth 2.0 step that lets the client act in Retool on the user's behalf. The user gives consent, the MCP client receives it, and Retool issues the client an access token limited to the scopes the user approves. The flow uses GET /auth/oauth2/authorize to show the approval page and POST /api/oauth2/authorize to submit the user's decision.
These routes can stay behind your interactive SSO flow, because the user completes them in a browser. After sign-in, the browser must return to the authorization URL with its query parameters intact and submit consent to Retool with the user's session.
If MCP calls from the MCP service to the Retool backend pass through a public SSO gateway, they fail. Use the private backend URL for these calls.
Verify the connection
From the network where your MCP client runs, request the MCP and discovery URLs:
curl -si "https://example.retool.com/mcp"
curl -si "https://example.retool.com/.well-known/oauth-protected-resource"
curl -si "https://example.retool.com/.well-known/oauth-authorization-server"
An unauthenticated request to /mcp returns a 401 status with a WWW-Authenticate: Bearer header that points to the protected-resource metadata URL. Both discovery URLs return JSON. The protected-resource metadata identifies https://example.retool.com/mcp, and the authorization-server metadata identifies https://example.retool.com as its issuer.
A login redirect, an HTML page, or a 401 without a Bearer challenge means the public route or SSO gateway needs attention.
Next, connect an MCP client that supports HTTP transport to https://example.retool.com/mcp, complete the browser sign-in and consent, and run tools/list.
Troubleshooting
Why is my OAuth failing when discovery works?
Check that your SSO gateway forwards token exchange and dynamic registration requests without a browser login challenge.
Why do authenticated tool calls fail?
Check the MCP service's private backend URL and the shared introspection token. The backend and MCP service must use the same token.