mirror of
https://github.com/purocean/yn.git
synced 2026-09-01 15:37:16 +08:00
feat: add mcp settings plugin
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
@@ -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',
|
||||
|
||||
@@ -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': 'Пусто',
|
||||
|
||||
@@ -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': '无结果',
|
||||
|
||||
@@ -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': '無結果',
|
||||
|
||||
Reference in New Issue
Block a user