MCP OAuth redirect URI mismatch in Cursor Desktop

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

I found an OAuth interoperability issue while connecting an MCP server to Cursor Desktop.

During registration, Cursor uses:

https://www.cursor.com/agents/mcp/oauth/callback

However, during authorization, Cursor sends:

http://localhost:8787/callback

According to RFC 6749 §3.1.2.3, these redirect URIs must match. Because they differ, a standards-compliant OAuth server rejects the request.

This prevents OAuth-based MCP connections from working in Cursor Desktop. API-key authentication works as a workaround.

Claude Desktop appears to use a consistent redirect through claude.ai, which then redirects back to the local desktop application.

Steps to Reproduce

Configure an OAuth-enabled MCP server in Cursor Desktop.
2. Start the connection flow.
3. Observe that Cursor registers https://www.cursor.com/agents/mcp/oauth/callback.
4. Continue the authorization process.
5. Observe that Cursor sends http://localhost:8787/callback instead.
6. The authorization server rejects the request because the redirect URI does not match.

Expected Behavior

Cursor should use the same redirect URI during registration and authorization, or otherwise implement a standards-compliant desktop OAuth flow.

Screenshots / Screen Recordings
Screenshot attached. No customer, company, account, or internal system information is included.

Operating System

MacOS

Version Information

3.19.13 (Universal)

Does this stop you from using Cursor

Yes - Cursor is unusable

Hey @Aklant_Sahu, thanks for the detailed report.

A bit of context on how Cursor registers with an MCP OAuth server: the Dynamic Client Registration request sends three redirect URIs in a single redirect_uris array, not just one:

  • cursor://anysphere.cursor-mcp/oauth/callback
  • https://www.cursor.com/agents/mcp/oauth/callback (used by Cloud Agents / web)
  • http://localhost:8787/callback (used by the desktop app, loopback flow)

So when the desktop app authorizes with http://localhost:8787/callback, that URI should already be in the set your server stored at registration. If your server only kept the https://www.cursor.com/... entry, it is likely storing a single redirect URI or filtering out the non-https ones at registration time, which is where the mismatch comes from.

Could you check two things and report back?

  1. The full response body your server returned to Cursor’s POST /register call. Does the redirect_uris array in that response contain all three URIs, or only the https one?
  2. Whether your authorization server accepts http://localhost:8787/callback (loopback) as a registered redirect URI at all.

If your server can accept all three URIs at registration, the desktop flow should complete. As an alternative, you can pre-register a client on your server with http://localhost:8787/callback as its redirect URI and put its credentials in your mcp.json under the server’s auth block (CLIENT_ID, and CLIENT_SECRET if applicable). Cursor then skips dynamic registration entirely.