[BUG] claude mcp add --client-id writes clientId (camelCase) but SDK reads client_id (snake_case), causing pre-configured OAuth to fail
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?
Bug Report: claude mcp add --client-id writes clientId (camelCase) but SDK reads client_id (snake_case), causing pre-configured OAuth to fail
Summary
When adding an MCP server with pre-configured OAuth credentials using --client-id, Claude Code writes the client ID to ~/.claude.json as clientId (camelCase). However, the OAuth SDK reads client_id (snake_case). This mismatch causes the auth flow to ignore the provided credentials entirely and fall back to Dynamic Client Registration (DCR), which fails for servers that use pre-registered OAuth clients and do not support DCR.
Steps to Reproduce
- Add an MCP server with pre-configured OAuth credentials:
claude mcp add --transport http \
--client-id YOUR_CLIENT_ID --client-secret --callback-port 3000 \
myserver https://mcp-server.example.com/mcp
- Verify the config was written:
grep -A8 "myserver" ~/.claude.json
- Observe that the config contains
"clientId"(camelCase), not"client_id"(snake_case) - Launch Claude Code and run
/mcp - Observe the error:
SDK auth failed: Incompatible auth server: does not support dynamic client registration
Expected Behavior
claude mcp add --client-idshould writeclient_id(snake_case) to~/.claude.json- The OAuth flow should use the provided client ID and secret instead of attempting DCR
- The browser auth flow should complete successfully for servers that use pre-registered OAuth clients
Actual Behavior
claude mcp add --client-idwritesclientId(camelCase) to~/.claude.json- The OAuth SDK does not recognize
clientIdand treats the server as having no pre-configured credentials - Claude Code falls back to DCR, which fails for servers that don't support it
- Manually fixing the config via
seddoes not resolve the issue because Claude Code re-reads config at startup before the auth flow begins and still does not pick up the credentials
Config Written (Incorrect)
"myserver": {
"type": "http",
"url": "https://mcp-server.example.com/mcp",
"oauth": {
"clientId": "YOUR_CLIENT_ID",
"callbackPort": 3000
}
}
Config Expected (Correct)
"myserver": {
"type": "http",
"url": "https://mcp-server.example.com/mcp",
"oauth": {
"client_id": "YOUR_CLIENT_ID",
"callbackPort": 3000
}
}
Environment
- Claude Code version: 2.1.178
- OS: macOS (darwin-arm64)
- MCP server: OneCal (
https://mcp-server.onecal.io/mcp) - Auth method attempted: Pre-configured OAuth credentials per docs at https://code.claude.com/docs/en/mcp#use-pre-configured-oauth-credentials
Additional Context
claude mcp get <name> correctly reports client_id configured, client_secret configured after adding the server, confirming the credentials were accepted by the CLI. However the runtime OAuth flow does not use them. This suggests the CLI and the OAuth SDK are using different field name conventions when reading the config.
What Should Happen?
Expected Behavior
claude mcp add --client-idshould writeclient_id(snake_case) to~/.claude.json- The OAuth flow should use the provided client ID and secret instead of attempting DCR
- The browser auth flow should complete successfully for servers that use pre-registered OAuth clients
Error Messages/Logs
## Actual Behavior
- `claude mcp add --client-id` writes `clientId` (camelCase) to `~/.claude.json`
- The OAuth SDK does not recognize `clientId` and treats the server as having no pre-configured credentials
- Claude Code falls back to DCR, which fails for servers that don't support it
- Manually fixing the config via `sed` does not resolve the issue because Claude Code re-reads config at startup before the auth flow begins and still does not pick up the credentials
Steps to Reproduce
Steps to Reproduce
- Add an MCP server with pre-configured OAuth credentials:
claude mcp add --transport http \
--client-id YOUR_CLIENT_ID --client-secret --callback-port 3000 \
myserver https://mcp-server.example.com/mcp
- Verify the config was written:
grep -A8 "myserver" ~/.claude.json
- Observe that the config contains
"clientId"(camelCase), not"client_id"(snake_case) - Launch Claude Code and run
/mcp - Observe the error:
SDK auth failed: Incompatible auth server: does not support dynamic client registration
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.178
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗