fix(core): refresh MCP OAuth token usage after re-auth#26312
Conversation
Summary of ChangesHello, 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 an issue where MCP OAuth tokens would become stale, requiring a full CLI restart to refresh. By introducing a dynamic token provider, the system now resolves tokens at the time of authentication, ensuring that refreshed or updated credentials are used immediately. This change improves the robustness of the Gemini CLI's authentication flow for MCP servers. Highlights
Using Gemini Code AssistThe 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
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 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
|
There was a problem hiding this comment.
Code Review
This pull request implements dynamic OAuth token retrieval for MCP clients by introducing the DynamicStoredOAuthProvider class. This allows tokens to be looked up or refreshed at request time rather than being fixed at transport creation. The createTransport function was updated to utilize this dynamic provider when OAuth is enabled or stored credentials are detected. Feedback was provided regarding the efficiency of the tokens() method in DynamicStoredOAuthProvider, specifically noting that instantiating storage and provider classes within the method leads to redundant disk I/O and should be refactored to use instance-scoped fields.
…(core): align MCP authProvider assertions with tokens() API
|
Hi maintainers, all requested MCP OAuth fixes are pushed and tests were updated accordingly. |
scidomino
left a comment
There was a problem hiding this comment.
Gemini spotted two issues:
-
Severe Performance Hit on HTTP Transports: The MCP SDK’s
StreamableHTTPClientTransportcallsauthProvider.tokens()for every single RPC request (inside_commonHeaders()).DynamicStoredOAuthProvider.tokens()delegates tooauthProvider.getValidToken().getValidToken()callstokenStorage.getCredentials(), which reads and parses the JSON file from the disk (or queries the system Keychain if using encrypted storage) synchronously/asynchronously.- Impact: This means every single MCP message sent via HTTP will perform a disk read or a slow Keychain lookup.
- Recommendation:
DynamicStoredOAuthProvidershould cache theaccessTokenandexpiresAtin memory, and only re-fetch/refresh when the token is expired (e.g., adding a 5-minute buffer).
-
Redundant Storage Reads on Fallback: When
oauth.enabledis falsy in the config, thetokens()method manually retrieves theclientIdby callingthis.tokenStorage.getCredentials(this.serverName). It then passes thisclientIdtothis.oauthProvider.getValidToken(...), which internally callsgetCredentials(...)again. This results in two back-to-back disk/keychain reads for a single request.- Recommendation: Can be fixed by reusing the retrieved credentials or by caching in memory (as per issue #1).
|
Okay @scidomino sir will do those changes |
|
Hello @scidomino sir i have fixed the issues:
Validated locally:
|
|
The architectural shift to a dynamic
|
Surely @scidomino sir I'll implement these changes |
hello @scidomino sir i am done with the changes , Moved DynamicStoredOAuthProvider out of mcp-client.ts into packages/core/src/mcp/stored-token-provider.ts. |
|
You have broken E2E tests. please fix. |
Sure @scidomino sir I'll do it |
Head branch was pushed to by a user without write access
|
Hello @scidomino sir i have fixed the issue please could you grant the github actions workflow execution |
|
Hello @scidomino sir ,I fixed the deterministic E2E failure in integration-tests/file-system.test.ts (newline normalization). Current remaining failures are in test:always_passing_evals with repeated 503 retries and cross-suite timeouts (not tied to changed files). Could you please re-run eval gates?” |
🚨 Action Required: Eval Regressions DetectedModel: The following trustworthy evaluations passed on
The check passed or was cleared for 79 other trustworthy evaluations. 🛠️ Troubleshooting & Fix Instructions1. Ask Gemini CLI to fix it (Recommended)Copy and paste this prompt to the agent: 2. Reproduce LocallyRun the following command to see the failure trajectory: GEMINI_MODEL=gemini-3-flash-preview npm run test:all_evals -- evals/plan_mode.eval.ts --testNamePattern="should create a plan in plan mode and implement it for a refactoring task"3. Manual FixSee the Fixing Guide for detailed troubleshooting steps. This PR modifies files that affect the model's behavior (prompts, tools, or instructions).
This is an automated guidance message triggered by steering logic signatures. |
…#26312) Co-authored-by: Tommaso Sciortino <[email protected]>
Summary
Fixes MCP OAuth token reuse after token refresh/re-auth.
Previously, transport auth could continue using a stale access token until CLI restart.
This change makes token retrieval dynamic so refreshed/stored tokens are used without restarting Gemini CLI.
Closes #18895
Details
oauth.enabledservers, token is fetched viagetValidToken(...)at auth time.oauth.enabled), token is also resolved dynamically.Related issues
Validation
Ran successfully:
npm run build --workspace @google/gemini-cli-corenpm run test --workspace @google/gemini-cli-core -- src/tools/mcp-client.test.tsNotes