MCP OAuth sometimes fails on first attempt - concurrent reinitializations overwrite PKCE flow state #13530
Replies: 2 comments 2 replies
I will look into your suggested change but is it a partial fix if you can’t reproduce it without this? |
|
The diagnosis in the report is right, and the proposed fix is the correct direction, but I'd push it one step further before calling it done. The core issue is that "start OAuth for this server" has two independent call sites ( Redirecting What actually closes this is making the write itself a get-or-create keyed by flowId instead of a check in one place and a write in another. If the flow store is in-process (the One thing worth keeping in the design: |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
What happened?
Symptom: First 1–2 OAuth attempts sometimes fail with invalid code verifier from the token endpoint; subsequent retries succeed.
Root cause: GET /:serverName/oauth/initiate calls MCPOAuthHandler.initiateOAuthFlow() which
generates a brand-new PKCE code_verifier + code_challenge on every invocation. However,
MCPConnectionFactory.handleOAuthEvents() already called initiateOAuthFlow() and stored a
different code_verifier in the flow state (via initFlow, packages/api/src/mcp/MCPConnectionFactory.ts ~line 462).
The browser is then redirected to Salesforce with the /initiate route's new code_challenge,
but the OAuth callback retrieves the flow state's original code_verifier for the token exchange —
causing a permanent PKCE mismatch on every first attempt.
Expected behavior: OAuth completes on the first attempt. The stored code_verifier should
match the code_challenge sent to Salesforce, since they are derived from the same PKCE pair
The fix: the /initiate route should redirect to the authorizationUrl already stored in the flow
metadata (metadataWithUrl includes authorizationUrl at initFlow time) rather than generating a
new one. No new code_verifier would be produced and the mismatch would not occur.
Affected file: api/server/routes/mcp.js, GET /:serverName/oauth/initiate handler
Also relevant: packages/api/src/mcp/MCPConnectionFactory.ts handleOAuthEvents(), ~line 435–479
Related merged PR (partial fix — scope on refresh, not PKCE): #13412
Version Information
Version: v0.8.6 (https://github.com/danny-avila/LibreChat/releases/tag/v0.8.6)
Deployment: source install, single instance
Note: PR #13412 (fix/mcp-salesforce-oauth — scope retry on refresh) is not included in this build.
Steps to Reproduce
(authorization_url, token_url, client_id, client_secret, redirect_uri, skip_code_challenge_check: true)
InvalidGrantError: invalid code verifierand authentication failsWhat browsers are you seeing the problem on?
Chrome, Safari, Firefox, Microsoft Edge
Note: not browser-specific — this is a server-side OAuth flow bug.
Relevant log output
Screenshots
No response
Code of Conduct
All reactions