Skip to content

Commit fd56c25

Browse files
committed
address stray 404
1 parent 5f51dc2 commit fd56c25

2 files changed

Lines changed: 45 additions & 5 deletions

File tree

  • apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/mcp/mcp.tsx

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ import {
1313
Skeleton,
1414
Textarea,
1515
} from '@/components/emcn'
16+
import { ApiClientError } from '@/lib/api/client/errors'
1617
import { cn } from '@/lib/core/utils/cn'
1718
import {
1819
extractDescriptionOverrides,
20+
extractInputFormatFromBlocks,
1921
generateToolInputSchema,
2022
getMeaningfulWorkflowDescription,
2123
sanitizeToolName,
@@ -35,6 +37,7 @@ import {
3537
} from '@/hooks/queries/workflow-mcp-servers'
3638
import { EMPTY_SUBBLOCK_VALUES, useSubBlockStore } from '@/stores/workflows/subblock/store'
3739
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
40+
import type { WorkflowState } from '@/stores/workflows/workflow/types'
3841

3942
const logger = createLogger('McpToolDeploy')
4043

@@ -54,6 +57,7 @@ interface McpDeployProps {
5457
workflowName: string
5558
workflowDescription?: string | null
5659
isDeployed: boolean
60+
deployedState?: WorkflowState | null
5761
onAddedToServer?: () => void
5862
onSubmittingChange?: (submitting: boolean) => void
5963
onCanSaveChange?: (canSave: boolean) => void
@@ -122,6 +126,7 @@ export function McpDeploy({
122126
workflowName,
123127
workflowDescription,
124128
isDeployed,
129+
deployedState,
125130
onAddedToServer,
126131
onSubmittingChange,
127132
onCanSaveChange,
@@ -153,7 +158,7 @@ export function McpDeploy({
153158
(state) => (workflowId ? state.workflowValues[workflowId] : undefined) ?? EMPTY_SUBBLOCK_VALUES
154159
)
155160

156-
const inputFormat = useMemo((): NormalizedField[] => {
161+
const liveInputFormat = useMemo((): NormalizedField[] => {
157162
if (!starterBlockId) return []
158163

159164
const storeValue = subBlockValues[starterBlockId]?.inputFormat
@@ -165,6 +170,19 @@ export function McpDeploy({
165170
return normalizeInputFormatValue(blockValue) as NormalizedField[]
166171
}, [starterBlockId, subBlockValues, blocks])
167172

173+
// The served tool is built from the DEPLOYED Start block and the server materializes overrides
174+
// against it, so base the form on the deployed inputs (falling back to the live editor only while
175+
// the deployed state loads) to keep the modal's defaults and override classification matching what
176+
// is actually served.
177+
const deployedInputFormat = useMemo((): NormalizedField[] => {
178+
const deployedBlocks = deployedState?.blocks
179+
if (!deployedBlocks) return []
180+
return (extractInputFormatFromBlocks(deployedBlocks as Record<string, unknown>) ??
181+
[]) as NormalizedField[]
182+
}, [deployedState])
183+
184+
const inputFormat = deployedState ? deployedInputFormat : liveInputFormat
185+
168186
const [toolName, setToolName] = useState(() => sanitizeToolName(workflowName))
169187
const [toolDescription, setToolDescription] = useState('')
170188
const workflowDescriptionFallback = getMeaningfulWorkflowDescription(
@@ -238,7 +256,9 @@ export function McpDeploy({
238256
} | null>(null)
239257

240258
useEffect(() => {
241-
if (savedValues) return
259+
// Wait for the deployed state so the legacy migration diffs against the deployed base (what the
260+
// server uses), not the live editor — otherwise unpublished Start-block edits mis-classify.
261+
if (savedValues || !deployedState) return
242262

243263
for (const server of servers) {
244264
const toolInfo = serverToolsMap[server.id]
@@ -268,7 +288,7 @@ export function McpDeploy({
268288
break
269289
}
270290
}
271-
}, [servers, serverToolsMap, startBlockDescriptions, inputFormat, savedValues])
291+
}, [servers, serverToolsMap, startBlockDescriptions, inputFormat, deployedState, savedValues])
272292

273293
const selectedServerIdsForForm = draftSelectedServerIds ?? selectedServerIds
274294

@@ -400,8 +420,27 @@ export function McpDeploy({
400420
})
401421
} catch (error) {
402422
const serverName = servers.find((s) => s.id === serverId)?.name || serverId
403-
errors.push(`Failed to update on ${serverName}`)
404-
logger.error(`Failed to update tool on server ${serverId}:`, error)
423+
// The tool can be removed out-of-band (undeploying a workflow deletes its MCP tools), so
424+
// a stale-cache update may hit a missing tool — re-create it instead of failing the save.
425+
if (error instanceof ApiClientError && error.status === 404) {
426+
try {
427+
const recreated = await addToolMutation.mutateAsync({
428+
workspaceId,
429+
serverId,
430+
workflowId,
431+
toolName: toolName.trim(),
432+
toolDescription: toolDescriptionForSave,
433+
parameterDescriptionOverrides,
434+
})
435+
addedEntries[serverId] = { tool: recreated, isLoading: false }
436+
} catch (recreateError) {
437+
errors.push(`Failed to update on ${serverName}`)
438+
logger.error(`Failed to re-add tool on server ${serverId}:`, recreateError)
439+
}
440+
} else {
441+
errors.push(`Failed to update on ${serverName}`)
442+
logger.error(`Failed to update tool on server ${serverId}:`, error)
443+
}
405444
}
406445
}
407446
}

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/deploy-modal.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ export function DeployModal({
669669
workflowName={workflowMetadata?.name || 'Workflow'}
670670
workflowDescription={workflowMetadata?.description}
671671
isDeployed={isDeployed}
672+
deployedState={deployedState}
672673
onSubmittingChange={setMcpToolSubmitting}
673674
onCanSaveChange={setMcpToolCanSave}
674675
onActiveServerChange={setMcpActiveServerId}

0 commit comments

Comments
 (0)