]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/commitdiff
WebUI: Persist the on/off state of the MCP servers for new conversations (#20750)
authorPascal <redacted>
Thu, 19 Mar 2026 11:54:06 +0000 (12:54 +0100)
committerGitHub <redacted>
Thu, 19 Mar 2026 11:54:06 +0000 (12:54 +0100)
* webui: add persistent storage for MCP server on/off state in new chats

* webui: simplify MCP enabled checks, remove dead server.enabled fallback

* chore: update webui build output

* chore: update webui build output

---------

Co-authored-by: Aleksander Grygier <redacted>
tools/server/public/index.html.gz
tools/server/webui/src/lib/constants/localstorage-keys.ts
tools/server/webui/src/lib/stores/conversations.svelte.ts
tools/server/webui/src/lib/stores/mcp.svelte.ts

index 20523afa3394d6d0727cdb4768985f3ebf4fbe16..ea4e6ed8ab1b06817accf57d407549bbd703c560 100644 (file)
Binary files a/tools/server/public/index.html.gz and b/tools/server/public/index.html.gz differ
index 6b9a9e0e2f8ff12d875f3f0e4743f0763c617a86..dc4d69b4eca9d6ef3e57a7bfbfd190321b586ca0 100644 (file)
@@ -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';
index 39f206479faa51aeca6b37f82a5a7e13eb59d2d9..3cfbd3d1c9e89e2aa69e0359875f4eccba4b91af 100644 (file)
@@ -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<McpServerOverride[]>([]);
+       pendingMcpServerOverrides = $state<McpServerOverride[]>(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<boolean>;
@@ -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();
        }
 
        /**
index dadf8fda62496696e36403c1ffd8c38ed7e29ae3..efc8cf060ed6e5e5d4c8122cee0770507f28eb73 100644 (file)
@@ -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);
                });
        }