[BUG] Slack MCP (direct HTTP) OAuth never completes — callback listener torn down ~3s after browser opens
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet (closest are #23468 and #47937, but neither captures the deterministic ~3s callback-listener teardown)
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
A user-config direct HTTP MCP server pointing at https://mcp.slack.com/mcp (with a pre-registered OAuth clientId and a fixed callbackPort) can never complete the /mcp OAuth flow.
The browser authorization page loads and shows success, but Claude Code's local OAuth callback listener is torn down ~3 seconds after the browser opens — long before a human can click "Allow". The flow then errors with Error during auth completion: <symbol>. The server stays permanently at ! Needs authentication, and the auth cache (~/.claude/mcp-needs-auth-cache.json) records the server with a timestamp but no registration id (working servers like Linear have an id).
This is not a Slack-side problem:
- With the configured
callbackPort(e.g.12714), Slack accepts theredirect_uriand returns no error — the failure is entirely local. - Removing
callbackPort(so Claude Code picks a random port) makes Slack correctly reject it:redirect_uri did not match any configured URIs. Passed URI: http://localhost:<random>/callback, confirming the app's allowlist requires the exact registeredhttp://localhost:12714/callback.
The claude.ai-managed Slack connector at the same URL works fine, because it authenticates server-side via the claudeai-proxy transport and never touches the local callback listener.
What Should Happen?
After authorizing in the browser, the redirect to http://localhost:12714/callback should be received, OAuth completion should store a token/registration, and the server should connect with its tools available.
Error Messages/Logs
Using redirect port: 12714 (from config)
Opening authorization URL: https://slack.com/oauth/v2_user/authorize?...redirect_uri=http%3A%2F%2Flocalhost%3A12714%2Fcallback...
Initial auth result: REDIRECT @ T+0.0s
Redirection handling is disabled, skipping redirect
MCP OAuth server cleaned up @ T+~3.1s
Error during auth completion: <minified symbol; "L7H" on 2.1.176, "Dse" on 2.1.185>
(from ~/Library/Caches/claude-cli-nodejs/<cwd-slug>/mcp-logs-slack/*.jsonl)
Steps to Reproduce
- Add a user-scope HTTP MCP server in
~/.claude.json:
``json``
{
"type": "http",
"url": "https://mcp.slack.com/mcp",
"oauth": { "clientId": "<pre-registered-slack-client-id>", "callbackPort": 12714 }
}
- Run
/mcp→ select the server → Authenticate. - Browser opens the Slack authorize page; complete authorization.
- Return to Claude Code.
Result: server stays at ! Needs authentication; logs show the listener cleaned up ~3s after the redirect followed by Error during auth completion, on every attempt.
Things ruled out: removing/re-adding the server, full restart, upgrading 2.1.176 → 2.1.185 — none help. Reproducible on both versions.
Claude Model
Not sure / Multiple models (model-independent — this is an MCP OAuth issue)
Is this a regression?
Yes, this worked in a previous version (the server had previously been used successfully; it broke after a Claude Code update when the cached token needed re-authentication and the re-auth path was first exercised).
Last Working Version
Unknown exact version — Homebrew replaced the prior cask during upgrade. Broke on/around 2.1.176; still broken on 2.1.185.
Claude Code Version
2.1.185 (Claude Code)
Platform
Anthropic API (Claude subscription)
Operating System
macOS
Terminal/Shell
Warp
Additional Information
Suspected root cause: the local OAuth callback HTTP server is shut down (MCP OAuth server cleaned up) before the user completes the browser authorization, so the redirect to localhost:12714/callback has no listener and completion fails deterministically. The Redirection handling is disabled, skipping redirect line may be related to #23468 (302 from mcp.slack.com not followed).
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗