diff --git a/clients/web/src/App.tsx b/clients/web/src/App.tsx index 1511ce27..350213f4 100644 --- a/clients/web/src/App.tsx +++ b/clients/web/src/App.tsx @@ -2569,7 +2569,16 @@ function App() { if (deepLinkConnectRef.current) return; deepLinkConnectRef.current = true; - if (activeServerId !== deepLink.serverId) { + // Connect unless we're already *connected* to the deep-link server. Gating + // on `activeServerId` identity alone would skip the connect when a prior + // session restored `activeServerId` to the `deep-link` id while the socket + // is disconnected — a reload of the same deep-link URL would then silently + // never connect. `onToggleConnection` only disconnects when the id is the + // active one AND the status is connected, so this condition also avoids + // toggling a live connection off. + const alreadyConnected = + activeServerId === deepLink.serverId && connectionStatus === "connected"; + if (!alreadyConnected) { void onToggleConnection(deepLink.serverId).catch((err) => { // The toast fires from inside `onToggleConnection` for the common // cases; this catch covers the rest (surfaced on `data-error-message`). @@ -2581,6 +2590,7 @@ function App() { deepLink, servers, activeServerId, + connectionStatus, addServer, updateServer, onToggleConnection, diff --git a/clients/web/src/components/views/InspectorView/InspectorView.tsx b/clients/web/src/components/views/InspectorView/InspectorView.tsx index cd18bded..d8d335cd 100644 --- a/clients/web/src/components/views/InspectorView/InspectorView.tsx +++ b/clients/web/src/components/views/InspectorView/InspectorView.tsx @@ -892,6 +892,13 @@ export function InspectorView({ ...collectSchemaDefaults(target.inputSchema), ...deepLink.appArgs, }; + // Seed the selection directly rather than routing through + // AppsScreen.handleSelect. This deliberately bypasses handleSelect's + // no-input-app auto-launch: a deep link must never invoke a tool against + // the target server unless the token-gated `autoOpen` is set — even a + // no-input app waits for that explicit signal (or a manual "Open App" + // click), matching the security stance that a crafted URL alone can't fire + // a tool call. onActiveTabChange("Apps"); onAppsUiChange({ ...appsUi,