Add disconnect to MCP plugin

This commit is contained in:
alonso.torres 2026-02-25 12:09:57 +01:00 committed by Alonso Torres
parent 7e287bacfd
commit 701443c3d7
4 changed files with 50 additions and 4 deletions

View File

@ -11,6 +11,7 @@
[app.config :as cf] [app.config :as cf]
[app.main.data.plugins :as dp] [app.main.data.plugins :as dp]
[app.main.repo :as rp] [app.main.repo :as rp]
[app.main.store :as st]
[app.plugins.register :refer [mcp-plugin-id]] [app.plugins.register :refer [mcp-plugin-id]]
[beicon.v2.core :as rx] [beicon.v2.core :as rx]
[potok.v2.core :as ptk])) [potok.v2.core :as ptk]))
@ -29,8 +30,12 @@
"comment:read" "comment:write" "comment:read" "comment:write"
"content:write" "content:read"}}) "content:write" "content:read"}})
(defn finalize-workspace?
[event]
(= (ptk/type event) :app.main.data.workspace/finalize-workspace))
(defn init-mcp! (defn init-mcp!
[] [stream]
(->> (rp/cmd! :get-current-mcp-token) (->> (rp/cmd! :get-current-mcp-token)
(rx/subs! (rx/subs!
(fn [{:keys [token]}] (fn [{:keys [token]}]
@ -48,13 +53,35 @@
:setMcpStatus :setMcpStatus
(fn [status] (fn [status]
;; TODO: Visual feedback ;; TODO: Visual feedback
(log/info :hint "MCP STATUS" :status status))}})))))) (log/info :hint "MCP STATUS" :status status))
:on
(fn [event cb]
(when-let [event
(case event
"disconnect" ::disconnect
"connect" ::connect
nil)]
(let [stopper (rx/filter finalize-workspace? stream)]
(->> stream
(rx/filter (ptk/type? event))
(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-connexion (defn init-mcp-connexion
[] []
(ptk/reify ::init-mcp-connexion (ptk/reify ::init-mcp-connexion
ptk/EffectEvent ptk/EffectEvent
(effect [_ state _] (effect [_ state stream]
(when (and (contains? cf/flags :mcp) (when (and (contains? cf/flags :mcp)
(-> state :profile :props :mcp-status)) (-> state :profile :props :mcp-status))
(init-mcp!))))) (init-mcp! stream)))))

View File

@ -2,6 +2,7 @@ interface McpOptions {
getToken(): string; getToken(): string;
getServerUrl(): string; getServerUrl(): string;
setMcpStatus(status: string); setMcpStatus(status: string);
on(eventType: "disconnect" | "connect", cb: () => void);
} }
declare global { declare global {

View File

@ -118,6 +118,9 @@ document.querySelector("[data-handler='connect-mcp']")?.addEventListener("click"
window.addEventListener("message", (event) => { window.addEventListener("message", (event) => {
if (event.data.type === "start-server") { if (event.data.type === "start-server") {
connectToMcpServer(event.data.url, event.data.token); connectToMcpServer(event.data.url, event.data.token);
}
if (event.data.type === "stop-server") {
ws?.close();
} else if (event.data.source === "penpot") { } else if (event.data.source === "penpot") {
document.body.dataset.theme = event.data.theme; document.body.dataset.theme = event.data.theme;
} else if (event.data.type === "task-response") { } else if (event.data.type === "task-response") {

View File

@ -73,6 +73,21 @@ async function handlePluginTaskRequest(request: { id: string; task: string; para
} }
} }
if (mcp) {
mcp.on("disconnect", async () => {
penpot.ui.sendMessage({
type: "stop-server",
});
});
mcp.on("connect", async () => {
penpot.ui.sendMessage({
type: "start-server",
url: mcp?.getServerUrl(),
token: mcp?.getToken(),
});
});
}
// Handle theme change in the iframe // Handle theme change in the iframe
penpot.on("themechange", (theme) => { penpot.on("themechange", (theme) => {
penpot.ui.sendMessage({ penpot.ui.sendMessage({