feat: add OAuth proxy support to eliminate CORS issues

Add server-side proxy endpoints for OAuth discovery, client registration,
and token exchange to avoid CORS issues when using proxy connection mode.

Server proxy endpoints:
- GET /oauth/resource-metadata - proxies OAuth protected resource metadata
- GET /oauth/metadata - proxies OAuth authorization server metadata
- POST /oauth/register - proxies dynamic client registration
- POST /oauth/token - proxies token exchange

Client changes:
- Construct correct RFC 9728/8414 path-aware well-known URLs client-side
- Route all OAuth discovery through proxy when in proxy connection mode
- Eliminate direct browser fetches that fail with CORS in proxy mode
This commit is contained in:
Ahmet Soormally 2026-02-23 22:45:25 +00:00
commit b083d4e1a0

View file

@ -12,21 +12,31 @@ import { discoverAuthorizationServerMetadata } from "@modelcontextprotocol/sdk/c
import { SESSION_KEYS, getServerSpecificKey } from "./constants";
import { generateOAuthState } from "@/utils/oauthUtils";
import { validateRedirectUrl } from "@/utils/urlValidation";
import { discoverAuthorizationServerMetadataViaProxy } from "./oauth-proxy";
import { InspectorConfig } from "./configurationTypes";
/**
* Discovers OAuth scopes from server metadata, with preference for resource metadata scopes
* @param serverUrl - The MCP server URL
* @param connectionType - Whether to use proxy or direct connection
* @param config - Inspector configuration (needed for proxy mode)
* @param resourceMetadata - Optional resource metadata containing preferred scopes
* @returns Promise resolving to space-separated scope string or undefined
*/
export const discoverScopes = async (
serverUrl: string,
connectionType: "direct" | "proxy",
config: InspectorConfig,
resourceMetadata?: OAuthProtectedResourceMetadata,
): Promise<string | undefined> => {
try {
const metadata = await discoverAuthorizationServerMetadata(
new URL("/", serverUrl),
);
const metadata =
connectionType === "proxy"
? await discoverAuthorizationServerMetadataViaProxy(
new URL(serverUrl),
config,
)
: await discoverAuthorizationServerMetadata(new URL("/", serverUrl));
// Prefer resource metadata scopes, but fall back to OAuth metadata if empty
const resourceScopes = resourceMetadata?.scopes_supported;