'use client' import type { MCPServerDetail, } from '@/app/components/tools/types' import { Button } from '@langgenius/dify-ui/button' import { Dialog, DialogContent } from '@langgenius/dify-ui/dialog' import { RiCloseLine } from '@remixicon/react' import * as React from 'react' import { useTranslation } from 'react-i18next' import Divider from '@/app/components/base/divider' import Textarea from '@/app/components/base/textarea' import MCPServerParamItem from '@/app/components/tools/mcp/mcp-server-param-item' import { webSocketClient } from '@/app/components/workflow/collaboration/core/websocket-manager' import { useCreateMCPServer, useInvalidateMCPServerDetail, useUpdateMCPServer, } from '@/service/use-tools' type ModalProps = { appID: string latestParams?: MCPServerParam[] data?: MCPServerDetail show: boolean onHide: () => void appInfo?: { description?: string } } type MCPServerParam = { variable?: string label?: string type?: string } const MCPServerModal = ({ appID, latestParams = [], data, show, onHide, appInfo, }: ModalProps) => { const { t } = useTranslation() const { mutateAsync: createMCPServer, isPending: creating } = useCreateMCPServer() const { mutateAsync: updateMCPServer, isPending: updating } = useUpdateMCPServer() const invalidateMCPServerDetail = useInvalidateMCPServerDetail() const defaultDescription = data?.description || appInfo?.description || '' const [description, setDescription] = React.useState(defaultDescription) const [params, setParams] = React.useState>(data?.parameters || {}) const handleParamChange = (variable: string, value: string) => { setParams(prev => ({ ...prev, [variable]: value, })) } const getParamValue = () => { const res: Record = {} latestParams.forEach((param) => { if (!param.variable) return const value = params[param.variable] if (value !== undefined) res[param.variable] = value }) return res } const emitMcpServerUpdate = (action: 'created' | 'updated') => { const socket = webSocketClient.getSocket(appID) if (!socket) return const timestamp = Date.now() socket.emit('collaboration_event', { type: 'mcp_server_update', data: { action, timestamp, }, timestamp, }) } const submit = async () => { if (!data) { const payload: { appID: string description?: string parameters: Record } = { appID, parameters: getParamValue(), } if (description.trim()) payload.description = description await createMCPServer(payload) invalidateMCPServerDetail(appID) emitMcpServerUpdate('created') onHide() } else { const payload: { appID: string id: string description: string parameters: Record } = { appID, id: data.id, parameters: getParamValue(), description, } await updateMCPServer(payload) invalidateMCPServerDetail(appID) emitMcpServerUpdate('updated') onHide() } } return ( { if (!open) onHide() }} >
{!data ? t('mcp.server.modal.addTitle', { ns: 'tools' }) : t('mcp.server.modal.editTitle', { ns: 'tools' })}
{t('mcp.server.modal.description', { ns: 'tools' })}
*
{latestParams.length > 0 && (
{t('mcp.server.modal.parameters', { ns: 'tools' })}
{t('mcp.server.modal.parametersTip', { ns: 'tools' })}
{latestParams.map((paramItem) => { if (!paramItem.variable) return null const { variable } = paramItem return ( handleParamChange(variable, value)} /> ) })}
)}
) } export default MCPServerModal