fix: 更新 MCP 相关术语,统一界面表述

This commit is contained in:
Wenjie Zhang 2026-04-04 15:11:53 +08:00
parent 6df070ddb6
commit 034f0fc910
3 changed files with 55 additions and 55 deletions

View File

@ -4,13 +4,13 @@
<div class="loading-bar"></div> <div class="loading-bar"></div>
</div> </div>
<div class="layout-wrapper" :class="{ 'content-loading': loading }"> <div class="layout-wrapper" :class="{ 'content-loading': loading }">
<!-- 左侧服务器列表 --> <!-- 左侧MCP 列表 -->
<div class="sidebar-list"> <div class="sidebar-list">
<!-- 搜索框 --> <!-- 搜索框 -->
<div class="search-box"> <div class="search-box">
<a-input <a-input
v-model:value="searchQuery" v-model:value="searchQuery"
placeholder="搜索服务器..." placeholder="搜索 MCP..."
allow-clear allow-clear
class="search-input" class="search-input"
> >
@ -21,17 +21,17 @@
<!-- 统计信息 --> <!-- 统计信息 -->
<!-- <div class="stats-section" v-if="filteredServers.length > 0"> <!-- <div class="stats-section" v-if="filteredServers.length > 0">
<span class="stats-text"> <span class="stats-text">
{{ filteredServers.length }} 服务器 HTTP: {{ httpCount }} · SSE: {{ sseCount }} · StdIO: {{ stdioCount }} {{ filteredServers.length }} MCP HTTP: {{ httpCount }} · SSE: {{ sseCount }} · StdIO: {{ stdioCount }}
</span> </span>
</div> --> </div> -->
<!-- 服务器列表 --> <!-- MCP 列表 -->
<div class="list-container"> <div class="list-container">
<div <div
v-if="!filteredEnabledServers.length && !filteredDisabledServers.length" v-if="!filteredEnabledServers.length && !filteredDisabledServers.length"
class="empty-text" class="empty-text"
> >
<a-empty :image="false" :description="searchQuery ? '无匹配服务器' : '暂无服务器'" /> <a-empty :image="false" :description="searchQuery ? '无匹配 MCP' : '暂无 MCP'" />
</div> </div>
<div v-if="filteredEnabledServers.length" class="list-section-title">已添加</div> <div v-if="filteredEnabledServers.length" class="list-section-title">已添加</div>
<template <template
@ -113,7 +113,7 @@
<div v-if="!currentServer" class="unselected-state"> <div v-if="!currentServer" class="unselected-state">
<div class="hint-box"> <div class="hint-box">
<Plug :size="40" class="text-muted" /> <Plug :size="40" class="text-muted" />
<p>请在左侧选择服务器进行操作</p> <p>请在左侧选择 MCP 进行操作</p>
</div> </div>
</div> </div>
@ -199,7 +199,7 @@
" "
> >
<div class="info-item" v-if="currentServer.url"> <div class="info-item" v-if="currentServer.url">
<label>服务器 URL</label> <label>MCP URL</label>
<span class="code-inline text-break-all">{{ currentServer.url }}</span> <span class="code-inline text-break-all">{{ currentServer.url }}</span>
</div> </div>
<div <div
@ -357,10 +357,10 @@
</div> </div>
</div> </div>
<!-- 添加/编辑服务器模态框 --> <!-- 添加/编辑 MCP 模态框 -->
<a-modal <a-modal
v-model:open="formModalVisible" v-model:open="formModalVisible"
:title="editMode ? '编辑 MCP 服务器' : '添加 MCP 服务器'" :title="editMode ? '编辑 MCP' : '添加 MCP'"
@ok="handleFormSubmit" @ok="handleFormSubmit"
:confirmLoading="formLoading" :confirmLoading="formLoading"
@cancel="formModalVisible = false" @cancel="formModalVisible = false"
@ -378,16 +378,16 @@
<!-- 表单模式 --> <!-- 表单模式 -->
<a-form v-if="formMode === 'form'" layout="vertical" class="extension-form"> <a-form v-if="formMode === 'form'" layout="vertical" class="extension-form">
<a-form-item label="服务器名称" required class="form-item"> <a-form-item label="MCP 名称" required class="form-item">
<a-input <a-input
v-model:value="form.name" v-model:value="form.name"
placeholder="请输入服务器名称(唯一标识)" placeholder="请输入 MCP 名称(唯一标识)"
:disabled="editMode" :disabled="editMode"
/> />
</a-form-item> </a-form-item>
<a-form-item label="描述" class="form-item"> <a-form-item label="描述" class="form-item">
<a-input v-model:value="form.description" placeholder="请输入服务器描述" /> <a-input v-model:value="form.description" placeholder="请输入 MCP 描述" />
</a-form-item> </a-form-item>
<a-row :gutter="16"> <a-row :gutter="16">
@ -409,7 +409,7 @@
<!-- HTTP 类型 --> <!-- HTTP 类型 -->
<template v-if="form.transport === 'streamable_http' || form.transport === 'sse'"> <template v-if="form.transport === 'streamable_http' || form.transport === 'sse'">
<a-form-item label="服务器 URL" required class="form-item"> <a-form-item label="MCP URL" required class="form-item">
<a-input v-model:value="form.url" placeholder="https://example.com/mcp" /> <a-input v-model:value="form.url" placeholder="https://example.com/mcp" />
</a-form-item> </a-form-item>
@ -485,7 +485,7 @@
"name": "my-server", "name": "my-server",
"transport": "streamable_http", "transport": "streamable_http",
"url": "https://example.com/mcp", "url": "https://example.com/mcp",
"description": "服务器描述", "description": "MCP 描述",
"headers": {"Authorization": "Bearer xxx"}, "headers": {"Authorization": "Bearer xxx"},
"tags": ["工具", "AI"] "tags": ["工具", "AI"]
}' }'
@ -502,7 +502,7 @@
<script setup> <script setup>
import { ref, reactive, computed, onMounted } from 'vue' import { ref, reactive, computed, onMounted } from 'vue'
import { message, notification, Modal } from 'ant-design-vue' import { message, Modal } from 'ant-design-vue'
import { import {
Search, Search,
Plug, Plug,
@ -598,7 +598,7 @@ const filteredTools = computed(() => {
) )
}) })
// // MCP
const fetchServers = async () => { const fetchServers = async () => {
try { try {
loading.value = true loading.value = true
@ -618,11 +618,11 @@ const fetchServers = async () => {
} }
} }
} else { } else {
error.value = result.message || '获取服务器列表失败' error.value = result.message || '获取 MCP 列表失败'
} }
} catch (err) { } catch (err) {
console.error('获取服务器列表失败:', err) console.error('获取 MCP 列表失败:', err)
error.value = err.message || '获取服务器列表失败' error.value = err.message || '获取 MCP 列表失败'
} finally { } finally {
loading.value = false loading.value = false
} }
@ -659,17 +659,17 @@ const handleToggleTool = async (tool) => {
toggleToolLoading.value = tool.name toggleToolLoading.value = tool.name
const result = await mcpApi.toggleMcpServerTool(currentServer.value.name, tool.name) const result = await mcpApi.toggleMcpServerTool(currentServer.value.name, tool.name)
if (result.success) { if (result.success) {
notification.success({ message: result.message }) message.success(result.message)
const targetTool = tools.value.find((t) => t.name === tool.name) const targetTool = tools.value.find((t) => t.name === tool.name)
if (targetTool) { if (targetTool) {
targetTool.enabled = result.enabled targetTool.enabled = result.enabled
} }
} else { } else {
notification.error({ message: result.message || '操作失败' }) message.error(result.message || '操作失败')
} }
} catch (err) { } catch (err) {
console.error('切换工具状态失败:', err) console.error('切换工具状态失败:', err)
notification.error({ message: err.message || '操作失败' }) message.error(err.message || '操作失败')
} finally { } finally {
toggleToolLoading.value = null toggleToolLoading.value = null
} }
@ -679,9 +679,9 @@ const handleToggleTool = async (tool) => {
const copyToolName = async (name) => { const copyToolName = async (name) => {
try { try {
await navigator.clipboard.writeText(name) await navigator.clipboard.writeText(name)
notification.success({ message: '已复制到剪贴板' }) message.success('已复制到剪贴板')
} catch { } catch {
notification.error({ message: '复制失败' }) message.error('复制失败')
} }
} }
@ -698,7 +698,7 @@ const getTransportColor = (transport) => {
return colors[transport] || 'blue' return colors[transport] || 'blue'
} }
// // MCP
const selectServer = (server) => { const selectServer = (server) => {
currentServer.value = server currentServer.value = server
detailTab.value = 'general' detailTab.value = 'general'
@ -756,7 +756,7 @@ const showEditModal = async (server) => {
return return
} }
} catch (err) { } catch (err) {
console.error('获取服务器详情失败,回退使用列表数据:', err) console.error('获取 MCP 详情失败,回退使用列表数据:', err)
} }
applyServerToForm(server) applyServerToForm(server)
} }
@ -771,7 +771,7 @@ const handleFormSubmit = async () => {
try { try {
data = JSON.parse(jsonContent.value) data = JSON.parse(jsonContent.value)
} catch { } catch {
notification.error({ message: 'JSON 格式错误' }) message.error('JSON 格式错误')
return return
} }
} else { } else {
@ -781,7 +781,7 @@ const handleFormSubmit = async () => {
try { try {
headers = JSON.parse(form.headersText) headers = JSON.parse(form.headersText)
} catch { } catch {
notification.error({ message: '请求头 JSON 格式错误' }) message.error('请求头 JSON 格式错误')
return return
} }
} }
@ -804,24 +804,24 @@ const handleFormSubmit = async () => {
// //
if (!data.name?.trim()) { if (!data.name?.trim()) {
notification.error({ message: '服务器名称不能为空' }) message.error('MCP 名称不能为空')
return return
} }
if (!data.transport) { if (!data.transport) {
notification.error({ message: '请选择传输类型' }) message.error('请选择传输类型')
return return
} }
// HTTP URL // HTTP URL
if (['sse', 'streamable_http'].includes(data.transport)) { if (['sse', 'streamable_http'].includes(data.transport)) {
if (!data.url?.trim()) { if (!data.url?.trim()) {
notification.error({ message: 'HTTP 类型必须填写服务器 URL' }) message.error('HTTP 类型必须填写 MCP URL')
return return
} }
} }
// StdIO command // StdIO command
if (data.transport === 'stdio') { if (data.transport === 'stdio') {
if (!data.command?.trim()) { if (!data.command?.trim()) {
notification.error({ message: 'StdIO 类型必须填写命令' }) message.error('StdIO 类型必须填写命令')
return return
} }
} }
@ -829,17 +829,17 @@ const handleFormSubmit = async () => {
if (editMode.value) { if (editMode.value) {
const result = await mcpApi.updateMcpServer(data.name, data) const result = await mcpApi.updateMcpServer(data.name, data)
if (result.success) { if (result.success) {
notification.success({ message: '服务器更新成功' }) message.success('MCP 更新成功')
} else { } else {
notification.error({ message: result.message || '更新失败' }) message.error(result.message || '更新失败')
return return
} }
} else { } else {
const result = await mcpApi.createMcpServer(data) const result = await mcpApi.createMcpServer(data)
if (result.success) { if (result.success) {
notification.success({ message: '服务器创建成功' }) message.success('MCP 创建成功')
} else { } else {
notification.error({ message: result.message || '创建失败' }) message.error(result.message || '创建失败')
return return
} }
} }
@ -848,13 +848,13 @@ const handleFormSubmit = async () => {
await fetchServers() await fetchServers()
} catch (err) { } catch (err) {
console.error('操作失败:', err) console.error('操作失败:', err)
notification.error({ message: err.message || '操作失败' }) message.error(err.message || '操作失败')
} finally { } finally {
formLoading.value = false formLoading.value = false
} }
} }
// // MCP
const handleSetServerEnabled = async (server, enabled) => { const handleSetServerEnabled = async (server, enabled) => {
try { try {
toggleLoading.value = server.name toggleLoading.value = server.name
@ -866,29 +866,29 @@ const handleSetServerEnabled = async (server, enabled) => {
tools.value = [] tools.value = []
} }
} else { } else {
notification.error({ message: result.message || '操作失败' }) message.error(result.message || '操作失败')
} }
} catch (err) { } catch (err) {
console.error('更新状态失败:', err) console.error('更新状态失败:', err)
notification.error({ message: err.message || '操作失败' }) message.error(err.message || '操作失败')
} finally { } finally {
toggleLoading.value = null toggleLoading.value = null
} }
} }
// // MCP
const handleTestServer = async (server) => { const handleTestServer = async (server) => {
try { try {
testLoading.value = server.name testLoading.value = server.name
const result = await mcpApi.testMcpServer(server.name) const result = await mcpApi.testMcpServer(server.name)
if (result.success) { if (result.success) {
notification.success({ message: result.message }) message.success(result.message)
} else { } else {
notification.warning({ message: result.message || '连接失败' }) message.warning(result.message || '连接失败')
} }
} catch (err) { } catch (err) {
console.error('测试连接失败:', err) console.error('测试连接失败:', err)
notification.error({ message: err.message || '测试失败' }) message.error(err.message || '测试失败')
} finally { } finally {
testLoading.value = null testLoading.value = null
} }
@ -919,11 +919,11 @@ const getServerActionTone = (server) => {
: 'extension-panel-action-danger' : 'extension-panel-action-danger'
} }
// // MCP
const confirmDeleteServer = (server) => { const confirmDeleteServer = (server) => {
Modal.confirm({ Modal.confirm({
title: '确认删除服务器', title: '确认删除 MCP',
content: `确定要删除服务器 "${server.name}" 吗?此操作不可撤销。`, content: `确定要删除 MCP "${server.name}" 吗?此操作不可撤销。`,
okText: '删除', okText: '删除',
okType: 'danger', okType: 'danger',
cancelText: '取消', cancelText: '取消',
@ -931,14 +931,14 @@ const confirmDeleteServer = (server) => {
try { try {
const result = await mcpApi.deleteMcpServer(server.name) const result = await mcpApi.deleteMcpServer(server.name)
if (result.success) { if (result.success) {
notification.success({ message: '服务器删除成功' }) message.success('MCP 删除成功')
await fetchServers() await fetchServers()
} else { } else {
notification.error({ message: result.message || '删除失败' }) message.error(result.message || '删除失败')
} }
} catch (err) { } catch (err) {
console.error('删除失败:', err) console.error('删除失败:', err)
notification.error({ message: err.message || '删除失败' }) message.error(err.message || '删除失败')
} }
} }
}) })
@ -950,7 +950,7 @@ const formatJson = () => {
const obj = JSON.parse(jsonContent.value) const obj = JSON.parse(jsonContent.value)
jsonContent.value = JSON.stringify(obj, null, 2) jsonContent.value = JSON.stringify(obj, null, 2)
} catch { } catch {
notification.error({ message: 'JSON 格式错误,无法格式化' }) message.error('JSON 格式错误,无法格式化')
} }
} }
@ -973,9 +973,9 @@ const parseJsonToForm = () => {
icon: obj.icon || '' icon: obj.icon || ''
}) })
formMode.value = 'form' formMode.value = 'form'
notification.success({ message: '已解析到表单' }) message.success('已解析到表单')
} catch { } catch {
notification.error({ message: 'JSON 格式错误' }) message.error('JSON 格式错误')
} }
} }

View File

@ -281,7 +281,7 @@
<div class="config-header"> <div class="config-header">
<div class="text"> <div class="text">
<h3>依赖声明</h3> <h3>依赖声明</h3>
<p>配置此 Skill 所需的工具MCP 服务器及其他 Skill 依赖</p> <p>配置此 Skill 所需的工具MCP 及其他 Skill 依赖</p>
</div> </div>
<a-button <a-button
type="primary" type="primary"

View File

@ -3,7 +3,7 @@
<div class="extensions-header"> <div class="extensions-header">
<a-tabs v-model:activeKey="activeTab" class="extensions-tabs"> <a-tabs v-model:activeKey="activeTab" class="extensions-tabs">
<a-tab-pane key="tools" tab="工具" /> <a-tab-pane key="tools" tab="工具" />
<a-tab-pane key="mcp" tab="MCP 服务器" /> <a-tab-pane key="mcp" tab="MCP 管理" />
<a-tab-pane key="subagents" tab="Subagents 管理" /> <a-tab-pane key="subagents" tab="Subagents 管理" />
<a-tab-pane key="skills" tab="Skills 管理" /> <a-tab-pane key="skills" tab="Skills 管理" />
</a-tabs> </a-tabs>