feat: add mcp settings plugin

This commit is contained in:
purocean
2026-05-01 12:53:43 +08:00
parent ecc66e12c3
commit fb637abb18
7 changed files with 94 additions and 17 deletions
-9
View File
@@ -511,15 +511,6 @@ const schema: SettingSchema = ({
format: 'checkbox',
required: true,
},
'mcp.enabled': {
defaultValue: false,
title: 'T_setting-panel.schema.mcp-enabled',
type: 'boolean',
group: 'other',
description: 'T_setting-panel.schema.mcp-enabled-desc',
format: 'checkbox',
required: true,
},
envs: {
defaultValue: '',
title: 'T_setting-panel.schema.envs',
+2
View File
@@ -78,6 +78,7 @@ import previewFont from '@fe/plugins/preview-font'
import dropToOpenFile from '@fe/plugins/drop-to-open-file'
import recordRecentDocument from '@fe/plugins/record-recent-document'
import aiCopilot from '@fe/plugins/ai-copilot'
import mcpServer from '@fe/plugins/mcp-server'
import viewLinks from '@fe/plugins/view-links'
import insertTable from '@fe/plugins/insert-table'
import textComparator from '@fe/plugins/text-comparator'
@@ -164,6 +165,7 @@ export default [
dropToOpenFile,
recordRecentDocument,
aiCopilot,
mcpServer,
viewLinks,
insertTable,
textComparator,
+76
View File
@@ -0,0 +1,76 @@
import type { Ctx, Plugin } from '@fe/context'
const settingKey = 'mcp.enabled'
const copyEndpointAction = 'plugin.mcp-server.copy-endpoint'
const endpointPath = '/api/mcp/message'
function getMcpEndpointUrl (ctx: Ctx) {
let port = ''
try {
const url = new URL(window.location.href)
port = url.searchParams.get('port') || ''
if (!port && /^https?:$/.test(url.protocol) && url.port && url.port !== '8066') {
port = url.port
}
} catch (error) {
// Ignore invalid URLs from non-standard runtime environments.
}
if (!port) {
port = String(ctx.setting.getSetting('server.port', 3044))
}
return `http://127.0.0.1:${port}${endpointPath}`
}
function appendEndpointLink (ctx: Ctx, editor: any) {
const field = editor.getEditor(`root.${settingKey}`)
const label = field?.label as HTMLLabelElement | undefined
if (!label || label.querySelector('.setting-mcp-endpoint')) {
return
}
const endpointUrl = getMcpEndpointUrl(ctx)
const wrapper = document.createElement('span')
const link = document.createElement('a')
link.href = `javascript:ctx.action.getActionHandler('${copyEndpointAction}')()`
link.className = 'setting-mcp-endpoint'
wrapper.style.cssText = 'display:inline-block;font-size:13px;line-height:1.35;word-break:break-all;'
wrapper.appendChild(document.createTextNode(endpointUrl + ' '))
link.textContent = ctx.i18n.t('copy')
link.title = ctx.i18n.t('click-to-copy')
wrapper.appendChild(link)
label.appendChild(wrapper)
}
export default {
name: 'mcp-server',
register: (ctx) => {
ctx.action.registerAction({
name: copyEndpointAction,
description: ctx.i18n.t('copy'),
handler: () => {
ctx.utils.copyText(getMcpEndpointUrl(ctx))
},
})
ctx.registerHook('SETTING_PANEL_BEFORE_SHOW', () => {
ctx.setting.changeSchema((schema) => {
;(schema.properties as any)[settingKey] = {
defaultValue: false,
title: ctx.i18n.t('plugin-mcp-server.enable' as any) as any,
type: 'boolean',
group: 'other',
format: 'checkbox',
required: true,
}
})
})
ctx.registerHook('SETTING_PANEL_AFTER_SHOW', ({ editor }) => {
appendEndpointLink(ctx, editor)
})
}
} as Plugin
+4 -2
View File
@@ -10,6 +10,7 @@ const data = {
'ok': 'OK',
'demo-tips': 'Some features are not available in DEMO mode.',
'more': 'More',
'copy': 'Copy',
'copied': 'Copied',
'others': 'Others',
'insert-different-repo-doc': 'Documents from different repository cannot be inserted',
@@ -495,10 +496,11 @@ const data = {
},
'hide-main-window-on-startup': 'Hide Main Window on Startup',
'keep-running-after-closing-window': 'Keep Running after Closing Window',
'mcp-enabled': 'Enable MCP Server',
'mcp-enabled-desc': 'Expose Yank Note actions through the MCP endpoint: /api/mcp/message. Clients must connect to the local server URL and use the same access permissions as the app.',
}
},
'plugin-mcp-server': {
'enable': 'Enable MCP Server (Streamable HTTP)',
},
'quick-open': {
'input-placeholder': 'Type characters...',
'empty': 'Empty',
+4 -2
View File
@@ -11,6 +11,7 @@ const data: BaseLanguage = {
'ok': 'OK',
'demo-tips': 'Некоторые функции недоступны в ДЕМО режиме.',
'more': 'Ещё',
'copy': 'Копировать',
'copied': 'Скопировано',
'others': 'Другие',
'insert-different-repo-doc': 'Документы не могут быть вставлены из другого репозитория',
@@ -496,10 +497,11 @@ const data: BaseLanguage = {
},
'hide-main-window-on-startup': 'Скрыть главное окно при запуске',
'keep-running-after-closing-window': 'Продолжать работу после закрытия окна',
'mcp-enabled': 'Включить MCP-сервер',
'mcp-enabled-desc': 'Предоставляет действия Yank Note через MCP endpoint: /api/mcp/message. Клиент должен подключаться к локальному адресу сервера и использовать те же права доступа, что и приложение.',
}
},
'plugin-mcp-server': {
'enable': 'Включить MCP-сервер (Streamable HTTP)',
},
'quick-open': {
'input-placeholder': 'Введите...',
'empty': 'Пусто',
+4 -2
View File
@@ -11,6 +11,7 @@ const data: BaseLanguage = {
'ok': '确定',
'demo-tips': 'DEMO 模式下一些功能不可用',
'more': '更多',
'copy': '复制',
'copied': '已复制',
'others': '其他',
'insert-different-repo-doc': '不能插入不同仓库的文档',
@@ -486,8 +487,6 @@ const data: BaseLanguage = {
},
'keep-running-after-closing-window': '关闭窗口后保持运行',
'hide-main-window-on-startup': '启动时隐藏主窗口',
'mcp-enabled': '启用 MCP 服务器',
'mcp-enabled-desc': '通过 MCP 端点暴露 Yank Note 操作:/api/mcp/message。客户端需要连接本地服务地址,并使用和应用一致的访问权限。',
},
'tabs': {
'repos': '仓库',
@@ -500,6 +499,9 @@ const data: BaseLanguage = {
'other': '其他',
},
},
'plugin-mcp-server': {
'enable': '启用 MCP 服务器(Streamable HTTP',
},
'quick-open': {
'input-placeholder': '键入字符……',
'empty': '无结果',
+4 -2
View File
@@ -11,6 +11,7 @@ const data: BaseLanguage = {
'ok': '確定',
'demo-tips': 'DEMO 模式下某些功能不可用',
'more': '更多',
'copy': '複製',
'copied': '已複製',
'others': '其他',
'insert-different-repo-doc': '不能插入不同倉庫的文檔',
@@ -486,8 +487,6 @@ const data: BaseLanguage = {
},
'keep-running-after-closing-window': '關閉視窗後保持執行',
'hide-main-window-on-startup': '啟動時隱藏主視窗',
'mcp-enabled': '啟用 MCP 伺服器',
'mcp-enabled-desc': '透過 MCP 端點暴露 Yank Note 操作:/api/mcp/message。客戶端需要連線本機服務位址,並使用和應用一致的存取權限。',
},
'tabs': {
'repos': '倉庫',
@@ -500,6 +499,9 @@ const data: BaseLanguage = {
'other': '其他',
},
},
'plugin-mcp-server': {
'enable': '啟用 MCP 伺服器(Streamable HTTP',
},
'quick-open': {
'input-placeholder': '輸入字元……',
'empty': '無結果',