Project-local MCP servers (url/streamable HTTP) don't trigger OAuth browser flow
Summary
Project-local MCP servers configured in .claude/settings.json with the url field (streamable HTTP transport) that require OAuth/SSO browser authentication silently fail to connect. No browser window is opened for authentication, and the servers don't appear in the /mcp dialog.
Environment
- Claude Code Version: 2.1.97
- Platform: macOS (Darwin 24.5.0)
- Shell: zsh
Configuration
.claude/settings.json (project-level):
{
"mcpServers": {
"my-server": {
"url": "https://my-corp-server.example.com/mcp"
}
}
}
The servers are corporate internal MCP servers that require browser-based SSO authentication (OAuth flow). They are reachable — curl returns 401 (auth required) and 406 responses.
Expected Behavior
When Claude Code connects to a url-based MCP server and receives a 401 with OAuth metadata:
- Claude Code should open the default browser for SSO authentication
- After auth completes, tokens should be stored and reused
- The servers should appear in the
/mcpdialog alongside plugin-based MCPs - Token refresh should happen automatically
This is how Cursor handles the same MCP servers — it opens a browser, the user authenticates once via SSO, and the session stays active.
Actual Behavior
- No browser window opens for authentication
- No OAuth tokens are stored (
~/.claude/has no credentials/oauth files for these servers) - The servers silently fail to connect — no error is shown to the user
- The
/mcpdialog only shows plugin-based MCPs, not project-local ones - No tools from these servers are available during the session
Key Observations
- Plugin-based MCPs (e.g.,
github@claude-plugins-official) DO have anauthenticatetool that triggers the OAuth flow correctly - Project-local
urlMCPs don't get the same treatment — no auth flow is triggered - The same servers work perfectly in Cursor with browser-based SSO
- There is no visible error or log output indicating the connection failure
Workaround
Manually obtain a bearer token and add it via headers:
{
"mcpServers": {
"my-server": {
"url": "https://my-corp-server.example.com/mcp",
"headers": {
"Authorization": "Bearer <manually-obtained-token>"
}
}
}
}
This is impractical for SSO tokens that expire frequently.
Requested Improvements
- Trigger OAuth browser flow for project-local
urlMCP servers that return401, matching Cursor's behavior - Show project-local servers in
/mcpdialog so users can see connection status and manually trigger auth - Surface connection errors instead of silently failing — at minimum log a warning
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗