cancel
Showing results for 
Search instead for 
Did you mean: 
Generative AI
Explore discussions on generative artificial intelligence techniques and applications within the Databricks Community. Share ideas, challenges, and breakthroughs in this cutting-edge field.
cancel
Showing results for 
Search instead for 
Did you mean: 

Salesforce Hosted MCP + UC HTTP connection — stops working after ~1 hour?

iankizer
New Contributor II

We're wiring Salesforce Hosted MCP (read-only SObject server on api.salesforce.com) through a Unity Catalog HTTP connection and an MCP service, using OAuth User-to-Machine Per User.

Login on the MCP service works and tools respond at first. After about an hour, MCP calls fail until we log in again on the service.

On the HTTP connection, access token expiration shows “Not provided by provider.” Other OAuth HTTP connections in the same workspace (different vendors) show an expiration and don’t hit this hourly cliff.

Salesforce side is an External Client App with mcp_api / refresh_token, PKCE, and JWT-based access tokens (as in Salesforce’s Hosted MCP docs). Callback uses the standard Databricks /login/oauth/http.html redirect.

Has anyone got this combo stable past ~1 hour?
 Is missing expires_in on Salesforce token responses a known issue for UC / AI Gateway refresh? Any connection settings that actually help (token exchange method, client secret on refresh, etc.)—without turning off JWT on the ECA?

Has anyone seen this sort of pattern and what fixed it (or if you had to escalate to support)? Or, if you've configured a Salesforce MCP in UC AI Gateway, how do have your External Client App set up so this refresh works properply

Thanks.

2 REPLIES 2

iankizer
New Contributor II
  • Exact error: HTTP 401, JSON-RPC -32006, "You're not signed in"

anuj_lathi
Databricks Employee
Databricks Employee

Your symptom points to the refresh path never firing. Once Databricks has an access token with no known expiry and no successful refresh, the per-user credential goes stale at the Salesforce-side lifetime and you get bounced to login. I'd treat the missing expiry as the main clue, and I'd split the problem into two checks.

1. Confirm Salesforce is issuing and honoring a refresh token

"Not provided by provider" means the token response had no expires_in. Salesforce typically omits it when JWT-based access tokens are enabled, because the lifetime lives in the JWT exp claim and the session/token policy instead. That alone isn't fatal, but it makes the refresh token the only thing keeping you signed in. On the ECA, check these:

  • Scopes: refresh_token (or offline_access) must be on the ECA and requested in the scopes on the UC connection. Scopes on the ECA alone aren't enough, because the authorize request has to ask for it. If you changed scopes, delete the user's stored credential and log in again, since old grants won't magically gain a refresh token.
  • Refresh token policy: set it to valid until revoked, not tied to session expiry. A session-bound refresh token will die with the session and look exactly like your hourly cliff.
  • Require secret for refresh token flow: if this is on, the client secret has to be configured on the UC connection. If you use PKCE with a public-style setup, turn it off. A mismatch here fails silently from the user's point of view.
  • Refresh token rotation: if it's enabled, test with it disabled. Rotation breaks any client that doesn't persist the new refresh token on every refresh.
  • Session/token timeout on the ECA policy: with JWT access tokens this value governs the access token lifetime. Raising it won't fix the underlying issue, but it moves the cliff out and helps you confirm the diagnosis (if the failure moves with the setting, it's lifetime-related).

2. Test the refresh grant directly against Salesforce

Use the same ECA client ID, ideally with a throwaway authorization-code + PKCE flow, and hit the token endpoint:

curl -s -X POST "https://<your-my-domain-or-login>.salesforce.com/services/oauth2/token" \
  -d "grant_type=refresh_token" \
  -d "client_id=<ECA_CONSUMER_KEY>" \
  -d "refresh_token=<REFRESH_TOKEN>" \
  # add -d "client_secret=<SECRET>" if the ECA requires it

You're looking for three things:

  • Does it succeed at all?
  • Does the response include expires_in?
  • Does it return a new refresh token?

If this works but UC still fails after an hour, the issue is on the Databricks side. If it fails, fix the ECA policy first.

3. Work out where the 401 originates

JSON-RPC -32006 "You're not signed in" suggests the MCP service didn't have a usable per-user credential. It doesn't look like a raw Salesforce rejection. Check whether the failing call ever reaches Salesforce. The Salesforce login history and the ECA's connected-app usage should show whether a refresh attempt or an API call arrived at that time. If nothing arrived, Databricks gave up before calling out, which fits the "no expiry, so no proactive refresh" theory.

4. What I'd do

  • Fix the ECA items above first (scope, refresh policy, secret requirement, rotation). In my experience that resolves most "works for an hour" cases.
  • If the direct refresh test succeeds and UC still doesn't refresh, open a support case. Include the connection name, workspace ID, the timestamp of the first failure, and the fact that the token response lacks expires_in. Ask specifically whether UC attempts a refresh on a 401 when the provider omits expiry. I wouldn't assume that's guaranteed behavior, so get it confirmed on your runtime/region.
  • Disabling JWT is the cleanest workaround, but you've ruled it out. The next option is a longer ECA session timeout, which makes re-logins rarer but doesn't eliminate them.
  • If your use case allows a shared service identity rather than per-user access, an M2M OAuth connection avoids the interactive refresh problem entirely. You lose per-user Salesforce permissions, though, so it may not be acceptable for a read-only SObject server.

If you post the ECA's OAuth policy settings (refresh token policy, secret requirement, timeout) and what the direct refresh call returns, I can help narrow it down further.

Anuj Lathi
Solutions Engineer @ Databricks