Atlassian MCP plugin returns 401 after successful token exchange

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

Cursor 3.23.12 on Windows, Atlassian plugin 0.1.0 (plugin-atlassian-atlassian), endpoint https://mcp.atlassian.com/v2/mcp. The OAuth callback exchange completes and the tokens are saved. The next streamable HTTP call then returns “401 after successful authentication” and the status goes back to needsAuth (v2). The UI stays on “Exchanging token”. The same sequence happened at 9:45, 9:59, 10:12, and 10:32, including after I removed the Atlassian MCP grant under Connected apps and signed in again. The same plugin connects successfully outside the local Cursor app.

Steps to Reproduce

  1. Install the Atlassian plugin 0.1.0 in Cursor 3.23.12 on Windows.
  2. Click Authenticate on the atlassian MCP row.
  3. Finish the Atlassian consent screen and return to Cursor.
  4. The row stays on Exchanging token and the log shows needsAuth (v2).

Expected Behavior

After the token is saved, the Atlassian MCP connects and its tools become available.

Operating System

Windows 10/11

Version Information

Cursor 3.23.12

Does this stop you from using Cursor

No - Cursor works, but with this issue

Hey, thanks for the detailed report. The Server returned 401 after successful authentication error means Atlassian rejected the token Cursor just received. Most often this points to a stale local sign-in state, not an issue with your Atlassian grant. Let’s try a clean sign-in.

  1. If Grok Bot desktop is open, close it for this test.
  2. In Cursor: Cursor Settings > Tools & MCP.
  3. Open the Atlassian entry and under Environments > Local click Logout.
  4. Check your mcp.json files global and project for another Atlassian entry. If you find one, temporarily remove it or disable it.
  5. Fully close Cursor all windows, then reopen it.
  6. Go back to Tools & MCP, click Authenticate for Atlassian, and complete the consent screen.

If it gets stuck on Exchanging token again, here’s a workaround that helped in similar cases. Disable the plugin and add Atlassian directly in mcp.json, pinning your site:

"atlassian": { "url": "https://mcp.atlassian.com/v2/mcp?site=YOURSITE.atlassian.net" }

If neither helps, please send:

  • The log from View > Output, selecting the Atlassian MCP channel, right after the failed attempt
  • The approximate time of the attempt with your timezone
  • Whether your Atlassian account has access to more than one site

Let me know how it goes.

Thanks. I tested the direct mcp.json configuration as suggested, with the Atlassian plugin disabled.

The connection still gets stuck on “Exchanging token”. The log shows that the OAuth refresh completes and the tokens are persisted, but the subsequent Streamable HTTP connection is rejected:

Auth-related error connecting to streamableHttp server:

Server returned 401 after successful authentication

The client then returns to:

MCP OAuth needsAuth (v2)

Attempt time:

4 October 2026 at approximately 12:41 EEST (UTC+3)

I can confirm that the mcp.json connection was pinned to the relevant Atlassian site.

Could this indicate a Cursor OAuth/resource-audience issue, or is there a specific Atlassian-side authorization setting I should check?

my Atlassian account only has access to a single site.

Here’s the log:

2026-10-04 12:40:54.207 [info] connecting streamableHttp for “atlassian” (user-atlassian)
2026-10-04 12:40:54.208 [info] [V2 FSM] connection:connect_start: conn=idle,auth=unknown → conn=connecting,auth=unknown
2026-10-04 12:40:54.661 [info] MCP OAuth redirect
2026-10-04 12:40:54.662 [info] Connect failed after auth_required; returning needsAuth (streamableHttp)
2026-10-04 12:40:54.666 [info] MCP OAuth needsAuth (v2)
2026-10-04 12:40:59.142 [info] stopped connection: user-atlassian
2026-10-04 12:40:59.159 [info] stopped connection: user-atlassian
2026-10-04 12:40:59.165 [info] connecting streamableHttp for “atlassian” (user-atlassian)
2026-10-04 12:40:59.165 [info] [V2 FSM] connection:connect_start: conn=idle,auth=unknown → conn=connecting,auth=unknown
2026-10-04 12:40:59.654 [info] MCP OAuth redirect
2026-10-04 12:40:59.654 [info] Connect failed after auth_required; returning needsAuth (streamableHttp)
2026-10-04 12:40:59.656 [info] MCP OAuth needsAuth (v2)
2026-10-04 12:41:07.265 [info] MCP OAuth tokens persisted
2026-10-04 12:41:07.269 [info] MCP OAuth callback exchange completed
2026-10-04 12:41:07.269 [info] stopped connection: user-atlassian
2026-10-04 12:41:07.277 [info] connecting streamableHttp for “atlassian” (user-atlassian)
2026-10-04 12:41:07.277 [info] [V2 FSM] connection:connect_start: conn=idle,auth=unknown → conn=connecting,auth=unknown
2026-10-04 12:41:07.351 [warning] MCP HTTP exchange completed
2026-10-04 12:41:07.583 [info] MCP OAuth refresh lock acquired
2026-10-04 12:41:07.583 [info] MCP OAuth refresh prepared
2026-10-04 12:41:08.021 [info] MCP OAuth tokens persisted
2026-10-04 12:41:08.021 [info] MCP OAuth refresh result
2026-10-04 12:41:08.022 [info] MCP OAuth refresh lock released
2026-10-04 12:41:08.086 [warning] MCP HTTP exchange completed
2026-10-04 12:41:08.087 [error] Auth-related error connecting to streamableHttp server: Streamable HTTP error: Server returned 401 after successful authentication Streamable HTTP error: Server returned 401 after successful authentication
2026-10-04 12:41:08.090 [info] MCP OAuth needsAuth (v2)

Thanks for the logs and for confirming the single-site configuration. That helps narrow things down.

From the log, it looks like token exchange and refresh are both succeeding, and the tokens are being saved (MCP OAuth tokens persisted, callback exchange completed). Then the very next Streamable HTTP request returns 401 after successful authentication. So at the request stage, Atlassian is rejecting the newly saved token. This does not look like a token persistence issue or a problem with your Atlassian grant.

Since using a direct mcp.json with pinned ?site= and doing a clean re-auth also didn’t help, and the same server connects fine outside the local app, this looks more like something in the desktop token or request handling path, not an issue with your setup or Atlassian config. I’ve passed it to the team. I can’t give a timeline yet, but I’ll follow up in this thread as soon as I have an update.

If you get a chance before then, a couple quick checks would help speed things up:

  • Does the 401 still happen after a full machine restart, not just restarting Cursor?
  • If you have another OAuth MCP handy, like Linear or GitHub, does it connect on this same machine without a 401? That would help show whether this is specific to Atlassian v2 or a broader local issue.

On Windows, the GitHub MCP server at https://api.githubcopilot.com/mcp/ connects and then fails about half a second later with Client error: terminated. The row shows “Error · terminated”. This happens with the GitHub plugin and also with a direct entry in ~/.cursor/mcp.json that has the plugin turned off. Authentication uses a fine-grained personal access token sent as Authorization: Bearer.

The token and the server are fine outside Cursor. From the same machine, a manual initialize, initialized, and tools/list sequence returns 200 with 46 tools, and api.github.com/user returns my account. The server answers the optional GET event stream with 405. Limiting toolsets with X-MCP-Toolsets: repos,issues,pull_requests made no difference.

Log from the mcp.json entry (the plugin log is the same):

14:03:52.428 [info] connecting streamableHttp for "github-direct" (user-github-direct)
14:03:53.013 [info] Successfully connected to streamableHttp server
14:03:53.013 [info] [V2 FSM] connection:connect_success: conn=connecting,auth=unknown -> conn=connected,auth=unknown
14:03:53.454 [warning] MCP HTTP exchange completed
14:03:53.455 [error] Client error: terminated terminated
14:03:53.455 [warning] [V2 FSM] connection:transport_error: conn=connected,auth=unknown -> conn=failed,auth=unknown

Steps to Reproduce

  1. Set GITHUB_PERSONAL_ACCESS_TOKEN as a Windows user environment variable.
  2. Enable the GitHub plugin, or add https://api.githubcopilot.com/mcp/ to mcp.json with the Bearer header.
  3. Restart Cursor and open Tools & MCP.

Restarted, no effect.