diff --git a/tools/ui/src/lib/stores/agentic/index.svelte.ts b/tools/ui/src/lib/stores/agentic/index.svelte.ts index bf39b5e34f..50db1be0cc 100644 --- a/tools/ui/src/lib/stores/agentic/index.svelte.ts +++ b/tools/ui/src/lib/stores/agentic/index.svelte.ts @@ -329,20 +329,12 @@ class AgenticStore { const disabledToolCategories = new Set( toolPolicy?.disabledToolCategories ?? toolsStore.disabledToolCategories ); - // servers usable under this flow's policy: globally enabled, category on, - // and their server-scoped group key not disabled - const policyEnabledServerIds = new Set( - disabledToolCategories.has(ToolSource.MCP) - ? [] - : mcpStore - .getServers() - .filter((s) => s.enabled && !disabledTools.has(toolsStore.getMcpServerToolsKey(s.id))) - .map((s) => s.id) - ); - const hasMcpServers = policyEnabledServerIds.size > 0; + // initialize every settings-enabled server; tool collection filters by this + // flow's policy, so switching policies never re-initializes connections + const hasMcpServers = conversationsStore.preferences.policyEnabledServerIds().length > 0; if (hasMcpServers) { - const initialized = await mcpStore.ensureInitialized(policyEnabledServerIds); + const initialized = await mcpStore.ensureInitialized(); if (!initialized) { console.log('[AgenticStore] MCP not initialized'); diff --git a/tools/ui/src/lib/stores/conversations/preferences.svelte.ts b/tools/ui/src/lib/stores/conversations/preferences.svelte.ts index fdbf5da99f..916911a145 100644 --- a/tools/ui/src/lib/stores/conversations/preferences.svelte.ts +++ b/tools/ui/src/lib/stores/conversations/preferences.svelte.ts @@ -15,6 +15,7 @@ import { REASONING_EFFORT_DEFAULT_LOCALSTORAGE_KEY } from '$lib/constants'; import { ReasoningEffort, ToolSource } from '$lib/enums'; import { DatabaseService } from '$lib/services/database.service'; // direct imports between stores, not via the barrel, to avoid circular deps +import { mcpStore } from '$lib/stores/mcp/index.svelte'; import { toolsStore } from '$lib/stores/tools.svelte'; import type { DatabaseConversation, ToolEntry, ToolGroup } from '$lib/types'; @@ -180,6 +181,21 @@ export class ConversationPreferences { ); } + /** + * MCP servers usable under the effective policy: globally enabled, url set, + * MCP category on and the server-scoped key not disabled. + */ + policyEnabledServerIds(): string[] { + if (!this.isCategoryEnabled(ToolSource.MCP)) return []; + + return mcpStore + .getServers() + .filter( + (server) => server.enabled && server.url.trim() && this.isServerToolsEnabled(server.id) + ) + .map((server) => server.id); + } + /** Reload persisted defaults, e.g. when the active conversation is cleared. */ resetPending(): void { this.pendingReasoningEffort = loadReasoningEffortDefault(); diff --git a/tools/ui/src/lib/stores/mcp/index.svelte.ts b/tools/ui/src/lib/stores/mcp/index.svelte.ts index 6a952294a3..0da5e871fe 100644 --- a/tools/ui/src/lib/stores/mcp/index.svelte.ts +++ b/tools/ui/src/lib/stores/mcp/index.svelte.ts @@ -307,17 +307,15 @@ class MCPStore implements McpHealthHost { } /** - * Initialize connections. Callers can restrict which servers connect by - * passing their ids (e.g. a conversation's tool policy); a different set - * changes the config signature and re-initializes, same as a settings - * change. + * Initialize every settings-enabled server. Policy filtering happens at tool + * collection time, so switching conversation policies never re-initializes. */ - async ensureInitialized(serverIds?: ReadonlySet): Promise { + async ensureInitialized(): Promise { if (!browser) { return false; } - const mcpConfig = this.buildMcpClientConfig(settingsStore.config, serverIds); + const mcpConfig = this.buildMcpClientConfig(settingsStore.config); const signature = mcpConfig ? JSON.stringify(mcpConfig) : null; if (!signature) { @@ -1119,10 +1117,7 @@ class MCPStore implements McpHealthHost { /** * Builds MCP client configuration from settings. */ - private buildMcpClientConfig( - cfg: SettingsConfigType, - serverIds?: ReadonlySet - ): MCPClientConfig | undefined { + private buildMcpClientConfig(cfg: SettingsConfigType): MCPClientConfig | undefined { const rawServers = parseMcpServerSettings(cfg.mcpServers); if (!rawServers.length) { @@ -1134,8 +1129,6 @@ class MCPStore implements McpHealthHost { for (const [index, entry] of rawServers.entries()) { if (!entry.enabled) continue; - if (serverIds && !serverIds.has(entry.id)) continue; - const normalized = this.buildServerConfig(entry); if (normalized) servers[this.generateServerId(entry.id, index)] = normalized;