MCP OAuth Redirect URIs for Cursor, Claude and ChatGPT: Registering MCP Clients in Casdoor
Every MCP client sends its own redirect URI when it signs in to an OAuth-protected MCP server. Cursor desktop uses http://localhost:8787/callback (releases before mid-2026 used cursor://anysphere.cursor-mcp/oauth/callback), Cursor on the web and Cursor Cloud Agents use https://www.cursor.com/agents/mcp/oauth/callback, claude.ai, Claude Desktop connectors, Claude mobile and Cowork use https://claude.ai/api/mcp/auth_callback, and ChatGPT uses https://chatgpt.com/connector_platform_oauth_redirect or a per-connection https://chatgpt.com/connector/oauth/<callback-id>. If you turn on dynamic client registration in Casdoor, you don't enter any of these: the clients register themselves or hand Casdoor a client ID metadata document. You add them to Redirect URLs only when you create a Casdoor application for a client by hand.
Redirect URIs by client
| Client | Redirect URI | How it gets a client ID from Casdoor | Notes |
|---|---|---|---|
| Cursor desktop (current) | http://localhost:8787/callback | DCR, or auth.CLIENT_ID in mcp.json | Fixed port 8787 |
| Cursor web and Cloud Agents | https://www.cursor.com/agents/mcp/oauth/callback | DCR, or auth.CLIENT_ID | With DCR, the desktop app registers this URI and the localhost one |
| Cursor desktop (older releases) | cursor://anysphere.cursor-mcp/oauth/callback | DCR, or auth.CLIENT_ID | Cursor made the loopback URI the default in July 2026 |
| claude.ai, Claude Desktop connectors, Claude mobile, Cowork | https://claude.ai/api/mcp/auth_callback | CIMD, then DCR, or a client ID entered in the custom connector dialog | Anthropic's servers make the requests |
| Claude Code | http://localhost:<port>/callback and http://127.0.0.1:<port>/callback | CIMD | The port changes per session |
Claude Desktop through mcp-remote | http://localhost:<port>/oauth/callback | DCR | The port is derived from the server URL |
| ChatGPT | https://chatgpt.com/connector_platform_oauth_redirect, or https://chatgpt.com/connector/oauth/<callback-id> | CIMD, DCR, or a predefined client | Copy the exact value from ChatGPT |
These values come from the vendors' documentation as of November 2, 2026 (see References). Clients change them. When a sign-in fails, read the redirect_uri parameter of the authorization request in the browser's address bar and compare it with what Casdoor has.
The table applies in two setups: the MCP server built into Casdoor at /api/mcp, and your own MCP server that uses Casdoor as its authorization server. In both, the client finds Casdoor through protected resource metadata (RFC 9728) and gets its client ID from Casdoor.
Option 1: let clients register themselves
Casdoor supports dynamic client registration (RFC 7591) at /api/oauth/register, and client ID metadata documents (CIMD), where the client_id is an HTTPS URL of a JSON document that lists the client's redirect URIs. One switch controls both: Enable dynamic client registration on the organization. It is off by default, for every organization including built-in.
With the switch on for built-in, the discovery document shows what the clients look for:
curl -s https://your-casdoor.com/.well-known/openid-configuration | jq '{
registration_endpoint,
client_id_metadata_document_supported,
code_challenge_methods_supported,
token_endpoint_auth_methods_supported,
authorization_response_iss_parameter_supported
}'
{
"registration_endpoint": "https://your-casdoor.com/api/oauth/register",
"client_id_metadata_document_supported": true,
"code_challenge_methods_supported": ["S256"],
"token_endpoint_auth_methods_supported": ["client_secret_basic", "client_secret_post", "private_key_jwt", "none"],
"authorization_response_iss_parameter_supported": true
}
Each client then picks its method:
- Claude uses CIMD only when the metadata has both
client_id_metadata_document_supported: trueandnoneintoken_endpoint_auth_methods_supported. Casdoor has both once the switch is on, so Claude identifies itself with a document URL and Casdoor creates an application namedcimd_.... Otherwise Claude falls back to DCR. - ChatGPT prefers CIMD, with the
client_idhttps://chatgpt.com/oauth/client.json(or a per-callback variant), and uses DCR when CIMD isn't available. - Cursor registers through DCR as a public client without a secret. Cursor's documentation doesn't mention CIMD.
mcp-remoteregisters through DCR.
The redirect URIs come from the registration request or the metadata document, so there is nothing to type. Registered clients run under a restricted role and their tokens can't call the management API. See Dynamic client registration for the full rules and the organization a client lands in.
Option 2: create an application for the client
If you keep registration off, create one application per client, so that you can revoke them separately:
- In the Casdoor admin console, go to Identity > Applications and add an application, for example
cursor-mcp. - Add the client's redirect URIs from the table to Redirect URLs. For Cursor, add all three, because different Cursor installs send different ones.
- Set Category to
Agent. See Set up Casdoor for your MCP server for scopes and grant types. - Give the Client ID to the client.
A client secret is optional for these clients. Casdoor accepts an authorization code exchange without a secret when the request used PKCE, and Cursor, Claude and ChatGPT all use PKCE with S256. If a client does send a secret, it must be the right one.
Where the client ID goes:
-
Cursor: an
authobject in~/.cursor/mcp.jsonor.cursor/mcp.json. With a staticCLIENT_ID, the Cursor desktop app sends only its localhost redirect URI.{
"mcpServers": {
"casdoor": {
"url": "https://your-casdoor.com/api/mcp",
"auth": {
"CLIENT_ID": "${env:CASDOOR_MCP_CLIENT_ID}",
"scopes": ["application:read", "user:read"]
}
}
}
} -
Claude: the OAuth client ID field in the custom connector dialog. Register
https://claude.ai/api/mcp/auth_callback. -
ChatGPT: ChatGPT also works with predefined OAuth clients. Copy the redirect URI from the MCP server's management page in ChatGPT, since which of the two forms it uses depends on the authorization server.
Step-by-step guides: Cursor, Claude Desktop, ChatGPT.
How Casdoor matches redirect URIs
Casdoor compares the redirect_uri of a request with each entry in Redirect URLs:
- The scheme, the host and the path must match. The query string isn't compared.
- The port must match, except on loopback hosts. When both URIs use the same loopback host (
localhost,127.0.0.1or::1), Casdoor ignores the port, as RFC 8252 asks for native apps.localhostand127.0.0.1are different hosts, so Claude Code needs bothhttp://localhost/callbackandhttp://127.0.0.1/callback. - A redirect URI on a subdomain of a registered host also matches, so
https://example.com/cbacceptshttps://app.example.com/cb. Register the most specific host you can. - Custom schemes such as
cursor://match by the same rules.javascript:,data:andvbscript:URIs are always rejected.
Because the loopback port is ignored, an mcp-remote or Claude Code registration keeps working when the local port changes between sessions.
Where claude_desktop_config.json lives
The MCP documentation gives these paths. In Claude Desktop, Settings > Developer > Edit Config opens the file and creates it if it's missing.
| Operating system | Path |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
Claude Desktop reaches a remote MCP server in one of two ways, and they use different redirect URIs:
-
As a connector, added in Claude's connector settings. Anthropic's servers run the OAuth flow, the redirect URI is
https://claude.ai/api/mcp/auth_callback, and Casdoor must be reachable from the internet. -
Through
claude_desktop_config.json, withmcp-remoteas a local bridge. The OAuth flow runs on your computer, and the redirect URI ishttp://localhost:<port>/oauth/callback:{
"mcpServers": {
"casdoor": {
"command": "npx",
"args": ["mcp-remote", "https://your-casdoor.com/api/mcp"]
}
}
}
Quit Claude Desktop completely and start it again after you edit the file.
Hosted clients need a public Casdoor
ChatGPT and Claude connectors call your MCP server and Casdoor from their vendors' servers, not from your computer. Casdoor must be reachable over public HTTPS with a valid certificate. Anthropic's requests come from 160.79.104.0/21, if you filter by IP. Cursor desktop, Claude Code and mcp-remote run the flow locally, so a Casdoor on your network works for them.
Two more things hosted clients check, which Casdoor already does:
- Issuer in the response (RFC 9207): ChatGPT rejects an authorization response without the right
iss, and uses its stable redirect URI only with authorization servers that meet its RFC 9207 requirements. Casdoor advertises the support in its metadata and addsissto the redirect. - Resource indicators (RFC 8707): ChatGPT sends
resourcewith the MCP server URL on the authorization and token requests. Casdoor puts that value in theaudclaim of the access token, and your MCP server should check it. See MCP authentication for the discovery flow.
Related reading on www.casdoor.com: OAuth for AI agents and authorization servers for MCP.
References
- Cursor: Model Context Protocol (MCP), section "Static OAuth for remote servers"
- Cursor forum: OAuth redirect URI changed from cursor:// to http://localhost
- Anthropic: Authentication for connectors
- Model Context Protocol: Connect to local MCP servers
- OpenAI: Authenticate users
mcp-remote: README- Casdoor: Dynamic client registration, Set up Casdoor for your MCP server