diff --git a/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/CustomNode/useCustomNode.tsx b/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/CustomNode/useCustomNode.tsx index cddfbabc52..6445a339fe 100644 --- a/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/CustomNode/useCustomNode.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/CustomNode/useCustomNode.tsx @@ -9,30 +9,22 @@ import { SpecialBlockID } from "@/lib/autogpt-server-api"; * Build a dynamic input schema for MCP blocks. * * When a tool has been selected (tool_input_schema is populated), the block - * should render: - * 1. The credentials field (from the static schema) - * 2. The selected tool's input parameters (from tool_input_schema) + * renders only the selected tool's input parameters. Credentials are NOT + * included because authentication is already handled by the MCP dialog's + * OAuth flow and stored server-side. * * Static fields like server_url, selected_tool, available_tools, and * tool_arguments are hidden because they're pre-configured from the dialog. */ function buildMCPInputSchema( - staticSchema: Record, toolInputSchema: Record, ): Record { - const credentialsProp = staticSchema.properties?.credentials; - const staticRequired = staticSchema.required ?? []; - return { type: "object", properties: { - ...(credentialsProp ? { credentials: credentialsProp } : {}), ...(toolInputSchema.properties ?? {}), }, - required: [ - ...staticRequired.filter((r: string) => r === "credentials"), - ...(toolInputSchema.required ?? []), - ], + required: [...(toolInputSchema.required ?? [])], }; } @@ -58,10 +50,7 @@ export const useCustomNode = ({ const currentInputSchema = isAgent ? (data.hardcodedValues.input_schema ?? {}) : isMCPWithTool - ? buildMCPInputSchema( - data.inputSchema, - data.hardcodedValues.tool_input_schema, - ) + ? buildMCPInputSchema(data.hardcodedValues.tool_input_schema) : data.inputSchema; const currentOutputSchema = isAgent ? (data.hardcodedValues.output_schema ?? {}) diff --git a/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/FormCreator.tsx b/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/FormCreator.tsx index ab834a0d04..839552c867 100644 --- a/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/FormCreator.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/build/components/FlowEditor/nodes/FormCreator.tsx @@ -44,12 +44,10 @@ export const FormCreator: React.FC = React.memo( inputs: formData, }; } else if (isMCPWithTool) { - // Separate credentials from tool arguments - const { credentials, ...toolArgs } = formData; + // All form fields are tool arguments (credentials handled by dialog) updatedValues = { ...getHardCodedValues(nodeId), - ...(credentials ? { credentials } : {}), - tool_arguments: toolArgs, + tool_arguments: formData, }; } else { updatedValues = formData; @@ -64,13 +62,7 @@ export const FormCreator: React.FC = React.memo( if (isAgent) { initialValues = hardcodedValues.inputs ?? {}; } else if (isMCPWithTool) { - // Merge credentials + tool_arguments for the combined schema - initialValues = { - ...(hardcodedValues.credentials - ? { credentials: hardcodedValues.credentials } - : {}), - ...(hardcodedValues.tool_arguments ?? {}), - }; + initialValues = hardcodedValues.tool_arguments ?? {}; } else { initialValues = hardcodedValues; } diff --git a/autogpt_platform/frontend/src/app/(platform)/build/components/legacy-builder/CustomNode/CustomNode.tsx b/autogpt_platform/frontend/src/app/(platform)/build/components/legacy-builder/CustomNode/CustomNode.tsx index 3f47c35d68..ffa70db26b 100644 --- a/autogpt_platform/frontend/src/app/(platform)/build/components/legacy-builder/CustomNode/CustomNode.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/build/components/legacy-builder/CustomNode/CustomNode.tsx @@ -222,20 +222,17 @@ export const CustomNode = React.memo( !!data.hardcodedValues?.tool_input_schema?.properties; if (isMCPWithTool) { - const credentialsProp = data.inputSchema?.properties?.credentials; + // Show only the tool's input parameters. Credentials are NOT included + // because authentication is handled by the MCP dialog's OAuth flow + // and stored server-side. const toolSchema = data.hardcodedValues.tool_input_schema; - const staticRequired = data.inputSchema?.required ?? []; data.inputSchema = { type: "object", properties: { - ...(credentialsProp ? { credentials: credentialsProp } : {}), ...(toolSchema.properties ?? {}), }, - required: [ - ...staticRequired.filter((r: string) => r === "credentials"), - ...(toolSchema.required ?? []), - ], + required: [...(toolSchema.required ?? [])], } as BlockIORootSchema; } @@ -562,8 +559,7 @@ export const CustomNode = React.memo( default: const getInputPropKey = (key: string) => { if (nodeType == BlockUIType.AGENT) return `inputs.${key}`; - if (isMCPWithTool && key !== "credentials") - return `tool_arguments.${key}`; + if (isMCPWithTool) return `tool_arguments.${key}`; return key; }; diff --git a/autogpt_platform/frontend/src/app/(platform)/build/components/legacy-builder/MCPToolDialog.tsx b/autogpt_platform/frontend/src/app/(platform)/build/components/legacy-builder/MCPToolDialog.tsx index 2a9f1331e8..dc50f244da 100644 --- a/autogpt_platform/frontend/src/app/(platform)/build/components/legacy-builder/MCPToolDialog.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/build/components/legacy-builder/MCPToolDialog.tsx @@ -66,33 +66,21 @@ export function MCPToolDialog({ const oauthHandledRef = useRef(false); const autoConnectAttemptedRef = useRef(false); - // Attempt auto-connect when dialog opens with a stored server URL + // Pre-fill last used server URL when dialog opens (without auto-connecting) useEffect(() => { if (!open) { autoConnectAttemptedRef.current = false; return; } - const lastUrl = localStorage.getItem(STORAGE_KEY); - if (!lastUrl || autoConnectAttemptedRef.current) return; + if (autoConnectAttemptedRef.current) return; autoConnectAttemptedRef.current = true; - setServerUrl(lastUrl); - setLoading(true); - api - .mcpDiscoverTools(lastUrl) - .then((result) => { - setTools(result.tools); - setServerName(result.server_name); - setStep("tool"); - }) - .catch(() => { - // Stored credential expired or server changed — stay on URL step - }) - .finally(() => { - setLoading(false); - }); - }, [open, api]); + const lastUrl = localStorage.getItem(STORAGE_KEY); + if (lastUrl) { + setServerUrl(lastUrl); + } + }, [open]); // Clean up listeners on unmount useEffect(() => {