-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Problem
When an OAuth authorization server returns an error response with HTTP 200 status (instead of 4xx), the SDK fails to detect the error and attempts to parse it as a successful token response, resulting in a confusing Zod validation error.
Reproduction Steps
- Configure an MCP client to use GitHub's MCP server with OAuth:
{
"mcp": {
"github": {
"type": "remote",
"url": "https://api.githubcopilot.com/mcp/",
"oauth": {
"clientId": "your-github-app-client-id"
// Missing clientSecret - GitHub requires this
}
}
}
}- Run OAuth authentication (example using OpenCode CLI):
opencode mcp auth github-
Complete the OAuth authorization in browser (user clicks "Authorize")
-
Token exchange fails with confusing error:
┌ MCP OAuth Authentication
│
■ Authentication failed
│
■ [
│ {
│ "expected": "string",
│ "code": "invalid_type",
│ "path": [
│ "access_token"
│ ],
│ "message": "Invalid input: expected string, received undefined"
│ },
│ {
│ "expected": "string",
│ "code": "invalid_type",
│ "path": [
│ "token_type"
│ ],
│ "message": "Invalid input: expected string, received undefined"
│ }
│ ]
│
└ Done
Root Cause
GitHub's OAuth token endpoint returns errors with HTTP 200:
curl -s -X POST "https://github.com/login/oauth/access_token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: application/json" \
-d "grant_type=authorization_code&code=test&client_id=YOUR_CLIENT_ID"Response (HTTP 200):
{
"error": "incorrect_client_credentials",
"error_description": "The client_id and/or client_secret passed are incorrect.",
"error_uri": "https://docs.github.com/apps/managing-oauth-apps/troubleshooting-oauth-app-access-token-request-errors/#incorrect-client-credentials"
}Current SDK Behavior
The SDK checks response.ok (which is true for HTTP 200), then tries to parse the response as OAuthTokensSchema:
// src/client/auth.ts - executeTokenRequest()
if (!response.ok) {
throw await parseErrorResponse(response);
}
return OAuthTokensSchema.parse(await response.json());Expected Behavior
The SDK should check for an error field in the JSON response before attempting to parse as tokens.
Expected error message:
Authentication failed
The client_id and/or client_secret passed are incorrect.
This tells the user exactly what's wrong and how to fix it.
Why This Should Be Fixed in the SDK (Not Just GitHub)
-
Defensive programming: The SDK should handle real-world OAuth servers gracefully, even when they deviate from the spec. Users shouldn't need to debug Zod errors for common OAuth misconfigurations.
-
GitHub isn't the only one: Other OAuth providers may have similar behavior. A quick check for
errorin the response is cheap and makes the SDK more robust. -
No breaking changes: This fix only affects error paths - successful token exchanges are unaffected.
-
GitHub won't change: Their OAuth has worked this way for years. Millions of integrations depend on this behavior.
-
MCP promotes GitHub integration: The official GitHub MCP server uses GitHub OAuth. Users following the docs will hit this issue if they misconfigure their OAuth client.
Suggested Fix
const json: unknown = await response.json();
if (typeof json === 'object' && json !== null && 'error' in json) {
throw await parseErrorResponse(JSON.stringify(json));
}
return OAuthTokensSchema.parse(json);Environment
- SDK version: 1.25.1
- OAuth server: GitHub (
https://github.com/login/oauth/access_token) - MCP client: OpenCode CLI