fix: add origin-only well-known URL fallback for OAuth discovery

Some MCP servers (e.g., eschat.microsoft.com/mcp) serve their
OAuth Protected Resource Metadata at the origin without the path
suffix. Add a third candidate URL that strips the path, matching
VS Code's discovery behavior.

Tried in order:
1. RFC 9728: {origin}/.well-known/{suffix}{path}
2. Appended: {origin}{path}/.well-known/{suffix}
3. Origin-only: {origin}/.well-known/{suffix}

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-28 19:53:25 +01:00
co-authored by Copilot
parent b985a06df3
commit 216b17b2ac
3 changed files with 41 additions and 3 deletions
+13 -2
View File
@@ -5,7 +5,7 @@ import electron from 'electron';
import type { McpOauthStaticClientConfig } from '@shared/domain/mcpAuth';
import { storeToken, buildWellKnownUrl, buildWellKnownUrlFallback, type McpOAuthToken } from './mcpTokenStore';
import { storeToken, buildWellKnownUrl, buildWellKnownUrlFallback, buildWellKnownUrlOriginOnly, type McpOAuthToken } from './mcpTokenStore';
const { shell } = electron;
@@ -228,7 +228,18 @@ interface AuthServerMetadata {
async function fetchWellKnownMetadata(baseUrl: string, suffix: string): Promise<Record<string, unknown> | undefined> {
const rfcUrl = buildWellKnownUrl(baseUrl, suffix);
const fallbackUrl = buildWellKnownUrlFallback(baseUrl, suffix);
const urls = rfcUrl === fallbackUrl ? [rfcUrl] : [rfcUrl, fallbackUrl];
const originOnlyUrl = buildWellKnownUrlOriginOnly(baseUrl, suffix);
// Deduplicate: RFC path, appended fallback, then origin-only (for servers
// that serve metadata at the origin without the resource path suffix).
const seen = new Set<string>();
const urls: string[] = [];
for (const url of [rfcUrl, fallbackUrl, originOnlyUrl]) {
if (!seen.has(url)) {
seen.add(url);
urls.push(url);
}
}
for (const url of urls) {
try {
+5
View File
@@ -66,3 +66,8 @@ export function buildWellKnownUrlFallback(baseUrl: string, wellKnownSuffix: stri
const base = baseUrl.replace(/\/+$/, '');
return `${base}/.well-known/${wellKnownSuffix}`;
}
export function buildWellKnownUrlOriginOnly(baseUrl: string, wellKnownSuffix: string): string {
const parsed = new URL(baseUrl);
return `${parsed.origin}/.well-known/${wellKnownSuffix}`;
}