From f30f06f40f8d1ddbad0b81fbd3cf50b91b73a0b1 Mon Sep 17 00:00:00 2001 From: xu-ya Date: Tue, 18 Nov 2025 14:30:44 +0800 Subject: [PATCH] feat: add mcp Execute Tool --- src/renderer/src/i18n/locales/en-us.json | 31 +++++++- src/renderer/src/i18n/locales/zh-cn.json | 31 +++++++- .../pages/settings/MCPSettings/McpTool.tsx | 79 +++++++++++++++---- 3 files changed, 123 insertions(+), 18 deletions(-) diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index c1c0dc2620..b3d04b7abf 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -3985,7 +3985,36 @@ }, "loadError": "Get tools Error", "noToolsAvailable": "No tools available", - "run": "Run" + "run": "Run", + "execute": { + "label": "Execute", + "button": "Execute", + "tooltip": "Execute tool with custom parameters", + "title": "Execute Tool: {{name}}", + "params": "Parameters (JSON)", + "paramsPlaceholder": "Enter JSON parameters...", + "execute": "Execute", + "copied": "Copied to clipboard", + "copyFailed": "Failed to copy", + "copy": "Copy", + "result": { + "success": "Result", + "error": "Error Result", + "text": "Text" + }, + "view": { + "json": "JSON", + "formatted": "Formatted" + }, + "table": { + "name": "Name", + "value": "Value" + }, + "error": { + "noToolOrServer": "Tool or server not found", + "invalidJson": "Invalid JSON format: {{error}}" + } + } }, "type": "Type", "types": { diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 2a1ee09688..57873468a3 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -3985,7 +3985,36 @@ }, "loadError": "获取工具失败", "noToolsAvailable": "无可用工具", - "run": "运行" + "run": "运行", + "execute": { + "label": "执行", + "button": "执行", + "tooltip": "使用自定义参数执行工具", + "title": "执行工具: {{name}}", + "params": "参数 (JSON)", + "paramsPlaceholder": "输入 JSON 参数...", + "execute": "执行", + "copied": "已复制到剪贴板", + "copyFailed": "复制失败", + "copy": "复制", + "result": { + "success": "结果", + "error": "错误结果", + "text": "文本" + }, + "view": { + "json": "JSON", + "formatted": "美化" + }, + "table": { + "name": "名称", + "value": "值" + }, + "error": { + "noToolOrServer": "未找到工具或服务器", + "invalidJson": "无效的 JSON 格式: {{error}}" + } + } }, "type": "类型", "types": { diff --git a/src/renderer/src/pages/settings/MCPSettings/McpTool.tsx b/src/renderer/src/pages/settings/MCPSettings/McpTool.tsx index bfd9992dc4..aeb00e8bc9 100644 --- a/src/renderer/src/pages/settings/MCPSettings/McpTool.tsx +++ b/src/renderer/src/pages/settings/MCPSettings/McpTool.tsx @@ -1,9 +1,11 @@ import type { MCPServer, MCPTool } from '@renderer/types' import { isToolAutoApproved } from '@renderer/utils/mcp-tools' -import { Badge, Descriptions, Empty, Flex, Switch, Table, Tag, Tooltip, Typography } from 'antd' +import { Badge, Button, Descriptions, Empty, Flex, Switch, Table, Tag, Tooltip, Typography } from 'antd' import type { ColumnsType } from 'antd/es/table' -import { Hammer, Info, Zap } from 'lucide-react' +import { Hammer, Info, Play, Zap } from 'lucide-react' +import { useState } from 'react' import { useTranslation } from 'react-i18next' +import ExecuteToolModal from './ExecuteToolModal' interface MCPToolsSectionProps { tools: MCPTool[] @@ -14,6 +16,8 @@ interface MCPToolsSectionProps { const MCPToolsSection = ({ tools, server, onToggleTool, onToggleAutoApprove }: MCPToolsSectionProps) => { const { t } = useTranslation() + const [executeModalOpen, setExecuteModalOpen] = useState(false) + const [selectedTool, setSelectedTool] = useState(null) // Check if a tool is enabled (not in the disabledTools array) const isToolEnabled = (tool: MCPTool) => { @@ -30,6 +34,12 @@ const MCPToolsSection = ({ tools, server, onToggleTool, onToggleAutoApprove }: M onToggleAutoApprove(tool, checked) } + // Handle execute tool + const handleExecuteTool = (tool: MCPTool) => { + setSelectedTool(tool) + setExecuteModalOpen(true) + } + // Render tool properties from the input schema const renderToolProperties = (tool: MCPTool) => { if (!tool.inputSchema?.properties) return null @@ -102,6 +112,7 @@ const MCPToolsSection = ({ tools, server, onToggleTool, onToggleAutoApprove }: M } const columns: ColumnsType = [ + // 工具列表列定义:可用工具、启用工具、自动批准、执行工具 { title: {t('settings.mcp.tools.availableTools')}, dataIndex: 'name', @@ -141,7 +152,7 @@ const MCPToolsSection = ({ tools, server, onToggleTool, onToggleAutoApprove }: M ), key: 'enable', - width: 150, // Fixed width might be good for alignment + width: 130, // Fixed width might be good for alignment align: 'center', render: (_, tool) => ( handleToggle(tool, checked)} size="small" /> @@ -155,7 +166,7 @@ const MCPToolsSection = ({ tools, server, onToggleTool, onToggleAutoApprove }: M ), key: 'autoApprove', - width: 150, // Fixed width + width: 130, // Fixed width align: 'center', render: (_, tool) => ( ) + }, + { + title: ( + + + {t('settings.mcp.tools.execute.label', 'Execute')} + + ), + key: 'execute', + width: 130, + align: 'center', + render: (_, tool) => ( + + + + ) } ] - return tools.length > 0 ? ( - renderToolProperties(tool) - }} - /> - ) : ( - + return ( + <> + {tools.length > 0 ? ( +
renderToolProperties(tool) + }} + /> + ) : ( + + )} + { + setExecuteModalOpen(false) + setSelectedTool(null) + }} + /> + ) }