Skip to content

Conversation

@asoorm
Copy link

@asoorm asoorm commented Jan 7, 2026

fix: OAuth DCR scope field compliance and error handling

Problem

OAuth Dynamic Client Registration (DCR) was sending scope: "" (empty string) when no scopes were discovered, violating OAuth 2.0 RFC 7591. This caused some OAuth servers (like Keycloak) to reject the registration request. Additionally, OAuth errors were not being caught or displayed to users.

Root Cause

When scope discovery failed (e.g., due to CORS), the clientMetadata getter in InspectorOAuthClientProvider was setting scope: this.scope ?? "", which sent an empty string instead of omitting the field entirely as required by the OAuth 2.0 specification.

Changes

1. Fix OAuth Client Metadata Scope Field

File: client/src/lib/auth.ts (line 155)

Modified clientMetadata to conditionally include the scope field only when it's defined and non-empty, per OAuth 2.0 RFC 7591 specification.

get clientMetadata(): OAuthClientMetadata {
  const metadata: OAuthClientMetadata = {
    redirect_uris: this.redirect_uris,
    token_endpoint_auth_method: "none",
    grant_types: ["authorization_code", "refresh_token"],
    response_types: ["code"],
    client_name: "MCP Inspector",
    client_uri: "https://github.com/modelcontextprotocol/inspector",
  };

  // Only include scope if it's defined and non-empty
  // Per OAuth spec, omit the scope field entirely if no scopes are requested
  if (this.scope) {
    metadata.scope = this.scope;
  }

  return metadata;
}

2. Improve OAuth Error Handling

File: client/src/lib/hooks/useConnection.ts (line 396)

Added try-catch block around auth() call in handleAuthError to catch OAuth failures and display user-friendly error messages via toast notifications.

try {
  const result = await auth(serverAuthProvider, {
    serverUrl: sseUrl,
    scope,
  });
  return result === "AUTHORIZED";
} catch (authError) {
  // Show user-friendly error message for OAuth failures
  toast({
    title: "OAuth Authentication Failed",
    description:
      authError instanceof Error ? authError.message : String(authError),
    variant: "destructive",
  });
  return false;
}

Testing

  • Tested with OAuth-protected MCP server (Keycloak)
  • OAuth DCR now works correctly with undefined scopes
  • Clear error messages displayed when OAuth fails
  • No breaking changes to existing functionality

Impact

  • OAuth servers that reject empty scope strings (like Keycloak) now work correctly
  • Users see clear, actionable error messages when OAuth authentication fails
  • Complies with OAuth 2.0 RFC 7591 specification

Related Issue

Fixes (follow-up to PR #999)

Note

This PR builds on top of PR #999 which fixed the initial OAuth flow trigger issue. This PR addresses the remaining OAuth spec compliance and error handling improvements.

@asoorm
Copy link
Author

asoorm commented Jan 7, 2026

@cliffhall PTAL

@asoorm asoorm force-pushed the fix/982-direct-oauth-connection-failure branch from 5601411 to 5858ab3 Compare January 8, 2026 08:16
@asoorm asoorm force-pushed the fix/982-direct-oauth-connection-failure branch from 5858ab3 to 87fff8b Compare January 8, 2026 08:19
@asoorm asoorm changed the title fix: direct OAuth connections failing in v0.18.0 fix: OAuth DCR scope field compliance and error handling Jan 8, 2026
@asoorm
Copy link
Author

asoorm commented Jan 8, 2026

@cliffhall Thanks for merging #999 - this PR is now a followup!

I've rebased this PR on the latest main. This PR addresses outstanding OAuth spec compliance issue where the scope field was being sent as an empty string instead of being omitted entirely (per RFC 7591), which caused some OAuth servers like Keycloak to reject the DCR request.

It also adds better error handling to display user-friendly messages when OAuth fails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants