[BUG] MCP OAuth: state parameter not sent in authorize request but validated on callback
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When connecting to a remote MCP server with OAuth, Claude Code fails with "OAuth state mismatch - possible CSRF attack" even though authentication completes successfully.
Server logs show Claude Code sends:
GET /oauth/authorize?response_type=code&client_id=xxx&code_challenge=xxx
Missing: redirect_uri, state
But Claude Code validates state on callback, causing the error even when the server returns a valid auth code.
Environment: Claude Code version: 2.1.0, Windows.
What Should Happen?
Expected: Either send state in the request, or don't validate it on callback.
Error Messages/Logs
Steps to Reproduce
- Set up a remote MCP server with OAuth 2.0 that implements:
- /.well-known/oauth-protected-resource (returns authorization server URL)
- /.well-known/oauth-authorization-server (returns OAuth metadata)
- /oauth/register (Dynamic Client Registration - RFC 7591)
- /oauth/authorize (Authorization endpoint with PKCE)
- /oauth/token (Token endpoint)
- Configure Claude Code to connect to the server:
claude mcp add --transport sse my-server https://my-server.example.com/mcp/sse
- Trigger OAuth flow by using any MCP tool or letting Claude Code connect
- Observe:
- Claude Code discovers OAuth endpoints ✓
- Claude Code registers a client via /oauth/register ✓
- Claude Code opens browser to /oauth/authorize but the URL is missing state and redirect_uri parameters:
/oauth/authorize?response_type=code&client_id=xxx&code_challenge=xxx
- User authenticates successfully via IdP
- Server redirects to Claude Code's localhost callback with auth code
- Claude Code shows error: "OAuth state mismatch - possible CSRF attack"
Server logs showing missing parameters:
INFO: OAuth authorize request: {'response_type': 'code', 'client_id': 'xxx', 'code_challenge': 'xxx'}
WARNING: Client xxx didn't provide state parameter
INFO: Redirecting to client: http://localhost:xxxxx/callback?code=xxx
Expected behavior: Claude Code should include state in the authorize request if it validates state on callback.
Actual behavior: Claude Code omits state from request but rejects callback due to state mismatch.
Workaround: None for automated OAuth. Manual token configuration works:
claude mcp add --transport sse my-server https://example.com/mcp/sse \
--header "Authorization: Bearer <manually-obtained-token>"
Claude Model
Opus
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.0
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Cursor
Additional Information
_No response_
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗