From db86ea871261d4ba4e8ea5837402ad90f1d1087c Mon Sep 17 00:00:00 2001 From: "Bhavya ." Date: Thu, 21 May 2026 01:01:58 +0530 Subject: [PATCH 1/3] umi support for custom mcp server --- .../createConnection/createConnection.tsx | 28 +++++- .../createConnectionInternal.tsx | 5 +- .../recommendation/browse/mcpToolWizard.tsx | 94 ++++++++++++++++++- 3 files changed, 124 insertions(+), 3 deletions(-) diff --git a/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnection.tsx b/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnection.tsx index 5e00d564d51..f477160f364 100644 --- a/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnection.tsx +++ b/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnection.tsx @@ -232,6 +232,15 @@ export const CreateConnection = (props: CreateConnectionProps) => { const isMultiAuth = useMemo(() => (connectionParameterSets?.values?.length ?? 0) > 0, [connectionParameterSets?.values]); const showMultiAuthDropdown = useMemo(() => (connectionParameterSets?.values?.length ?? 0) > 1, [connectionParameterSets?.values]); + // Check if the currently selected multi-auth parameter set is a managed identity type. + // When true, we show the identity picker instead of the hidden managedIdentity parameter. + const isMultiAuthManagedIdentitySet = useMemo(() => { + if (!isMultiAuth) { + return false; + } + return Object.values(multiAuthParams).some((param) => param.type === ConnectionParameterTypes.managedIdentity); + }, [isMultiAuth, multiAuthParams]); + const hasOnlyOnPremGateway = useMemo( () => (connectorCapabilities?.includes(Capabilities.gateway) && !connectorCapabilities?.includes(Capabilities.cloud)) ?? false, [connectorCapabilities] @@ -439,6 +448,9 @@ export const CreateConnection = (props: CreateConnectionProps) => { if (legacyManagedIdentitySelected && !selectedManagedIdentity) { return false; } + if (isMultiAuthManagedIdentitySet && !selectedManagedIdentity) { + return false; + } if (Object.keys(capabilityEnabledParameters ?? {}).length === 0) { return true; } @@ -497,7 +509,7 @@ export const CreateConnection = (props: CreateConnectionProps) => { } const alternativeParameterValues = legacyManagedIdentitySelected ? {} : undefined; - const identitySelected = legacyManagedIdentitySelected ? selectedManagedIdentity : undefined; + const identitySelected = legacyManagedIdentitySelected || isMultiAuthManagedIdentitySet ? selectedManagedIdentity : undefined; return createConnectionCallback?.( showNameInput ? connectionDisplayName : undefined, @@ -919,6 +931,20 @@ export const CreateConnection = (props: CreateConnectionProps) => { /> )} + {/* Multi-auth Managed Identity Selection (for MCP custom connectors with MI parameter set) */} + {isMultiAuthManagedIdentitySet && ( +
+
+ )} + {/* OAuth tenant ID selection */} {showTenantIdSelection && ( { const { classes, @@ -68,6 +70,7 @@ export const CreateConnectionInternal = (props: { operationManifest, workflowKind, workflowMetadata, + connectionParameterSetsOverride, } = props; const dispatch = useDispatch(); @@ -320,7 +323,7 @@ export const CreateConnectionInternal = (props: { classes={classes} connector={connector} connectionParameterSets={getSupportedParameterSets( - connector.properties.connectionParameterSets, + connector.properties.connectionParameterSets ?? connectionParameterSetsOverride, operationType, connector.properties.capabilities )} diff --git a/libs/designer-v2/src/lib/ui/panel/recommendation/browse/mcpToolWizard.tsx b/libs/designer-v2/src/lib/ui/panel/recommendation/browse/mcpToolWizard.tsx index 1fca4777b28..a6dbf74d546 100644 --- a/libs/designer-v2/src/lib/ui/panel/recommendation/browse/mcpToolWizard.tsx +++ b/libs/designer-v2/src/lib/ui/panel/recommendation/browse/mcpToolWizard.tsx @@ -30,10 +30,95 @@ import { isConnectionValid, getAssistedConnectionProps } from '../../../../core/ import { addOperation } from '../../../../core/actions/bjsworkflow/add'; import { useMcpToolWizardStyles } from './styles/McpToolWizard.styles'; import { useConnector } from '../../../../core/state/connection/connectionSelector'; -import type { Connection, DiscoveryOperation, DiscoveryResultTypes } from '@microsoft/logic-apps-shared'; +import type { Connection, ConnectionParameterSets, DiscoveryOperation, DiscoveryResultTypes } from '@microsoft/logic-apps-shared'; import { useQuery } from '@tanstack/react-query'; import { MCP_CLIENT_CONNECTOR_ID } from '../helpers'; +/** + * Connection parameter sets for MCP servers. Used as a fallback when a custom connector + * doesn't have its own connectionParameterSets, so users can select auth type + * (None, Basic, Managed Identity, OAuth, etc.) during connection creation. + */ +const mcpConnectionParameterSets: ConnectionParameterSets = { + uiDefinition: { + displayName: 'Authentication type', + description: 'The authentication type to use.', + }, + values: [ + { + name: 'None', + parameters: {}, + uiDefinition: { displayName: 'None', description: 'None' }, + }, + { + name: 'Basic', + parameters: { + username: { + type: 'string', + uiDefinition: { + displayName: 'Username', + constraints: { propertyPath: ['authentication'], required: 'true' }, + description: 'Username', + }, + }, + password: { + type: 'securestring', + uiDefinition: { + displayName: 'Password', + constraints: { propertyPath: ['authentication'], required: 'true' }, + description: 'Password', + }, + }, + }, + uiDefinition: { displayName: 'Basic', description: 'Basic authentication' }, + }, + { + name: 'Key', + parameters: { + key: { + type: 'securestring', + uiDefinition: { + displayName: 'Key', + constraints: { required: 'true', propertyPath: ['authentication'] }, + description: 'Key', + }, + }, + keyHeaderName: { + type: 'string', + uiDefinition: { + displayName: 'Key Header Name', + constraints: { propertyPath: ['authentication'] }, + description: 'Key header name', + }, + }, + }, + uiDefinition: { displayName: 'Key', description: 'Key authentication' }, + }, + { + name: 'ManagedServiceIdentity', + parameters: { + identity: { + type: 'string', + uiDefinition: { + displayName: 'Managed identity', + constraints: { required: 'false', editor: 'identitypicker', propertyPath: ['authentication'] }, + description: 'The managed identity to use for authentication', + }, + }, + audience: { + type: 'string', + uiDefinition: { + displayName: 'Audience', + constraints: { required: 'true', propertyPath: ['authentication'] }, + description: 'The audience', + }, + }, + }, + uiDefinition: { displayName: 'Managed identity', description: 'Managed identity authentication' }, + }, + ], +}; + export const McpToolWizard = () => { const intl = useIntl(); const dispatch = useDispatch(); @@ -603,6 +688,12 @@ export const McpToolWizard = () => { // Managed MCP servers use the default Azure connection flow const connectionMetadata = isManagedMcpServer ? undefined : { type: ConnectionType.Mcp, required: true }; + // For managed MCP servers (custom connectors), the connector from Azure API + // may not include connectionParameterSets (auth options). Provide MCP auth + // parameter sets as a fallback so users can select auth type (None, Basic, + // Managed Identity, etc.) when creating a connection. + const parameterSetsOverride = isManagedMcpServer ? mcpConnectionParameterSets : undefined; + return (
{ onConnectionCreated={handleConnectionCreated} onConnectionCancelled={handleConnectionCancelled} description=" " + connectionParameterSetsOverride={parameterSetsOverride} />
); From 01e292a0d9bf2d6540bf0c866b403391e13495b4 Mon Sep 17 00:00:00 2001 From: "Bhavya ." Date: Thu, 21 May 2026 15:58:19 +0530 Subject: [PATCH 2/3] resolve comments --- .../createConnection/createConnection.tsx | 16 +++++++++++++--- .../formInputs/legacyManagedIdentityPicker.tsx | 4 +++- .../recommendation/browse/mcpToolWizard.tsx | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnection.tsx b/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnection.tsx index f477160f364..2dc580bfba7 100644 --- a/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnection.tsx +++ b/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnection.tsx @@ -238,7 +238,11 @@ export const CreateConnection = (props: CreateConnectionProps) => { if (!isMultiAuth) { return false; } - return Object.values(multiAuthParams).some((param) => param.type === ConnectionParameterTypes.managedIdentity); + return Object.values(multiAuthParams).some( + (param) => + param.type === ConnectionParameterTypes.managedIdentity || + equals(param.uiDefinition?.constraints?.default, 'managedserviceidentity') + ); }, [isMultiAuth, multiAuthParams]); const hasOnlyOnPremGateway = useMemo( @@ -542,6 +546,7 @@ export const CreateConnection = (props: CreateConnectionProps) => { operationParameterValues, isUsingDynamicConnection, isDynamicConnectionOptionValidForConnector, + isMultiAuthManagedIdentitySet, ]); // INTL STRINGS @@ -938,10 +943,15 @@ export const CreateConnection = (props: CreateConnectionProps) => { className="label" isRequiredField={true} text={legacyManagedIdentityLabelText} - htmlFor={'connection-param-set-select'} + htmlFor={'multi-auth-managed-identity-select'} + disabled={isLoading} + /> + - )} diff --git a/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/formInputs/legacyManagedIdentityPicker.tsx b/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/formInputs/legacyManagedIdentityPicker.tsx index 44175422b2d..cf675e42d58 100644 --- a/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/formInputs/legacyManagedIdentityPicker.tsx +++ b/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/formInputs/legacyManagedIdentityPicker.tsx @@ -4,13 +4,14 @@ import { useEffect, useMemo, useRef } from 'react'; import { useIntl } from 'react-intl'; interface LegacyManagedIdentityDropdownProps { + id?: string; identity?: ManagedIdentity; onChange: (event: any, item?: IDropdownOption) => void; disabled?: boolean; } const LegacyManagedIdentityDropdown = (props: LegacyManagedIdentityDropdownProps) => { - const { identity, onChange, disabled } = props; + const { id, identity, onChange, disabled } = props; const intl = useIntl(); const dropdownOptions = useMemo(() => getIdentityDropdownOptions(identity, intl), [identity, intl]); @@ -29,6 +30,7 @@ const LegacyManagedIdentityDropdown = (props: LegacyManagedIdentityDropdownProps return ( Date: Sat, 23 May 2026 00:29:05 +0530 Subject: [PATCH 3/3] resolve comments --- .../createConnection/createConnection.tsx | 24 +++++++++---------- .../createConnectionInternal.tsx | 3 +++ .../recommendation/browse/mcpToolWizard.tsx | 1 + 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnection.tsx b/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnection.tsx index 2dc580bfba7..f28a8977930 100644 --- a/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnection.tsx +++ b/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnection.tsx @@ -115,6 +115,7 @@ export interface CreateConnectionProps { operationManifest?: OperationManifest; workflowKind?: string; workflowMetadata?: ConsumptionWorkflowMetadata; + enableManagedIdentityPicker?: boolean; } export const CreateConnection = (props: CreateConnectionProps) => { @@ -232,19 +233,6 @@ export const CreateConnection = (props: CreateConnectionProps) => { const isMultiAuth = useMemo(() => (connectionParameterSets?.values?.length ?? 0) > 0, [connectionParameterSets?.values]); const showMultiAuthDropdown = useMemo(() => (connectionParameterSets?.values?.length ?? 0) > 1, [connectionParameterSets?.values]); - // Check if the currently selected multi-auth parameter set is a managed identity type. - // When true, we show the identity picker instead of the hidden managedIdentity parameter. - const isMultiAuthManagedIdentitySet = useMemo(() => { - if (!isMultiAuth) { - return false; - } - return Object.values(multiAuthParams).some( - (param) => - param.type === ConnectionParameterTypes.managedIdentity || - equals(param.uiDefinition?.constraints?.default, 'managedserviceidentity') - ); - }, [isMultiAuth, multiAuthParams]); - const hasOnlyOnPremGateway = useMemo( () => (connectorCapabilities?.includes(Capabilities.gateway) && !connectorCapabilities?.includes(Capabilities.cloud)) ?? false, [connectorCapabilities] @@ -419,6 +407,15 @@ export const CreateConnection = (props: CreateConnectionProps) => { return output ?? {}; }, [enabledCapabilities, parametersByCapability]); + // Show MI picker only when explicitly enabled by the caller (e.g. MCP wizard) AND + // there are no visible parameters (form would be empty without it). + const isMultiAuthManagedIdentitySet = useMemo(() => { + if (!props.enableManagedIdentityPicker || !isMultiAuth) { + return false; + } + return Object.keys(capabilityEnabledParameters ?? {}).length === 0; + }, [props.enableManagedIdentityPicker, isMultiAuth, capabilityEnabledParameters]); + // Don't show name for simple connections const showNameInput = useMemo(() => { const isMcpClientConnection = connectorId?.toLowerCase().includes('mcpclient'); @@ -467,6 +464,7 @@ export const CreateConnection = (props: CreateConnectionProps) => { resourceSelectorProps, legacyManagedIdentitySelected, selectedManagedIdentity, + isMultiAuthManagedIdentitySet, capabilityEnabledParameters, parameterValues, ]); diff --git a/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnectionInternal.tsx b/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnectionInternal.tsx index e11eec064ae..0fd43933260 100644 --- a/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnectionInternal.tsx +++ b/libs/designer-v2/src/lib/ui/panel/connectionsPanel/createConnection/createConnectionInternal.tsx @@ -48,6 +48,7 @@ export const CreateConnectionInternal = (props: { workflowKind?: string; workflowMetadata?: { agentType?: string }; connectionParameterSetsOverride?: ConnectionParameterSets; + enableManagedIdentityPicker?: boolean; }) => { const { classes, @@ -71,6 +72,7 @@ export const CreateConnectionInternal = (props: { workflowKind, workflowMetadata, connectionParameterSetsOverride, + enableManagedIdentityPicker, } = props; const dispatch = useDispatch(); @@ -348,6 +350,7 @@ export const CreateConnectionInternal = (props: { operationManifest={operationManifest} workflowKind={workflowKind} workflowMetadata={workflowMetadata} + enableManagedIdentityPicker={enableManagedIdentityPicker} /> ); }; diff --git a/libs/designer-v2/src/lib/ui/panel/recommendation/browse/mcpToolWizard.tsx b/libs/designer-v2/src/lib/ui/panel/recommendation/browse/mcpToolWizard.tsx index ad983470d97..d88acfacdc3 100644 --- a/libs/designer-v2/src/lib/ui/panel/recommendation/browse/mcpToolWizard.tsx +++ b/libs/designer-v2/src/lib/ui/panel/recommendation/browse/mcpToolWizard.tsx @@ -709,6 +709,7 @@ export const McpToolWizard = () => { onConnectionCancelled={handleConnectionCancelled} description=" " connectionParameterSetsOverride={parameterSetsOverride} + enableManagedIdentityPicker={isManagedMcpServer} /> );