Custom MCP connector: token refresh fires on every chat turn, but the model says the tool is not connected (no MCP call made)

Setup: Gemini Enterprise trial, custom MCP connector (custom_mcp) to our own MCP server, OAuth 2.1 + PKCE against our own IdP. Actions were enabled via the public “PATCH dataConnector?updateMask=bapConfig” workaround (the console Reload custom actions 401 is covered in Gemini Enterprise Custom MCP: "Reload custom actions" always fails with 401 - UI uses API key instead of OAuth token ). Per-user Authorize works, tools/list is fetched, and in some chats the model calls our tools and we serve them.

The problem: in most chats the actions never reach the model. Repro (2026-08-20, UTC): three fresh chats, one prompt each naming the connector action, sent 15:23:28 / 15:25:07 / 15:26:13. Our IdP logged a successful refresh_token grant from Google infrastructure 4 seconds after each prompt (15:23:32, 15:25:11, 15:26:17). Each time the model replied the tool “is not currently connected” or “not available in my configured tools”. Our edge logs show zero requests from Google ranges in the window at any status. So the connector runtime engages and refreshes the token on every turn, while the model toolset never receives the actions. Binding looks nondeterministic per chat (earlier the same day 3 of 6 chats bound and worked).

Two more observations from the same day. The authorize flow once produced two logins one second apart, after which the backend redeemed one code and failed the other with pkce_verification_failed (racing OAuth legs). And in one unbound chat the UI rendered a tool activity step named after our connector with web citation chips attached, while our server received no request. For a data-source vendor, a fabricated tool step with mislabeled citations is worse than the binding failure itself.

Anyone else seeing per-chat binding roulette with custom MCP connectors, or found a way to force binding? Happy to share more repro detail.

1 Like