OAuth redirect URI changed from cursor:// to http://localhost for Streamable HTTP MCP

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

I’m developing a Streamable HTTP MCP server with OAuth support and noticed a change in Cursor’s behavior.

Previously, Cursor sent the following redirect URI in the authorization request:

cursor://anysphere.cursor-mcp/oauth/callback

Recently (currently on Cursor 3.10.17), Cursor now sends:

http ://localhost:/…

“mcp-server”: {
“type”: “streamable-http”,
“url”: “”,
“auth”: {
“CLIENT_ID”: “”,
“CLIENT_SECRET”: “”,
“scopes”: “openid profile email”
}
}

I’m using Streamable HTTP (not stdio or mcp-remote) and testing with multiple OAuth providers (Okta, Auth0, and Keycloak). The behavior is the same across all of them.

Steps to Reproduce

  1. Set up a Streamable HTTP MCP server that requires OAuth authentication.
  2. Configure the server with a static OAuth client (tested with Okta, Auth0, and Keycloak).
  3. Connect to the MCP server using Cursor IDE 3.10.17.
  4. Initiate the OAuth authentication flow.
  5. Inspect the authorization request received by the OAuth provider.

Expected Behavior

The authorization request uses:

redirect_uri= cursor://anysphere.cursor-mcp/oauth/callback

(This was the behavior observed previously.)

Actual Behavior

The authorization request now uses:

redirect_uri=http ://localhost:8787

No changes were made to:

the MCP server,
the OAuth provider,
the OAuth client configuration,
or the OAuth metadata.

The only observed change is that Cursor now sends a localhost redirect URI instead of the previously used cursor:// callback.

Operating System

Windows 10/11

Version Information

Version: 3.10.17 (user setup)
VS Code Extension API: 1.125.0
Commit: c89f45b831621cdc5e951694db44fecd8fab1150
Date: 2026-07-05T06:39:45.228Z
Layout: IDE
Build Type: Stable
Release Track: Default
Electron: 40.10.3
Chromium: 144.0.7559.236
Node.js: 24.15.0
V8: 14.4.258.32-electron.0
xterm.js: 6.1.0-beta.256
OS: Windows_NT x64 10.0.26200

Additional Information

A few questions:

Is this an intentional change in Cursor’s OAuth implementation?
Is auth.redirect_uri in mcp.json no longer honored?
Should Streamable HTTP MCP servers now expect http ://localhost loopback callbacks instead of cursor://?

Any clarification would be appreciated.

Does this stop you from using Cursor

No - Cursor works, but with this issue

Hi Tejaswini,

We recently moved MCP OAuth in the IDE/CLI from the cursor:// custom-scheme deeplink to a loopback redirect, http://localhost:8787/callback. That’s the redirect style recommended for native apps in RFC 8252, and we switched because a lot of OAuth providers won’t accept a custom-scheme (cursor://) URI. This has been rolling out recently, which is why it changed without any edit on your end.

To your specific questions:

  1. Intentional? Yes. The loopback redirect is the new default for IDE/CLI MCP auth.
  2. auth.redirect_uri in mcp.json? There’s no redirect_uri field to honor. The auth block only supports CLIENT_ID, CLIENT_SECRET, and scopes — Cursor manages the redirect URI itself.
  3. Should static servers expect http://localhost now? Yes. With a static OAuth client (Client ID/Secret), Cursor doesn’t register redirect URIs with your provider the way it would with Dynamic Client Registration, so your provider’s allowlist has to include whatever Cursor sends.

The fix: in your OAuth app (Okta/Auth0/Keycloak), add http://localhost:8787/callback to the allowed redirect URIs. Keep cursor://anysphere.cursor-mcp/oauth/callback allowlisted too, since the desktop flow still falls back to it in some cases. The port is fixed at 8787.

One heads-up: the Static OAuth docs currently list only the web and desktop callbacks and don’t yet mention the loopback URL - so adding http://localhost:8787/callback alongside them is the missing piece. Let me know if the mismatch persists after you allowlist it.

Hey @mohitjain ,

I recently hit this while re-authenticating to the honeycomb mcp.

It caused a .. sort of related bug. Here’s the summary from cursor itself:

Symptom: OAuth consent on honeycomb.io succeeds, but the browser then fails to connect when redirected to http://127.0.0.1:8787/callback?... (connection refused / site can’t be reached). Auth never completes in Cursor.

Root cause (on my machine): Cursor’s MCP OAuth callback listener binds to IPv6 loopback only, while the OAuth provider redirects to IPv4 127.0.0.1.

Diagnostics during an active auth attempt

$ lsof -iTCP:8787 -sTCP:LISTEN -P -n
COMMAND  PID USER   FD   TYPE  NODE NAME
Cursor   ...  mp   43u  IPv6  ...  TCP [::1]:8787 (LISTEN)

$ curl -sS -o /dev/null -w "localhost: %{http_code}\n" http://localhost:8787/callback
localhost: 200

$ curl -sS -o /dev/null -w "127.0.0.1: %{http_code}\n" http://127.0.0.1:8787/callback
curl: (7) Failed to connect to 127.0.0.1 port 8787: Couldn't connect to server

So localhost works (resolves to ::1 on macOS), but 127.0.0.1 does not — even though both are semantically “loopback”. OAuth requires exact redirect URI string matching, and many providers (including Honeycomb via dynamic client registration) redirect to 127.0.0.1 rather than localhost.

Workaround that works: When the browser lands on the failed 127.0.0.1:8787 URL, manually change the host to localhost (keep port/path/query intact). Cursor then receives the callback and auth completes.

Suggested fix: The MCP OAuth callback server on port 8787 should listen on both 127.0.0.1 and ::1 (dual-stack loopback), or consistently use one host in both the registered redirect URI and the listener bind address. For reference, OpenAI Codex’s MCP OAuth implementation explicitly binds local callbacks to 127.0.0.1.

Environment:

  • Cursor 3.10.20 (arm64), macOS 25.5.0
  • MCP config: { "hcpServers": { "honeycomb": { "url": "https://mcp.honeycomb.io/mcp" } } }
  • Provider: Honeycomb MCP (OAuth via ui.honeycomb.io)

You’re right that this is a separate issue from the original thread: that one was a provider-side allowlist gap, whereas you’re hitting a genuine bug on our side — the MCP OAuth callback server binds to IPv6 loopback ([::1]:8787) only, so a provider that redirects the browser to IPv4 127.0.0.1:8787 gets a connection refused. I reproduced the same binding behavior on my end, so it’s on us to fix.

Since it’s a distinct root cause, could you open a new thread in Bug Reports for it? That keeps it trackable separately from this one. You’ve basically already got everything - please include:

  1. The symptom: OAuth consent succeeds, but the browser can’t reach http://127.0.0.1:8787/callback (connection refused) and auth never completes in Cursor.
  2. Your lsof -iTCP:8787 -sTCP:LISTEN -P -n output showing Cursor bound to [::1]:8787, plus the two curl checks (localhost → 200, 127.0.0.1 → refused).
  3. Cursor version and OS/arch (3.10.20, macOS arm64), the MCP server/provider (Honeycomb, OAuth via dynamic client registration), and your MCP logs from Output → MCP: honeycomb if you have them.

In the meantime, the workaround you found is the right one: when the browser lands on the failed http://127.0.0.1:8787/callback, change the host to localhost (keep the port, path, and query intact) and auth completes.

Re-raised here: MCP OAuth binds to IPv6 loopback, breaking 127.0.0.1 MCP redirect

Cursor’s OAuth redirect_uri is using a fixed localhost port (8787) that conflicts with quite a few things that might be running on a developer machine: Dask’s web interface, Cloudflare’s wrangler dev, probably some others. This breaks the OAuth flow if one of those apps happens to be running.

Cursor could use a random free high port. This is allowed by RFC 8252, and seems to be what most tools do:

The authorization server MUST allow any port to be specified at the
time of the request for loopback IP redirect URIs, to accommodate
clients that obtain an available ephemeral port from the operating
system at the time of the request.