fix(mcp): address automation review feedback
- Serialize runtime lifecycle operations and connect only after health checks - Identify externally managed servers and disable misleading restart controls - Cover enable-all behavior and sync MCP settings locale keys
This commit is contained in:
parent
4db24bd124
commit
d3bbd29ac2
|
|
@ -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.',
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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<void> | null = null
|
||||
let lifecycle = Promise.resolve()
|
||||
|
||||
function enqueueLifecycle(operation: () => Promise<void>): Promise<void> {
|
||||
const next = lifecycle.then(operation, operation)
|
||||
lifecycle = next.catch(() => undefined)
|
||||
return next
|
||||
}
|
||||
|
||||
export async function refreshMCPRuntime(): Promise<void> {
|
||||
mcpRuntime.checking = true
|
||||
|
|
@ -44,17 +51,29 @@ export async function refreshMCPRuntime(): Promise<void> {
|
|||
async function start(): Promise<void> {
|
||||
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<void> {
|
|||
|
||||
export function startMCPRuntime(getStore: () => EditorStore): Promise<void> {
|
||||
activeStore = getStore
|
||||
operation ??= start().finally(() => {
|
||||
operation = null
|
||||
})
|
||||
return operation
|
||||
return enqueueLifecycle(start)
|
||||
}
|
||||
|
||||
export async function stopMCPRuntime(): Promise<void> {
|
||||
async function stop(): Promise<void> {
|
||||
disconnectAutomation?.()
|
||||
disconnectAutomation = null
|
||||
await server?.disconnect()
|
||||
server = null
|
||||
mcpRuntime.status = 'stopped'
|
||||
mcpRuntime.version = null
|
||||
mcpRuntime.externallyManaged = false
|
||||
setMCPToolCatalog([])
|
||||
}
|
||||
|
||||
export async function restartMCPRuntime(): Promise<void> {
|
||||
if (operation) await operation
|
||||
await stopMCPRuntime()
|
||||
await startMCPRuntime(
|
||||
activeStore ??
|
||||
(() => {
|
||||
throw new Error('Editor is not ready')
|
||||
})
|
||||
)
|
||||
export function stopMCPRuntime(): Promise<void> {
|
||||
return enqueueLifecycle(stop)
|
||||
}
|
||||
|
||||
export function restartMCPRuntime(): Promise<void> {
|
||||
return enqueueLifecycle(async () => {
|
||||
await stop()
|
||||
if (!activeStore) throw new Error('Editor is not ready')
|
||||
await start()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ export interface AutomationHealth {
|
|||
export interface AutomationServerHandle {
|
||||
disconnect: () => void | Promise<void>
|
||||
authToken: string | null
|
||||
managed: boolean
|
||||
}
|
||||
|
||||
const DEV_AUTOMATION_AUTH_TOKEN =
|
||||
|
|
@ -239,32 +240,36 @@ export async function getAutomationAuthToken(): Promise<string | null> {
|
|||
return runtimeAutomationAuthToken
|
||||
}
|
||||
|
||||
async function readExistingServerHandle(): Promise<AutomationServerHandle | null> {
|
||||
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<AutomationServerHandle | null> {
|
||||
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<AutomationServerHandle | null> {
|
|||
runtimeAutomationAuthToken = null
|
||||
}
|
||||
},
|
||||
authToken: token
|
||||
authToken: token,
|
||||
managed: true
|
||||
}
|
||||
} catch (err) {
|
||||
await child.kill().catch(() => undefined)
|
||||
|
|
|
|||
|
|
@ -224,7 +224,11 @@ function enableAllTools(): void {
|
|||
</ul>
|
||||
|
||||
<p class="border-t border-border px-3 py-2 text-[10px] text-muted">
|
||||
{{ dialogs.mcpToolsRestartNotice }}
|
||||
{{
|
||||
mcpRuntime.externallyManaged
|
||||
? dialogs.mcpExternalRestartNotice
|
||||
: dialogs.mcpToolsRestartNotice
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -232,14 +236,16 @@ function enableAllTools(): void {
|
|||
<button
|
||||
type="button"
|
||||
class="rounded bg-accent px-3 py-1.5 text-[11px] font-medium text-white hover:bg-accent/90 disabled:opacity-50"
|
||||
:disabled="mcpRuntime.status === 'starting'"
|
||||
:disabled="mcpRuntime.status === 'starting' || mcpRuntime.externallyManaged"
|
||||
data-test-id="settings-mcp-restart"
|
||||
@click="restart"
|
||||
>
|
||||
{{
|
||||
mcpRuntime.status === 'starting' || mcpRuntime.checking
|
||||
? dialogs.mcpStarting
|
||||
: dialogs.mcpRestart
|
||||
: mcpRuntime.externallyManaged
|
||||
? dialogs.mcpExternallyManaged
|
||||
: dialogs.mcpRestart
|
||||
}}
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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 }) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue