diff --git a/canvas/src/components/ExternalConnectModal.tsx b/canvas/src/components/ExternalConnectModal.tsx index 29e4e7de..6cb37de8 100644 --- a/canvas/src/components/ExternalConnectModal.tsx +++ b/canvas/src/components/ExternalConnectModal.tsx @@ -195,7 +195,7 @@ export function ExternalConnectModal({ info, onClose }: Props) { {tab === "mcp" && filledUniversalMcp && ( copy(filledUniversalMcp, "mcp")} diff --git a/workspace-server/internal/handlers/external_connection.go b/workspace-server/internal/handlers/external_connection.go index f236678b..d0313db3 100644 --- a/workspace-server/internal/handlers/external_connection.go +++ b/workspace-server/internal/handlers/external_connection.go @@ -104,7 +104,7 @@ claude --channels plugin:molecule@Molecule-AI/molecule-mcp-claude-channel # pairing flow, push-mode upgrade, and v0.2 roadmap. ` -// externalUniversalMcpTemplate — runtime-agnostic outbound tool path. +// externalUniversalMcpTemplate — runtime-agnostic standalone path. // Ships as the `molecule-mcp` console script in the // molecule-ai-workspace-runtime PyPI wheel (workspace/mcp_cli.py). // Any MCP-aware runtime (Claude Code, hermes, codex, third-party) @@ -112,41 +112,38 @@ claude --channels plugin:molecule@Molecule-AI/molecule-mcp-claude-channel // container-bound runtimes use today: delegate_task, list_peers, // send_message_to_user, commit_memory, etc. // -// Outbound-only: the binary doesn't heartbeat or accept inbound A2A. -// Pair with the Claude Code channel tab (poll-based inbound) or the -// Python SDK tab (push-mode inbound + heartbeat) to keep the workspace -// online and surface inbound messages. The snippet calls that out -// explicitly so an operator copy-pasting it doesn't end up with a -// silently-offline workspace. +// Standalone: the binary itself handles register-on-startup + +// continuous heartbeats (daemon thread, 20s cadence). No separate +// SDK or channel process needed to keep the workspace online. The +// only thing it does NOT yet do is poll inbound A2A messages — for +// runtimes that need their agent to react to canvas messages or +// peer-initiated tasks, pair with the Claude Code channel tab +// (poll-based inbound delivery into a Claude Code session) or the +// Python SDK tab (push-mode inbound + heartbeat). // // Origin/WAF: handled automatically by platform_auth.auth_headers() // in the wheel — operator doesn't need to configure anything. -const externalUniversalMcpTemplate = `# Universal MCP — call platform tools from any MCP-aware runtime -# (Claude Code, hermes, codex, etc.). Outbound-only — pair with the -# Claude Code or Python SDK tab for heartbeat + inbound messages. +const externalUniversalMcpTemplate = `# Universal MCP — standalone register + heartbeat + outbound platform tools +# for any MCP-aware runtime (Claude Code, hermes, codex, etc.). +# Pair with the Claude Code or Python SDK tab if your runtime needs +# inbound A2A delivery (canvas messages → agent conversation turns). # 1. Install the workspace runtime wheel: pip install molecule-ai-workspace-runtime -# 2. One-shot register (pair with SDK/channel for ongoing heartbeat): -export WORKSPACE_AUTH_TOKEN="" -curl -fsS -X POST "{{PLATFORM_URL}}/registry/register" \ - -H "Authorization: Bearer $WORKSPACE_AUTH_TOKEN" \ - -H "Origin: {{PLATFORM_URL}}" \ - -H "Content-Type: application/json" \ - -d '{"id":"{{WORKSPACE_ID}}","url":"","agent_card":{"name":"My Agent"},"delivery_mode":"poll"}' - -# 3. Wire molecule-mcp into your agent's MCP config. Claude Code: +# 2. Wire molecule-mcp into your agent's MCP config. Claude Code: claude mcp add molecule -s user -- env \ WORKSPACE_ID={{WORKSPACE_ID}} \ PLATFORM_URL={{PLATFORM_URL}} \ - MOLECULE_WORKSPACE_TOKEN="$WORKSPACE_AUTH_TOKEN" \ + MOLECULE_WORKSPACE_TOKEN="" \ molecule-mcp -# Same env-var contract works with hermes-agent, codex, or any MCP -# stdio runtime. Tools exposed: delegate_task, delegate_task_async, -# check_task_status, list_peers, get_workspace_info, -# send_message_to_user, commit_memory, recall_memory. +# molecule-mcp registers the workspace + heartbeats every 20s in a +# daemon thread, then runs the MCP stdio loop. Same env-var contract +# works with hermes-agent, codex, or any MCP stdio runtime. Tools +# exposed: delegate_task, delegate_task_async, check_task_status, +# list_peers, get_workspace_info, send_message_to_user, +# commit_memory, recall_memory. # # Origin/WAF handling is built into the wheel — no manual headers # needed when calling tools through the MCP server.