Atlas rejects the MCP OAuth callback with "OAuth state mismatch - potential CSRF attack" because the state parameter returned by the authorization server does not match the state Atlas generated for the pending OAuth flow, so the callback handler refuses to exchange the code and the server stays in needs_auth. Fix it by closing stale browser tabs from an earlier `atlas mcp auth` attempt and re-running `atlas mcp auth <name>` in one pass without reusing an old authorization URL.
Why does Atlas report OAuth state mismatch
Atlas reports "OAuth state mismatch - potential CSRF attack" when the state parameter returned by the authorization server does not match the state Atlas generated for the pending OAuth flow. Only 1 flow at a time holds a valid state, so the callback handler refuses to exchange the code and the MCP server stays in needs_auth.
The state parameter is a one-time value that ties a callback to the exact login Atlas started. Atlas generates it, sends it out with the authorization request, and checks it when the callback lands. A mismatch means the callback belongs to some other flow, and Atlas refuses to trade the code for a token rather than trusting it. The wording is blunt on purpose: a state mismatch is what a cross-site request forgery attempt looks like. Almost always the real cause is far more mundane, a leftover browser tab from an earlier `atlas mcp auth` attempt whose state is no longer the current one.
How to fix an OAuth state mismatch in Atlas
Fix the Atlas OAuth state mismatch in 4 steps: close every stale browser tab from an earlier `atlas mcp auth` attempt, re-run `atlas mcp auth <name>` and complete the flow in one pass, set an explicit `redirectUri` if a proxy rewrites query strings, and confirm no other local service holds the callback port.
Start with the browser. Only the newest Atlas flow has a valid state, so any tab left open from a previous attempt is carrying a state Atlas will now reject. Close all of them, then run `atlas mcp auth <name>` fresh and walk through consent without pausing, without going back, and without opening an old authorization URL from your history. Completing the flow in one pass is the single most reliable fix. If a mismatch survives a clean run, the state is being altered in transit and you move on to the proxy and callback port causes.
How a corporate proxy causes an Atlas OAuth state mismatch
A corporate proxy can cause an Atlas OAuth state mismatch by rewriting query strings on the callback URL. When the state parameter is stripped or altered in transit, the value that reaches Atlas is no longer the state Atlas generated, and setting an explicit `redirectUri` on that server's oauth config is the 1 documented fix.
Setting an explicit `redirectUri` on that server's oauth config is the documented fix in Atlas. A fixed, known redirect gives the proxy and the authorization server one agreed target instead of a value assembled on the fly, which removes the rewriting opportunity. The signature of this cause is a state mismatch that reproduces every single time, on a clean flow, with no stale tabs anywhere. Ordinary stale-tab mismatches are intermittent and disappear once you run the flow in one pass. A deterministic mismatch on a corporate network points at the network path.
Check whether another service is holding the Atlas OAuth callback port
Confirm the Atlas OAuth callback port is not being intercepted by another local service. When a 2nd process answers on that port, the callback never reaches Atlas with the state it generated, the pending flow for that MCP server never completes, and the status stays at needs_auth.
Port collisions are common on developer machines running several tools at once, and the symptom is easy to misread as an Atlas bug. Check what is listening on the callback port before assuming the OAuth flow is broken. The Atlas oauth config block for an MCP server accepts callbackPort and redirectUri alongside clientId, so moving Atlas to an uncontested port is a config change on that server entry rather than a fight with the other service. Be aware of the caveat: if the authorization server pre-registered a specific redirect, changing the port on the Atlas side means updating the registered redirect too.
How to verify the MCP OAuth flow completed in Atlas
Verify the Atlas MCP OAuth flow by running `atlas mcp` after consent and reading 1 line, the status row for that server. A server that completed the exchange leaves needs_auth and reaches connected. A row still sitting at needs_auth means the callback was rejected again and the state mismatch is unresolved.
`atlas mcp` is the authoritative check because the status row is written by the same code path that refused the exchange. Do not judge success by the browser page, which can show a friendly confirmation while Atlas rejected the callback moments later. If the row still reads needs_auth, work back through the causes in order: stale tabs first, then a proxy rewriting the callback query string, then a callback port held by another local service. Once the row reads connected, that MCP server's tools are exposed to the agent again.
How to fix it
- 01Close any stale browser tabs from an earlier `atlas mcp auth` attempt; only the newest flow has a valid state.
- 02Re-run `atlas mcp auth <name>` and complete the flow in one pass without reusing an old authorization URL.
- 03If a corporate proxy rewrites query strings on the callback URL, set an explicit `redirectUri` on the server's oauth config.
- 04Confirm the callback port is not being intercepted by another local service.
Frequently asked questions
- What does "OAuth state mismatch - potential CSRF attack" mean in Atlas?
- It means the state parameter returned by the authorization server does not match the state Atlas generated for the pending OAuth flow, so the callback handler refuses to exchange the authorization code and the MCP server stays in needs_auth.
- How do I fix an MCP OAuth state mismatch in Atlas?
- Close stale browser tabs from any earlier `atlas mcp auth` attempt, then re-run `atlas mcp auth <name>` and complete the flow in one pass without reusing an old authorization URL. Only the newest flow has a valid state.
- Am I actually under a CSRF attack when Atlas says this?
- Usually not. The message is worded that way because a state mismatch is what CSRF looks like, but the common cause is a leftover browser tab from an earlier `atlas mcp auth` attempt carrying an old state.
- Can a corporate proxy break the Atlas OAuth callback?
- Yes. A proxy that rewrites query strings on the callback URL can alter the state parameter in transit. Set an explicit `redirectUri` on that server's oauth config so the redirect target is fixed and known.
- Why does my MCP server stay in needs_auth after the OAuth state mismatch?
- Because the Atlas callback handler refused to exchange the code, no token was ever obtained. The server therefore remains at needs_auth until an OAuth flow completes with a matching state.
- Does the callback port matter for atlas mcp auth?
- Yes. If another local service intercepts the callback port, the callback never reaches Atlas. Confirm nothing else is listening on it. The Atlas oauth config accepts callbackPort and redirectUri on the server entry.
- Can I reuse an old authorization URL for atlas mcp auth?
- No. An old authorization URL carries a state from a previous flow, which Atlas will reject. Re-run `atlas mcp auth <name>` and complete the fresh flow in one pass.
Try SeaShell in your terminal
The terminal-native AI coding agent. Free core, single binary.
Install SeaShellRelated guides
Atlas with GLM-4.5-Air in 2026
Explore GLM-4.5-Air's cost-effective performance with Atlas in 2026. This 12B active parameter model offers a 128K token context window for $0.20/Mtok input.
Atlas vs Codebuff: Terminal AI Coding Agents in 2026
Comparing Atlas and Codebuff in 2026 for terminal AI coding agents. Atlas offers a free core with permission-gated tools and diff review. Codebuff provides free hours on DeepSeek V4 Flash.
Atlas with Mixtral 8x22B in 2026
Evaluate Mixtral 8x22B for Atlas in 2026. This open-weights MoE model offers a 64,000 token context window, ideal for complex coding tasks, with transparent pricing.
Atlas with Kimi K2.7 Code in 2026: A Developer's Guide
Drive Atlas with Kimi K2.7 Code, Moonshot AI's 2026 open-weights coding model. Leverage its 262K token context and cost-effective $0.95/Mtok input for powerful, privacy-aware code generation.
Atlas with Qwen3.5 Plus in 2026
Drive Atlas, the terminal-native AI coding agent, with Qwen3.5 Plus. Leverage its 1,000,000 token context window and cost-effective $0.40 per Mtok input for deep code understanding.
Atlas with Ministral 3B in 2026
Explore Ministral 3B's role in Atlas for high-volume, low-stakes tasks. Discover its 128,000 token context window and cost-effective $0.04/Mtok pricing.
Atlas with Devstral Medium (2507) in 2026
Explore Atlas with Devstral Medium (2507) in 2026. This agent-trained model offers a 128,000 token context window for complex repo-level tasks, balancing capability and cost for developers.
Atlas with GLM-4.6 in 2026
Explore GLM-4.6 with Atlas in 2026: an open-weights model featuring a 200K token context window and 131,072 max output, ideal for complex coding tasks. Understand its pricing and tradeoffs.