Merge branch 'origin/main' into feature/elicitations

Resolved conflicts by adopting the improved form input handling from main:
- Standardized JsonSchemaType.required to only accept string arrays (JSON Schema standard)
- Adopted enhanced object and array rendering with proper nested support
- Improved boolean field rendering (removed extra wrapper div)
- Enhanced array handling with add/remove functionality
- Simplified required field validation logic

This maintains elicitation functionality while benefiting from the form input fixes.
This commit is contained in:
Alex Andru 2025-07-03 16:14:21 +02:00
commit 19ff315dd1
2 changed files with 1363 additions and 393 deletions

View file

@ -30,6 +30,7 @@ export interface AuthDebuggerState {
oauthStep: OAuthStep;
resourceMetadata: OAuthProtectedResourceMetadata | null;
resourceMetadataError: Error | null;
resource: URL | null;
authServerUrl: URL | null;
oauthMetadata: OAuthMetadata | null;
oauthClientInfo: OAuthClientInformationFull | OAuthClientInformation | null;
@ -47,6 +48,7 @@ export const EMPTY_DEBUGGER_STATE: AuthDebuggerState = {
oauthMetadata: null,
resourceMetadata: null,
resourceMetadataError: null,
resource: null,
authServerUrl: null,
oauthClientInfo: null,
authorizationUrl: null,

View file

@ -6,6 +6,7 @@ import {
startAuthorization,
exchangeAuthorization,
discoverOAuthProtectedResourceMetadata,
selectResourceURL,
} from "@modelcontextprotocol/sdk/client/auth.js";
import {
OAuthMetadataSchema,
@ -29,17 +30,15 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
metadata_discovery: {
canTransition: async () => true,
execute: async (context) => {
let authServerUrl = new URL(context.serverUrl);
// Default to discovering from the server's URL
let authServerUrl = new URL("/", context.serverUrl);
let resourceMetadata: OAuthProtectedResourceMetadata | null = null;
let resourceMetadataError: Error | null = null;
try {
resourceMetadata = await discoverOAuthProtectedResourceMetadata(
context.serverUrl,
);
if (
resourceMetadata &&
resourceMetadata.authorization_servers?.length
) {
if (resourceMetadata?.authorization_servers?.length) {
authServerUrl = new URL(resourceMetadata.authorization_servers[0]);
}
} catch (e) {
@ -50,6 +49,13 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
}
}
const resource: URL | undefined = await selectResourceURL(
context.serverUrl,
context.provider,
// we default to null, so swap it for undefined if not set
resourceMetadata ?? undefined,
);
const metadata = await discoverOAuthMetadata(authServerUrl);
if (!metadata) {
throw new Error("Failed to discover OAuth metadata");
@ -58,6 +64,7 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
context.provider.saveServerMetadata(parsedMetadata);
context.updateState({
resourceMetadata,
resource,
resourceMetadataError,
authServerUrl,
oauthMetadata: parsedMetadata,
@ -113,6 +120,7 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
clientInformation,
redirectUrl: context.provider.redirectUrl,
scope,
resource: context.state.resource ?? undefined,
},
);
@ -163,6 +171,7 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
authorizationCode: context.state.authorizationCode,
codeVerifier,
redirectUri: context.provider.redirectUrl,
resource: context.state.resource ?? undefined,
});
context.provider.saveTokens(tokens);