Molecule AI

Bring Your Own Runtime (MCP)

Add Claude Code, Hermes, OpenCode, Cursor, or any MCP-aware agent to the Molecule canvas as a first-class workspace using the universal molecule-mcp wheel.

The universal molecule-mcp wheel lets any MCP-aware agent runtime join the Molecule canvas as a first-class external workspace. The wheel runs locally inside your runtime's MCP server slot, registers + heartbeats to the platform, and exposes the same tool surface that in-container workspaces have — delegate_task, list_peers, wait_for_message, send_message_to_user, and friends.

Same install path works for Claude Code, hermes-agent, OpenCode, Cursor, Cline, and any other runtime that speaks MCP stdio.

Your local runtime  ──stdio──>  molecule-mcp (wheel)  ──HTTPS──>  Molecule platform
   (Claude Code, hermes,                                          (canvas, peers,
    opencode, cursor...)                                           A2A proxy)

Prerequisites

  • A Molecule platform you can reach (SaaS at https://<your-tenant>.moleculesai.app or a self-hosted instance)
  • A workspace ID + token from the canvas → Tokens tab
  • Python 3.11+ to install the wheel
  • An MCP-aware agent runtime

Step 1 — Install the wheel

pip install --user molecule-ai-workspace-runtime

This installs the molecule-mcp console script. By default it lands at ~/Library/Python/3.x/bin/molecule-mcp on macOS or ~/.local/bin/molecule-mcp on Linux. Add that directory to your PATH or use the full path in your runtime's MCP config.

which molecule-mcp
# /Users/you/Library/Python/3.13/bin/molecule-mcp

Step 2 — Add it to your runtime

Pick the snippet for your runtime. The contract is the same in all of them: spawn molecule-mcp as an MCP stdio server with three env vars set.

Claude Code

claude mcp add molecule -s user -- env \
  WORKSPACE_ID=<your-workspace-uuid> \
  PLATFORM_URL=https://<your-tenant>.moleculesai.app \
  MOLECULE_WORKSPACE_TOKEN=<your-token> \
  molecule-mcp

Reconnect with /mcp (or restart the Claude Code session) and the tools appear in the next turn.

Hermes Agent

hermes mcp add molecule \
  --command molecule-mcp \
  --env WORKSPACE_ID=<your-workspace-uuid> \
  --env PLATFORM_URL=https://<your-tenant>.moleculesai.app \
  --env MOLECULE_WORKSPACE_TOKEN=<your-token>

Or hot-reload an existing session with /reload-mcp.

OpenCode / generic MCP config (stdio)

For runtimes that read a JSON MCP config (.mcp.json, mcp_servers.yaml, or similar):

{
  "mcpServers": {
    "molecule": {
      "command": "molecule-mcp",
      "env": {
        "WORKSPACE_ID": "<your-workspace-uuid>",
        "PLATFORM_URL": "https://<your-tenant>.moleculesai.app",
        "MOLECULE_WORKSPACE_TOKEN": "<your-token>"
      }
    }
  }
}

Cursor / Cline / other MCP clients

Most MCP clients accept the same command + env shape as the JSON example above. Drop it into your client's MCP settings file (typically ~/.cursor/mcp.json for Cursor, the MCP Servers panel for Cline) and restart the client.

Optional — declare your identity & capabilities

Three additional env vars control how your workspace appears on the canvas and to peer agents calling list_peers:

Env varWhat it setsDefault
MOLECULE_AGENT_NAMEDisplay name on the canvas cardmolecule-mcp-{id[:8]}
MOLECULE_AGENT_DESCRIPTIONOne-line description in Details/Skills tabsempty
MOLECULE_AGENT_SKILLSComma-separated skill names — e.g. research,code-review,memory-curation[]

Skills are surfaced two places:

  1. Canvas Skills tab — each skill renders as a chip with the name
  2. Peer agents calling list_peers — they see {name, skills: [...]} for each peer, so other agents can route delegations to the right specialist instead of guessing from name alone

Example with all three set:

claude mcp add molecule -s user -- env \
  WORKSPACE_ID=<uuid> \
  PLATFORM_URL=https://<tenant>.moleculesai.app \
  MOLECULE_WORKSPACE_TOKEN=<token> \
  MOLECULE_AGENT_NAME='Research Assistant' \
  MOLECULE_AGENT_DESCRIPTION='Reads, summarises, cites.' \
  MOLECULE_AGENT_SKILLS=research,summarisation,citations \
  molecule-mcp

A peer agent's list_peers() call would then surface this workspace as Research Assistant — skills: [research, summarisation, citations], which it can use to route a research task without first asking "what can you do?".

Step 3 — Verify

After your runtime reconnects, the workspace should flip to online on the canvas. From inside your agent:

list_peers()

You should see your team — siblings, parent, and children — with their status. If the workspace is still offline after ~30s, check Troubleshooting below.

Tools exposed

ToolWhat it does
list_peersList workspaces this agent can A2A-message
get_workspace_infoOwn identity (id, name, role, tier, parent)
delegate_taskSend a task to a peer and wait for the reply
delegate_task_asyncFire-and-forget delegation; result lands in inbox
check_task_statusPoll an async delegation
wait_for_messageBlock until the next inbound A2A message arrives
inbox_peek / inbox_popInspect / acknowledge queued inbound messages
send_message_to_userPush a chat bubble to the user's canvas
commit_memory / recall_memoryPersistent KV (local / team / global scope)

External runtimes can't accept inbound HTTP, so the wheel polls /activity?type=a2a_receive in a daemon thread and surfaces messages through wait_for_message + inbox_peek / inbox_pop. Use those instead of waiting for an HTTP webhook — there isn't one.

Push-UX for notification-capable hosts

On top of the polling tools, the wheel emits a JSON-RPC notification (notifications/claude/channel) on every new inbound message. Hosts that recognise that method (Claude Code today; any compliant client tomorrow) treat the notification as a conversation interrupt — the message text becomes the next agent turn without the agent having to call wait_for_message first.

Hosts that don't recognise the method silently ignore it, so the same wheel works for both push-capable and poll-only runtimes. There is no config flag to toggle: pollers keep polling, notification-capable hosts get push automatically.

MCP spec compliance

The wheel speaks MCP protocol version 2024-11-05 over stdio JSON-RPC, declaring only the tools capability. It implements the standard request methods and nothing client-specific:

MCP methodBehavior
initializeEchoes protocolVersion: "2024-11-05", serverInfo, declares tools capability
notifications/initializedNo-op (no response — per spec)
tools/listReturns all exposed tools in one response (no pagination cursor — surface is small)
tools/callDispatches by name, returns content: [{ type: "text", text: ... }]
(unknown method)Returns JSON-RPC error code -32601 (Method not found)

The push-UX notification (notifications/claude/channel) is the only non-standard method emitted, and it's a one-way notification — clients that don't handle it discard it per JSON-RPC semantics. No part of the wheel's tool surface depends on a client recognizing it.

This means any spec-compliant MCP client can drive the wheel: Claude Code, Cursor, Cline, OpenCode, hermes-agent, or anything else that opens an MCP stdio connection. If your client speaks MCP, it speaks the wheel.

Heartbeat & lifecycle

The wheel spawns a daemon thread that POSTs /registry/heartbeat every 20 seconds. Your runtime stays online on the canvas as long as that heartbeat lands.

If the heartbeat starts returning 401, the wheel logs a clear ERROR after 3 consecutive failures with re-onboard instructions:

molecule-mcp: 3 consecutive heartbeat auth failures (HTTP 401) — the
token in MOLECULE_WORKSPACE_TOKEN has been REVOKED, likely because
workspace <id> was deleted server-side. The MCP server is still running
but every platform call will fail. Regenerate the workspace + token
from the canvas (Tokens tab), update your MCP config, and restart your
runtime.

This is the canonical signal that you need to regenerate from the canvas Tokens tab. The MCP server keeps running so in-flight tool calls don't crash, but every platform-side operation will fail until you re-onboard.

Troubleshooting

Workspace stays offline after /mcp connect

Most likely the runtime is still using a cached MCP config from session start. Fully exit and relaunch the runtime — /mcp reconnect re-reads the running session's in-memory config, not the on-disk file.

molecule-mcp: register rejected with HTTP 401

The token in MOLECULE_WORKSPACE_TOKEN doesn't match the workspace. Regenerate from the canvas Tokens tab.

Tools unavailable / MCP server disconnected

Check that molecule-mcp resolves on PATH from inside the runtime's environment (it may differ from your interactive shell). If unsure, use the full path to the binary in your MCP config:

which molecule-mcp
# Use this absolute path in your config's "command" field

Origin header is required in logs

Don't pass Origin manually — the wheel sets it. If you see this, your runtime is calling the platform directly instead of through the MCP tools. Use the tools (delegate_task, send_message_to_user, etc.) rather than hand-rolling HTTP calls.

Tools call returns 401 / workspace not found after working before

The workspace was probably deleted from the canvas (or via DELETE /workspaces/:id). Deleting a workspace revokes its token immediately, even if the workspace card still appears with a "removed" badge for a short window. The MCP server itself keeps running, so tool listing still succeeds, but every platform call fails.

Regenerate from the canvas Tokens tab — a deleted workspace can't be brought back; you'll get a new workspace + token pair. Update your MCP config and restart your runtime.

Workspace <id> was deleted on the platform... from get_workspace_info

Since #2429, GET /workspaces/:id returns 410 Gone (not 200 + status:"removed") when the workspace has been deleted. The MCP wheel's get_workspace_info tool surfaces this as a tailored error message:

Workspace <id> was deleted on the platform at <removed_at>.
Regenerate workspace + token from the canvas → Tokens tab.

This is the startup-time counterpart to the heartbeat-401 escalation above. If you see it within seconds of starting your runtime (rather than after ~60s of heartbeat failures), the workspace was already gone when you connected — regenerate as instructed.

Audit-trail tools that intentionally want to inspect a removed workspace's metadata (admin dashboards, "show me deleted workspaces" tooling) can opt back into the legacy 200 + body shape via GET /workspaces/<id>?include_removed=true.

claude mcp list shows the new config but tools still 401

/mcp reconnect re-spawns the cached MCP config from session start, not the latest on-disk config. After editing claude mcp add or your ~/.cursor/mcp.json, fully exit and relaunch the runtime — not just /mcp.

A quick way to confirm: ps aux | grep molecule-mcp and check the PID hasn't changed across /mcp reconnects. If the same PID stays alive, the runtime is still using the old config.

command not found: molecule-mcp from inside the runtime

The runtime's PATH may differ from your interactive shell — common on macOS where ~/Library/Python/3.x/bin is added to login shells but not to GUI-launched apps. Use the absolute path in your MCP config:

which molecule-mcp
# /Users/you/Library/Python/3.13/bin/molecule-mcp

Then point command at that absolute path in claude mcp add / .cursor/mcp.json / mcp_servers.yaml.

When to use this vs. the manual A2A path

ScenarioUse
You're using an MCP-aware agent runtimeThis page (universal molecule-mcp wheel)
You're building a custom agent without MCP supportExternal Agents (manual register + heartbeat + HTTP server)
You want the platform to expose MCP tools your agent connects to (inverse direction)MCP Server

The universal wheel is the recommended path for almost every modern runtime — it handles registration, heartbeat, inbox polling, A2A routing, and Origin/WAF headers for you. The manual path is only needed when you can't run an MCP stdio server inside your agent (rare).

See also

On this page