diff --git a/apps/broker/src/index.ts b/apps/broker/src/index.ts index bb1f607..217438e 100644 --- a/apps/broker/src/index.ts +++ b/apps/broker/src/index.ts @@ -2487,6 +2487,25 @@ function handleConnection(ws: WebSocket): void { toolCount: mr.tools.length, ...(_reqId ? { _reqId } : {}), }); + // Broadcast to all peers: new MCP server available + const mcpJoinMsg: WSServerMessage = { + type: "push", + subtype: "system", + event: "mcp_registered", + eventData: { serverName: mr.serverName, description: mr.description, tools: mr.tools.map(t => t.name), hostedBy: conn.displayName }, + messageId: crypto.randomUUID(), + meshId: conn.meshId, + senderPubkey: "system", + priority: "low", + nonce: "", + ciphertext: "", + createdAt: new Date().toISOString(), + }; + for (const [pid, peer] of connections) { + if (pid === presenceId) continue; + if (peer.meshId !== conn.meshId) continue; + sendToPeer(pid, mcpJoinMsg); + } log.info("ws mcp_register", { presence_id: presenceId, server: mr.serverName, @@ -2500,6 +2519,25 @@ function handleConnection(ws: WebSocket): void { const entry = mcpRegistry.get(unregKey); if (entry && entry.presenceId === presenceId) { mcpRegistry.delete(unregKey); + // Broadcast: MCP server removed + const mcpLeaveMsg: WSServerMessage = { + type: "push", + subtype: "system", + event: "mcp_unregistered", + eventData: { serverName: mu.serverName, hostedBy: conn.displayName }, + messageId: crypto.randomUUID(), + meshId: conn.meshId, + senderPubkey: "system", + priority: "low", + nonce: "", + ciphertext: "", + createdAt: new Date().toISOString(), + }; + for (const [pid, peer] of connections) { + if (pid === presenceId) continue; + if (peer.meshId !== conn.meshId) continue; + sendToPeer(pid, mcpLeaveMsg); + } } log.info("ws mcp_unregister", { presence_id: presenceId, diff --git a/apps/cli/src/mcp/server.ts b/apps/cli/src/mcp/server.ts index adca709..d1e1290 100644 --- a/apps/cli/src/mcp/server.ts +++ b/apps/cli/src/mcp/server.ts @@ -1354,6 +1354,11 @@ Your message mode is "${messageMode}". content = `[system] Peer "${data.name ?? "unknown"}" joined the mesh`; } else if (eventName === "peer_left") { content = `[system] Peer "${data.name ?? "unknown"}" left the mesh`; + } else if (eventName === "mcp_registered") { + const tools = Array.isArray(data.tools) ? (data.tools as string[]).join(", ") : ""; + content = `[system] New MCP server available: "${data.serverName}" (hosted by ${data.hostedBy}). Tools: ${tools}. Use mesh_tool_call to invoke.`; + } else if (eventName === "mcp_unregistered") { + content = `[system] MCP server "${data.serverName}" removed (was hosted by ${data.hostedBy})`; } else { content = `[system] ${eventName}: ${JSON.stringify(data)}`; }