diff --git a/web/package.json b/web/package.json index 7999c74e9..cdf2d8d8b 100644 --- a/web/package.json +++ b/web/package.json @@ -37,6 +37,7 @@ "marked": "^9.1.2", "next": "14.2.3", "next-themes": "^0.2.1", + "npx-scope-finder": "^1.3.0", "openai": "^4.90.0", "postcss": "8.4.31", "postcss-url": "10.1.3", diff --git a/web/screens/Settings/MCP/configuration.tsx b/web/screens/Settings/MCP/configuration.tsx new file mode 100644 index 000000000..b829066d2 --- /dev/null +++ b/web/screens/Settings/MCP/configuration.tsx @@ -0,0 +1,98 @@ +import React, { useState, useEffect, useCallback } from 'react' + +import { Button, TextArea } from '@janhq/joi' +import { useAtomValue } from 'jotai' + +import { janDataFolderPathAtom } from '@/helpers/atoms/AppConfig.atom' + +const MCPConfiguration = () => { + const janDataFolderPath = useAtomValue(janDataFolderPathAtom) + const [configContent, setConfigContent] = useState('') + const [isSaving, setIsSaving] = useState(false) + const [error, setError] = useState('') + const [success, setSuccess] = useState('') + + const readConfigFile = useCallback(async () => { + try { + // Read the file + const content = await window.core?.api.getMcpConfigs() + setConfigContent(content) + + setError('') + } catch (err) { + console.error('Error reading config file:', err) + setError('Failed to read config file') + } + }, [janDataFolderPath]) + + useEffect(() => { + if (janDataFolderPath) { + readConfigFile() + } + }, [janDataFolderPath, readConfigFile]) + + const saveConfigFile = useCallback(async () => { + try { + setIsSaving(true) + setSuccess('') + setError('') + + // Validate JSON + try { + JSON.parse(configContent) + } catch (err) { + setError('Invalid JSON format') + setIsSaving(false) + return + } + await window.core?.api?.saveMcpConfigs({ configs: configContent }) + + setSuccess('Config saved successfully') + setIsSaving(false) + } catch (err) { + console.error('Error saving config file:', err) + setError('Failed to save config file') + setIsSaving(false) + } + }, [janDataFolderPath, configContent]) + + return ( + <> + {error && ( +
+ {error} +
+ )} + + {success && ( +
+ {success} +
+ )} + +
+ +