diff --git a/packages/core/src/tools/create/components.ts b/packages/core/src/tools/create/components.ts index b8d59a15a..dac3811d0 100644 --- a/packages/core/src/tools/create/components.ts +++ b/packages/core/src/tools/create/components.ts @@ -40,6 +40,7 @@ export const createInstance = defineTool({ export const combineAsVariants = defineTool({ name: 'combine_as_variants', mutates: true, + documentAccess: 'modify', description: 'Combine components sharing a parent into a component set (variant set). Components named ' + '"Category/Value" (e.g. "Button/Primary") derive variant properties from the name segments.', diff --git a/packages/vue/src/i18n/locales/de/dialogs.json b/packages/vue/src/i18n/locales/de/dialogs.json index 459c84326..30fde081a 100644 --- a/packages/vue/src/i18n/locales/de/dialogs.json +++ b/packages/vue/src/i18n/locales/de/dialogs.json @@ -308,5 +308,34 @@ "harnessToolPermissions": "Tool-Berechtigungen", "harnessPermissionReads": "Vor Änderungen und Befehlen fragen", "harnessPermissionEdits": "Vor Befehlen fragen", - "harnessPermissionAll": "Alle Tools zulassen" + "harnessPermissionAll": "Alle Tools zulassen", + "settingsMCP": "MCP & automation", + "mcpDescription": "Monitor and restart the local MCP server used by agents and automation.", + "mcpStatus": "Status", + "mcpPort": "Port", + "mcpAddress": "Address", + "mcpVersion": "Version", + "mcpAuthentication": "Require authentication", + "mcpAuthenticationDescription": "Protect the localhost MCP endpoint with a bearer token. Disable only on a trusted machine. Restart the server to apply changes.", + "mcpRootDirectory": "MCP root directory", + "mcpRootDirectoryDefault": "User home directory (default)", + "mcpChooseRootDirectory": "Choose folder", + "mcpUseDefaultRoot": "Use default", + "mcpRootDirectoryDescription": "File tools are limited to this folder. Restart the MCP server to apply changes.", + "mcpTools": "Available tools", + "mcpInspectionTools": "Inspection tools", + "mcpModificationTools": "Modification tools", + "mcpToolsEnabled": "{enabled} of {total} enabled", + "mcpEnableAllTools": "Enable all", + "mcpSearchTools": "Search MCP tools", + "mcpToolsRestartNotice": "Restart the MCP server, then reconnect stdio clients, to apply tool availability changes.", + "mcpExternalRestartNotice": "This server is managed by another process. Restart that process to apply changes.", + "mcpRestart": "Restart MCP server", + "mcpExternallyManaged": "Managed externally", + "mcpStarting": "Starting…", + "mcpStatus_idle": "Not initialized", + "mcpStatus_starting": "Starting", + "mcpStatus_running": "Running", + "mcpStatus_stopped": "Stopped", + "mcpStatus_error": "Error" } diff --git a/packages/vue/src/i18n/locales/es/dialogs.json b/packages/vue/src/i18n/locales/es/dialogs.json index 026012e94..0634ffbd0 100644 --- a/packages/vue/src/i18n/locales/es/dialogs.json +++ b/packages/vue/src/i18n/locales/es/dialogs.json @@ -308,5 +308,34 @@ "harnessToolPermissions": "Permisos de herramientas", "harnessPermissionReads": "Preguntar antes de editar y ejecutar comandos", "harnessPermissionEdits": "Preguntar antes de ejecutar comandos", - "harnessPermissionAll": "Permitir todas las herramientas" + "harnessPermissionAll": "Permitir todas las herramientas", + "settingsMCP": "MCP & automation", + "mcpDescription": "Monitor and restart the local MCP server used by agents and automation.", + "mcpStatus": "Status", + "mcpPort": "Port", + "mcpAddress": "Address", + "mcpVersion": "Version", + "mcpAuthentication": "Require authentication", + "mcpAuthenticationDescription": "Protect the localhost MCP endpoint with a bearer token. Disable only on a trusted machine. Restart the server to apply changes.", + "mcpRootDirectory": "MCP root directory", + "mcpRootDirectoryDefault": "User home directory (default)", + "mcpChooseRootDirectory": "Choose folder", + "mcpUseDefaultRoot": "Use default", + "mcpRootDirectoryDescription": "File tools are limited to this folder. Restart the MCP server to apply changes.", + "mcpTools": "Available tools", + "mcpInspectionTools": "Inspection tools", + "mcpModificationTools": "Modification tools", + "mcpToolsEnabled": "{enabled} of {total} enabled", + "mcpEnableAllTools": "Enable all", + "mcpSearchTools": "Search MCP tools", + "mcpToolsRestartNotice": "Restart the MCP server, then reconnect stdio clients, to apply tool availability changes.", + "mcpExternalRestartNotice": "This server is managed by another process. Restart that process to apply changes.", + "mcpRestart": "Restart MCP server", + "mcpExternallyManaged": "Managed externally", + "mcpStarting": "Starting…", + "mcpStatus_idle": "Not initialized", + "mcpStatus_starting": "Starting", + "mcpStatus_running": "Running", + "mcpStatus_stopped": "Stopped", + "mcpStatus_error": "Error" } diff --git a/packages/vue/src/i18n/locales/fr/dialogs.json b/packages/vue/src/i18n/locales/fr/dialogs.json index 9d0693ab6..8af7d48bc 100644 --- a/packages/vue/src/i18n/locales/fr/dialogs.json +++ b/packages/vue/src/i18n/locales/fr/dialogs.json @@ -308,5 +308,34 @@ "harnessToolPermissions": "Autorisations des outils", "harnessPermissionReads": "Demander avant les modifications et les commandes", "harnessPermissionEdits": "Demander avant les commandes", - "harnessPermissionAll": "Autoriser tous les outils" + "harnessPermissionAll": "Autoriser tous les outils", + "settingsMCP": "MCP & automation", + "mcpDescription": "Monitor and restart the local MCP server used by agents and automation.", + "mcpStatus": "Status", + "mcpPort": "Port", + "mcpAddress": "Address", + "mcpVersion": "Version", + "mcpAuthentication": "Require authentication", + "mcpAuthenticationDescription": "Protect the localhost MCP endpoint with a bearer token. Disable only on a trusted machine. Restart the server to apply changes.", + "mcpRootDirectory": "MCP root directory", + "mcpRootDirectoryDefault": "User home directory (default)", + "mcpChooseRootDirectory": "Choose folder", + "mcpUseDefaultRoot": "Use default", + "mcpRootDirectoryDescription": "File tools are limited to this folder. Restart the MCP server to apply changes.", + "mcpTools": "Available tools", + "mcpInspectionTools": "Inspection tools", + "mcpModificationTools": "Modification tools", + "mcpToolsEnabled": "{enabled} of {total} enabled", + "mcpEnableAllTools": "Enable all", + "mcpSearchTools": "Search MCP tools", + "mcpToolsRestartNotice": "Restart the MCP server, then reconnect stdio clients, to apply tool availability changes.", + "mcpExternalRestartNotice": "This server is managed by another process. Restart that process to apply changes.", + "mcpRestart": "Restart MCP server", + "mcpExternallyManaged": "Managed externally", + "mcpStarting": "Starting…", + "mcpStatus_idle": "Not initialized", + "mcpStatus_starting": "Starting", + "mcpStatus_running": "Running", + "mcpStatus_stopped": "Stopped", + "mcpStatus_error": "Error" } diff --git a/packages/vue/src/i18n/locales/it/dialogs.json b/packages/vue/src/i18n/locales/it/dialogs.json index 772d658ec..5e600ad10 100644 --- a/packages/vue/src/i18n/locales/it/dialogs.json +++ b/packages/vue/src/i18n/locales/it/dialogs.json @@ -308,5 +308,34 @@ "harnessToolPermissions": "Autorizzazioni degli strumenti", "harnessPermissionReads": "Chiedi prima di modifiche e comandi", "harnessPermissionEdits": "Chiedi prima dei comandi", - "harnessPermissionAll": "Consenti tutti gli strumenti" + "harnessPermissionAll": "Consenti tutti gli strumenti", + "settingsMCP": "MCP & automation", + "mcpDescription": "Monitor and restart the local MCP server used by agents and automation.", + "mcpStatus": "Status", + "mcpPort": "Port", + "mcpAddress": "Address", + "mcpVersion": "Version", + "mcpAuthentication": "Require authentication", + "mcpAuthenticationDescription": "Protect the localhost MCP endpoint with a bearer token. Disable only on a trusted machine. Restart the server to apply changes.", + "mcpRootDirectory": "MCP root directory", + "mcpRootDirectoryDefault": "User home directory (default)", + "mcpChooseRootDirectory": "Choose folder", + "mcpUseDefaultRoot": "Use default", + "mcpRootDirectoryDescription": "File tools are limited to this folder. Restart the MCP server to apply changes.", + "mcpTools": "Available tools", + "mcpInspectionTools": "Inspection tools", + "mcpModificationTools": "Modification tools", + "mcpToolsEnabled": "{enabled} of {total} enabled", + "mcpEnableAllTools": "Enable all", + "mcpSearchTools": "Search MCP tools", + "mcpToolsRestartNotice": "Restart the MCP server, then reconnect stdio clients, to apply tool availability changes.", + "mcpExternalRestartNotice": "This server is managed by another process. Restart that process to apply changes.", + "mcpRestart": "Restart MCP server", + "mcpExternallyManaged": "Managed externally", + "mcpStarting": "Starting…", + "mcpStatus_idle": "Not initialized", + "mcpStatus_starting": "Starting", + "mcpStatus_running": "Running", + "mcpStatus_stopped": "Stopped", + "mcpStatus_error": "Error" } diff --git a/packages/vue/src/i18n/locales/ja/dialogs.json b/packages/vue/src/i18n/locales/ja/dialogs.json index 1a9713609..8650467df 100644 --- a/packages/vue/src/i18n/locales/ja/dialogs.json +++ b/packages/vue/src/i18n/locales/ja/dialogs.json @@ -308,5 +308,34 @@ "harnessToolPermissions": "ツール権限", "harnessPermissionReads": "編集とコマンドの前に確認", "harnessPermissionEdits": "コマンドの前に確認", - "harnessPermissionAll": "すべてのツールを許可" + "harnessPermissionAll": "すべてのツールを許可", + "settingsMCP": "MCP & automation", + "mcpDescription": "Monitor and restart the local MCP server used by agents and automation.", + "mcpStatus": "Status", + "mcpPort": "Port", + "mcpAddress": "Address", + "mcpVersion": "Version", + "mcpAuthentication": "Require authentication", + "mcpAuthenticationDescription": "Protect the localhost MCP endpoint with a bearer token. Disable only on a trusted machine. Restart the server to apply changes.", + "mcpRootDirectory": "MCP root directory", + "mcpRootDirectoryDefault": "User home directory (default)", + "mcpChooseRootDirectory": "Choose folder", + "mcpUseDefaultRoot": "Use default", + "mcpRootDirectoryDescription": "File tools are limited to this folder. Restart the MCP server to apply changes.", + "mcpTools": "Available tools", + "mcpInspectionTools": "Inspection tools", + "mcpModificationTools": "Modification tools", + "mcpToolsEnabled": "{enabled} of {total} enabled", + "mcpEnableAllTools": "Enable all", + "mcpSearchTools": "Search MCP tools", + "mcpToolsRestartNotice": "Restart the MCP server, then reconnect stdio clients, to apply tool availability changes.", + "mcpExternalRestartNotice": "This server is managed by another process. Restart that process to apply changes.", + "mcpRestart": "Restart MCP server", + "mcpExternallyManaged": "Managed externally", + "mcpStarting": "Starting…", + "mcpStatus_idle": "Not initialized", + "mcpStatus_starting": "Starting", + "mcpStatus_running": "Running", + "mcpStatus_stopped": "Stopped", + "mcpStatus_error": "Error" } diff --git a/packages/vue/src/i18n/locales/pl/dialogs.json b/packages/vue/src/i18n/locales/pl/dialogs.json index d3a84cb7e..8614284d9 100644 --- a/packages/vue/src/i18n/locales/pl/dialogs.json +++ b/packages/vue/src/i18n/locales/pl/dialogs.json @@ -308,5 +308,34 @@ "harnessToolPermissions": "Uprawnienia narzędzi", "harnessPermissionReads": "Pytaj przed zmianami i poleceniami", "harnessPermissionEdits": "Pytaj przed poleceniami", - "harnessPermissionAll": "Zezwalaj na wszystkie narzędzia" + "harnessPermissionAll": "Zezwalaj na wszystkie narzędzia", + "settingsMCP": "MCP & automation", + "mcpDescription": "Monitor and restart the local MCP server used by agents and automation.", + "mcpStatus": "Status", + "mcpPort": "Port", + "mcpAddress": "Address", + "mcpVersion": "Version", + "mcpAuthentication": "Require authentication", + "mcpAuthenticationDescription": "Protect the localhost MCP endpoint with a bearer token. Disable only on a trusted machine. Restart the server to apply changes.", + "mcpRootDirectory": "MCP root directory", + "mcpRootDirectoryDefault": "User home directory (default)", + "mcpChooseRootDirectory": "Choose folder", + "mcpUseDefaultRoot": "Use default", + "mcpRootDirectoryDescription": "File tools are limited to this folder. Restart the MCP server to apply changes.", + "mcpTools": "Available tools", + "mcpInspectionTools": "Inspection tools", + "mcpModificationTools": "Modification tools", + "mcpToolsEnabled": "{enabled} of {total} enabled", + "mcpEnableAllTools": "Enable all", + "mcpSearchTools": "Search MCP tools", + "mcpToolsRestartNotice": "Restart the MCP server, then reconnect stdio clients, to apply tool availability changes.", + "mcpExternalRestartNotice": "This server is managed by another process. Restart that process to apply changes.", + "mcpRestart": "Restart MCP server", + "mcpExternallyManaged": "Managed externally", + "mcpStarting": "Starting…", + "mcpStatus_idle": "Not initialized", + "mcpStatus_starting": "Starting", + "mcpStatus_running": "Running", + "mcpStatus_stopped": "Stopped", + "mcpStatus_error": "Error" } diff --git a/packages/vue/src/i18n/locales/ru/dialogs.json b/packages/vue/src/i18n/locales/ru/dialogs.json index 6efadaf1c..51ddb9793 100644 --- a/packages/vue/src/i18n/locales/ru/dialogs.json +++ b/packages/vue/src/i18n/locales/ru/dialogs.json @@ -308,5 +308,34 @@ "harnessToolPermissions": "Разрешения инструментов", "harnessPermissionReads": "Спрашивать перед изменениями и командами", "harnessPermissionEdits": "Спрашивать перед командами", - "harnessPermissionAll": "Разрешить все инструменты" + "harnessPermissionAll": "Разрешить все инструменты", + "settingsMCP": "MCP & automation", + "mcpDescription": "Monitor and restart the local MCP server used by agents and automation.", + "mcpStatus": "Status", + "mcpPort": "Port", + "mcpAddress": "Address", + "mcpVersion": "Version", + "mcpAuthentication": "Require authentication", + "mcpAuthenticationDescription": "Protect the localhost MCP endpoint with a bearer token. Disable only on a trusted machine. Restart the server to apply changes.", + "mcpRootDirectory": "MCP root directory", + "mcpRootDirectoryDefault": "User home directory (default)", + "mcpChooseRootDirectory": "Choose folder", + "mcpUseDefaultRoot": "Use default", + "mcpRootDirectoryDescription": "File tools are limited to this folder. Restart the MCP server to apply changes.", + "mcpTools": "Available tools", + "mcpInspectionTools": "Inspection tools", + "mcpModificationTools": "Modification tools", + "mcpToolsEnabled": "{enabled} of {total} enabled", + "mcpEnableAllTools": "Enable all", + "mcpSearchTools": "Search MCP tools", + "mcpToolsRestartNotice": "Restart the MCP server, then reconnect stdio clients, to apply tool availability changes.", + "mcpExternalRestartNotice": "This server is managed by another process. Restart that process to apply changes.", + "mcpRestart": "Restart MCP server", + "mcpExternallyManaged": "Managed externally", + "mcpStarting": "Starting…", + "mcpStatus_idle": "Not initialized", + "mcpStatus_starting": "Starting", + "mcpStatus_running": "Running", + "mcpStatus_stopped": "Stopped", + "mcpStatus_error": "Error" } diff --git a/packages/vue/src/i18n/locales/zh-cn/dialogs.json b/packages/vue/src/i18n/locales/zh-cn/dialogs.json index bb8b36e3c..dba63c144 100644 --- a/packages/vue/src/i18n/locales/zh-cn/dialogs.json +++ b/packages/vue/src/i18n/locales/zh-cn/dialogs.json @@ -308,5 +308,34 @@ "harnessToolPermissions": "工具权限", "harnessPermissionReads": "编辑和执行命令前询问", "harnessPermissionEdits": "执行命令前询问", - "harnessPermissionAll": "允许所有工具" + "harnessPermissionAll": "允许所有工具", + "settingsMCP": "MCP & automation", + "mcpDescription": "Monitor and restart the local MCP server used by agents and automation.", + "mcpStatus": "Status", + "mcpPort": "Port", + "mcpAddress": "Address", + "mcpVersion": "Version", + "mcpAuthentication": "Require authentication", + "mcpAuthenticationDescription": "Protect the localhost MCP endpoint with a bearer token. Disable only on a trusted machine. Restart the server to apply changes.", + "mcpRootDirectory": "MCP root directory", + "mcpRootDirectoryDefault": "User home directory (default)", + "mcpChooseRootDirectory": "Choose folder", + "mcpUseDefaultRoot": "Use default", + "mcpRootDirectoryDescription": "File tools are limited to this folder. Restart the MCP server to apply changes.", + "mcpTools": "Available tools", + "mcpInspectionTools": "Inspection tools", + "mcpModificationTools": "Modification tools", + "mcpToolsEnabled": "{enabled} of {total} enabled", + "mcpEnableAllTools": "Enable all", + "mcpSearchTools": "Search MCP tools", + "mcpToolsRestartNotice": "Restart the MCP server, then reconnect stdio clients, to apply tool availability changes.", + "mcpExternalRestartNotice": "This server is managed by another process. Restart that process to apply changes.", + "mcpRestart": "Restart MCP server", + "mcpExternallyManaged": "Managed externally", + "mcpStarting": "Starting…", + "mcpStatus_idle": "Not initialized", + "mcpStatus_starting": "Starting", + "mcpStatus_running": "Running", + "mcpStatus_stopped": "Stopped", + "mcpStatus_error": "Error" } diff --git a/packages/vue/src/i18n/messages/dialogs.ts b/packages/vue/src/i18n/messages/dialogs.ts index a5630cfd2..fb48d42aa 100644 --- a/packages/vue/src/i18n/messages/dialogs.ts +++ b/packages/vue/src/i18n/messages/dialogs.ts @@ -270,7 +270,10 @@ export const dialogMessageDefaults = { mcpSearchTools: 'Search MCP tools', mcpToolsRestartNotice: 'Restart the MCP server, then reconnect stdio clients, to apply tool availability changes.', + mcpExternalRestartNotice: + 'This server is managed by another process. Restart that process to apply changes.', mcpRestart: 'Restart MCP server', + mcpExternallyManaged: 'Managed externally', mcpStarting: 'Starting…', mcpStatus_idle: 'Not initialized', mcpStatus_starting: 'Starting', diff --git a/src/app/automation/mcp/runtime.ts b/src/app/automation/mcp/runtime.ts index 078d690d7..4ccfc4701 100644 --- a/src/app/automation/mcp/runtime.ts +++ b/src/app/automation/mcp/runtime.ts @@ -16,13 +16,20 @@ export const mcpRuntime = reactive({ port: AUTOMATION_HTTP_PORT, version: null as string | null, error: null as string | null, - checking: false + checking: false, + externallyManaged: false }) let server: AutomationServerHandle | null = null let disconnectAutomation: (() => void) | null = null let activeStore: (() => EditorStore) | null = null -let operation: Promise | null = null +let lifecycle = Promise.resolve() + +function enqueueLifecycle(operation: () => Promise): Promise { + const next = lifecycle.then(operation, operation) + lifecycle = next.catch(() => undefined) + return next +} export async function refreshMCPRuntime(): Promise { mcpRuntime.checking = true @@ -44,17 +51,29 @@ export async function refreshMCPRuntime(): Promise { async function start(): Promise { mcpRuntime.status = 'starting' mcpRuntime.error = null + mcpRuntime.externallyManaged = false try { server = await spawnMCPIfNeeded() + const health = await readAutomationHealth() + if (!health) throw new Error('MCP server did not become healthy') + mcpRuntime.externallyManaged = server?.managed === false if (activeStore && (import.meta.env.DEV || isTauri())) { disconnectAutomation = connectAutomation(activeStore, server?.authToken ?? null).disconnect } - const health = await readAutomationHealth() - if (!health) throw new Error('MCP server did not become healthy') mcpRuntime.version = health.version ?? null setMCPToolCatalog(health.tools ?? []) mcpRuntime.status = 'running' } catch (error) { + disconnectAutomation?.() + disconnectAutomation = null + if (server) { + try { + await server.disconnect() + } catch (disconnectError) { + console.warn('[MCP] Failed to stop server after startup error:', disconnectError) + } + } + server = null mcpRuntime.status = 'error' mcpRuntime.error = error instanceof Error ? error.message : String(error) console.warn('[MCP]', error) @@ -63,29 +82,28 @@ async function start(): Promise { export function startMCPRuntime(getStore: () => EditorStore): Promise { activeStore = getStore - operation ??= start().finally(() => { - operation = null - }) - return operation + return enqueueLifecycle(start) } -export async function stopMCPRuntime(): Promise { +async function stop(): Promise { disconnectAutomation?.() disconnectAutomation = null await server?.disconnect() server = null mcpRuntime.status = 'stopped' mcpRuntime.version = null + mcpRuntime.externallyManaged = false setMCPToolCatalog([]) } -export async function restartMCPRuntime(): Promise { - if (operation) await operation - await stopMCPRuntime() - await startMCPRuntime( - activeStore ?? - (() => { - throw new Error('Editor is not ready') - }) - ) +export function stopMCPRuntime(): Promise { + return enqueueLifecycle(stop) +} + +export function restartMCPRuntime(): Promise { + return enqueueLifecycle(async () => { + await stop() + if (!activeStore) throw new Error('Editor is not ready') + await start() + }) } diff --git a/src/app/automation/mcp/spawn.ts b/src/app/automation/mcp/spawn.ts index 3e715209a..0ee1b11d1 100644 --- a/src/app/automation/mcp/spawn.ts +++ b/src/app/automation/mcp/spawn.ts @@ -23,6 +23,7 @@ export interface AutomationHealth { export interface AutomationServerHandle { disconnect: () => void | Promise authToken: string | null + managed: boolean } const DEV_AUTOMATION_AUTH_TOKEN = @@ -239,32 +240,36 @@ export async function getAutomationAuthToken(): Promise { return runtimeAutomationAuthToken } +async function readExistingServerHandle(): Promise { + const expectedDiscoveryPath = await computeExpectedDiscoveryPath() + if (!(await discoveryFileExists(expectedDiscoveryPath))) return null + + const health = await readAutomationHealth() + if (!health) return null + assertCompatibleMCPVersion(health) + const discoveryPath = await resolveDiscoveryPath(health.discoveryPath) + const token = await readDiscoveryToken(discoveryPath) + if (health.authRequired && !token) { + throw new Error( + 'MCP server requires authentication but the discovery token could not be read. ' + + 'Ensure the discovery file is accessible and contains an auth token.' + ) + } + runtimeAutomationAuthToken = token + return { disconnect: noop, authToken: token, managed: false } +} + async function startMCPIfNeeded(): Promise { runtimeAutomationStartupError = null if (import.meta.env.DEV || !isTauri()) { return DEV_AUTOMATION_AUTH_TOKEN - ? { disconnect: noop, authToken: DEV_AUTOMATION_AUTH_TOKEN } + ? { disconnect: noop, authToken: DEV_AUTOMATION_AUTH_TOKEN, managed: false } : null } - const expectedDiscoveryPath = await computeExpectedDiscoveryPath() - const hasDiscovery = await discoveryFileExists(expectedDiscoveryPath) - const existing = hasDiscovery ? await readAutomationHealth() : null + const existing = await readExistingServerHandle() if (existing) { - assertCompatibleMCPVersion(existing) - const discoveryPath = await resolveDiscoveryPath(existing.discoveryPath) - const token = await readDiscoveryToken(discoveryPath) - if (existing.authRequired && !token) { - throw new Error( - 'MCP server requires authentication but the discovery token could not be read. ' + - 'Ensure the discovery file is accessible and contains an auth token.' - ) - } - runtimeAutomationAuthToken = token - return { - disconnect: noop, - authToken: runtimeAutomationAuthToken - } + return existing } const { invoke } = await import('@tauri-apps/api/core') @@ -346,7 +351,8 @@ async function startMCPIfNeeded(): Promise { runtimeAutomationAuthToken = null } }, - authToken: token + authToken: token, + managed: true } } catch (err) { await child.kill().catch(() => undefined) diff --git a/src/components/settings/mcp/MCPSettingsPanel.vue b/src/components/settings/mcp/MCPSettingsPanel.vue index 63a6cb810..336551681 100644 --- a/src/components/settings/mcp/MCPSettingsPanel.vue +++ b/src/components/settings/mcp/MCPSettingsPanel.vue @@ -224,7 +224,11 @@ function enableAllTools(): void {

- {{ dialogs.mcpToolsRestartNotice }} + {{ + mcpRuntime.externallyManaged + ? dialogs.mcpExternalRestartNotice + : dialogs.mcpToolsRestartNotice + }}

@@ -232,14 +236,16 @@ function enableAllTools(): void { diff --git a/tests/e2e/settings/credentials.spec.ts b/tests/e2e/settings/credentials.spec.ts index e2db9b696..9af4acfaa 100644 --- a/tests/e2e/settings/credentials.spec.ts +++ b/tests/e2e/settings/credentials.spec.ts @@ -123,6 +123,10 @@ test('MCP automation settings filter and persist tool availability', async ({ pa ) await page.getByRole('button', { name: 'Enable all' }).click() + await expect(page.getByTestId('settings-mcp-tool-create_shape')).toHaveAttribute( + 'data-state', + 'checked' + ) }) test('model library keeps reusable profiles and role assignments', async ({ page }) => {