[BUG] - Hardcoded OAuth callback port 3118 prevents authentication when multiple Claude Code sessions run in parallel
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
I am resubmitting this because it was closed as duplicate, but it is not a duplicate. This is a particularly major issue if you are using devcontainers. I have to bind the port in order to use the Slack MCP. If I want to run multiple devcontainers in different repos (which is something I frequently do), then having the port hardcoded to 3118 means the port binding fails and the container will not build. This makes it not just impossible to use the Slack MCP in multiple Claude sessions, but actually impossible to run two containers which are configured to run the MCP. The only way to start the other container is to remove the port binding, otherwise you get this error on build:
Bind for 127.0.0.1:3118 failed: port is already allocated
Summary
The Slack MCP plugin's OAuth config hardcodes callbackPort: 3118. Because the OAuth callback server binds to this single fixed port, only one Claude Code session on the machine can complete Slack OAuth at a time. Users running multiple parallel sessions (per-project, cmux-managed, detached terminals) hit unrecoverable auth failures whenever another session is already listening on 3118.
Reproduction
- Start a Claude Code session (A) that has loaded the Slack plugin. It binds
localhost:3118at some point during Slack MCP lifecycle. - In another terminal, start session B.
- In session B, run
/mcpand select Slack → Authenticate. - Auth fails with:
Error: OAuth callback port 3118 is already in use — another process may be holding it.
Run `lsof -ti:3118 -sTCP:LISTEN` to find it.
lsofreveals the port is held by another Claude Code process — a sibling session, not malware — with no way to proceed without killing that session.
Config
~/.claude/plugins/cache/claude-plugins-official/slack/1.0.0/.mcp.json:
{
"mcpServers": {
"slack": {
"type": "http",
"url": "https://mcp.slack.com/mcp",
"oauth": {
"clientId": "1601185624273.8899143856786",
"callbackPort": 3118
}
}
}
}
Root Cause
OAuth 2.0 requires redirect_uri to match a pre-registered value in the Slack OAuth app configuration. The Slack app (client_id: 1601185624273.8899143856786) has http://localhost:3118/callback registered as the only loopback redirect URI, so the MCP client cannot fall back to a different port.
Proposed Solutions (in order of preference)
1. RFC 8252 loopback redirect with wildcard port (recommended)
Per RFC 8252 §7.3, loopback redirect URIs SHOULD allow any port. Register http://127.0.0.1/callback (no port) in the Slack OAuth app and have the MCP client bind to an OS-assigned ephemeral port. This is the idiomatic modern approach and eliminates port collision entirely.
2. Port range fallback (GitHub CLI pattern)
Register a range (e.g., 3118-3127) in the Slack OAuth app, and have the client try each sequentially until one is free. This is what gh, gcloud, heroku, flyctl and many other dev-CLIs do.
3. Device Authorization Grant (RFC 8628)
No callback server needed. User copies a short code from terminal into browser. More user-friction but entirely port-independent. Good fallback if ①/② are blocked by Slack app policy.
4. Short-term UX improvement
The current error message points to lsof -ti:3118 -sTCP:LISTEN but doesn't tell the user that the port is almost always held by a sibling Claude Code session. Adding this context — and ideally offering to SIGTERM the blocking Claude process after confirmation — would reduce frustration significantly while ①/②/③ are being evaluated.
Environment
- Claude Code:
2.1.114 - Plugin:
claude-plugins-official/slack@1.0.0 - OS: macOS (Darwin 25.3.0)
- Usage pattern: 5-10 parallel Claude Code sessions per day (
cmux-managed + ad-hoc terminals). Common among heavy users.
Workaround
# Find the blocking Claude session
lsof -i:3118 -sTCP:LISTEN -n -P
# Kill it (destructive to that session)
lsof -ti:3118 -sTCP:LISTEN | xargs kill
# Then retry OAuth in the current session
This works but is destructive to the other session and counterintuitive — nothing in the error message hints that you're being blocked by your own previous Claude process.
Related Issues
- #37714 — Slack MCP plugin OAuth fails: redirect_uri not registered (different root cause, resolved by Slack OSS team)
- #37747 — MCP OAuth regression: client metadata document redirect_uris missing port
- #48993 — Remote HTTP MCP (Slack): forces frequent re-OAuth despite valid refresh tokens
Impact
This affects any user who runs multiple Claude Code sessions simultaneously — a workflow that Anthropic actively supports (project-scoped sessions, cmux, background agents). Without a fix, users must serialize all Slack MCP auth attempts, which contradicts the parallel-session design of the product.
What Should Happen?
The Slack MCP should not be hardcoded against a single port. You should be able to run multiple Claude sessions with the Slack MCP.
Error Messages/Logs
Steps to Reproduce
- Create a dev container with the port binding for the Slack MCP (3118)
- Build the container
- Create a second dev container with the port binding for the Slack MCP (3118)
- Attempt to build the second container. It fails
Claude Model
Not sure / Multiple models
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.140
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Windows Terminal
Additional Information
_No response_
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗