From 40d63853ecf18ffafd83c1025b1d563c72bbcc12 Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Mon, 14 Apr 2025 15:26:13 +0700 Subject: [PATCH 1/5] chore: initial commit mcp setting --- web/screens/Settings/MCP/index.tsx | 13 +++++++++++++ web/screens/Settings/SettingDetail/index.tsx | 4 ++++ web/screens/Settings/index.tsx | 1 + 3 files changed, 18 insertions(+) create mode 100644 web/screens/Settings/MCP/index.tsx diff --git a/web/screens/Settings/MCP/index.tsx b/web/screens/Settings/MCP/index.tsx new file mode 100644 index 000000000..905416cea --- /dev/null +++ b/web/screens/Settings/MCP/index.tsx @@ -0,0 +1,13 @@ +import React from 'react' + +const MCP = () => { + return ( +

+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui, cumque + deleniti dolorem ducimus nisi rerum cum et sunt maxime, dicta sequi + assumenda sit illum? Minima beatae repudiandae praesentium sed incidunt! +

+ ) +} + +export default MCP diff --git a/web/screens/Settings/SettingDetail/index.tsx b/web/screens/Settings/SettingDetail/index.tsx index 8ceb600e6..43bbd6c1c 100644 --- a/web/screens/Settings/SettingDetail/index.tsx +++ b/web/screens/Settings/SettingDetail/index.tsx @@ -15,6 +15,7 @@ import RemoteEngineSettings from '@/screens/Settings/Engines/RemoteEngineSetting import ExtensionSetting from '@/screens/Settings/ExtensionSetting' import Hardware from '@/screens/Settings/Hardware' import Hotkeys from '@/screens/Settings/Hotkeys' +import MCP from '@/screens/Settings/MCP' import MyModels from '@/screens/Settings/MyModels' import Privacy from '@/screens/Settings/Privacy' @@ -31,6 +32,9 @@ const SettingDetail = () => { case 'Engines': return + case 'MCP Servers': + return + case 'Extensions': return diff --git a/web/screens/Settings/index.tsx b/web/screens/Settings/index.tsx index d126f0d0e..8db1dd0b3 100644 --- a/web/screens/Settings/index.tsx +++ b/web/screens/Settings/index.tsx @@ -19,6 +19,7 @@ export const SettingScreenList = [ 'Privacy', 'Advanced Settings', 'Engines', + 'MCP Servers', 'Extensions', ] as const From ef1a85b58c9d756c8515c01fc296483daef1b372 Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Mon, 14 Apr 2025 21:32:04 +0700 Subject: [PATCH 2/5] chore: setting mcp --- web/screens/Settings/MCP/index.tsx | 126 +++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 6 deletions(-) diff --git a/web/screens/Settings/MCP/index.tsx b/web/screens/Settings/MCP/index.tsx index 905416cea..28f26d5f0 100644 --- a/web/screens/Settings/MCP/index.tsx +++ b/web/screens/Settings/MCP/index.tsx @@ -1,12 +1,126 @@ -import React from 'react' +import React, { useState, useEffect, useCallback } from 'react' + +import { fs, joinPath } from '@janhq/core' +import { Button } from '@janhq/joi' +import { useAtomValue } from 'jotai' + +import { janDataFolderPathAtom } from '@/helpers/atoms/AppConfig.atom' const MCP = () => { + const janDataFolderPath = useAtomValue(janDataFolderPathAtom) + const [configContent, setConfigContent] = useState('') + const [isSaving, setIsSaving] = useState(false) + const [error, setError] = useState('') + const [success, setSuccess] = useState('') + + console.log(janDataFolderPath, 'janDataFolderPath') + + const readConfigFile = useCallback(async () => { + try { + const configPath = await joinPath([janDataFolderPath, 'mcp_config.json']) + + // Check if the file exists + const fileExists = await fs.existsSync(configPath) + + if (fileExists) { + // Read the file + const content = await fs.readFileSync(configPath, 'utf-8') + setConfigContent(content) + } else { + // Create a default config if it doesn't exist + const defaultConfig = JSON.stringify( + { + servers: [], + settings: { + enabled: true, + }, + }, + null, + 2 + ) + + await fs.writeFileSync(configPath, defaultConfig) + setConfigContent(defaultConfig) + } + + 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 + } + + const configPath = await joinPath([janDataFolderPath, 'mcp_config.json']) + + // Write to the file + await fs.writeFileSync(configPath, 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 ( -

- Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui, cumque - deleniti dolorem ducimus nisi rerum cum et sunt maxime, dicta sequi - assumenda sit illum? Minima beatae repudiandae praesentium sed incidunt! -

+
+

MCP Configuration

+ + {error && ( +
+ {error} +
+ )} + + {success && ( +
+ {success} +
+ )} + +
+ +