🎉 Make the mcp plugin switching between tabs work correctly (#8597)

*  Make the MCP plugin switching between tabs work correctly

* 🎉 Show notification when the plugin is loaded in another tab

* 📎 PR changes

*  Add events
This commit is contained in:
Luis de Dios
2026-03-17 10:17:02 +01:00
committed by GitHub
parent 3bf145a749
commit a5f09e18a8
6 changed files with 74 additions and 29 deletions

View File

@@ -1,10 +0,0 @@
name: New MCP server
version: 0.0.1
schema: v1
mcpServers:
- name: New MCP server
command: npx
args:
- -y
- <your-mcp-server>
env: {}

View File

@@ -373,7 +373,15 @@
(when (contains? cf/flags :mcp)
(->> mbc/stream
(rx/filter (mbc/type? :mcp-enabled-change))
(rx/filter (mbc/type? :mcp-enabled-change-connection))
(rx/map deref)
(rx/mapcat (fn [value]
(rx/of (mcp/update-mcp-connection value)
(mcp/disconnect-mcp))))))
(when (contains? cf/flags :mcp)
(->> mbc/stream
(rx/filter (mbc/type? :mcp-enabled-change-status))
(rx/map deref)
(rx/map mcp/update-mcp-status)))

View File

@@ -9,10 +9,14 @@
[app.common.logging :as log]
[app.common.uri :as u]
[app.config :as cf]
[app.main.broadcast :as mbc]
[app.main.data.event :as ev]
[app.main.data.notifications :as ntf]
[app.main.data.plugins :as dp]
[app.main.repo :as rp]
[app.main.store :as st]
[app.plugins.register :refer [mcp-plugin-id]]
[app.util.i18n :refer [tr]]
[beicon.v2.core :as rx]
[potok.v2.core :as ptk]))
@@ -34,6 +38,37 @@
[event]
(= (ptk/type event) :app.main.data.workspace/finalize-workspace))
(defn disconnect-mcp
[]
(st/emit! (ptk/data-event ::disconnect)))
(defn connect-mcp
[]
(ptk/reify ::connect-mcp
ptk/WatchEvent
(watch [_ _ stream]
(mbc/emit! :mcp-enabled-change-connection false)
(->> stream
(rx/filter (ptk/type? ::disconnect))
(rx/take 1)
(rx/map #(ptk/data-event ::connect))))))
(defn manage-notification
[mcp-enabled? mcp-connected?]
(if mcp-enabled?
(if mcp-connected?
(rx/of (ntf/hide))
(rx/of (ntf/dialog :content (tr "notifications.mcp.active-tab-switching.text")
:cancel {:label (tr "labels.dismiss")
:callback #(st/emit! (ntf/hide)
(ptk/event ::ev/event {::ev/name "confirm-mcp-tab-switch"
::ev/origin "workspace-notification"}))}
:accept {:label (tr "labels.switch")
:callback #(st/emit! (connect-mcp)
(ptk/event ::ev/event {::ev/name "dismiss-mcp-tab-switch"
::ev/origin "workspace-notification"}))})))
(rx/of (ntf/hide))))
(defn update-mcp-status
[value]
(ptk/reify ::update-mcp-status
@@ -42,18 +77,26 @@
(update-in state [:profile :props] assoc :mcp-enabled value))
ptk/WatchEvent
(watch [_ _ _]
(case value
true (rx/of (ptk/data-event ::connect))
false (rx/of (ptk/data-event ::disconnect))
nil))))
(watch [_ state _]
(rx/merge
(let [mcp-connected? (-> state :workspace-local :mcp :connected)]
(manage-notification value mcp-connected?))
(case value
true (rx/of (ptk/data-event ::connect))
false (rx/of (ptk/data-event ::disconnect))
nil)))))
(defn update-mcp-connection
[value]
(ptk/reify ::update-mcp-plugin-connection
ptk/UpdateEvent
(update [_ state]
(update-in state [:workspace-local :mcp] assoc :connected value))))
(update-in state [:workspace-local :mcp] assoc :connected value))
ptk/WatchEvent
(watch [_ state _]
(let [mcp-enabled? (-> state :profile :props :mcp-enabled)]
(manage-notification mcp-enabled? value)))))
(defn init-mcp!
[stream]
@@ -94,14 +137,6 @@
(rx/take-until stopper)
(rx/subs! #(cb))))))}}))))))
(defn disconnect-mcp
[]
(st/emit! (ptk/data-event ::disconnect)))
(defn connect-mcp
[]
(st/emit! (ptk/data-event ::connect)))
(defn init-mcp-connection
[]
(ptk/reify ::init-mcp-connection

View File

@@ -279,7 +279,7 @@
(ev/event {::ev/name "enable-mcp"
::ev/origin "integrations"
:source "key-creation"}))
(mbc/emit! :mcp-enabled-change true)
(mbc/emit! :mcp-enabled-change-status true)
(reset! created? true)))]
[:div {:class (stl/css :modal-overlay)}
@@ -320,7 +320,7 @@
(du/update-profile-props {:mcp-enabled true})
(ev/event {::ev/name "regenerate-mcp-key"
::ev/origin "integrations"}))
(mbc/emit! :mcp-enabled-change true)
(mbc/emit! :mcp-enabled-change-status true)
(reset! created? true)))]
[:div {:class (stl/css :modal-overlay)}
@@ -431,7 +431,7 @@
(ev/event {::ev/name (if (true? value) "enable-mcp" "disable-mcp")
::ev/origin "integrations"
:source "toggle"}))
(mbc/emit! :mcp-enabled-change value)))
(mbc/emit! :mcp-enabled-change-status value)))
handle-generate-mcp-key
(mf/use-fn
@@ -449,7 +449,7 @@
mdata {:on-success #(st/emit! (du/fetch-access-tokens))}]
(st/emit! (du/delete-access-token (with-meta params mdata))
(du/update-profile-props {:mcp-enabled false}))
(mbc/emit! :mcp-enabled-change false))))
(mbc/emit! :mcp-enabled-change-status false))))
on-copy-to-clipboard
(mf/use-fn

View File

@@ -2514,6 +2514,9 @@ msgstr "Director"
msgid "labels.discard"
msgstr "Discard"
msgid "labels.dismiss"
msgstr "Dismiss"
#: src/app/main/ui/settings/feedback.cljs:134, src/app/main/ui/static.cljs:409
msgid "labels.download"
msgstr "Download %s"
@@ -3830,6 +3833,9 @@ msgstr "Invitation sent successfully"
msgid "notifications.invitation-link-copied"
msgstr "Invitation link copied"
msgid "notifications.mcp.active-tab-switching.text"
msgstr "MCP is active in another tab. Switch here?"
#: src/app/main/ui/settings/delete_account.cljs:24
msgid "notifications.profile-deletion-not-allowed"
msgstr "You can't delete your profile. Reassign your teams before proceed."

View File

@@ -2471,6 +2471,9 @@ msgstr "Director"
msgid "labels.discard"
msgstr "Descartar"
msgid "labels.dismiss"
msgstr "Cancelar"
#: src/app/main/ui/settings/feedback.cljs:134, src/app/main/ui/static.cljs:409
msgid "labels.download"
msgstr "Descargar %s"
@@ -3787,6 +3790,9 @@ msgstr "Invitación enviada con éxito"
msgid "notifications.invitation-link-copied"
msgstr "Enlace de invitacion copiado"
msgid "notifications.mcp.active-tab-switching.text"
msgstr "MCP está activo en otra pestaña. ¿Cambiar a esta?"
#: src/app/main/ui/settings/delete_account.cljs:24
msgid "notifications.profile-deletion-not-allowed"
msgstr "No puedes borrar tu perfil. Reasigna tus equipos antes de seguir."