Skip to content

fix(core): refresh OAuth-backed HTTP MCP sessions in chat#23493

Open
nivbrook wants to merge 4 commits intogoogle-gemini:mainfrom
nivbrook:fix-mcp-chat-refresh
Open

fix(core): refresh OAuth-backed HTTP MCP sessions in chat#23493
nivbrook wants to merge 4 commits intogoogle-gemini:mainfrom
nivbrook:fix-mcp-chat-refresh

Conversation

@nivbrook
Copy link
Copy Markdown

Fixes #18895
Related: #23296

Summary

Stored OAuth-backed HTTP MCP servers could reconnect and refresh successfully on a fresh connection path, but tool calls inside an already-running chat session could still fail after the access token expired.

This change fixes two parts of that behavior:

  • stored OAuth-backed HTTP MCP chat transports now use a refresh-capable auth provider, so the MCP SDK can refresh expired access tokens
  • Gemini no longer treats transient Streamable HTTP background disconnects during auth recovery/reconnect as fatal MCP ERROR events

It also retries one MCP tool call after a recoverable auth-expiry failure so the first in-chat tool call after expiry can succeed without requiring a manual reconnect.

Background

The user-visible failure looked like this:

  1. /mcp auth <server> succeeds
  2. MCP tools work in chat
  3. the access token expires
  4. a later MCP tool call in the same chat fails with MCP ERROR
  5. a fresh reconnect path like gemini mcp list can refresh successfully immediately afterward

That pointed to a transport/auth wiring problem in long-lived chat sessions rather than a refresh-token problem in the MCP server.

During debugging, the remaining chat-visible error after refresh wiring was traced to Gemini surfacing a background Streamable HTTP SSE disconnect such as:

SSE stream disconnected: TypeError: terminated

The MCP SDK treats that as part of its reconnect behavior, but Gemini was treating any such transport error as fatal.

Changes

  • add a small storage-backed OAuth provider adapter for MCP SDK HTTP transports
  • use that provider for stored OAuth-backed HTTP MCP transports instead of baking in a one-time bearer token
  • retry one MCP tool call after a recoverable auth failure by reconnecting once
  • ignore transient Streamable HTTP background disconnect/reconnect errors for HTTP MCP transports
  • continue surfacing terminal transport failures such as reconnect exhaustion

Validation

Passed:

  • npm run typecheck --workspace=@google/gemini-cli-core
  • npm test --workspace=@google/gemini-cli-core -- src/mcp/stored-oauth-provider.test.ts src/tools/mcp-client.test.ts

Also ran broader checks locally:

  • root typecheck passed
  • lint:ci passed in local environment
  • root test:ci hit unrelated existing failures outside the MCP codepath:
    • src/tools/ls.test.ts
    • src/utils/googleQuotaErrors.test.ts

@nivbrook nivbrook requested review from a team as code owners March 22, 2026 22:49
@google-cla
Copy link
Copy Markdown

google-cla bot commented Mar 22, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses issues where OAuth-backed HTTP MCP sessions would fail after access tokens expired or due to transient network disconnects during chat interactions. The changes introduce a robust authentication provider that can refresh tokens and modify error handling to gracefully manage temporary HTTP transport issues. Additionally, a retry logic for tool calls after authentication failures has been added, significantly enhancing the stability and user experience of MCP tools within chat sessions.

Highlights

  • OAuth Token Refresh for HTTP MCP Sessions: OAuth-backed HTTP MCP chat transports now utilize a refresh-capable authentication provider, enabling the MCP SDK to automatically refresh expired access tokens during long-lived chat sessions.
  • Improved Streamable HTTP Error Handling: Gemini no longer treats transient Streamable HTTP background disconnects (e.g., SSE stream disconnected) during authentication recovery or reconnect as fatal MCP ERROR events, improving resilience.
  • Tool Call Retry Mechanism: A mechanism has been implemented to retry one MCP tool call after a recoverable authentication-expiry failure, ensuring the first in-chat tool call after expiry can succeed without manual intervention.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively addresses the issue of expired OAuth tokens in long-lived MCP chat sessions. The introduction of the StoredOAuthMcpProvider is a solid architectural improvement that enables token refreshing for HTTP-based MCP servers. The addition of tool-call retry logic for recoverable authentication errors and the more nuanced handling of transient transport errors significantly improve the robustness and user experience of MCP interactions. The code is well-structured and the accompanying tests are thorough. I've identified one potential high-severity issue in the new token handling logic that could lead to a refresh loop, for which I've provided a specific comment and suggestion.

@gemini-cli gemini-cli bot added priority/p2 Important but can be addressed in a future release. area/core Issues related to User Interface, OS Support, Core Functionality help wanted We will accept PRs from all issues marked as "help wanted". Thanks for your support! labels Mar 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality help wanted We will accept PRs from all issues marked as "help wanted". Thanks for your support! priority/p2 Important but can be addressed in a future release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI cannot use fresh token in MCP OAuth

1 participant