molecule-core/docs/api-reference.md
Hongming Wang 24fec62d7f initial commit — Molecule AI platform
Forked clean from public hackathon repo (Starfire-AgentTeam, BSL 1.1)
with full rebrand to Molecule AI under github.com/Molecule-AI/molecule-monorepo.

Brand: Starfire → Molecule AI.
Slug: starfire / agent-molecule → molecule.
Env vars: STARFIRE_* → MOLECULE_*.
Go module: github.com/agent-molecule/platform → github.com/Molecule-AI/molecule-monorepo/platform.
Python packages: starfire_plugin → molecule_plugin, starfire_agent → molecule_agent.
DB: agentmolecule → molecule.

History truncated; see public repo for prior commits and contributor
attribution. Verified green: go test -race ./... (platform), pytest
(workspace-template 1129 + sdk 132), vitest (canvas 352), build (mcp).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:55:37 -07:00

15 KiB

API Reference

Platform API server runs on :8080 by default. All endpoints return JSON.

Rate limit: 600 req/min (configurable via RATE_LIMIT env var). CORS: http://localhost:3000, http://localhost:3001 by default (configurable via CORS_ORIGINS).


REST Endpoints

Workspaces

Method Path Description
POST /workspaces Create workspace and provision container
GET /workspaces List all workspaces
GET /workspaces/:id Get single workspace
PATCH /workspaces/:id Update workspace fields
DELETE /workspaces/:id Delete workspace and remove container
POST /workspaces/:id/restart Restart workspace container
POST /workspaces/:id/pause Pause workspace (cascades to children)
POST /workspaces/:id/resume Resume paused workspace

POST /workspaces

Create a new workspace. Provisions a Docker container automatically.

{
  "name": "Marketing Lead",
  "role": "Manages marketing campaigns",
  "template": "general-assistant",
  "tier": 2,
  "model": "anthropic:claude-sonnet-4-6",
  "runtime": "langgraph",
  "parent_id": "uuid-of-parent",
  "canvas": { "x": 100, "y": 200 }
}

Response: workspace object with id, status: "provisioning".


A2A Proxy

Method Path Description
POST /workspaces/:id/a2a Proxy A2A JSON-RPC to workspace agent

Forwards JSON-RPC 2.0 requests to the workspace's agent container. Automatically wraps in JSON-RPC envelope if missing.

Headers:

  • X-Workspace-ID -- set to caller workspace ID for agent-to-agent calls; empty for canvas-initiated

Timeouts:

  • Canvas-initiated (no X-Workspace-ID): 5 minutes
  • Agent-to-agent (X-Workspace-ID set): 30 minutes

Example -- send message:

{
  "jsonrpc": "2.0",
  "id": "uuid",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [{ "kind": "text", "text": "Hello agent" }]
    }
  }
}

On success for canvas-initiated requests, also broadcasts an A2A_RESPONSE WebSocket event.


Secrets

Secrets are encrypted with AES-256-GCM at rest. Values are never returned to the client.

Global Secrets

Method Path Description
GET /settings/secrets List global secrets (keys only)
PUT /settings/secrets Set a global secret
POST /settings/secrets Set a global secret (alias)
DELETE /settings/secrets/:key Delete a global secret

Legacy aliases: GET/POST/DELETE /admin/secrets (backward compatible).

PUT /settings/secrets:

{ "key": "ANTHROPIC_API_KEY", "value": "sk-ant-..." }

Response: { "status": "saved", "key": "ANTHROPIC_API_KEY", "scope": "global" }

Workspace Secrets

Method Path Description
GET /workspaces/:id/secrets List merged secrets (workspace + inherited global)
PUT /workspaces/:id/secrets Set workspace-level secret override
POST /workspaces/:id/secrets Set workspace-level secret override (alias)
DELETE /workspaces/:id/secrets/:key Delete workspace-level secret

GET /workspaces/:id/secrets returns a merged view:

[
  { "key": "ANTHROPIC_API_KEY", "has_value": true, "scope": "workspace", "created_at": "...", "updated_at": "..." },
  { "key": "OPENAI_API_KEY", "has_value": true, "scope": "global", "created_at": "...", "updated_at": "..." }
]
  • scope: "workspace" -- set directly on this workspace (overrides global)
  • scope: "global" -- inherited from global secrets (not overridden)

Setting or deleting a workspace secret triggers an automatic container restart.

Precedence

When provisioning a container, secrets are loaded: global first, then workspace-specific. Workspace secrets with the same key override globals. The merged set is injected as environment variables.

Model Config

Method Path Description
GET /workspaces/:id/model Get current MODEL_PROVIDER config

Activity Logs

Method Path Description
GET /workspaces/:id/activity List activity logs (?type=&limit=)
GET /workspaces/:id/session-search Full-text search across activity + memories (?q=&limit=)
POST /workspaces/:id/activity Agent self-reports activity
POST /workspaces/:id/notify Agent pushes a chat message to canvas

POST /workspaces/:id/notify:

{ "message": "I've completed the analysis." }

Broadcasts an AGENT_MESSAGE WebSocket event. Does not persist to activity_logs.

POST /workspaces/:id/activity:

{
  "activity_type": "a2a_send",
  "method": "message/send",
  "summary": "Delegated task to Dev Lead",
  "target_id": "uuid-of-target",
  "status": "ok",
  "duration_ms": 1500,
  "request_body": {},
  "response_body": {}
}

Valid activity types: a2a_send, a2a_receive, task_update, agent_log, skill_promotion, error.


Registry (agent-facing)

Used by workspace agents to self-register and maintain liveness.

Method Path Description
POST /registry/register Agent registers on startup
POST /registry/heartbeat Agent heartbeat (includes task state)
POST /registry/update-card Agent updates its AgentCard

POST /registry/register:

{
  "id": "workspace-uuid",
  "url": "http://hostname:9000",
  "agent_card": { "name": "...", "skills": [...], "capabilities": {...} }
}

Transitions workspace status to online, broadcasts WORKSPACE_ONLINE.

POST /registry/heartbeat:

{
  "workspace_id": "uuid",
  "current_task": "Analyzing report...",
  "active_tasks": 2,
  "error_rate": 0.0,
  "uptime_seconds": 3600
}

If error_rate > 0.5, broadcasts WORKSPACE_DEGRADED. Recovery broadcasts WORKSPACE_ONLINE.


Discovery

Method Path Description
GET /registry/discover/:id Discover workspace by ID
GET /registry/:id/peers List accessible peer workspaces
POST /registry/check-access Check if two workspaces can communicate

Team Expansion

Method Path Description
POST /workspaces/:id/expand Expand workspace into a sub-team
POST /workspaces/:id/collapse Remove all children, collapse back to single workspace

Agents

Method Path Description
POST /workspaces/:id/agent Assign agent to workspace
PATCH /workspaces/:id/agent Replace agent
DELETE /workspaces/:id/agent Remove agent
POST /workspaces/:id/agent/move Move agent between workspaces

Config & Memory

Method Path Description
GET /workspaces/:id/config Get workspace config (JSONB)
PATCH /workspaces/:id/config Merge-patch config
GET /workspaces/:id/memory List KV memory entries
GET /workspaces/:id/memory/:key Get single KV entry
POST /workspaces/:id/memory Set KV entry (with optional TTL)
DELETE /workspaces/:id/memory/:key Delete KV entry

Agent Memories (HMA)

Method Path Description
POST /workspaces/:id/memories Commit a memory (LOCAL, TEAM, or GLOBAL scope)
GET /workspaces/:id/memories Search memories
DELETE /workspaces/:id/memories/:memoryId Delete a memory

Approvals

Method Path Description
GET /approvals/pending List all pending approvals (cross-workspace)
POST /workspaces/:id/approvals Create approval request
GET /workspaces/:id/approvals List workspace approvals
POST /workspaces/:id/approvals/:approvalId/decide Approve or reject

Async Delegation

Method Path Description
POST /workspaces/:id/delegate Fire-and-forget delegation ({target_id, task})
GET /workspaces/:id/delegations List delegations with status and results

Templates & Files

Method Path Description
GET /templates List available workspace templates
POST /templates/import Import template from URL
GET /workspaces/:id/shared-context Get shared context files
PUT /workspaces/:id/files Replace all config files
GET /workspaces/:id/files List files (lazy: ?depth=1&path=subdir)
GET /workspaces/:id/files/*path Read a config file
PUT /workspaces/:id/files/*path Write a config file
DELETE /workspaces/:id/files/*path Delete a config file

Plugins

Method Path Description
GET /plugins List available plugins (?runtime=<name> filters to compatible)
GET /plugins/sources List registered install-source schemes (e.g. github, local)
GET /workspaces/:id/plugins List plugins installed in workspace
GET /workspaces/:id/plugins/available Plugins filtered to the workspace's runtime
GET /workspaces/:id/plugins/compatibility?runtime=X Preflight runtime change
POST /workspaces/:id/plugins Install plugin ({"source":"<scheme>://<spec>"}, e.g. local://ecc, github://owner/repo#v1.0) — auto-restarts
DELETE /workspaces/:id/plugins/:name Uninstall plugin — auto-restarts

Bundles

Method Path Description
GET /bundles/export/:id Export workspace as portable bundle
POST /bundles/import Import workspace from bundle

Other

Method Path Description
GET /health Health check ({"status": "ok"})
GET /metrics Prometheus metrics
GET /events List structure events
GET /events/:workspaceId List events for a workspace
GET /workspaces/:id/traces Proxy to Langfuse traces
GET /workspaces/:id/terminal WebSocket terminal into container
GET /canvas/viewport Get saved canvas viewport
PUT /canvas/viewport Save canvas viewport
POST /webhooks/github GitHub webhook receiver

WebSocket Events

Connect to ws://localhost:8080/ws. All messages use this envelope:

{
  "event": "EVENT_TYPE",
  "workspace_id": "uuid",
  "timestamp": "2024-01-01T00:00:00Z",
  "payload": { ... }
}

Routing: Canvas clients (no workspace ID) receive all events. Workspace clients receive only events for workspaces they can communicate with (per hierarchy rules).

Workspace Lifecycle Events

These are persisted to the structure_events table.

Event Payload Trigger
WORKSPACE_PROVISIONING {name, tier, parent_id?} Container creation or restart begins
WORKSPACE_ONLINE {url, agent_card} Agent self-registers or recovers from degraded
WORKSPACE_OFFLINE {} A2A proxy detects dead container
WORKSPACE_PAUSED {} Pause operation completes
WORKSPACE_DEGRADED {error_rate, sample_error} Heartbeat reports error_rate > 0.5
WORKSPACE_REMOVED {name?} Workspace deleted
WORKSPACE_PROVISION_FAILED {error} Container start failed
WORKSPACE_EXPANDED {children: [ids]} Team expansion complete
WORKSPACE_COLLAPSED {children: [ids]} Team collapse complete

Agent Events

Persisted to structure_events.

Event Payload Trigger
AGENT_CARD_UPDATED {agent_card} Agent updates its discovery card
AGENT_ASSIGNED {agent_id, name} Agent assigned to workspace
AGENT_REPLACED {agent_id, name} Agent replaced in workspace
AGENT_REMOVED {agent_id} Agent removed from workspace
AGENT_MOVED {from, to, agent_id} Agent moved (fired on both source and target)

Approval Events

Persisted to structure_events.

Event Payload Trigger
APPROVAL_REQUESTED {approval_id, workspace_id, ...} Agent requests human approval
APPROVAL_ESCALATED {approval_id, child_id, ...} Approval escalated to parent workspace

High-Frequency Events (broadcast only, not persisted)

Event Payload Trigger
TASK_UPDATED {current_task, active_tasks} Heartbeat includes task state changes
AGENT_MESSAGE {message, workspace_id, name} Agent pushes chat message via POST /notify
ACTIVITY_LOGGED {activity_type, method, summary, status, source_id, target_id, duration_ms} Any activity log insert
A2A_RESPONSE {response_body, method, duration_ms} Canvas-initiated A2A proxy returns success

Frontend Handling

The canvas (canvas-events.ts) handles these events in its Zustand store:

Event Frontend Action
WORKSPACE_ONLINE Set node status to "online"
WORKSPACE_OFFLINE Set node status to "offline"
WORKSPACE_PAUSED Set node status to "paused", clear currentTask
WORKSPACE_DEGRADED Set node status to "degraded", store error rate
WORKSPACE_PROVISIONING Update existing node or create new node
WORKSPACE_REMOVED Remove node, reparent children, clean edges
AGENT_CARD_UPDATED Update node's agentCard
TASK_UPDATED Update node's currentTask and activeTasks
AGENT_MESSAGE Append to chat messages for the workspace
A2A_RESPONSE Extract response text, append to chat messages

A2A JSON-RPC Methods

Workspace agents implement the A2A protocol via the a2a-sdk. The Platform A2A proxy forwards these methods transparently.

message/send

Synchronous message exchange. Blocks until the agent completes processing.

{
  "jsonrpc": "2.0",
  "id": "unique-id",
  "method": "message/send",
  "params": {
    "message": {
      "messageId": "unique-msg-id",
      "role": "user",
      "parts": [
        { "kind": "text", "text": "Analyze the Q4 report" }
      ]
    }
  }
}

Response contains the agent's reply message with parts (text, data, etc.).

message/stream

SSE streaming variant of message/send. Returns token-level Server-Sent Events as the agent generates its response.

tasks/get

Poll the status of a previously submitted async task.

{
  "jsonrpc": "2.0",
  "id": "unique-id",
  "method": "tasks/get",
  "params": {
    "id": "task-uuid"
  }
}

Returns task state: submitted, working, input-required, completed, failed, canceled.