MCP HTTP OAuth: "client secret is invalid" with Google Desktop OAuth clients; SDK rejects valid credentials

Open 💬 3 comments Opened Jun 12, 2026 by chadsmall-hh

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?

Summary

Claude Code's HTTP MCP transport (drivemcp.googleapis.com/mcp/v1) cannot
complete OAuth token exchange when configured with a Google Desktop OAuth
client. The error surfaces in /mcp UI as "The provided client secret is
invalid" — but the credentials are objectively valid (verified via direct
curl to Google's token endpoint).

This blocks all use of Google's hosted MCP services (Drive, etc.) via Claude
Code unless the user has access to a working Web-app OAuth client (which has
its own separate issue — a 403 at the data plane).

Environment

  • Claude Code: latest as of 2026-06-12 (claude --version output: [Chad to confirm])
  • OS: macOS Darwin 25.4.0 (arm64)
  • Node: v24.15.0 (npm global install path)
  • MCP server: https://drivemcp.googleapis.com/mcp/v1 (Google-hosted)
  • OAuth client type: Desktop (per Google Support guidance to switch from Web)

Repro

  1. Create Google OAuth client of type "Desktop application" in a GCP project

with Drive API enabled + the standard Drive scopes added to the OAuth
consent screen

  1. Configure ~/.claude.json MCP server:

```json
"gdrive": {
"type": "http",
"url": "https://drivemcp.googleapis.com/mcp/v1",
"oauth": {
"clientId": "<desktop client id>",
"clientSecret": "<desktop client secret>",
"callbackPort": 8080
}
}

  1. Start Claude Code with claude --debug-file /tmp/debug.log
  2. In /mcp, select gdrive → Authenticate
  3. Complete the browser OAuth consent flow (succeeds; "Authentication

Successful" page renders)

  1. /mcp now shows gdrive · ⚠ needs authentication with detail:

Status: needs authentication
Auth: not authenticated
The provided client secret is invalid.

Debug log excerpt

2026-06-12T17:11:25.020Z [DEBUG] MCP server "gdrive": Opening authorization URL: ...
2026-06-12T17:11:25.278Z [DEBUG] MCP server "gdrive": Initial auth result: REDIRECT
2026-06-12T17:11:30.739Z [DEBUG] MCP server "gdrive": MCP OAuth server cleaned up
2026-06-12T17:11:30.742Z [DEBUG] MCP server "gdrive": Completing auth flow with authorization code
2026-06-12T17:11:30.744Z [DEBUG] MCP server "gdrive": Returning cached discovery state (authServer: https://accounts.google.com/)
2026-06-12T17:11:31.058Z [DEBUG] MCP server "gdrive": Using pre-configured client ID
2026-06-12T17:11:31.064Z [DEBUG] MCP server "gdrive": Returning code verifier
2026-06-12T17:11:31.637Z [DEBUG] MCP server "gdrive": Error during auth completion: IeH: The provided client secret is invalid.

Reproduces with and without clientSecret in config (PKCE-only attempt
hits the same error).

Diagnostic — Google accepts the credentials

To isolate whether the issue is on Google's side or in Claude Code's SDK:

curl -X POST https://oauth2.googleapis.com/token \
-d "client_id=<our client id>" \
-d "client_secret=<our client secret>" \
-d "grant_type=refresh_token" \
-d "refresh_token=dummy_invalid_token_to_test_client_creds"

Response: HTTP 400 {"error": "invalid_grant", "error_description": "Bad Request"}

The invalid_grant (NOT invalid_client) response confirms Google's OAuth
endpoint accepts our client_id + client_secret pair. The dummy refresh
token was correctly rejected as expected. Our credentials are valid.

Expected behavior

Claude Code's MCP OAuth SDK should successfully complete the token exchange
using a Desktop OAuth client's client_id + client_secret, given that the
credentials are valid per Google's OAuth endpoint.

Actual behavior

The SDK rejects the credentials internally (note IeH: prefix on the error
message = minified class name from the compiled binary). The HTTP request to
Google's token endpoint either does not happen or its response is misinterpreted.

Additional context

  • Google Support (Dragos, 2026-06-02) recommended Web → Desktop OAuth client

switch to resolve a separate 403 issue at the data plane that occurred with
the Web-app client type. The switch fixed the 403 issue but exposed this
SDK-side error.

hosted Drive MCP service.

  • We discovered Claude Code has a beta XAA (SEP-990) shared-IdP path gated by

CLAUDE_CODE_ENABLE_XAA=1 — possibly a future-direction for HTTP MCP OAuth,
but not opt-in for drivemcp currently.

Workaround

Use the macOS Google Drive filesystem mount
(~/Library/CloudStorage/GoogleDrive-<email>/...) via Claude Code's standard
Read/Write/Edit tools instead of the MCP integration. Marginal feature loss
(no MCP-driven search/metadata) but full Drive file access.

Question for maintainers

Is the per-server OAuth config in ~/.claude.json.mcpServers.<n>.oauth.{clientId,clientSecret,callbackPort}
intended to work with Google Desktop OAuth clients, or is the XAA path the
only supported path going forward? If the latter, would appreciate a clear
deprecation/migration message in the /mcp UI instead of a misleading
"client secret is invalid" error.

What Should Happen?

Expected behavior

Claude Code's MCP OAuth SDK should successfully complete the token exchange
using a Desktop OAuth client's client_id + client_secret, given that the
credentials are valid per Google's OAuth endpoint.

Error Messages/Logs

Response: HTTP 400 {"error": "invalid_grant", "error_description": "Bad Request"}

The invalid_grant (NOT invalid_client) response confirms Google's OAuth
endpoint accepts our client_id + client_secret pair. The dummy refresh
token was correctly rejected as expected. Our credentials are valid.

Steps to Reproduce

  1. Create Google OAuth client of type "Desktop application" in a GCP project

with Drive API enabled + the standard Drive scopes added to the OAuth
consent screen

  1. Configure ~/.claude.json MCP server:

```json
"gdrive": {
"type": "http",
"url": "https://drivemcp.googleapis.com/mcp/v1",
"oauth": {
"clientId": "<desktop client id>",
"clientSecret": "<desktop client secret>",
"callbackPort": 8080
}
}

  1. Start Claude Code with claude --debug-file /tmp/debug.log
  2. In /mcp, select gdrive → Authenticate
  3. Complete the browser OAuth consent flow (succeeds; "Authentication

Successful" page renders)

  1. /mcp now shows gdrive · ⚠ needs authentication with detail:

Status: needs authentication
Auth: not authenticated
The provided client secret is invalid.

Claude Model

Opus

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

2.1.175 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗