Kaggle MCP OAuth fails at token exchange: "client_secret_basic authentication requires a client_secret"

Status Open
Reported on v2.1.224
Maintainer reply None cached
Activity 0 comments · opened Aug 7, 2026

Description

Adding Kaggle's official MCP server (https://www.kaggle.com/mcp) as a user-scoped HTTP MCP server and authenticating via /mcp fails at the token-exchange step, even though the browser-side authorization succeeds.

Steps to reproduce

  1. claude mcp add --transport http --scope user kaggle https://www.kaggle.com/mcp
  2. In an interactive claude session, run /mcp and select kaggle → Authenticate
  3. Browser opens Kaggle's "API Authorization" consent screen, requesting resources.admin scope, redirecting to http://localhost:<port>/callback
  4. Approve — browser shows "Authentication successful / Connected. You can close this tab and return to Claude Code."
  5. Back in the terminal, /mcp still shows the server as unauthenticated:
Kaggle MCP Server
Status:         needs authentication
Auth:           not authenticated
URL:            https://www.kaggle.com/mcp
Config location: /Users/<user>/.claude.json

client_secret_basic authentication requires a client_secret

Expected behavior

Authentication should complete successfully after the browser consent step, matching what the callback page itself reports ("Authentication successful").

Actual behavior

Token exchange fails with client_secret_basic authentication requires a client_secret. This suggests Claude Code registered as a public OAuth client (PKCE, no secret) during dynamic client registration, but Kaggle's authorization server is requiring client_secret_basic at the token endpoint — a mismatch between the two sides that leaves the server permanently stuck in a re-auth loop (every retry gets a fresh authorization code, then fails at the same step).

Environment

  • Claude Code version: 2.1.224
  • OS: macOS (Darwin 25.5.0)
  • Transport: HTTP, scope: user

Additional context

Removing and re-adding the MCP server config does not help, since the failure is in the OAuth token exchange, not local config state.

View original on GitHub ↗