feat(mcp): add json import
This commit is contained in:
parent
90077a519d
commit
1e830c0613
@ -839,7 +839,13 @@
|
||||
"scope_required": "Please enter npm scope",
|
||||
"no_packages": "No packages found",
|
||||
"search_error": "Search error"
|
||||
}
|
||||
},
|
||||
"jsonMode": "JSON Schema",
|
||||
"normalMode": "Normal mode",
|
||||
"jsonModeHint": "Edit the JSON representation of the MCP server configuration. Please ensure the format is correct before saving.",
|
||||
"jsonFormatError": "JSON formatting error",
|
||||
"jsonSaveSuccess": "JSON configuration has been saved.",
|
||||
"jsonSaveError": "Failed to save JSON configuration."
|
||||
},
|
||||
"messages.divider": "Show divider between messages",
|
||||
"messages.grid_columns": "Message grid display columns",
|
||||
|
||||
@ -839,7 +839,13 @@
|
||||
"scope_required": "npm スコープを入力してください",
|
||||
"no_packages": "パッケージが見つかりません",
|
||||
"search_error": "パッケージの検索に失敗しました"
|
||||
}
|
||||
},
|
||||
"jsonMode": "JSONスキーマ",
|
||||
"normalMode": "通常モード",
|
||||
"jsonModeHint": "MCPサーバー設定のJSON表現を編集します。保存する前に、フォーマットが正しいことを確認してください。",
|
||||
"jsonFormatError": "JSONフォーマットエラー",
|
||||
"jsonSaveSuccess": "JSON設定が保存されました。",
|
||||
"jsonSaveError": "JSON設定の保存に失敗しました"
|
||||
},
|
||||
"messages.divider": "メッセージ間に区切り線を表示",
|
||||
"messages.grid_columns": "メッセージグリッドの表示列数",
|
||||
|
||||
@ -839,7 +839,13 @@
|
||||
"scope_required": "Пожалуйста, введите область npm",
|
||||
"no_packages": "Ничего не найдено",
|
||||
"search_error": "Ошибка поиска"
|
||||
}
|
||||
},
|
||||
"jsonMode": "JSON-схема",
|
||||
"normalMode": "Обычный режим",
|
||||
"jsonModeHint": "Редактируйте JSON-форматирование конфигурации сервера MCP. Перед сохранением убедитесь, что формат правильный.",
|
||||
"jsonFormatError": "Ошибка форматирования JSON",
|
||||
"jsonSaveSuccess": "JSON конфигурация сохранена",
|
||||
"jsonSaveError": "Не удалось сохранить конфигурацию JSON"
|
||||
},
|
||||
"messages.divider": "Показывать разделитель между сообщениями",
|
||||
"messages.grid_columns": "Количество столбцов сетки сообщений",
|
||||
|
||||
@ -839,7 +839,13 @@
|
||||
"scope_required": "请输入 npm 作用域",
|
||||
"no_packages": "未找到包",
|
||||
"search_error": "搜索失败"
|
||||
}
|
||||
},
|
||||
"jsonMode": "JSON模式",
|
||||
"normalMode": "常规模式",
|
||||
"jsonModeHint": "编辑MCP服务器配置的JSON表示。保存前请确保格式正确。",
|
||||
"jsonFormatError": "JSON格式化错误",
|
||||
"jsonSaveSuccess": "JSON配置已保存",
|
||||
"jsonSaveError": "保存JSON配置失败"
|
||||
},
|
||||
"messages.divider": "消息分割线",
|
||||
"messages.grid_columns": "消息网格展示列数",
|
||||
|
||||
@ -839,7 +839,13 @@
|
||||
"scope_required": "請輸入 npm 作用域",
|
||||
"no_packages": "未找到包",
|
||||
"search_error": "搜索失敗"
|
||||
}
|
||||
},
|
||||
"jsonMode": "JSON模式",
|
||||
"normalMode": "常規模式",
|
||||
"jsonModeHint": "編輯MCP伺服器配置的JSON表示。保存前請確保格式正確。",
|
||||
"jsonFormatError": "JSON格式錯誤",
|
||||
"jsonSaveSuccess": "JSON配置已儲存",
|
||||
"jsonSaveError": "保存JSON配置失敗"
|
||||
},
|
||||
"messages.divider": "訊息間顯示分隔線",
|
||||
"messages.grid_columns": "訊息網格展示列數",
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import { DeleteOutlined, EditOutlined, PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons'
|
||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { useAppSelector } from '@renderer/store'
|
||||
import { useAppDispatch, useAppSelector } from '@renderer/store'
|
||||
import { setMCPServers } from '@renderer/store/mcp'
|
||||
import { MCPServer } from '@renderer/types'
|
||||
import { Button, Card, Space, Switch, Table, Tag, Tooltip, Typography } from 'antd'
|
||||
import { FC } from 'react'
|
||||
import { Button, Card, Input, Space, Switch, Table, Tabs, Tag, Tooltip, Typography } from 'antd'
|
||||
import { FC, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { SettingContainer, SettingDivider, SettingGroup, SettingTitle } from '..'
|
||||
@ -14,6 +15,13 @@ const MCPSettings: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const { theme } = useTheme()
|
||||
const { Paragraph, Text } = Typography
|
||||
const { TextArea } = Input
|
||||
const [activeTab, setActiveTab] = useState('normal')
|
||||
const [jsonConfig, setJsonConfig] = useState('')
|
||||
const [jsonSaving, setJsonSaving] = useState(false)
|
||||
const [jsonError, setJsonError] = useState('')
|
||||
const dispatch = useAppDispatch()
|
||||
const ipcRenderer = window.electron.ipcRenderer
|
||||
const mcpServers = useAppSelector((state) => state.mcp.servers)
|
||||
|
||||
const handleDelete = (serverName: string) => {
|
||||
@ -43,6 +51,72 @@ const MCPSettings: FC = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const handleTabChange = (key: string) => {
|
||||
setActiveTab(key)
|
||||
|
||||
if (key === 'json') {
|
||||
try {
|
||||
const mcpServersObj: Record<string, any> = {}
|
||||
|
||||
mcpServers.forEach((server) => {
|
||||
const { name, ...serverData } = server
|
||||
mcpServersObj[name] = serverData
|
||||
})
|
||||
|
||||
const standardFormat = {
|
||||
mcpServers: mcpServersObj
|
||||
}
|
||||
|
||||
const formattedJson = JSON.stringify(standardFormat, null, 2)
|
||||
setJsonConfig(formattedJson)
|
||||
setJsonError('')
|
||||
} catch (error) {
|
||||
console.error('Failed to format JSON:', error)
|
||||
setJsonError(t('settings.mcp.jsonFormatError'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleSaveJson = async () => {
|
||||
setJsonSaving(true)
|
||||
try {
|
||||
if (!jsonConfig.trim()) {
|
||||
dispatch(setMCPServers([]))
|
||||
window.message.success(t('settings.mcp.jsonSaveSuccess'))
|
||||
setJsonError('')
|
||||
setJsonSaving(false)
|
||||
return
|
||||
}
|
||||
const parsedConfig = JSON.parse(jsonConfig)
|
||||
|
||||
if (!parsedConfig.mcpServers || typeof parsedConfig.mcpServers !== 'object') {
|
||||
throw new Error(t('settings.mcp.invalidMcpFormat'))
|
||||
}
|
||||
|
||||
const serversArray: MCPServer[] = []
|
||||
for (const [name, serverConfig] of Object.entries(parsedConfig.mcpServers)) {
|
||||
const server: MCPServer = {
|
||||
name,
|
||||
isActive: false,
|
||||
...(serverConfig as any)
|
||||
}
|
||||
serversArray.push(server)
|
||||
}
|
||||
|
||||
dispatch(setMCPServers(serversArray))
|
||||
ipcRenderer.send('mcp:servers-from-renderer', mcpServers)
|
||||
|
||||
window.message.success(t('settings.mcp.jsonSaveSuccess'))
|
||||
setJsonError('')
|
||||
} catch (error: any) {
|
||||
console.error('Failed to save JSON config:', error)
|
||||
setJsonError(error.message || t('settings.mcp.jsonSaveError'))
|
||||
window.message.error(t('settings.mcp.jsonSaveError'))
|
||||
} finally {
|
||||
setJsonSaving(false)
|
||||
}
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: t('settings.mcp.name'),
|
||||
@ -137,6 +211,15 @@ const MCPSettings: FC = () => {
|
||||
{t('settings.mcp.config_description')}
|
||||
</Paragraph>
|
||||
|
||||
<Tabs
|
||||
activeKey={activeTab}
|
||||
onChange={handleTabChange}
|
||||
items={[
|
||||
{
|
||||
label: t('settings.mcp.normalMode'),
|
||||
key: 'normal',
|
||||
children: (
|
||||
<>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}>
|
||||
<Button type="primary" icon={<PlusOutlined />} onClick={() => AddMcpServerPopup.show()}>
|
||||
{t('settings.mcp.addServer')}
|
||||
@ -163,6 +246,38 @@ const MCPSettings: FC = () => {
|
||||
})}
|
||||
/>
|
||||
</Card>
|
||||
</>
|
||||
)
|
||||
},
|
||||
{
|
||||
label: t('settings.mcp.jsonMode'),
|
||||
key: 'json',
|
||||
children: (
|
||||
<>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}>
|
||||
<Button type="primary" onClick={handleSaveJson} loading={jsonSaving}>
|
||||
{t('common.save')}
|
||||
</Button>
|
||||
<Text type="secondary">{jsonError ? <span style={{ color: 'red' }}>{jsonError}</span> : ''}</Text>
|
||||
</div>
|
||||
<Card bordered={false} style={{ background: theme === 'dark' ? '#1f1f1f' : '#fff' }}>
|
||||
<TextArea
|
||||
value={jsonConfig}
|
||||
onChange={(e) => setJsonConfig(e.target.value)}
|
||||
style={{
|
||||
width: '100%',
|
||||
fontFamily: 'monospace',
|
||||
minHeight: '400px',
|
||||
marginBottom: '16px'
|
||||
}}
|
||||
onFocus={() => setJsonError('')}
|
||||
/>
|
||||
<Text type="secondary">{t('settings.mcp.jsonModeHint')}</Text>
|
||||
</Card>
|
||||
</>
|
||||
)
|
||||
}
|
||||
]}></Tabs>
|
||||
</SettingGroup>
|
||||
<NpxSearch />
|
||||
</SettingContainer>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user