diff --git a/client/src/lib/__tests__/auth.test.ts b/client/src/lib/__tests__/auth.test.ts index 329b7f027..101198054 100644 --- a/client/src/lib/__tests__/auth.test.ts +++ b/client/src/lib/__tests__/auth.test.ts @@ -85,6 +85,39 @@ describe("discoverScopes", () => { }, expected: "read", }, + { + name: "uses authorization_servers URL from resource metadata for discovery", + mockResolves: baseMetadata, + serverUrl: "https://mcp-server.com", + resourceMetadata: { + resource: "https://mcp-server.com", + authorization_servers: ["https://auth-server.com/"], + }, + expected: "read write", + expectedCallUrl: "https://auth-server.com/", + }, + { + name: "uses authorization_servers URL with path for discovery", + mockResolves: baseMetadata, + serverUrl: "https://mcp-server.com", + resourceMetadata: { + resource: "https://mcp-server.com", + authorization_servers: ["https://auth-server.com/realms/my-realm/"], + }, + expected: "read write", + expectedCallUrl: "https://auth-server.com/realms/my-realm/", + }, + { + name: "falls back to serverUrl when authorization_servers is empty", + mockResolves: baseMetadata, + serverUrl: "https://mcp-server.com", + resourceMetadata: { + resource: "https://mcp-server.com", + authorization_servers: [], + }, + expected: "read write", + expectedCallUrl: "https://mcp-server.com/", + }, ]; const undefinedCases = [ diff --git a/client/src/lib/auth.ts b/client/src/lib/auth.ts index 879936104..e1ed8d639 100644 --- a/client/src/lib/auth.ts +++ b/client/src/lib/auth.ts @@ -24,9 +24,12 @@ export const discoverScopes = async ( resourceMetadata?: OAuthProtectedResourceMetadata, ): Promise => { try { - const metadata = await discoverAuthorizationServerMetadata( - new URL("/", serverUrl), - ); + // Use the authorization server URL from resource metadata if available, + // otherwise fall back to the MCP server URL + const authServerUrl = resourceMetadata?.authorization_servers?.length + ? new URL(resourceMetadata.authorization_servers[0]) + : new URL("/", serverUrl); + const metadata = await discoverAuthorizationServerMetadata(authServerUrl); // Prefer resource metadata scopes, but fall back to OAuth metadata if empty const resourceScopes = resourceMetadata?.scopes_supported;