[BUG] claude mcp add --client-id writes clientId (camelCase) but SDK reads client_id (snake_case), causing pre-configured OAuth to fail

Resolved 💬 1 comment Opened Jun 16, 2026 by whoisthatpanda Closed Jun 24, 2026

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

  1. 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
  1. Verify the config was written:
grep -A8 "myserver" ~/.claude.json
  1. Observe that the config contains "clientId" (camelCase), not "client_id" (snake_case)
  2. Launch Claude Code and run /mcp
  3. Observe the error: SDK auth failed: Incompatible auth server: does not support dynamic client registration

Expected Behavior

  • claude mcp add --client-id should write client_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-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

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

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-id should write client_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

  1. 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
  1. Verify the config was written:
grep -A8 "myserver" ~/.claude.json
  1. Observe that the config contains "clientId" (camelCase), not "client_id" (snake_case)
  2. Launch Claude Code and run /mcp
  3. 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_

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗