diff --git a/tools/server/public/index.html.gz b/tools/server/public/index.html.gz
index 20523afa33..ea4e6ed8ab 100644
Binary files a/tools/server/public/index.html.gz and b/tools/server/public/index.html.gz differ
diff --git a/tools/server/webui/src/lib/constants/localstorage-keys.ts b/tools/server/webui/src/lib/constants/localstorage-keys.ts
index 6b9a9e0e2f..dc4d69b4ec 100644
--- a/tools/server/webui/src/lib/constants/localstorage-keys.ts
+++ b/tools/server/webui/src/lib/constants/localstorage-keys.ts
@@ -1,3 +1,4 @@
export const CONFIG_LOCALSTORAGE_KEY = 'LlamaCppWebui.config';
export const USER_OVERRIDES_LOCALSTORAGE_KEY = 'LlamaCppWebui.userOverrides';
export const FAVOURITE_MODELS_LOCALSTORAGE_KEY = 'LlamaCppWebui.favouriteModels';
+export const MCP_DEFAULT_ENABLED_LOCALSTORAGE_KEY = 'LlamaCppWebui.mcpDefaultEnabled';
diff --git a/tools/server/webui/src/lib/stores/conversations.svelte.ts b/tools/server/webui/src/lib/stores/conversations.svelte.ts
index 39f206479f..3cfbd3d1c9 100644
--- a/tools/server/webui/src/lib/stores/conversations.svelte.ts
+++ b/tools/server/webui/src/lib/stores/conversations.svelte.ts
@@ -36,7 +36,8 @@ import {
ISO_TIME_SEPARATOR,
ISO_TIME_SEPARATOR_REPLACEMENT,
NON_ALPHANUMERIC_REGEX,
- MULTIPLE_UNDERSCORE_REGEX
+ MULTIPLE_UNDERSCORE_REGEX,
+ MCP_DEFAULT_ENABLED_LOCALSTORAGE_KEY
} from '$lib/constants';
class ConversationsStore {
@@ -61,7 +62,37 @@ class ConversationsStore {
isInitialized = $state(false);
/** Pending MCP server overrides for new conversations (before first message) */
- pendingMcpServerOverrides = $state([]);
+ pendingMcpServerOverrides = $state(ConversationsStore.loadMcpDefaults());
+
+ /** Load MCP default overrides from localStorage */
+ private static loadMcpDefaults(): McpServerOverride[] {
+ if (typeof globalThis.localStorage === 'undefined') return [];
+ try {
+ const raw = localStorage.getItem(MCP_DEFAULT_ENABLED_LOCALSTORAGE_KEY);
+ if (!raw) return [];
+ const parsed = JSON.parse(raw);
+ if (!Array.isArray(parsed)) return [];
+ return parsed.filter(
+ (o: unknown) => typeof o === 'object' && o !== null && 'serverId' in o && 'enabled' in o
+ ) as McpServerOverride[];
+ } catch {
+ return [];
+ }
+ }
+
+ /** Persist MCP default overrides to localStorage */
+ private saveMcpDefaults(): void {
+ if (typeof globalThis.localStorage === 'undefined') return;
+ const plain = this.pendingMcpServerOverrides.map((o) => ({
+ serverId: o.serverId,
+ enabled: o.enabled
+ }));
+ if (plain.length > 0) {
+ localStorage.setItem(MCP_DEFAULT_ENABLED_LOCALSTORAGE_KEY, JSON.stringify(plain));
+ } else {
+ localStorage.removeItem(MCP_DEFAULT_ENABLED_LOCALSTORAGE_KEY);
+ }
+ }
/** Callback for title update confirmation dialog */
titleUpdateConfirmationCallback?: (currentTitle: string, newTitle: string) => Promise;
@@ -261,6 +292,8 @@ class ConversationsStore {
clearActiveConversation(): void {
this.activeConversation = null;
this.activeMessages = [];
+ // reload MCP defaults so new chats inherit persisted state
+ this.pendingMcpServerOverrides = ConversationsStore.loadMcpDefaults();
}
/**
@@ -597,6 +630,7 @@ class ConversationsStore {
this.pendingMcpServerOverrides = [...this.pendingMcpServerOverrides, { serverId, enabled }];
}
}
+ this.saveMcpDefaults();
}
/**
@@ -621,6 +655,7 @@ class ConversationsStore {
*/
clearPendingMcpServerOverrides(): void {
this.pendingMcpServerOverrides = [];
+ this.saveMcpDefaults();
}
/**
diff --git a/tools/server/webui/src/lib/stores/mcp.svelte.ts b/tools/server/webui/src/lib/stores/mcp.svelte.ts
index dadf8fda62..efc8cf060e 100644
--- a/tools/server/webui/src/lib/stores/mcp.svelte.ts
+++ b/tools/server/webui/src/lib/stores/mcp.svelte.ts
@@ -208,23 +208,16 @@ class MCPStore {
}
/**
- * Checks if a server is enabled, considering per-chat overrides.
+ * Checks if a server is enabled for a given chat.
+ * Only per-chat overrides (persisted in localStorage for new chats,
+ * or in IndexedDB for existing conversations) control enabled state.
*/
#checkServerEnabled(
server: MCPServerSettingsEntry,
perChatOverrides?: McpServerOverride[]
): boolean {
- if (!server.enabled) {
- return false;
- }
-
- if (perChatOverrides) {
- const override = perChatOverrides.find((o) => o.serverId === server.id);
-
- return override?.enabled ?? false;
- }
-
- return false;
+ const override = perChatOverrides?.find((o) => o.serverId === server.id);
+ return override?.enabled ?? false;
}
/**
@@ -570,18 +563,8 @@ class MCPStore {
getEnabledServersForConversation(
perChatOverrides?: McpServerOverride[]
): MCPServerSettingsEntry[] {
- if (!perChatOverrides?.length) {
- return [];
- }
-
return this.getServers().filter((server) => {
- if (!server.enabled) {
- return false;
- }
-
- const override = perChatOverrides.find((o) => o.serverId === server.id);
-
- return override?.enabled ?? false;
+ return this.#checkServerEnabled(server, perChatOverrides);
});
}