diff --git a/content/docs/architecture.mdx b/content/docs/architecture.mdx index 3fd0b33..f23156c 100644 --- a/content/docs/architecture.mdx +++ b/content/docs/architecture.mdx @@ -5,10 +5,24 @@ description: System architecture, components, infrastructure, and communication # Architecture -Molecule AI is a platform for orchestrating AI agent workspaces that form an organizational hierarchy. Workspaces register with a central platform, communicate via A2A (Agent-to-Agent) protocol, and are visualized on a drag-and-drop canvas. +Molecule AI is an **open-source operating system for AI agent organizations** — run the entire stack yourself (self-hosted) or use the hosted SaaS. It orchestrates agent **workspaces** that form an organizational hierarchy: each workspace registers with a control plane, runs on its **own dedicated machine**, communicates over the A2A (Agent-to-Agent) protocol, and appears live on a drag-and-drop canvas. The core is **provider-agnostic** — runtimes, models, and even physical devices are pluggable — so the ecosystem grows without forking the platform. ## System Overview +Molecule AI platform architecture: operator surfaces (Canvas, CLI, MCP server, channels, REST) drive a Go control plane (provisioner, registry/discovery with CanCommunicate ACL, A2A proxy, WebSocket hub, scheduler, secrets, audit) backed by Postgres and Redis; the control plane provisions an isolated org tenant of workspace containers that communicate directly peer-to-peer over A2A governed by the org hierarchy; runtimes (claude-code, langgraph, crewai, autogen, deepagents, openclaw, hermes, gemini-cli, google-adk, external) and model providers (Anthropic, OpenAI, Google Vertex, OpenRouter) are pluggable integrations. + +Three properties define the architecture: + +- **Hard isolation by machine.** Every workspace is one agent on its **own dedicated machine** (own OS, filesystem, secrets). Workspaces **cannot** read each other's environment — there is no shared disk or shared process space. **A2A over the network is the only sanctioned channel**, and it is gated by the org hierarchy (`CanCommunicate`). +- **Anything can be a runtime.** Behind one `BaseAdapter` contract, a workspace can be any agent framework (claude-code, langgraph, crewai, autogen, deepagents, openclaw, hermes, gemini-cli, **google-adk**), an external/BYO agent, or — on the roadmap — an **intelligent device**: smart glasses, watches, robots, home/building systems, vehicles. Any A2A/MCP-speaking endpoint joins the org as a governed workspace. Models are equally pluggable (Anthropic, OpenAI/-compatible, **Google Vertex/Gemini**, OpenRouter). +- **Deep, namespaced memory.** A hierarchical memory architecture (HMA) gives each workspace a durable namespace and three scopes — **LOCAL** (private), **TEAM** (parent + siblings), **GLOBAL** (org-wide) — whose reach follows the same org tree as communication. + +A text summary of the same flow: + ``` Canvas (Next.js :3000) <--WebSocket--> Platform (Go :8080) <--HTTP--> Postgres + Redis | diff --git a/content/docs/channels.mdx b/content/docs/channels.mdx index a1823fb..f4a2326 100644 --- a/content/docs/channels.mdx +++ b/content/docs/channels.mdx @@ -5,6 +5,12 @@ description: Connect workspaces to Telegram, Slack, Discord, and Lark/Feishu for ## Overview +Channel message flow: a chat platform (Telegram, Slack, Discord, Lark) delivers an inbound user message to POST /webhooks/:type; the control-plane adapter parses it, checks an allowlist, and forwards it over A2A to the target workspace agent; the agent's reply routes back out through the same adapter to the user. + Channels let workspaces send and receive messages on social platforms. Each workspace can have multiple channel integrations — a Telegram bot, a Slack webhook, a Discord webhook, a Lark/Feishu Custom Bot — configured independently with per-channel diff --git a/content/docs/concepts.mdx b/content/docs/concepts.mdx index ae426c0..88b0293 100644 --- a/content/docs/concepts.mdx +++ b/content/docs/concepts.mdx @@ -3,6 +3,12 @@ title: Concepts description: The core primitives that compose every Molecule AI org — workspaces, plugins, channels, schedules, tokens, external agents, and the canvas. --- +Molecule AI core concepts: an org.yaml is imported by the Control Plane, which provisions a tenant of agent workspaces that communicate peer-to-peer over A2A — governed by the org hierarchy — while the Canvas streams live state and external agents join over HTTP. + ## Workspaces A **workspace** is a real Docker container running a real LLM agent. Each diff --git a/content/docs/external-agents.mdx b/content/docs/external-agents.mdx index 85e7b99..db73b76 100644 --- a/content/docs/external-agents.mdx +++ b/content/docs/external-agents.mdx @@ -10,6 +10,14 @@ cloud, an edge device, or your laptop — that join the Molecule AI canvas as first-class workspaces. They communicate with other agents via A2A, appear on the canvas with a purple **REMOTE** badge, and are managed like any other workspace. +Like every workspace, they speak the A2A task protocol. Its lifecycle and the discovery → direct-call flow: + +A2A task lifecycle: a task moves submitted → working → completed (with artifacts), failed, or canceled, with a working ↔ input-required loop when the agent needs a caller reply; message/send is synchronous and message/sendSubscribe streams SSE events where the terminal event closes the stream. Below, the discovery sequence: caller asks the platform GET /registry/discover/:id, the platform applies CanCommunicate and returns the target URL (or 403), then the caller calls the target agent directly over A2A — the platform is not in the data path. + **Using an MCP-aware agent runtime** (Claude Code, Hermes, OpenCode, Cursor, Cline, etc.)? The universal `molecule-mcp` wheel handles registration, diff --git a/content/docs/google-adk.mdx b/content/docs/google-adk.mdx index e6d6194..1211f45 100644 --- a/content/docs/google-adk.mdx +++ b/content/docs/google-adk.mdx @@ -15,6 +15,16 @@ The `google-adk` runtime adapter integrates [Google's Agent Development Kit](htt --- +## Architecture + +A `google-adk` workspace runs Google's ADK engine (`LlmAgent` + `Runner` + `McpToolset`); a Molecule-authored A2A executor bridges ADK `Runner` events into the platform's a2a-1.x event model, so the agent is a fully governed citizen of the org. Platform tools reach the agent over **MCP**, and Gemini is served by **Vertex AI using keyless credentials** (Application Default Credentials over Workload Identity Federation — no API key on disk). + +End-to-end google-adk architecture: Canvas declarative intent to Control Plane provisioning to a per-agent ADK runtime (LlmAgent + Runner + Molecule A2A executor + McpToolset), with a keyless Workload Identity Federation chain (GCP STS to a least-privilege service account to Vertex AI gemini-2.5-pro) — zero API keys. + ## When to use Google ADK vs other runtimes | | Google ADK | LangGraph | AutoGen | diff --git a/content/docs/hermes.mdx b/content/docs/hermes.mdx index 5865692..8db100f 100644 --- a/content/docs/hermes.mdx +++ b/content/docs/hermes.mdx @@ -9,6 +9,12 @@ import { Callout } from 'fumadocs-ui/components/callout'; Hermes is Molecule AI's built-in inference router powering `runtime: hermes` workspaces. It supports three dispatch paths — a native Anthropic Messages API path, a native Gemini `generateContent` path, and an OpenAI-compatible shim for 13+ other providers — keyed automatically by which API secret is present on the workspace. +Hermes multi-provider dispatch: a key-priority resolver checks workspace secrets in order (HERMES_API_KEY, then OPENROUTER_API_KEY, then ANTHROPIC_API_KEY, then GEMINI_API_KEY) and routes into one of three transports — native Anthropic /v1/messages, native Gemini generateContent, or an OpenAI-compatible shim for 13+ providers (OpenRouter, DeepSeek, Together, and any OpenAI-compatible gateway). If the chosen path's SDK is not installed, Hermes raises a RuntimeError at startup rather than silently falling back. + Phases 2a through 2e are fully merged to `main`: - **Phase 2a** (PR #240) — native Anthropic dispatch diff --git a/content/docs/mcp-server.mdx b/content/docs/mcp-server.mdx index 208beca..3ec1cde 100644 --- a/content/docs/mcp-server.mdx +++ b/content/docs/mcp-server.mdx @@ -7,6 +7,12 @@ The Molecule AI MCP server lets any MCP-compatible AI agent (Claude Code, Cursor, etc.) manage workspaces, agents, secrets, memory, schedules, channels, and more through the platform API. +MCP as one tool surface in two directions: on the left, any MCP host (Claude Desktop/Code, Cursor, your own client) connects via @molecule-ai/mcp-server over stdio to drive the platform; in the center, the platform exposes 80+ tools 1:1 with API routes (workspaces, delegation, memory, secrets, schedules, approvals, files, channels) with auth and hierarchy ACL applied; on the right, in-workspace runtimes (claude-code, google-adk via McpToolset, langgraph, external) consume the same tools natively — no per-framework tool glue. + ## Quick start ### Install diff --git a/content/docs/org-template.mdx b/content/docs/org-template.mdx index fec8929..01ad3c6 100644 --- a/content/docs/org-template.mdx +++ b/content/docs/org-template.mdx @@ -7,6 +7,12 @@ description: Deploy entire multi-workspace organizations from a single YAML file Org templates let you define an entire agent organization -- hierarchy of workspaces with roles, configurations, and relationships -- in a single YAML file. Import one template and the platform provisions every workspace, wires parent-child relationships, seeds schedules, and installs plugins automatically. +org.yaml on the left (org_name, defaults, nested workspaces with roles/runtimes/children) imports into a rendered org chart on the right; children become parent_id nesting, defaults merge by union with per-workspace overrides and !name opt-outs, and schedules/plugins are seeded on import. + ## YAML Structure A minimal org template looks like this: diff --git a/content/docs/schedules.mdx b/content/docs/schedules.mdx index f301687..92f4bc7 100644 --- a/content/docs/schedules.mdx +++ b/content/docs/schedules.mdx @@ -5,6 +5,12 @@ description: Run recurring prompts on cron schedules — automated audits, repor ## Overview +Schedule lifecycle: a 30s scheduler loop reads due rows from workspace_schedules, passes them through a concurrency semaphore (max 10, 5-minute timeout), fires an A2A message/send to the workspace agent as system:scheduler, then records the outcome (success/error/skipped) and recomputes next_run back into the table. + Schedules let you run recurring prompts against a workspace on a cron schedule. Each tick fires an A2A `message/send` into the workspace, so the agent processes the prompt as if it received a normal message. This enables automated diff --git a/content/docs/security/owasp-agentic-top-10.mdx b/content/docs/security/owasp-agentic-top-10.mdx index cf4b32e..87c173d 100644 --- a/content/docs/security/owasp-agentic-top-10.mdx +++ b/content/docs/security/owasp-agentic-top-10.mdx @@ -5,6 +5,14 @@ description: Mapping the OWASP Agentic AI Top 10 to Molecule AI security control ## Overview +The platform's primary access-control mechanism is hierarchy-based: the org chart itself is the policy that governs which agents may communicate, what memory they reach, and which events they see — backed by per-machine isolation underneath. + +Governance model: CanCommunicate(caller, target) allows self, siblings, and parent↔child edges (green) and denies skip-level and cross-team edges (red, 403) across the org tree; the same hierarchy scopes A2A messaging, LOCAL/TEAM/GLOBAL memory reach, ACL-filtered WebSocket event fan-out, and peer discovery; underneath, each workspace is its own machine with no shared filesystem, env, or secrets — defense in depth with the ACL above and machine isolation below. + This page documents Molecule AI's coverage of the [OWASP Agentic AI Top 10](https://owasp.org/agentic-ai-top-10/) security risks for AI agents and agentic systems. Coverage is assessed against the platform as diff --git a/content/docs/self-hosting.mdx b/content/docs/self-hosting.mdx index d9dde0f..11f276b 100644 --- a/content/docs/self-hosting.mdx +++ b/content/docs/self-hosting.mdx @@ -3,6 +3,14 @@ title: Self-Hosting description: Run the full Molecule AI stack on your own infrastructure. --- +Molecule AI is open source and runs entirely on your own infrastructure — the same binary as the hosted SaaS, in single-org mode. The whole stack sits on one Docker network: + +Self-hosting topology on the molecule-monorepo-net Docker network: the Canvas (Next.js :3000) talks to the Platform (Go :8080) over REST and WebSocket; the platform connects to Postgres (:5432, source of truth), Redis (:6379, liveness and pub/sub), Langfuse (:3001, traces, with ClickHouse), and Temporal (:7233/:8233, durable workflows), and provisions tiered workspace containers that register and heartbeat back. Secrets are encrypted at rest with AES-256-GCM or a KMS envelope; the platform refuses to boot without an encryption key. SaaS adds a Cloudflare wildcard-DNS edge that self-host omits. + ## Prerequisites | Requirement | Minimum Version | diff --git a/content/docs/tokens.mdx b/content/docs/tokens.mdx index b4c659b..35495f1 100644 --- a/content/docs/tokens.mdx +++ b/content/docs/tokens.mdx @@ -7,6 +7,14 @@ Workspace bearer tokens authenticate agents and API clients against the Molecule AI platform. Each token is scoped to a single workspace — a token from workspace A cannot access workspace B. +These workspace bearer tokens are the narrowest of three credential tiers — sitting below org API keys and the control-plane admin token. The full model: + +Three scoped credential tiers, authority narrowing top to bottom: ADMIN_TOKEN authorizes the whole control plane and all orgs (mints org keys); an Org API key authorizes one entire org and nothing on the control plane or other orgs; a Workspace bearer token (256-bit, sha256-stored, shown once) authorizes only its own workspace and is the only credential an agent holds. All secrets are encrypted at rest and masked on read. + ## Endpoints All endpoints are behind `WorkspaceAuth` middleware — you need an existing diff --git a/content/docs/workspace-config.mdx b/content/docs/workspace-config.mdx index 6b8a00e..8528a08 100644 --- a/content/docs/workspace-config.mdx +++ b/content/docs/workspace-config.mdx @@ -9,6 +9,12 @@ import { Callout } from 'fumadocs-ui/components/callout'; Every Molecule AI workspace is backed by a `config.yaml` file. The **Config tab** in the canvas lets you edit this file through a structured form or in raw YAML mode. Changes take effect on the next workspace restart. +config.yaml drives runtime resolution: the workspace loads config.yaml, selects an adapter from the registry by its runtime field (claude-code, langgraph, hermes, google-adk, external, etc.), and runs a boot pipeline — preflight, setup, create_executor, system prompt + agent card, register, heartbeat, serve A2A. Model is provider:model-id; tools are tier-gated; preflight fails loud on a runtime/config mismatch. + --- ## Opening the Config tab diff --git a/public/diagrams/a2a-lifecycle.svg b/public/diagrams/a2a-lifecycle.svg new file mode 100644 index 0000000..a8c41e2 --- /dev/null +++ b/public/diagrams/a2a-lifecycle.svg @@ -0,0 +1,72 @@ + + + + + + + + + + A2A task lifecycle + A caller sends a message (JSON-RPC); the agent's task moves through states and streams events. Terminal SSE event ends the stream — no polling. + + + + Task states + + + submitted + message accepted + + + working + agent executing + + + input-required + needs caller reply + + + completed + + artifacts + + + failed + + + canceled + + + + success + error + + caller replies + tasks/cancel + + + + Transports + message/send — sync request/response + message/sendSubscribe — SSE stream + Streaming events (SSE) + each state change emits an event; + the terminal event closes the stream. + Cancel + tasks/cancel → executor interrupt + + + Discovery + direct call (platform exits the data path) + + + Caller agent + Platform (discovery) + Target agent + + + + ① GET /registry/discover/:id + ② CanCommunicate ✓ → target URL (403 if denied) + ③ direct A2A message/send (platform NOT in path) + ④ task events / result + diff --git a/public/diagrams/architecture-keyless-adk.svg b/public/diagrams/architecture-keyless-adk.svg new file mode 100644 index 0000000..1680399 --- /dev/null +++ b/public/diagrams/architecture-keyless-adk.svg @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + Molecule AI — From One Agent to a Governed AI Org + Net-new Gemini agents on Google ADK · tools over MCP · served by Vertex AI with keyless (WIF/ADC) credentials — zero key material anywhere + + + + + 🔒 Keyless by design + No API keys · no long-lived secrets · AWS→GCP federation + + + + + + + 1 + Operator · Molecule Canvas + Declarative intent — org.yaml + roles · charters · model · tools + “describe the org, don’t wire the code” + + + + + + 2 + Control Plane · Railway + + Provisioner + renders per-agent EC2 user-data; + injects keyless ADC cred-config + + envs.yaml — SSOT + vertex: project / location + GCP_WIF_CRED_CONFIG_JSON (non-secret) + + + + + + 3 + Org Tenant — isolated EC2 · Postgres · Redis + + + + + + Marketing PM + coordinator + + + + + + + + Research + trends · audience + Content Writer + drafts · creative + Reviewer + brand · compliance + + + + + + + + delegates over A2A + + + + Governance Layer · what raw A2A omits + discovery / registry · access-control (who-may-call-whom) + hierarchical shared memory · human-approval gates + A2A routing · OTEL · compliance hooks + + + + a2a_mcp_server (MCP) + platform tools: filesystem · shell · web · peer messaging + the “securely connect to external tools via MCP” pattern + + + each agent runs a per-agent ADK runtime ▸ + + + + + + 4 + Per-agent ADK runtime + google-adk[mcp] 2.1.0 + + + LlmAgent + Runner + the ADK agent engine + + + Molecule A2A Executor + Runner events → a2a-1.x + EventQueue / TaskUpdater · heartbeat + + + McpToolset + native ADK → platform MCP tools + + + + + + 5 + Google Cloud + + + GCP STS + Workload Identity + Federation (WIF) + AWS EC2 role → aws_role + + + Service Account + molecule-vertex-adc@ + roles/aiplatform.user + least-privilege · impersonated + + + Vertex AI + gemini-2.5-pro + no key — short-lived token only + + + + + + + federate + short-lived token + + + + + org.yaml + + + + + + provision + tenant + agents + + + + + + + MCP + + + + ADC · no key + + + + inference (Gemini) + + + + + + Live & verified in production + molecule-adk-demo.moleculesai.app — 4 agents · runtime google-adk · model vertex:gemini-2.5-pro · keyless (no GOOGLE_API_KEY) + Per-(provider×auth) serving E2E gate · provisioning fails loud on runtime/config mismatch · 100% unit coverage on the ADC path + a real no-key Gemini-on-Vertex E2E. + + + + keyless credential chain (WIF/ADC) + governance layer + MCP tools + Google Cloud (Vertex AI) + + diff --git a/public/diagrams/channels.svg b/public/diagrams/channels.svg new file mode 100644 index 0000000..6386068 --- /dev/null +++ b/public/diagrams/channels.svg @@ -0,0 +1,54 @@ + + + + + + + + Channels — chat in, agent out + External chat platforms bridge to a workspace over A2A. Inbound is allowlist-gated; outbound replies route back through the same adapter. + + + + Chat platform + + Telegramlong-poll / webhook + SlackEvents API + DiscordInteractions (no poll) + Lark / FeishuEvent Subscriptions + + + + + Control Plane · channel adapter + + POST /webhooks/:type + adapter.ParseWebhook → normalize + allowlist gate (chat_id / user) + A2A message/send → target workspace + + + + + Workspace agent + runs the turn, replies + caller = channel:<type> + + + + ① user message + + ② A2A in + + + + ③ reply + + ④ back to user + + + + Config & safety + • Tokens/webhook secrets are encrypted at rest and masked on read. • Inbound is gated by an allowlist (chat id / user) before any A2A call. + • Each channel binds to a workspace; the agent sees the sender as channel:<type> and replies through the same adapter (round-trip). + diff --git a/public/diagrams/concepts-overview.svg b/public/diagrams/concepts-overview.svg new file mode 100644 index 0000000..13a421c --- /dev/null +++ b/public/diagrams/concepts-overview.svg @@ -0,0 +1,141 @@ + + + + + + + + + + Molecule AI — Core Concepts + Run a multi-agent organization as code: one org.yaml → a tree of agent Workspaces that talk peer-to-peer over A2A, governed by the org hierarchy. + + + + Canvas (operator UI) + Next.js · React Flow org-chart + live nodes · drag/create · approvals + app.moleculesai.app + + + + org.yaml — declarative intent + org tree · roles · runtime · tier + model · plugins · schedules · channels + imported once → provisions the org + + + + Marketplace + L1 Plugins · L2 Agents · L3 Bundles + install → adds capability to a workspace + + + + Control Plane · Platform + Go / Gin · :8080 + + provisioner — spawns workspace containers + registry + discovery — who/where (ACL gate) + A2A proxy (canvas) · WebSocket event hub + scheduler · channels · secrets · budget + + + + Postgres + source of truth + event-sourced + + Redis + liveness TTL + pub/sub + platform is in the discovery path — + NOT in the agent↔agent data path. + one org = one isolated Tenant (EC2 · PG · Redis). + + + + Org Tenant — Workspaces (one agent each) + isolated container per workspace · per-workspace bearer token · pluggable runtime + + + + Org Lead + root workspace + + + + + + + Agent A + runtime · tier · skills + Team Lead B + coordinator + Agent C + specialist + + + + + + Agent B1 + sub-agent + Agent B2 + sub-agent + + + + + + + + + + + + + + + A2A allowed: siblings · parent ↔ child + ✕ skip-level / cross-team denied + The org chart is the access-control policy — comms, memory scope & event fan-out + all derive from parent_id. No edges to wire by hand. + + + Governance layer mediates every hop + + + + External / Remote agent + runtime: external — your infra, any A2A/MCP agent + register + 30s heartbeat → joins the same canvas + REMOTE badge · pulls secrets on demand + + + + + import + + + REST · WebSocket + + + install → workspace + + + provision + + + + + register · heartbeat · A2A + + + + A2A allowed + denied by hierarchy + control-plane (REST/WS/provision) + declarative import + + diff --git a/public/diagrams/governance-trust.svg b/public/diagrams/governance-trust.svg new file mode 100644 index 0000000..8689fb3 --- /dev/null +++ b/public/diagrams/governance-trust.svg @@ -0,0 +1,81 @@ + + + + + + + + Governance — the org chart is the access-control policy + CanCommunicate(caller, target) permits self · siblings · parent↔child, and denies everything else. The same hierarchy scopes memory and event fan-out. + + + + Org Lead (root) + + + + + + Team A lead + Team B lead + + + + + + + + A1 + A2 + B1 + B2 + + + + + + + + + + + + + + + + + siblings (root-level) ✓ + + + + ✕ skip-level (A1 → root) + + ✕ cross-team (A2 → B1) + + + + Allowed (CanCommunicate ✓) + • self • siblings (same parent / both root) + • parent → child • child → parent + Denied (403) + • skip-level (grandparent/grandchild) + • cross-team (different subtree) + canvas + system:* / webhook:* are explicit bypass callers + + + Same hierarchy governs + • A2A — who may message whom + • Memory — LOCAL / TEAM / GLOBAL reach + • Events — WebSocket fan-out is ACL-filtered + • Peer discovery — reachable set only + one rule, enforced at the A2A proxy + registry + + + Isolation underneath + • each workspace = its own machine + • no shared filesystem / env / secrets + • A2A over the network is the only path + • per-workspace bearer token + encrypted secrets + defense in depth: ACL above, machine isolation below + diff --git a/public/diagrams/hermes-dispatch.svg b/public/diagrams/hermes-dispatch.svg new file mode 100644 index 0000000..c8ac530 --- /dev/null +++ b/public/diagrams/hermes-dispatch.svg @@ -0,0 +1,64 @@ + + + + + + + Hermes — multi-provider dispatch + One runtime, many providers. Hermes routes by which API key is present, into the right protocol — fail-loud if the SDK is missing. + + + + Key-priority resolver + first key present wins + + 1 · HERMES_API_KEY + 2 · OPENROUTER_API_KEY + 3 · ANTHROPIC_API_KEY + 4 · GEMINI_API_KEY + + workspace secrets → resolver + picks transport for the model id + + + + + + + + Native Anthropic + /v1/messages — Claude + anthropic SDK + Native Gemini + generateContent — Gemini + google-genai SDK + OpenAI-compatible shim + /chat/completions — 13+ providers + OpenRouter · DeepSeek · … + + + + + + + + + + Providers reached + + Anthropic + Google Gemini + OpenRouter + DeepSeek · Together · … + + any OpenAI-compatible gateway + via the shim's base_url + + + + + + + Fail loud + If the chosen path's SDK isn't installed, Hermes raises a RuntimeError at startup — never a silent fallback to the wrong provider. + diff --git a/public/diagrams/mcp-tools.svg b/public/diagrams/mcp-tools.svg new file mode 100644 index 0000000..5a55a67 --- /dev/null +++ b/public/diagrams/mcp-tools.svg @@ -0,0 +1,62 @@ + + + + + + + + MCP — one tool surface for every runtime + Tools reach agents over the Model Context Protocol. The platform exposes the same 80+ tools to any MCP client and to every workspace runtime alike. + + + + Any MCP host + + Claude Desktop / Code + Cursor · IDEs + your own MCP client + + @molecule-ai/mcp-server + stdio · MOLECULE_URL + drive the whole platform + from outside + + + + Platform MCP surface + 80+ tools, 1:1 with API routes + + workspaces + delegation + memory + secrets + schedules + approvals + files + channels · … + + a2a_mcp_server — auth + hierarchy ACL applied + same tools, whether called from outside or by an agent + tools self-authenticate from /configs/.auth_token + + + + In-workspace runtimes + MCP toolset, per framework + + claude-code (native MCP) + google-adk → McpToolset + langgraph · others + external / BYO agent + + each adapter wraps the same + tools natively (e.g. ADK FunctionTool) + + + + MCP + + MCP + + One protocol, two directions: drive Molecule from any MCP host, and give every workspace the same governed tools — no per-framework tool glue. + diff --git a/public/diagrams/org-template.svg b/public/diagrams/org-template.svg new file mode 100644 index 0000000..a647839 --- /dev/null +++ b/public/diagrams/org-template.svg @@ -0,0 +1,71 @@ + + + + + + + org.yaml → a running org chart + One declarative template imports into a live tree of workspaces. Hierarchy comes from nesting — no edges to wire by hand. + + + + org.yaml + + org_name: Acme Marketing + defaults: + runtime: claude-code + tier: 2 + plugins: [molecule-audit] + workspaces: + lead: + role: Marketing PM + runtime: google-adk + children: + research: { role: Research } + writer: + role: Content Writer + plugins: [!molecule-audit] + reviewer: { role: Reviewer } + schedules: [daily-standup] + + defaults merge by UNION; !name opts a workspace out. + per-workspace runtime/tier/plugins override defaults. + POST /org/import (or Canvas template browser) + + + + import + + + + Rendered org (Canvas) + + Marketing PM + google-adk · lead + + + + + + Research + claude-code · T2 + Content Writer + no audit plugin + Reviewer + claude-code · T2 + + + + + + Each YAML key → a workspace node; childrenparent_id nesting. + Nesting sets the A2A comms rule + memory scope automatically. + + Seeded on import + • schedules & plugins from the template (source=template) + • re-import refreshes template rows; runtime-added rows survive + + Resolution rules + plugins = defaults ∪ per-workspace (— or !name to remove) + runtime / tier / model: per-workspace value wins over defaults + diff --git a/public/diagrams/platform-architecture.svg b/public/diagrams/platform-architecture.svg new file mode 100644 index 0000000..a01abe1 --- /dev/null +++ b/public/diagrams/platform-architecture.svg @@ -0,0 +1,203 @@ + + + + + + + + + + + Molecule AI — the open-source OS for AI agent organizations + Self-host the whole stack or use the hosted SaaS · provider-agnostic · plug in any runtime, model, or device · grow your ecosystem. + + Open source · self-hostable · one binary · community ecosystem + + + SURFACES — how you drive & reach the org + + + + + + + + Canvas + React-Flow org-chart UI + molecli (CLI) + scriptable control + MCP server + tools for any MCP host + Channels + telegram · slack · discord · lark + REST API / SDK + automate everything + + + + + + + + + + + + Control Plane · Platform + Go / Gin — the orchestration core (open source) + + Provisionerspawns workspace machines + Registry + DiscoveryCanCommunicate (hierarchy ACL) + A2A Proxycanvas → agent + WebSocket Hublive event fan-out + Schedulercron → A2A + Secretsper-workspace + Budget & metrics + Audit ledger + Event store (sourced) + Channels + + + + + + Postgres + event-sourced SoT + Redis + liveness · pub/sub + In the discovery / provisioning / governance path — never in the agent↔agent data path. + SaaS: one isolated tenant per org. Self-host: same binary, your infrastructure. + + + provision + register · heartbeat + events + + + + + Org Tenant — a hierarchy of Workspaces + each Workspace = one agent on its OWN dedicated machine · pluggable runtime · per-workspace token + + + + Org Lead + root · own machine + + + + + + + + + + ▢ dedicated EC2 · own OS · own filesystem + ▢ dedicated EC2 · own OS · own filesystem + ▢ dedicated EC2 · own OS · own filesystem + + Agent + runtime · tier · skills · secrets + Team Lead + coordinator + Agent + specialist + + + + + + + + + + + + + + hard gate + hard gate + + + + + A2A — the ONLY channel + network-only · hierarchy-gated. + No shared FS / env / secrets — + a workspace cannot touch another's. + + + + Governance layer + discovery · access-control + memory scope · approvals + the org chart IS the ACL + + + + Deep memory — hierarchical & namespaced (HMA) + durable per-workspace namespace · scoped reach follows the org tree + + + GLOBAL + read-all · write from root — org-wide knowledge + + TEAM + parent + siblings — shared team context + + LOCAL + self only — private working memory + + Surfaces + • agent_memories (scoped) • KV / canvas memory + • session recall (search) • awareness namespace + promotion: memory → repeated success → skill (hot-reload) + + + + each workspace selects a runtime ▸ + + + PLUGGABLE RUNTIMES — any agent, any device (one BaseAdapter contract) + + + Software agent frameworks + + claude-code + langgraph + crewai + autogen + deepagents + openclaw + hermes + gemini-cli + google-adk + external / BYO agent + + + + Embodied & edge devices — roadmap + + smart glasses + watches + robots + home / building systems + vehicles · IoT · … + + Any A2A/MCP-speaking endpoint — a software agent OR an intelligent device — registers as a governed workspace in the org. + + + + Model providers + runtimes call whichever the model id names + + Anthropic (Claude) + OpenAI & OpenAI-compatible + Google Vertex AI · Gemini + + + OpenRouter and any OpenAI-compatible gateway. + Orchestration core is provider-agnostic — all swappable. + + + + diff --git a/public/diagrams/schedules.svg b/public/diagrams/schedules.svg new file mode 100644 index 0000000..f5d3238 --- /dev/null +++ b/public/diagrams/schedules.svg @@ -0,0 +1,64 @@ + + + + + + + + + Schedules — cron that wakes an agent + A 30s scheduler loop fires due schedules as A2A messages (caller system:scheduler), bounded by a concurrency semaphore. + + + + Scheduler + polls every 30s + SELECT due rows + next_run_at <= now (≤ 50) + liveness watchdog · panic-recover + + + + workspace_schedules + cron_expr · timezone · prompt + last_run · run_count · next_run + last_status + + + + + Concurrency gate + semaphore — ≤ 10 in-flight + 5-min per-run timeout + + fire due + + + + Workspace agent + runs the scheduled prompt + A2A message/send + + A2A + + + + Record outcome + update last_run / next_run + log activity (cron_run) + success / error / skipped + + + + recompute next_run → back into the table + + + + Outcomes & resilience + + success — agent ran & replied + error — run failed (logged) + skipped — workspace busy + + Seeded from org.yaml on import (idempotent) · panic-recovery per tick · cross-org admin health flags phantom / consecutive-empty schedulers. + diff --git a/public/diagrams/self-hosting.svg b/public/diagrams/self-hosting.svg new file mode 100644 index 0000000..9fa78a6 --- /dev/null +++ b/public/diagrams/self-hosting.svg @@ -0,0 +1,74 @@ + + + + + + + Self-hosting topology + The whole open-source stack runs on one Docker network. Same binary as SaaS — single-org, your infrastructure, your keys. + + + + molecule-monorepo-net (Docker network) + + + + Canvas + Next.js · :3000 + operator UI + + + Platform (Go) + control plane · :8080 + prod: one image w/ Canvas (Dockerfile.tenant) + + + REST · /ws + + + + + + + + + Postgres + :5432 · source of truth + event-sourced + Redis + :6379 · liveness + pub/sub · TTL + Langfuse + :3001 · traces/cost + (+ ClickHouse) + Temporal + :7233 / :8233 + durable workflows + + + + Workspace containers + + agent · tier T1–T4 + agent · pluggable runtime + agent · A2A server + + provisioned by the platform; + register + heartbeat back + + + + + + + + + + provision · A2A proxy + + + + Secrets at rest + Static AES-256-GCM (SECRETS_ENCRYPTION_KEY) or KMS envelope (KMS_KEY_ARN, per-secret DEK). The platform refuses to boot with neither. + SaaS adds a Cloudflare wildcard-DNS edge in front of per-tenant instances; self-host skips that — everything inside the box is identical. + diff --git a/public/diagrams/token-model.svg b/public/diagrams/token-model.svg new file mode 100644 index 0000000..7beecc3 --- /dev/null +++ b/public/diagrams/token-model.svg @@ -0,0 +1,52 @@ + + + + + + + Credential model — three scoped tiers + Each credential authorizes a different blast radius. Authority narrows top → bottom; nothing crosses an org boundary. + + + + ADMIN_TOKEN — control-plane / break-glass + Scope: /admin/* across the deployment (AdminAuth). Self-host / operator only. + Mints org API keys. Highest authority — keep out of agents & CI. + middleware: AdminAuth · routes: /admin/* + + authorizes + entire control plane + + all orgs on it + + + mints ↓ + + + + Org API key — full org admin + Scope: everything inside ONE org (/org/*). Named, creation-attributed, audited, revocable. + Cannot touch the control plane or other orgs. Use for org-level automation / integrations. + issue: /org/tokens · attribution: org-token:<name> + + authorizes + one org (all its + workspaces & settings) + + + scopes ↓ + + + + Workspace bearer token — one workspace + Scope: a single workspace (/workspaces/:id/*). 256-bit, sha256-stored, shown once, no expiry. + Issued at first /registry/register; auto-revoked on delete. Rotate = create → verify → revoke. + This is the only credential an agent (or external/remote agent) holds. + middleware: WorkspaceAuth · header: Authorization: Bearer … + + authorizes + its own workspace only + A2A still hierarchy-gated + + + All secrets are encrypted at rest (AES-256-GCM or KMS envelope) and masked on read. The audit ledger records every credential's creation attribution. + diff --git a/public/diagrams/workspace-config.svg b/public/diagrams/workspace-config.svg new file mode 100644 index 0000000..6284052 --- /dev/null +++ b/public/diagrams/workspace-config.svg @@ -0,0 +1,73 @@ + + + + + + + + config.yaml → runtime adapter resolution + At boot the workspace loads config.yaml, selects an adapter by its runtime, builds an executor, and registers over A2A. One BaseAdapter contract — drop in any framework. + + + + config.yaml + + name: Content Writer + tier: 2 + runtime: google-adk + runtime_config: + model: vertex:gemini-2.5-pro + prompt_files: [system-prompt.md] + skills: [seo-research] + tools: [browser] # tier-gated + memory: { scope: team } + a2a: { port: 8000 } + env: + required: [GOOGLE_CLOUD_PROJECT] + + Hot-reload (live): + model · skills · tools + Needs restart / re-provision: + tier · a2a · sub_workspaces + Model id form: + provider:model-id + + + + select + + Runtime adapter registry + auto-discovered · BaseAdapter contract + + claude-code → ClaudeSDKExecutor + langgraph → LangGraphA2AExecutor + crewai · autogen · deepagents + hermes → HermesA2AExecutor + openclaw · gemini-cli (CLI exec) + google-adk → GoogleADKA2AExecutor + external → no container (BYO) + + contract: setup(config) · create_executor(config) + executor.execute(ctx, event_queue): + extract message + history → invoke framework + → write response to A2A event queue + MOLECULE_SMOKE_MODE short-circuits I/O + + + + + Workspace boot pipeline + + load config.yaml + preflight (required env) + resolve adapter(runtime) → setup() + create_executor() → A2A AgentExecutor + assemble system prompt + Agent Card + POST /registry/register → online + 30s heartbeat · skill file-watcher + serve A2A (Uvicorn) on a2a.port + + Preflight FAILS LOUD on a runtime/config or + missing-required-env mismatch — never a silent + wrong-agent fallback (core#2028). + tools gated by tier: browser ≥ T2 · computer ≥ T3 +