diff --git a/src/main/jsonrpc.ts b/src/main/jsonrpc.ts index 53ab70ed..d01e278a 100644 --- a/src/main/jsonrpc.ts +++ b/src/main/jsonrpc.ts @@ -6,7 +6,6 @@ type Ctx = { showSettingPanel: (key?: string) => void getSchemaForMcp: () => Promise getSettingsForMcp: () => Promise> - setSettingForMcp: (key: string, value: any) => Promise> }, doc: { switchDocByPath: (path: string) => Promise diff --git a/src/main/server/__tests__/mcp.ts b/src/main/server/__tests__/mcp.ts index 19c6dfc5..ea416846 100644 --- a/src/main/server/__tests__/mcp.ts +++ b/src/main/server/__tests__/mcp.ts @@ -15,9 +15,9 @@ const mocks = vi.hoisted(() => ({ executeAction: vi.fn(), }, setting: { + showSettingPanel: vi.fn(), getSchemaForMcp: vi.fn(), getSettingsForMcp: vi.fn(), - setSettingForMcp: vi.fn(), }, }, }, @@ -120,9 +120,9 @@ afterEach(() => { mocks.exportDocumentForMcp.mockReset() mocks.jsonRPCClient.call.ctx.action.getRawActions.mockReset() mocks.jsonRPCClient.call.ctx.action.executeAction.mockReset() + mocks.jsonRPCClient.call.ctx.setting.showSettingPanel.mockReset() mocks.jsonRPCClient.call.ctx.setting.getSchemaForMcp.mockReset() mocks.jsonRPCClient.call.ctx.setting.getSettingsForMcp.mockReset() - mocks.jsonRPCClient.call.ctx.setting.setSettingForMcp.mockReset() }) describe('MCP server request handling', () => { @@ -163,7 +163,7 @@ describe('MCP server request handling', () => { 'yn_export_document', 'yn_get_config_schema', 'yn_get_all_configs', - 'yn_set_config', + 'yn_show_setting_panel', ]) const callTool = server.handlers.get(CallToolRequestSchema) @@ -218,7 +218,7 @@ describe('MCP server request handling', () => { expect(JSON.parse(exported.content[0].text)).toEqual({ success: true, result: { base64: 'ZGF0YQ==' } }) }) - it('gets config schema, fetches all configs, and sets a config with refresh', async () => { + it('gets config schema, fetches all configs, and opens the setting panel', async () => { const { server } = await initEnabledServer() const callTool = server.handlers.get(CallToolRequestSchema) @@ -253,13 +253,12 @@ describe('MCP server request handling', () => { result: { theme: 'dark', readonly: true }, }) - mocks.jsonRPCClient.call.ctx.setting.setSettingForMcp.mockResolvedValue({ theme: 'light' }) - const setConfig = await callTool({ params: { name: 'yn_set_config', arguments: { key: 'theme', value: 'light' } } }) - expect(JSON.parse(setConfig.content[0].text)).toEqual({ + const openPanel = await callTool({ params: { name: 'yn_show_setting_panel', arguments: { key: 'theme' } } }) + expect(JSON.parse(openPanel.content[0].text)).toEqual({ success: true, - result: { key: 'theme', value: 'light', refreshed: true }, + result: { key: 'theme' }, }) - expect(mocks.jsonRPCClient.call.ctx.setting.setSettingForMcp).toHaveBeenCalledWith('theme', 'light') + expect(mocks.jsonRPCClient.call.ctx.setting.showSettingPanel).toHaveBeenCalledWith('theme') mocks.jsonRPCClient.call.ctx.setting.getSchemaForMcp.mockResolvedValue({ properties: {} }) const missing = await callTool({ params: { name: 'yn_get_config_schema', arguments: { key: 'missing' } } }) diff --git a/src/main/server/mcp.ts b/src/main/server/mcp.ts index f6efc0dd..3a3ae70b 100644 --- a/src/main/server/mcp.ts +++ b/src/main/server/mcp.ts @@ -61,13 +61,11 @@ async function getAllConfigs () { return await jsonRPCClient.call.ctx.setting.getSettingsForMcp() } -async function setConfig (key: string, value: any) { - const settings = await jsonRPCClient.call.ctx.setting.setSettingForMcp(key, value) +async function showSettingPanel (key?: string) { + await jsonRPCClient.call.ctx.setting.showSettingPanel(key) return { - key, - value: settings?.[key], - refreshed: true, + key: key || null, } } @@ -446,20 +444,16 @@ function createMCPServer (): Server { }, }, { - name: 'yn_set_config', - description: 'Set one Yank Note config value by key, persist it, and refresh frontend settings/hooks immediately.', + name: 'yn_show_setting_panel', + description: 'Open the Yank Note setting panel, optionally locating a specific config key or setting group.', inputSchema: { type: 'object', properties: { key: { type: 'string', - description: 'Config key to update.', - }, - value: { - description: 'New config value. Match the type defined in yn_get_config_schema.', + description: 'Optional config key or setting group to locate.', }, }, - required: ['key', 'value'], additionalProperties: false, }, }, @@ -647,11 +641,11 @@ function createMCPServer (): Server { } } - if (name === 'yn_set_config') { - const { key, value } = (args || {}) as any + if (name === 'yn_show_setting_panel') { + const { key } = (args || {}) as any try { - const result = await setConfig(key, value) + const result = await showSettingPanel(key) return { content: [ diff --git a/src/renderer/services/__tests__/setting.ts b/src/renderer/services/__tests__/setting.ts index 1f879ed2..48ac57f5 100644 --- a/src/renderer/services/__tests__/setting.ts +++ b/src/renderer/services/__tests__/setting.ts @@ -199,7 +199,7 @@ test('gets and sets individual settings without exposing mutable local state', a expect(mocks.writtenSettings).toStrictEqual({ readonly: true }) }) -test('provides MCP helpers for schema, refresh, and setting updates', async () => { +test('provides MCP helpers for schema and refreshed settings', async () => { const setting = await importSetting({ readonly: false }) mocks.fetchedSettings = { readonly: true } @@ -215,23 +215,6 @@ test('provides MCP helpers for schema, refresh, and setting updates', async () = const settings = await setting.getSettingsForMcp() expect(settings.readonly).toBe(true) expect(mocks.hooks[0]).toMatchObject({ name: 'SETTING_FETCHED' }) - - mocks.hooks = [] - await setting.setSettingForMcp('readonly', false) - expect(mocks.hooks[0]).toStrictEqual({ - name: 'SETTING_PANEL_BEFORE_SHOW', - payload: {}, - options: { breakable: true }, - }) - expect(mocks.writtenSettings).toStrictEqual({ readonly: false }) - - mocks.hooks = [] - mocks.fetchedSettings = { readonly: true } - const themeSettings = await setting.setSettingForMcp('theme', 'light') - expect(mocks.setTheme).toHaveBeenCalledWith('light') - expect(themeSettings.readonly).toBe(true) - - await expect(setting.setSettingForMcp('missing', true)).rejects.toThrow('Unknown setting key: missing') }) test('shows, locates, and hides setting panel', async () => { diff --git a/src/renderer/services/setting.ts b/src/renderer/services/setting.ts index a320c8bc..72b1340e 100644 --- a/src/renderer/services/setting.ts +++ b/src/renderer/services/setting.ts @@ -6,7 +6,7 @@ import { basename } from '@fe/utils/path' import { sleep } from '@fe/utils' import type { BuildInSettings, FileItem, PathItem, SettingGroup, SettingSchema } from '@fe/types' import { getDefaultSettingSchema } from '@fe/others/setting-schema' -import { getThemeName, setTheme } from './theme' +import { getThemeName } from './theme' import { t } from './i18n' type Schema = SettingSchema @@ -188,21 +188,6 @@ export async function setSetting (key: T, val: await writeSettings({ [key]: val }) } -export async function setSettingForMcp (key: string, val: any) { - await prepareSchemaForMcp() - - if (!Object.prototype.hasOwnProperty.call(schema.properties, key)) { - throw new Error(`Unknown setting key: ${key}`) - } - - if (key === 'theme') { - setTheme(val) - return await fetchSettings() - } - - return await writeSettings({ [key]: val }) -} - /** * Show setting panel. * @param keyOrGroup