Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions client/src/lib/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,38 @@ export class InspectorOAuthClientProvider implements OAuthClientProvider {
return getScopeFromSessionStorage(this.serverUrl);
}

/**
* Suppress the RFC 8707 `resource` parameter in authorization requests.
*
* The MCP TypeScript SDK reads the `resource` field from RFC 9728 Protected
* Resource Metadata (PRM) and by default forwards it as a `resource` query
* parameter on the /authorize URL. However, RFC 8707 defines the `resource`
* parameter as OPTIONAL — authorization servers are not required to support
* it. Some servers actively reject the parameter: specifically, Azure Entra
* ID v2.0 returns AADSTS9010010 ("The resource parameter … doesn't match …
* the requested scopes") when `resource` is present, even when the PRM
* `resource` value is a valid RFC 9728-compliant server URL.
*
* By implementing this hook and returning `undefined`, we tell the SDK to
* omit the `resource` parameter entirely. The authorization server identity
* and supported scopes are still fully discovered from PRM via the
* `authorization_servers` and `scopes_supported` fields, so discovery is
* unaffected.
*
* Trade-off: In multi-resource environments (one authorization server
* protecting several resource servers), the `resource` parameter helps
* audience-restrict tokens to a specific resource. For the Inspector — a
* single-connection developer tool where the scope already encodes the
* target resource — omitting it is safe and compatible with all major
* authorization servers (Keycloak, Auth0, Okta, PingFederate, Entra ID).
*/
validateResourceURL(
_serverUrl: URL,
_resourceMetadataUrl?: string,
): Promise<URL | undefined> {
return Promise.resolve(undefined);
}

get redirectUrl() {
return window.location.origin + "/oauth/callback";
}
Expand Down