Skip to content

Commit 2bf0dd1

Browse files
authored
fix: omit scope field in OAuth DCR when undefined and improve error handling (#1003)
fix: OAuth DCR scope field compliance Omits the scope field entirely when undefined, per RFC 7591. This allows OAuth servers to assign default scopes instead of registering clients with no scopes. Tested with Keycloak DCR.
1 parent 5a7f996 commit 2bf0dd1

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

client/src/lib/auth.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,22 @@ export class InspectorOAuthClientProvider implements OAuthClientProvider {
153153
}
154154

155155
get clientMetadata(): OAuthClientMetadata {
156-
return {
156+
const metadata: OAuthClientMetadata = {
157157
redirect_uris: this.redirect_uris,
158158
token_endpoint_auth_method: "none",
159159
grant_types: ["authorization_code", "refresh_token"],
160160
response_types: ["code"],
161161
client_name: "MCP Inspector",
162162
client_uri: "https://github.com/modelcontextprotocol/inspector",
163-
scope: this.scope ?? "",
164163
};
164+
165+
// Only include scope if it's defined and non-empty
166+
// Per OAuth spec, omit the scope field entirely if no scopes are requested
167+
if (this.scope) {
168+
metadata.scope = this.scope;
169+
}
170+
171+
return metadata;
165172
}
166173

167174
state(): string | Promise<string> {

client/src/lib/hooks/useConnection.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -393,11 +393,22 @@ export function useConnection({
393393
saveScopeToSessionStorage(sseUrl, scope);
394394
const serverAuthProvider = new InspectorOAuthClientProvider(sseUrl);
395395

396-
const result = await auth(serverAuthProvider, {
397-
serverUrl: sseUrl,
398-
scope,
399-
});
400-
return result === "AUTHORIZED";
396+
try {
397+
const result = await auth(serverAuthProvider, {
398+
serverUrl: sseUrl,
399+
scope,
400+
});
401+
return result === "AUTHORIZED";
402+
} catch (authError) {
403+
// Show user-friendly error message for OAuth failures
404+
toast({
405+
title: "OAuth Authentication Failed",
406+
description:
407+
authError instanceof Error ? authError.message : String(authError),
408+
variant: "destructive",
409+
});
410+
return false;
411+
}
401412
}
402413

403414
return false;

0 commit comments

Comments
 (0)