diff --git a/src/main/services/urlschema/mcp-install.ts b/src/main/services/urlschema/mcp-install.ts index e5f0a76501..f2e58eef2a 100644 --- a/src/main/services/urlschema/mcp-install.ts +++ b/src/main/services/urlschema/mcp-install.ts @@ -44,7 +44,9 @@ export function handleMcpProtocolUrl(url: URL) { // } // } // cherrystudio://mcp/install?servers={base64Encode(JSON.stringify(jsonConfig))} + const data = params.get('servers') + if (data) { const stringify = Buffer.from(data, 'base64').toString('utf8') Logger.info('install MCP servers from urlschema: ', stringify) @@ -63,10 +65,8 @@ export function handleMcpProtocolUrl(url: URL) { } } - const mainWindow = windowService.getMainWindow() - if (mainWindow && !mainWindow.isDestroyed()) { - mainWindow.webContents.executeJavaScript("window.navigate('/settings/mcp')") - } + windowService.getMainWindow()?.show() + break } default: diff --git a/src/renderer/src/hooks/useMCPServers.ts b/src/renderer/src/hooks/useMCPServers.ts index bc95bb2ff6..ca9c8e0212 100644 --- a/src/renderer/src/hooks/useMCPServers.ts +++ b/src/renderer/src/hooks/useMCPServers.ts @@ -1,4 +1,5 @@ import { createSelector } from '@reduxjs/toolkit' +import NavigationService from '@renderer/services/NavigationService' import store, { useAppDispatch, useAppSelector } from '@renderer/store' import { addMCPServer, deleteMCPServer, setMCPServers, updateMCPServer } from '@renderer/store/mcp' import { MCPServer } from '@renderer/types' @@ -8,8 +9,11 @@ import { IpcChannel } from '@shared/IpcChannel' window.electron.ipcRenderer.on(IpcChannel.Mcp_ServersChanged, (_event, servers) => { store.dispatch(setMCPServers(servers)) }) + window.electron.ipcRenderer.on(IpcChannel.Mcp_AddServer, (_event, server: MCPServer) => { store.dispatch(addMCPServer(server)) + NavigationService.navigate?.('/settings/mcp') + NavigationService.navigate?.('/settings/mcp/settings', { state: { server } }) }) const selectMcpServers = (state) => state.mcp.servers diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index bbf16eeb8b..5f27ecefed 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -1870,7 +1870,20 @@ "updateError": "Failed to update server", "updateSuccess": "Server updated successfully", "url": "URL", - "user": "User" + "user": "User", + "requiresConfig": "Requires Configuration", + "builtinServers": "Builtin Servers", + "more": { + "modelscope": "ModelScope Community MCP Server", + "higress": "Higress MCP Server", + "mcpso": "MCP Server Discovery Platform", + "smithery": "Smithery MCP Tools", + "glama": "Glama MCP Server Directory", + "pulsemcp": "Pulse MCP Server", + "composio": "Composio MCP Development Tools", + "official": "Official MCP Server Collection", + "awesome": "Curated MCP Server List" + } }, "messages.divider": "Show divider between messages", "messages.divider.tooltip": "Not applicable to bubble-style message", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index 19c7b77505..a803e2a081 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -1870,7 +1870,20 @@ "updateError": "サーバーの更新に失敗しました", "updateSuccess": "サーバーが正常に更新されました", "url": "URL", - "user": "ユーザー" + "user": "ユーザー", + "requiresConfig": "設定が必要", + "builtinServers": "組み込みサーバー", + "more": { + "modelscope": "魔搭コミュニティ MCP サーバー", + "higress": "Higress MCP サーバー", + "mcpso": "MCP サーバー発見プラットフォーム", + "smithery": "Smithery MCP ツール", + "glama": "Glama MCP サーバーディレクトリ", + "pulsemcp": "Pulse MCP サーバー", + "composio": "Composio MCP 開発ツール", + "official": "公式 MCP サーバーコレクション", + "awesome": "厳選された MCP サーバーリスト" + } }, "messages.divider": "メッセージ間に区切り線を表示", "messages.divider.tooltip": "バブルスタイルのメッセージには適用されません", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index d1e67501bf..6fd32362a1 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -1870,7 +1870,20 @@ "updateError": "Ошибка обновления сервера", "updateSuccess": "Сервер успешно обновлен", "url": "URL", - "user": "Пользователь" + "user": "Пользователь", + "requiresConfig": "Требуется настройка", + "builtinServers": "Встроенные серверы", + "more": { + "modelscope": "Сервер MCP сообщества ModelScope", + "higress": "Сервер Higress MCP", + "mcpso": "Платформа поиска серверов MCP", + "smithery": "Инструменты Smithery MCP", + "glama": "Каталог серверов Glama MCP", + "pulsemcp": "Сервер Pulse MCP", + "composio": "Инструменты разработки Composio MCP", + "official": "Официальная коллекция серверов MCP", + "awesome": "Кураторский список серверов MCP" + } }, "messages.divider": "Показывать разделитель между сообщениями", "messages.divider.tooltip": "Не применимо к сообщениям в стиле пузырей", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 5b244ef683..d8503085fd 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -1870,7 +1870,20 @@ "updateError": "更新服务器失败", "updateSuccess": "服务器更新成功", "url": "URL", - "user": "用户" + "user": "用户", + "requiresConfig": "需要配置", + "builtinServers": "内置服务器", + "more": { + "modelscope": "魔搭社区 MCP 服务器", + "higress": "Higress MCP 服务器", + "mcpso": "MCP 服务器发现平台", + "smithery": "Smithery MCP 工具", + "glama": "Glama MCP 服务器目录", + "pulsemcp": "Pulse MCP 服务器", + "composio": "Composio MCP 开发工具", + "official": "官方 MCP 服务器集合", + "awesome": "精选的 MCP 服务器列表" + } }, "messages.divider": "消息分割线", "messages.divider.tooltip": "不适用于气泡样式消息", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 03bbe2d8d2..55759eca01 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -1870,7 +1870,20 @@ "updateError": "更新伺服器失敗", "updateSuccess": "伺服器更新成功", "url": "URL", - "user": "用戶" + "user": "用戶", + "requiresConfig": "需要配置", + "builtinServers": "內置伺服器", + "more": { + "modelscope": "魔搭社區 MCP 伺服器", + "higress": "Higress MCP 伺服器", + "mcpso": "MCP 伺服器發現平台", + "smithery": "Smithery MCP 工具", + "glama": "Glama MCP 伺服器目錄", + "pulsemcp": "Pulse MCP 伺服器", + "composio": "Composio MCP 開發工具", + "official": "官方 MCP 伺服器集合", + "awesome": "精選的 MCP 伺服器清單" + } }, "messages.divider": "訊息間顯示分隔線", "messages.divider.tooltip": "不適用於氣泡樣式消息", diff --git a/src/renderer/src/pages/home/Messages/MessageHeader.tsx b/src/renderer/src/pages/home/Messages/MessageHeader.tsx index d99bae30f1..ddeae08c27 100644 --- a/src/renderer/src/pages/home/Messages/MessageHeader.tsx +++ b/src/renderer/src/pages/home/Messages/MessageHeader.tsx @@ -126,6 +126,7 @@ const Container = styled.div` align-items: center; gap: 10px; position: relative; + margin-bottom: 8px; ` const UserWrap = styled.div` diff --git a/src/renderer/src/pages/settings/MCPSettings/BuiltinMCPServersSection.tsx b/src/renderer/src/pages/settings/MCPSettings/BuiltinMCPServersSection.tsx new file mode 100644 index 0000000000..bf64898733 --- /dev/null +++ b/src/renderer/src/pages/settings/MCPSettings/BuiltinMCPServersSection.tsx @@ -0,0 +1,170 @@ +import { CheckOutlined, PlusOutlined } from '@ant-design/icons' +import { useMCPServers } from '@renderer/hooks/useMCPServers' +import { builtinMCPServers } from '@renderer/store/mcp' +import { Button, Popover, Tag } from 'antd' +import { FC } from 'react' +import { useTranslation } from 'react-i18next' +import styled from 'styled-components' + +import { SettingTitle } from '..' + +const BuiltinMCPServersSection: FC = () => { + const { t } = useTranslation() + const { addMCPServer, mcpServers } = useMCPServers() + + return ( + <> + {t('settings.mcp.builtinServers')} + + {builtinMCPServers.map((server) => { + const isInstalled = mcpServers.some((existingServer) => existingServer.name === server.name) + + return ( + + + + {server.name} + + + - - - diff --git a/src/renderer/src/pages/settings/MCPSettings/NpxSearch.tsx b/src/renderer/src/pages/settings/MCPSettings/NpxSearch.tsx index 54fa3201a9..0b6a001b8a 100644 --- a/src/renderer/src/pages/settings/MCPSettings/NpxSearch.tsx +++ b/src/renderer/src/pages/settings/MCPSettings/NpxSearch.tsx @@ -3,7 +3,6 @@ import { nanoid } from '@reduxjs/toolkit' import logo from '@renderer/assets/images/cherry-text-logo.svg' import { Center, HStack } from '@renderer/components/Layout' import { useMCPServers } from '@renderer/hooks/useMCPServers' -import { builtinMCPServers } from '@renderer/store/mcp' import { MCPServer } from '@renderer/types' import { getMcpConfigSampleFromReadme } from '@renderer/utils' import { Button, Card, Flex, Input, Space, Spin, Tag, Typography } from 'antd' @@ -23,7 +22,7 @@ interface SearchResult { configSample?: MCPServer['configSample'] } -const npmScopes = ['@cherry', '@modelcontextprotocol', '@gongrzhe', '@mcpmarket'] +const npmScopes = ['@modelcontextprotocol', '@gongrzhe', '@mcpmarket'] let _searchResults: SearchResult[] = [] @@ -32,7 +31,7 @@ const NpxSearch: FC = () => { const { Text, Link } = Typography // Add new state variables for npm scope search - const [npmScope, setNpmScope] = useState('@cherry') + const [npmScope, setNpmScope] = useState('@modelcontextprotocol') const [searchLoading, setSearchLoading] = useState(false) const [searchResults, setSearchResults] = useState(_searchResults) const { addMCPServer, mcpServers } = useMCPServers() @@ -52,22 +51,6 @@ const NpxSearch: FC = () => { return } - if (searchScope === '@cherry') { - setSearchResults( - builtinMCPServers.map((server) => ({ - key: server.id, - name: server.name, - description: server.description || '', - version: '1.0.0', - usage: '参考下方链接中的使用说明', - npmLink: 'https://docs.cherry-ai.com/advanced-basic/mcp/in-memory', - fullName: server.name, - type: server.type || 'inMemory' - })) - ) - return - } - setSearchLoading(true) try { @@ -190,14 +173,6 @@ const NpxSearch: FC = () => { return } - const buildInServer = builtinMCPServers.find((server) => server.name === record.name) - - if (buildInServer) { - addMCPServer(buildInServer) - window.message.success({ content: t('settings.mcp.addSuccess'), key: 'mcp-add-server' }) - return - } - const newServer = { id: nanoid(), name: record.name, diff --git a/src/renderer/src/pages/settings/SettingsPage.tsx b/src/renderer/src/pages/settings/SettingsPage.tsx index 9a37ceb263..59abda1ec4 100644 --- a/src/renderer/src/pages/settings/SettingsPage.tsx +++ b/src/renderer/src/pages/settings/SettingsPage.tsx @@ -71,18 +71,18 @@ const SettingsPage: FC = () => { {t('settings.display.title')} - - - - {t('settings.tool.title')} - - {t('settings.mcp.title')} + + + + {t('settings.tool.title')} + +