Compare commits

..

16 Commits

Author SHA1 Message Date
Hongming Wang
c6494de5ad docs: wrap <ws-id> placeholders in backticks to fix MDX build
Bare <ws-id> in headings emitted a `raw` HAST node that the renderer
couldn't handle ("Cannot handle unknown node `raw`"). Wrapping in
backticks renders as inline code instead of being parsed as JSX/HTML.

Verified locally with `npm run build` (106/106 static pages green).
2026-05-01 16:31:05 -07:00
Hongming Wang
c5421c61f5 docs: fix MDX build — escape <1 + drop Callout JSX
Two errors caught by the docs build CI on PR #98:

1. external-agents.mdx line 15 had `<1 min.` — the literal `<` made the
   MDX parser try to read it as a JSX tag opener. Replaced with prose
   "under a minute" — equivalent meaning, no escape gymnastics.
2. claude-code-channel-plugin.md used `<Callout type="info">` JSX, but
   the rest of /content/docs/guides/ is plain .md (no JSX). The .md
   loader can't resolve the Callout component → "Cannot handle unknown
   node `raw`". Replaced with a `> **Note:**` blockquote — same visual
   hierarchy, plain markdown.

Verified locally that the offending characters are gone; build CI on
push will re-run and should now pass.
2026-05-01 16:31:05 -07:00
Hongming Wang
2ccd4b99d0 docs: add Claude Code Channel Plugin guide + cross-references
Adds /docs/guides/claude-code-channel-plugin.md — the canonical guide
for connecting a Claude Code session as a Molecule external workspace
via the new Molecule-AI/molecule-mcp-claude-channel plugin. Polling-
based; no tunnel required.

Cross-references added:
- content/docs/external-agents.mdx — new "Pick the right path" table
  at top, distinguishing Claude Code (channel plugin) from generic
  HTTP-speaking agents (this page) at first glance.
- content/docs/guides/external-workspace-quickstart.md — short
  redirect callout near the top so laptop-Claude-Code users are
  routed to the channel plugin guide instead of the tunnel-required
  quickstart.

Per molecule-core's #2060 content-routing policy, public-facing docs
live in this repo. The plugin source + README live separately at
github.com/Molecule-AI/molecule-mcp-claude-channel; this guide
duplicates the operator-facing setup steps and adds Molecule-specific
context (how to get workspace_id + token from canvas, how /activity
shows up, troubleshooting against /activity endpoint shape).
2026-05-01 16:30:49 -07:00
Hongming Wang
5f0871707e
Merge pull request #99 from Molecule-AI/feat/marketplace-creator-docs
docs(marketplace): tier overview + creator listing guide
2026-05-01 16:24:48 -07:00
Hongming Wang
b80891b312
Merge branch 'main' into feat/marketplace-creator-docs 2026-05-01 16:24:11 -07:00
Hongming Wang
149c315dfa
Merge pull request #109 from Molecule-AI/feat/universal-push-poll-contract
docs(mcp): rewrite inbound-delivery section for dual push+poll contract
2026-05-01 15:38:17 -07:00
Hongming Wang
b26d7ee9b2 docs(mcp): rewrite inbound-delivery section for dual push+poll contract
Mirrors molecule-core feat/universal-push-via-instructions: documents
the universal poll path (instructions field → every MCP client) plus
the optional push path (notifications/claude/channel for Claude Code
with the dev-channels flag or a future allowlist entry).

Honesty pass on the prior text: previous version claimed push works
"automatically" and "there is no config flag to toggle." That was
true for the wire shape but false for live UX — standard `claude`
launches without --dangerously-load-development-channels silently
drop the notification, and non-Claude clients ignore the Claude-
namespaced method entirely. New text spells out exactly which clients
get push, which get poll, and the per-client capability matrix.

Adds MOLECULE_MCP_POLL_TIMEOUT_SECS to the env-var table — the new
operator knob landed in the wheel.

Successor to #44/#49 (which closed without the flag caveat).
2026-05-01 15:33:07 -07:00
Hongming Wang
1dd9cfaaf3
Merge pull request #108 from Molecule-AI/docs/smoke-gate-caveat-correction
docs(workspace-runtime): correct smoke-gate caveat factual errors
2026-05-01 00:01:09 -07:00
Hongming Wang
28600d7956 docs(workspace-runtime): correct smoke-gate caveat factual errors
Two errors in the merged caveat (#107):

1. Claimed the stub RequestContext "carries an empty user message"
   — actually carries "smoke test" text (smoke_mode.py:76 calls
   `new_text_message("smoke test")`, with the explicit comment
   that it's "enough that extract_message_text(context) returns
   non-empty input"). Adapter authors gating smoke-mode behavior
   on extract_message_text(ctx) == "" would have a logic that
   never fires.

2. Described only the timeout-pass path. The harness also returns
   0 on ANY non-import exception (smoke_mode.py:135-143) — the
   bare `except Exception` block treats RuntimeError, auth errors,
   validation errors etc. as "downstream of the import gate" and
   exits clean. Spelling out all three pass cases (clean return,
   timeout, non-import exception) is the honest description.

Caught while re-reading smoke_mode.py to verify claims for a
review pass — found I had asserted both behaviors from memory
without checking, exactly the failure mode my e2e-test memory
just got a worked-example update about.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 00:00:02 -07:00
Hongming Wang
36ab08129c
Merge pull request #107 from Molecule-AI/docs/smoke-gate-timeout-pass-caveat
docs(workspace-runtime): clarify what the boot-smoke gate does NOT prove
2026-04-30 23:56:05 -07:00
Hongming Wang
ec78c7637b docs(workspace-runtime): clarify what the boot-smoke gate does NOT prove
A green gate means imports are healthy enough that
executor.execute() reaches its body. It does NOT prove that
execute() produces the right output: adapters with real I/O
inside execute() (subprocess to a gateway, httpx call upstream)
time out under the 5s harness window, and the gate treats a clean
timeout as success.

Surfaced while running publish-image across all 8 templates: the
openclaw smoke "passed" with timing-out behavior in execute()
because OpenClawA2AExecutor proxies to a subprocess that doesn't
exist in the smoke env. Reading the green check, future operators
might over-trust it as a runtime-correctness signal — it isn't.

Add a "What the gate does NOT prove" subsection so readers don't
mistake the import-regression coverage for an integration test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 23:54:57 -07:00
Hongming Wang
aa710d9310
Merge pull request #105 from Molecule-AI/design/align-docs-to-landing
feat(docs): align doc.moleculesai.app chrome with landing's warm-paper design
2026-04-30 22:53:36 -07:00
Hongming Wang
050cd70060
Merge pull request #106 from Molecule-AI/docs/smoke-mode-adapter-contract
Document MOLECULE_SMOKE_MODE adapter contract
2026-04-30 22:51:42 -07:00
Hongming Wang
1ccd92e0c8 docs(workspace-runtime): document MOLECULE_SMOKE_MODE adapter contract
The publish-image boot-smoke gate (molecule-core#2275) invokes the
runtime with MOLECULE_SMOKE_MODE=1 + stub creds to catch lazy
imports inside executor.execute(). Adapters whose setup() does
real I/O (subprocess spawn, network calls, uid-sensitive writes)
need to opt out of that I/O when MOLECULE_SMOKE_MODE=1, otherwise
the gate fails before reaching the runtime's smoke short-circuit.

This documents:
- the contract (one-line opt-out for Python adapter.setup() and
  shell entrypoints that wrap molecule-runtime)
- which boot stages the gate exercises
- the stub env the harness sets so adapters can reason about what
  they can rely on under smoke mode

Surfaced when running publish-image across all 8 workspace
templates: openclaw and hermes hit the contract gap because both
spawn real gateway subprocesses in setup; six others passed
without any contract awareness because their setup is light.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 22:48:53 -07:00
Hongming Wang
403725b970 feat(docs): align doc.moleculesai.app chrome with landing's warm-paper design
Brings the docs site in visual parity with moleculesai.app so docs,
marketing, and the canvas read as one product. Five focused changes
inside the existing fumadocs shell — no MDX or content touched, no
runtime/build dep changes:

- global.css: override fumadocs @theme tokens with the warm-paper
  palette (#fafaf7 bg, #15181c ink, #3b5bdb governance blue,
  #efece4 muted, #e6e2d8 border). Dark mode keeps fumadocs' neutral
  defaults so dark-pref readers still get a readable docs site.

- layout.tsx: swap Inter → Geist (sans) + JetBrains Mono (code),
  matching the landing's font stack. Wired through @theme so
  Tailwind's font-sans / font-mono utilities pick them up.

- layout.config.tsx: brand the topbar — inline Molecule logo SVG +
  "Molecule AI · DOCS" lockup, plus three external links to the rest
  of the surface (Platform → app, Marketplace → market, Landing →
  www) and the org GitHub. Mirrors the landing's collapsed nav.

- (home)/page.tsx: replace the stock fumadocs landing with a
  hero-style page matching the landing — statusbar strip, "Phase 35
  Marketplace public beta" eyebrow, the same shimmering h1 copy,
  three quick-start lane cards (Build a workspace / Run an
  organisation / Publish to the Marketplace) pointing into the docs
  tree.

Build is clean (106 static pages still generate). Existing /docs/*
pages inherit the new tokens via fumadocs' DocsLayout, so the entire
site shifts to the warm-paper aesthetic without touching MDX.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 22:42:42 -07:00
Hongming Wang
03a222d9b5 docs(marketplace): add tier overview + creator listing guide
Two additive pages tied to the new Marketplace surfaces on the
landing page and molecule-app workspace UI:

- content/docs/marketplace.mdx — L1 plugins / L2 agents / L3 bundles
  tier model, trust tiers (Verified / Partner / Community), install
  flow, and workspace.yaml pin examples.
- content/docs/marketplace/creators.mdx — three-step (Build · List ·
  Earn) builder workflow: SDK refs, Creator Portal submission, pricing
  options, policy/safety terms, and maintenance.

Wired into meta.json under a new ---Marketplace--- section between
Troubleshooting and Security.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 18:35:21 -07:00
34 changed files with 970 additions and 141 deletions

View File

@ -6,7 +6,12 @@ on:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
# Self-hosted Mac mini — this repo is private and the org's
# GitHub-hosted minute budget is exhausted (every ubuntu-latest job
# dies in 2s with no step output). Per the 2026-04-22 carve-out:
# private repos run on self-hosted; public repos use ubuntu-latest
# (still free).
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4

View File

@ -1,29 +1,100 @@
import Link from 'next/link';
// Three quick-start lanes — keeps the home page from being a wall of text
// and lets builders, operators, and integrators each find their entry
// point in one click.
const lanes = [
{
kicker: '01',
title: 'Build a workspace',
body: 'Pick a runtime template (Claude Code, LangGraph, CrewAI, Hermes, …), wire your tools, and ship.',
href: '/docs/workspace',
cta: 'Workspace guide →',
},
{
kicker: '02',
title: 'Run an organisation',
body: 'Topology, A2A, three-tier memory, governance — the platform layer that ties multi-agent teams together.',
href: '/docs/platform',
cta: 'Platform reference →',
},
{
kicker: '03',
title: 'Publish to the Marketplace',
body: 'Plugins, agents, and org bundles ship as signed manifests. Authors keep 80%, paid via Stripe Connect.',
href: '/docs/marketplace',
cta: 'Author guide →',
},
];
export default function HomePage() {
return (
<main className="flex flex-1 flex-col items-center justify-center px-6 py-24 text-center">
<h1 className="mb-4 text-5xl font-bold tracking-tight sm:text-6xl">
Molecule AI
</h1>
<p className="mb-8 max-w-2xl text-lg text-fd-muted-foreground">
Build and run multi-agent organisations. Templates, plugins, channels,
and the runtime that ties them together documented end to end.
</p>
<div className="flex flex-wrap items-center justify-center gap-3">
<Link
href="/docs"
className="rounded-md bg-fd-primary px-5 py-2.5 text-sm font-medium text-fd-primary-foreground transition-colors hover:opacity-90"
>
Read the docs
</Link>
<Link
href="https://git.moleculesai.app/molecule-ai/molecule-core"
className="rounded-md border border-fd-border px-5 py-2.5 text-sm font-medium transition-colors hover:bg-fd-muted"
>
View on Gitea
</Link>
<main className="flex flex-1 flex-col">
{/* Statusbar — mirrors the landing's "All systems · status.* · phase" strip */}
<div className="border-b border-fd-border bg-fd-muted px-6 py-1.5 text-[11px] font-mono text-fd-muted-foreground flex flex-wrap justify-between gap-4">
<span>
<span className="inline-block size-1.5 rounded-full bg-[#2f7a4d] align-middle mr-1.5" />
All systems · status.moleculesai.app
</span>
<span>Phase 33 shipped · Phase 35 Marketplace public beta</span>
</div>
{/* Hero */}
<section className="px-6 py-20 sm:py-28 max-w-6xl mx-auto w-full">
<div className="text-[11px] font-mono uppercase tracking-[0.08em] text-fd-muted-foreground mb-4 flex items-center gap-2">
<span className="inline-block size-1.5 rounded-full bg-[#c0532b]" />
Documentation
</div>
<h1 className="text-5xl sm:text-6xl font-semibold tracking-tight leading-[1.05] mb-5 max-w-3xl">
The operating system for{' '}
<span className="text-[#3b5bdb]">AI agent organizations.</span>
</h1>
<p className="text-lg text-fd-muted-foreground max-w-2xl leading-relaxed mb-8">
Build and run multi-agent organisations the way you'd staff a company.
Templates, plugins, channels, runtimes, governance documented end
to end.
</p>
<div className="flex flex-wrap items-center gap-3">
<Link
href="/docs"
className="rounded-md bg-fd-primary px-5 py-2.5 text-sm font-medium text-fd-primary-foreground transition hover:opacity-90"
>
Read the docs
</Link>
<Link
href="https://github.com/Molecule-AI"
target="_blank"
rel="noopener noreferrer"
className="rounded-md border border-fd-border px-5 py-2.5 text-sm font-medium transition hover:bg-fd-muted"
>
View on GitHub
</Link>
</div>
</section>
{/* Three lanes */}
<section className="px-6 pb-24 max-w-6xl mx-auto w-full">
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{lanes.map((lane) => (
<Link
key={lane.kicker}
href={lane.href}
className="group rounded-lg border border-fd-border bg-fd-card p-6 transition hover:border-fd-foreground hover:-translate-y-0.5"
>
<div className="text-[11px] font-mono text-[#3b5bdb] mb-3 tracking-[0.08em]">
{lane.kicker}
</div>
<h3 className="text-base font-semibold mb-2">{lane.title}</h3>
<p className="text-sm text-fd-muted-foreground leading-relaxed mb-4">
{lane.body}
</p>
<div className="text-xs font-mono text-fd-foreground group-hover:text-[#3b5bdb] transition">
{lane.cta}
</div>
</Link>
))}
</div>
</section>
</main>
);
}

View File

@ -1,3 +1,32 @@
@import 'tailwindcss';
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
/* Warm-paper light theme aligned with the landing page (moleculesai.app).
Tokens map fumadocs' @theme variables onto our brand palette so docs,
marketing, and the canvas read as one product. */
@theme {
--font-sans: var(--font-geist), ui-sans-serif, system-ui, sans-serif;
--font-mono: var(--font-mono), ui-monospace, SFMono-Regular, monospace;
--color-fd-background: #fafaf7;
--color-fd-foreground: #15181c;
--color-fd-muted: #f3f1ec;
--color-fd-muted-foreground: #5a5e66;
--color-fd-popover: #ffffff;
--color-fd-popover-foreground: #15181c;
--color-fd-card: #ffffff;
--color-fd-card-foreground: #15181c;
--color-fd-border: #e6e2d8;
--color-fd-primary: #3b5bdb;
--color-fd-primary-foreground: #ffffff;
--color-fd-secondary: #efece4;
--color-fd-secondary-foreground: #15181c;
--color-fd-accent: #efece4;
--color-fd-accent-foreground: #15181c;
--color-fd-ring: #3b5bdb;
--color-fd-overlay: hsla(0, 0%, 0%, 0.18);
}
/* Dark mode keeps fumadocs' neutral defaults readers expect docs sites
to honor their system preference, and our landing only ships light. */

View File

@ -1,7 +1,50 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
// Molecule logo — the same triangle-of-nodes mark used on moleculesai.app.
// Inlined as a JSX element so fumadocs renders it in the topbar without a
// separate asset request.
const MoleculeLogo = (
<svg
width="22"
height="22"
viewBox="0 0 28 28"
fill="none"
aria-hidden="true"
>
<circle cx="14" cy="6" r="2.5" fill="currentColor" />
<circle cx="6" cy="20" r="2.5" fill="currentColor" />
<circle cx="22" cy="20" r="2.5" fill="currentColor" />
<circle
cx="14"
cy="14"
r="1.6"
fill="none"
stroke="currentColor"
strokeWidth="1.2"
/>
<line x1="14" y1="8.5" x2="14" y2="12.6" stroke="currentColor" strokeWidth="1.2" />
<line x1="8" y1="18.5" x2="12.7" y2="14.8" stroke="currentColor" strokeWidth="1.2" />
<line x1="20" y1="18.5" x2="15.3" y2="14.8" stroke="currentColor" strokeWidth="1.2" />
</svg>
);
export const baseOptions: BaseLayoutProps = {
nav: {
title: 'Molecule AI',
title: (
<span className="flex items-center gap-2 font-semibold tracking-tight">
{MoleculeLogo}
<span>Molecule AI</span>
<span className="text-xs uppercase tracking-[0.08em] text-fd-muted-foreground font-mono">
Docs
</span>
</span>
),
url: 'https://doc.moleculesai.app',
},
links: [
{ text: 'Platform', url: 'https://app.moleculesai.app', external: true },
{ text: 'Marketplace', url: 'https://market.moleculesai.app', external: true },
{ text: 'Landing', url: 'https://www.moleculesai.app', external: true },
],
githubUrl: 'https://github.com/Molecule-AI',
};

View File

@ -1,10 +1,16 @@
import './global.css';
import { RootProvider } from 'fumadocs-ui/provider/next';
import { Inter } from 'next/font/google';
import { Geist, JetBrains_Mono } from 'next/font/google';
import type { ReactNode } from 'react';
const inter = Inter({
const geist = Geist({
subsets: ['latin'],
variable: '--font-geist',
});
const jetbrains = JetBrains_Mono({
subsets: ['latin'],
variable: '--font-mono',
});
export const metadata = {
@ -19,8 +25,12 @@ export const metadata = {
export default function Layout({ children }: { children: ReactNode }) {
return (
<html lang="en" className={inter.className} suppressHydrationWarning>
<body className="flex flex-col min-h-screen">
<html
lang="en"
className={`${geist.variable} ${jetbrains.variable}`}
suppressHydrationWarning
>
<body className="flex flex-col min-h-screen font-sans">
<RootProvider>{children}</RootProvider>
</body>
</html>

View File

@ -73,6 +73,72 @@ At a high level, `workspace/main.py` does this:
10. Start the skill watcher when skills are configured.
11. Serve the A2A app through Uvicorn.
## Boot-Smoke Contract (`MOLECULE_SMOKE_MODE`)
The image-publish CI pipeline runs each template's image with `MOLECULE_SMOKE_MODE=1` to exercise lazy imports inside `executor.execute()` against stub credentials and no network. The runtime detects the env var, invokes `executor.execute()` once with a stubbed `RequestContext` and a short timeout, then exits — registration, heartbeats, and the A2A server are skipped.
This catches lazy imports that pure `python3 -c "import adapter"` smokes miss: imports nested inside `if`-branches, deferred until first call, or behind `importlib.import_module()`.
### What adapter authors need to do
**Most adapters need to do nothing.** If `setup()` only writes files, parses config, or instantiates Python objects, the smoke gate just works.
**Adapters whose `setup()` does real I/O must opt out of that I/O under smoke mode.** This applies to:
- spawning subprocesses that require valid credentials (e.g. a gateway daemon)
- making real network calls
- writing to filesystem locations that need a specific uid/gid the smoke harness can't guarantee
The contract:
```python
async def setup(self, config: AdapterConfig) -> None:
if os.environ.get("MOLECULE_SMOKE_MODE") == "1":
return # skip real I/O; runtime's smoke short-circuit handles the rest
# ... real setup ...
```
For shell entrypoints that wrap `molecule-runtime`:
```bash
if [ "${MOLECULE_SMOKE_MODE:-0}" = "1" ]; then
exec molecule-runtime
fi
```
### What gets exercised under smoke mode
- All `/app/*.py` modules import cleanly (covered by a separate static-import smoke step)
- `adapter.setup()` runs (with the opt-out above for I/O-heavy adapters)
- `adapter.create_executor()` runs
- `executor.execute()` is invoked once against a stub `RequestContext`/`EventQueue` with `MOLECULE_SMOKE_TIMEOUT_SECS` (default 5s); a clean timeout exits 0, an import error exits non-zero
### What the gate does NOT prove
A green gate means **"imports are healthy enough that `executor.execute()` reaches its body"** — that's the regression class the gate exists to catch (lazy `from x import y` inside an `if`-branch, or `importlib.import_module()` on a path that breaks after a wheel bump).
It does **not** prove that `execute()` produces the right output for real input. The harness reports PASS in three distinct cases:
1. **Clean return** — execute() ran to completion within the timeout.
2. **Timeout** — execute() was still running when the timer fired (typical for adapters that do real I/O inside execute(): subprocess to a gateway, httpx call to an upstream LLM).
3. **Any non-import exception** — execute() raised `RuntimeError`, auth errors, validation errors, etc. The harness only fails on `ImportError`/`ModuleNotFoundError`.
The stub `RequestContext` carries a non-empty `"smoke test"` text message (so adapters relying on `extract_message_text(ctx)` returning input still work), and the harness never drains the `EventQueue` — what `execute()` writes back is ignored.
If you need correctness coverage, write a separate integration test that runs the workspace against real or mocked infrastructure — the smoke gate is a strict subset.
### Stub env the smoke harness sets
| Var | Value |
|---|---|
| `MOLECULE_SMOKE_MODE` | `1` |
| `MOLECULE_SMOKE_TIMEOUT_SECS` | `10` (CI default) |
| `WORKSPACE_ID` | `fake-smoke` |
| `PYTHONPATH` | `/app` (mirrors the platform provisioner) |
| `CLAUDE_CODE_OAUTH_TOKEN`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, `OPENAI_API_KEY` | `sk-fake-smoke-*` |
A `config.yaml` from the template repo's root is mounted at `/configs/config.yaml`.
## Core Runtime Pieces
| File | Responsibility |

View File

@ -138,7 +138,7 @@ These controls complement the platform-level secret redaction described in the [
**Stack:** Go / Bubbletea + Lipgloss
A terminal UI dashboard for real-time workspace monitoring, event log streaming, health overview, and delete/filter operations. Reads `MOLECLI_URL` (default `http://localhost:8080`) to locate the platform. Now published as a standalone repo at `git.moleculesai.app/molecule-ai/molecule-cli`.
A terminal UI dashboard for real-time workspace monitoring, event log streaming, health overview, and delete/filter operations. Reads `MOLECLI_URL` (default `http://localhost:8080`) to locate the platform. Now published as a standalone repo at `github.com/Molecule-AI/molecule-cli`.
---

View File

@ -4,7 +4,7 @@ title: "Molecule AI — Comprehensive Technical Documentation"
# Molecule AI — Comprehensive Technical Documentation
> Definitive technical reference for the Molecule AI Agent Team platform.
> Based on a full non-invasive scan of the [molecule-core](https://git.moleculesai.app/molecule-ai/molecule-core) repository (formerly `molecule-monorepo`, renamed during the post-2026-05-06 GitHub-org-suspension recovery).
> Based on a full non-invasive scan of the [molecule-monorepo](https://github.com/Molecule-AI/molecule-monorepo) repository.
---
@ -1153,11 +1153,11 @@ Molecule AI's workspace abstraction is **runtime-agnostic by design**. A workspa
## Links
- **Gitea**: https://git.moleculesai.app/molecule-ai/molecule-core
- **Architecture Docs**: https://git.moleculesai.app/molecule-ai/molecule-core/src/branch/main/docs/architecture
- **API Protocol**: https://git.moleculesai.app/molecule-ai/molecule-core/src/branch/main/docs/api-protocol
- **Agent Runtime**: https://git.moleculesai.app/molecule-ai/molecule-core/src/branch/main/docs/agent-runtime
- **Product Docs**: https://git.moleculesai.app/molecule-ai/molecule-core/src/branch/main/docs/product
- **GitHub**: https://github.com/Molecule-AI/molecule-monorepo
- **Architecture Docs**: https://github.com/Molecule-AI/molecule-monorepo/tree/main/docs/architecture
- **API Protocol**: https://github.com/Molecule-AI/molecule-monorepo/tree/main/docs/api-protocol
- **Agent Runtime**: https://github.com/Molecule-AI/molecule-monorepo/tree/main/docs/agent-runtime
- **Product Docs**: https://github.com/Molecule-AI/molecule-monorepo/tree/main/docs/product
---

View File

@ -11,66 +11,66 @@ Entries are published daily at 23:50 UTC.
### ✨ New features
- **SaaS Federation v2 tutorial**: a clean, self-contained walkthrough for platform operators who want to run multi-tenant workspaces from a single control plane. Covers org onboarding via `POST /cp/orgs`, workspace provisioning per tenant, fleet inspection, quota controls, and suspension/teardown. (`molecule-core` [#1700](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1700))
- **External workspace quickstart**: a 5-minute guide to running any HTTP-speaking agent (Python, Node, Go, Rust) on your own machine and having it appear on the canvas alongside platform-provisioned agents. Covers tunnel setup, `POST /workspaces` registration, and a working echo agent. (`molecule-core` [#1760](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1760))
- **SaaS Federation v2 tutorial**: a clean, self-contained walkthrough for platform operators who want to run multi-tenant workspaces from a single control plane. Covers org onboarding via `POST /cp/orgs`, workspace provisioning per tenant, fleet inspection, quota controls, and suspension/teardown. (`molecule-core` [#1700](https://github.com/Molecule-AI/molecule-core/pull/1700))
- **External workspace quickstart**: a 5-minute guide to running any HTTP-speaking agent (Python, Node, Go, Rust) on your own machine and having it appear on the canvas alongside platform-provisioned agents. Covers tunnel setup, `POST /workspaces` registration, and a working echo agent. (`molecule-core` [#1760](https://github.com/Molecule-AI/molecule-core/pull/1760))
### 🔧 Fixes
- **SSRF guard in SaaS mode**: previously the SSRF protection was blocking all RFC-1918 private IP ranges (`10/8`, `172.16/12`, `192.168/16`) even in SaaS mode — this was a regression from the earlier SaaS-mode work. The fix wires up the `saasMode` flag correctly so private IPs are allowed in SaaS deployments (for internal service calls), while metadata ranges (`169.254/16`), CGNAT, loopback, and link-local remain blocked in every mode. IPv6 ULA (`fd00::/8`) handling is also now correct. (`molecule-core` [#1692](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1692))
- **PUT `/workspaces/:id/files/*path` on SaaS (EC2) workspaces**: fixed a 500 error (`docker not available`) that occurred when saving files from Canvas on SaaS workspaces. The handler now detects non-Docker workspaces via `workspaces.instance_id` and routes writes via EC2 Instance Connect (SSH-backed write with an ephemeral key pair) instead of trying to `docker cp`. (`molecule-core` [#1702](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1702))
- **SSRF guard in SaaS mode**: previously the SSRF protection was blocking all RFC-1918 private IP ranges (`10/8`, `172.16/12`, `192.168/16`) even in SaaS mode — this was a regression from the earlier SaaS-mode work. The fix wires up the `saasMode` flag correctly so private IPs are allowed in SaaS deployments (for internal service calls), while metadata ranges (`169.254/16`), CGNAT, loopback, and link-local remain blocked in every mode. IPv6 ULA (`fd00::/8`) handling is also now correct. (`molecule-core` [#1692](https://github.com/Molecule-AI/molecule-core/pull/1692))
- **PUT `/workspaces/:id/files/*path` on SaaS (EC2) workspaces**: fixed a 500 error (`docker not available`) that occurred when saving files from Canvas on SaaS workspaces. The handler now detects non-Docker workspaces via `workspaces.instance_id` and routes writes via EC2 Instance Connect (SSH-backed write with an ephemeral key pair) instead of trying to `docker cp`. (`molecule-core` [#1702](https://github.com/Molecule-AI/molecule-core/pull/1702))
### 📚 Docs
- **molecli shell completion**: tab completion for `molecule` CLI in bash, zsh, fish, and PowerShell — covers all subcommands and flags. (`docs` [#79](https://git.moleculesai.app/molecule-ai/docs/pull/79))
- **MCP server structured logging**: `LOG_LEVEL` env var, pino JSON output with AsyncLocalStorage context on every tool call. (`docs` [#78](https://git.moleculesai.app/molecule-ai/docs/pull/78))
- **molecli shell completion**: tab completion for `molecule` CLI in bash, zsh, fish, and PowerShell — covers all subcommands and flags. (`docs` [#79](https://github.com/Molecule-AI/docs/pull/79))
- **MCP server structured logging**: `LOG_LEVEL` env var, pino JSON output with AsyncLocalStorage context on every tool call. (`docs` [#78](https://github.com/Molecule-AI/docs/pull/78))
### 🧹 Internal
- SaaS Federation v2 tutorial published — clean rewrite of #1613, now with correct HTTP status codes, fleet metrics endpoint, and security model table (`molecule-core` [#1700](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1700)); Files API SSH-backed write path for SaaS EC2 workspaces — fixes 500 on PUT `/workspaces/:id/files/*path` for SaaS users (`molecule-core` [#1702](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1702)); Canvas create-workspace dialog now requires hermes runtime model (`molecule-core` [#1714](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1714)).
- EC2 Instance Connect SSH tutorial published (`molecule-core` [#1617](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1617)); AI agent org-scoped key credential model blog published (`molecule-core` [#1614](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1614)); Phase 30 Day 2 social package ready (`molecule-core` [#1662](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1662)).
- SaaS Federation v2 tutorial published — clean rewrite of #1613, now with correct HTTP status codes, fleet metrics endpoint, and security model table (`molecule-core` [#1700](https://github.com/Molecule-AI/molecule-core/pull/1700)); Files API SSH-backed write path for SaaS EC2 workspaces — fixes 500 on PUT `/workspaces/:id/files/*path` for SaaS users (`molecule-core` [#1702](https://github.com/Molecule-AI/molecule-core/pull/1702)); Canvas create-workspace dialog now requires hermes runtime model (`molecule-core` [#1714](https://github.com/Molecule-AI/molecule-core/pull/1714)).
- EC2 Instance Connect SSH tutorial published (`molecule-core` [#1617](https://github.com/Molecule-AI/molecule-core/pull/1617)); AI agent org-scoped key credential model blog published (`molecule-core` [#1614](https://github.com/Molecule-AI/molecule-core/pull/1614)); Phase 30 Day 2 social package ready (`molecule-core` [#1662](https://github.com/Molecule-AI/molecule-core/pull/1662)).
### 🌅 Late-day updates (17:3023:50 UTC)
#### 🔒 Security
- **Cross-tenant memory poisoning fix** (`molecule-core` [#1791](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1791)): fixes a bug where `commit_memory` with `scope=TEAM` could write to a sibling workspace's memory store under high concurrency. `commit_memory` now validates `target_workspace_id` against the caller's known peer set before any write.
- **CWE-78 shell injection hardening** (`molecule-core` [#1885](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1885)): `shellQuote` now uses `strconv.Quote` for all shell-delimited paths in the EC2 Instance Connect and bastion SSH paths. Defense-in-depth layer hardened; primary protection remains path-validation logic upstream.
- **Cross-tenant memory poisoning fix** (`molecule-core` [#1791](https://github.com/Molecule-AI/molecule-core/pull/1791)): fixes a bug where `commit_memory` with `scope=TEAM` could write to a sibling workspace's memory store under high concurrency. `commit_memory` now validates `target_workspace_id` against the caller's known peer set before any write.
- **CWE-78 shell injection hardening** (`molecule-core` [#1885](https://github.com/Molecule-AI/molecule-core/pull/1885)): `shellQuote` now uses `strconv.Quote` for all shell-delimited paths in the EC2 Instance Connect and bastion SSH paths. Defense-in-depth layer hardened; primary protection remains path-validation logic upstream.
#### ✨ New features
- **A2A priority queue — Phase 1** (`molecule-core` [#1892](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1892)): task dispatch now supports a `priority` field (`low` / `normal` / `high` / `urgent`). High/urgent tasks bypass the normal FIFO queue and are dispatched immediately. Phase 2 (priority inversion deadlock prevention) on the roadmap.
- **A2A priority queue — Phase 1** (`molecule-core` [#1892](https://github.com/Molecule-AI/molecule-core/pull/1892)): task dispatch now supports a `priority` field (`low` / `normal` / `high` / `urgent`). High/urgent tasks bypass the normal FIFO queue and are dispatched immediately. Phase 2 (priority inversion deadlock prevention) on the roadmap.
#### 🔧 Fixes
- **A2A queue nil-safe drain** (`molecule-core` [#1893](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1893), [#1896](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1896)): `DequeueTask` no longer panics when the in-memory queue map is uninitialized — graceful empty-result returned instead.
- **Workspaces stuck in `provisioning` after失败** (`molecule-core` [#1794](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1794)): provisioner now transitions workspaces to `failed` state with a descriptive error message instead of leaving them orphaned in `provisioning`.
- **Dedup settings hooks double-fire** (`molecule-core` [#1797](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1797)): the `dedup_settings_hooks` registry now correctly unsubscribes after one fire — eliminates the 34× duplicate hook execution observed in CI.
- **Semantic memory search returning stale results** (`molecule-core` [#1778](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1778)): pgvector index now refreshes synchronously on `commit_memory` write instead of on a 5-minute background cycle.
- **pgvector migration race in E2E CI** (`molecule-core` [#1777](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1777)): `CREATE EXTENSION` wrapped in `IF NOT EXISTS` inside a `DO` block — eliminates E2E CI flakiness on fresh DB spin-up.
- **EC2 Instance Connect endpoint not found in us-west-2** (`molecule-core` [#1779](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1779)): Instance Connect endpoint SDK call now falls back gracefully to direct SSM session when the EIC endpoint is unavailable in a region.
- **Canvas topology overlay edge labels clipped** (`molecule-core` [#1802](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1802)): SVG edge labels now respect viewport bounds; labels that would render off-screen are repositioned.
- **Audit trail panel not loading for large workspaces** (`molecule-core` [#1854](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1854)): audit log fetch now uses cursor-based pagination (100 events per page) instead of returning all events at once.
- **Hermes `response_format` not forwarded to MiniMax** (`molecule-core` [#1861](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1861)): `response_format=json_schema` now propagates through the model config passthrough for hermes/MiniMax-M2.7-highspeed workspaces.
- **Memory Inspector panel memory leak** (`molecule-core` [#1871](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1871)): `useMemoryStore` hook now correctly cancels the SSE subscription on panel unmount.
- **Token revocation cache stale-read window** (`molecule-core` [#1888](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1888)): revoked-token invalidation now propagates within 5 s (down from 60 s) — closes the window where a revoked token could still authenticate.
- **TenantGuard same-origin bypass (regression)** (`molecule-core` [#1898](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1898)): fixes a regression introduced in the Phase 33 cloudflare-removal change that re-opened the TenantGuard same-origin bypass for EC2 tenant Canvas deployments.
- **A2A queue nil-safe drain** (`molecule-core` [#1893](https://github.com/Molecule-AI/molecule-core/pull/1893), [#1896](https://github.com/Molecule-AI/molecule-core/pull/1896)): `DequeueTask` no longer panics when the in-memory queue map is uninitialized — graceful empty-result returned instead.
- **Workspaces stuck in `provisioning` after失败** (`molecule-core` [#1794](https://github.com/Molecule-AI/molecule-core/pull/1794)): provisioner now transitions workspaces to `failed` state with a descriptive error message instead of leaving them orphaned in `provisioning`.
- **Dedup settings hooks double-fire** (`molecule-core` [#1797](https://github.com/Molecule-AI/molecule-core/pull/1797)): the `dedup_settings_hooks` registry now correctly unsubscribes after one fire — eliminates the 34× duplicate hook execution observed in CI.
- **Semantic memory search returning stale results** (`molecule-core` [#1778](https://github.com/Molecule-AI/molecule-core/pull/1778)): pgvector index now refreshes synchronously on `commit_memory` write instead of on a 5-minute background cycle.
- **pgvector migration race in E2E CI** (`molecule-core` [#1777](https://github.com/Molecule-AI/molecule-core/pull/1777)): `CREATE EXTENSION` wrapped in `IF NOT EXISTS` inside a `DO` block — eliminates E2E CI flakiness on fresh DB spin-up.
- **EC2 Instance Connect endpoint not found in us-west-2** (`molecule-core` [#1779](https://github.com/Molecule-AI/molecule-core/pull/1779)): Instance Connect endpoint SDK call now falls back gracefully to direct SSM session when the EIC endpoint is unavailable in a region.
- **Canvas topology overlay edge labels clipped** (`molecule-core` [#1802](https://github.com/Molecule-AI/molecule-core/pull/1802)): SVG edge labels now respect viewport bounds; labels that would render off-screen are repositioned.
- **Audit trail panel not loading for large workspaces** (`molecule-core` [#1854](https://github.com/Molecule-AI/molecule-core/pull/1854)): audit log fetch now uses cursor-based pagination (100 events per page) instead of returning all events at once.
- **Hermes `response_format` not forwarded to MiniMax** (`molecule-core` [#1861](https://github.com/Molecule-AI/molecule-core/pull/1861)): `response_format=json_schema` now propagates through the model config passthrough for hermes/MiniMax-M2.7-highspeed workspaces.
- **Memory Inspector panel memory leak** (`molecule-core` [#1871](https://github.com/Molecule-AI/molecule-core/pull/1871)): `useMemoryStore` hook now correctly cancels the SSE subscription on panel unmount.
- **Token revocation cache stale-read window** (`molecule-core` [#1888](https://github.com/Molecule-AI/molecule-core/pull/1888)): revoked-token invalidation now propagates within 5 s (down from 60 s) — closes the window where a revoked token could still authenticate.
- **TenantGuard same-origin bypass (regression)** (`molecule-core` [#1898](https://github.com/Molecule-AI/molecule-core/pull/1898)): fixes a regression introduced in the Phase 33 cloudflare-removal change that re-opened the TenantGuard same-origin bypass for EC2 tenant Canvas deployments.
#### 📚 Docs
- **Chrome DevTools MCP tutorial** (`docs` [#1798](https://git.moleculesai.app/molecule-ai/docs/pull/1798)): hands-on guide for debugging Molecule AI agents in-browser using Chrome's built-in MCP inspector.
- **Phase 34 launch page** (`docs` [#1799](https://git.moleculesai.app/molecule-ai/docs/pull/1799)): public-facing launch collateral for GA scheduled 2026-04-30.
- **Tool Trace demo environment** (`docs` [#1844](https://git.moleculesai.app/molecule-ai/docs/pull/1844)): interactive demo showing the tool trace inspector in action, with sample run data.
- **Enterprise battlecard** (`docs` [#1864](https://git.moleculesai.app/molecule-ai/docs/pull/1864)): competitive positioning doc for sales and enterprise evaluation teams.
- **Chrome DevTools MCP tutorial** (`docs` [#1798](https://github.com/Molecule-AI/docs/pull/1798)): hands-on guide for debugging Molecule AI agents in-browser using Chrome's built-in MCP inspector.
- **Phase 34 launch page** (`docs` [#1799](https://github.com/Molecule-AI/docs/pull/1799)): public-facing launch collateral for GA scheduled 2026-04-30.
- **Tool Trace demo environment** (`docs` [#1844](https://github.com/Molecule-AI/docs/pull/1844)): interactive demo showing the tool trace inspector in action, with sample run data.
- **Enterprise battlecard** (`docs` [#1864](https://github.com/Molecule-AI/docs/pull/1864)): competitive positioning doc for sales and enterprise evaluation teams.
#### 🧹 Internal
- `a2a-sdk` hot-pinned to `0.3.x` across all workspace template repos (`molecule-core` [#1890](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1890)); SDK upgrade path documented in `KI-009` (`internal` [#1631](https://git.moleculesai.app/molecule-ai/internal/issues/1631)).
- `a2a-sdk` hot-pinned to `0.3.x` across all workspace template repos (`molecule-core` [#1890](https://github.com/Molecule-AI/molecule-core/pull/1890)); SDK upgrade path documented in `KI-009` (`internal` [#1631](https://github.com/Molecule-AI/internal/issues/1631)).
- Phase 34 CI matrix expanded to cover Node 22 and Go 1.24 (`molecule-ci`).
#### 🔧 Runtime fixes
- **Heartbeat 401 retry** (`molecule-ai-workspace-runtime` [#40](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pull/40)): heartbeat worker now retries with fresh token on 401 before declaring the workspace unreachable — eliminates false `disconnected` status during token rotation.
- **LLM token auto-detect** (`molecule-ai-workspace-runtime` [#38](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pull/38)): hermes runtime now auto-detects `max_tokens` from model context window and request timeout when not explicitly configured.
- **Heartbeat 401 retry** (`molecule-ai-workspace-runtime` [#40](https://github.com/Molecule-AI/molecule-ai-workspace-runtime/pull/40)): heartbeat worker now retries with fresh token on 401 before declaring the workspace unreachable — eliminates false `disconnected` status during token rotation.
- **LLM token auto-detect** (`molecule-ai-workspace-runtime` [#38](https://github.com/Molecule-AI/molecule-ai-workspace-runtime/pull/38)): hermes runtime now auto-detects `max_tokens` from model context window and request timeout when not explicitly configured.
---
@ -84,7 +84,7 @@ Customer selects `model=minimax/MiniMax-M2.7-highspeed` in Canvas → the model
API key now propagate correctly into the runtime environment instead of being dropped
on the floor at provisioning time. Works for hermes workspaces in both hosted SaaS
and self-hosted EC2 deployments.
(`molecule-core` [#1685](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1685))
(`molecule-core` [#1685](https://github.com/Molecule-AI/molecule-core/pull/1685))
#### EC2 Instance Connect Endpoint — one-click shell from Canvas
Canvas Terminal tab now uses AWS EC2 Instance Connect Endpoint to open a PTY inside
@ -92,7 +92,7 @@ any workspace EC2 instance — no SSH keys to manage, no IP to copy, no security
rules to configure. IAM policy gates access, STS pushes a short-lived key that
auto-expires, and every tunnel open is recorded in CloudTrail.
See the [EC2 Instance Connect guide](/docs/infra/workspace-terminal).
(`molecule-core` [#1554](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1554))
(`molecule-core` [#1554](https://github.com/Molecule-AI/molecule-core/pull/1554))
#### Phase 33 — Cloudflare Tunnel replaced with direct-connect public IPs
Cloud-hosted workspaces no longer route through `cloudflared`. Each workspace gets
@ -101,32 +101,32 @@ TLS on port 443. Reduces latency by ~2040 ms (region-dependent), removes the
Cloudflare egress cost dependency, and enables direct `curl` debugging without
the tunnel path.
See the [migration blog post](/blog/cloudflare-tunnel-migration).
(`molecule-core` [#1612](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1612))
(`molecule-core` [#1612](https://github.com/Molecule-AI/molecule-core/pull/1612))
### 🔒 Security
- **F1085 deleteViaEphemeral**: `rm` scope restricted to `/configs` volume only —
prevents deletion of application code or workspace files if the exec form is
exploited. Applied to both `main` and `staging`. (`molecule-core` [#1682](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1682), [#1616](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1616))
exploited. Applied to both `main` and `staging`. (`molecule-core` [#1682](https://github.com/Molecule-AI/molecule-core/pull/1682), [#1616](https://github.com/Molecule-AI/molecule-core/pull/1616))
### 🔧 Fixes
- Canvas now fetches the runtime and model dropdown from the `/templates` registry
at load time — runtime list stays current without code deploys. (`molecule-core` [#1666](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1666))
at load time — runtime list stays current without code deploys. (`molecule-core` [#1666](https://github.com/Molecule-AI/molecule-core/pull/1666))
- Canvas accessibility: `aria-hidden` correctly applied to decorative SVGs;
`MissingKeysModal` now uses correct dialog semantics and manages focus. (`molecule-core` [#1594](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1594))
`MissingKeysModal` now uses correct dialog semantics and manages focus. (`molecule-core` [#1594](https://github.com/Molecule-AI/molecule-core/pull/1594))
- Provisioner pulls workspace template images from GHCR instead of Docker Hub
for faster cold starts and reduced third-party dependency. (`molecule-core` [#1624](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1624))
for faster cold starts and reduced third-party dependency. (`molecule-core` [#1624](https://github.com/Molecule-AI/molecule-core/pull/1624))
- Shared runtime heartbeat no longer leaves workspaces in a phantom-busy state after
task completion. (`molecule-ai-workspace-runtime` [#37](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime/pull/37))
task completion. (`molecule-ai-workspace-runtime` [#37](https://github.com/Molecule-AI/molecule-ai-workspace-runtime/pull/37))
### 📚 Docs
- **MCP server structured logging**: `LOG_LEVEL` env var (`trace`/`debug`/`info`/`warn`/`error`/`fatal`),
pino JSON output in production, pretty-print in development, AsyncLocalStorage
context on every log entry (tool name, request ID, workspace ID). (`docs` [#78](https://git.moleculesai.app/molecule-ai/docs/pull/78))
context on every log entry (tool name, request ID, workspace ID). (`docs` [#78](https://github.com/Molecule-AI/docs/pull/78))
- **molecli shell completion**: tab completion for `molecule` CLI in bash, zsh, fish,
and PowerShell — covers all subcommands and flags. (`docs` [#79](https://git.moleculesai.app/molecule-ai/docs/pull/79))
and PowerShell — covers all subcommands and flags. (`docs` [#79](https://github.com/Molecule-AI/docs/pull/79))
### 🧹 Internal

View File

@ -21,6 +21,17 @@ register and heartbeat by hand. Use it when your agent can't run an MCP
stdio server.
</Callout>
## Pick the right path
| Your agent runs as | Best path | Why |
|---|---|---|
| **An MCP-aware runtime** (Claude Code, Hermes, OpenCode, Cursor, Cline) | [Bring Your Own Runtime (MCP)](/docs/runtime-mcp) | Universal `molecule-mcp` wheel — no HTTP server, no tunnel. |
| **A Claude Code session on your laptop** | [Claude Code Channel Plugin](/docs/guides/claude-code-channel-plugin) | Polling-based; no tunnel/public URL needed. Set up in under a minute. |
| Any HTTP server with a public URL | The flow on this page (or the [Python SDK guide](/docs/guides/external-agent-registration)) | Push-based; lower latency; works for any A2A-compatible HTTP endpoint. |
| A custom A2A server you wrote yourself | The flow on this page | Direct register + heartbeat + handler. |
The rest of this doc covers the third + fourth rows. For Claude Code or other MCP runtimes, follow the linked guides.
## Prerequisites
- A running Molecule AI platform (default `http://localhost:8080`)

View File

@ -0,0 +1,222 @@
---
title: "Claude Code Channel Plugin — Connect a Claude Code Session as an External Workspace"
description: "Bridge Molecule A2A traffic into a running Claude Code session via MCP. Polling-based, no tunnel required. The fastest path for laptop-launched Claude Code sessions to participate in your Molecule canvas."
---
# Claude Code Channel Plugin
Run [Claude Code](https://claude.com/claude-code) on your laptop and have it appear on the Molecule AI canvas as a first-class external workspace. Inbound A2A messages from peer workspaces surface as conversation turns; replies route back through Molecule's A2A endpoints.
> **What this is:** [`Molecule-AI/molecule-mcp-claude-channel`](https://github.com/Molecule-AI/molecule-mcp-claude-channel) — an MCP-based "channel plugin" that turns a Claude Code session into a Molecule workspace.
> **What this is NOT:** the [Python SDK / curl register flow](/docs/guides/external-agent-registration) for arbitrary HTTP-speaking agents. That flow needs a public URL the platform can POST to. This one polls — runs on any laptop behind any NAT.
---
## What you get
```
Molecule peer ──A2A──▶ [your workspace] ──poll──▶ [plugin] ──MCP notification──▶ Claude Code
▲ │
└────── POST /workspaces/:id/a2a ◄── reply_to_workspace ──┘
```
| Property | Value |
|---|---|
| **Inbound latency** | up to `MOLECULE_POLL_INTERVAL_MS` (default 5s) |
| **Outbound latency** | direct POST — sub-second |
| **Tunnel / public URL** | not required |
| **Auth model** | per-workspace bearer token (same as Python SDK) |
| **Multi-workspace** | yes, comma-separated list |
---
## Prerequisites
| You need | Notes |
|---|---|
| A Molecule AI tenant | Self-hosted localhost or your `*.staging.moleculesai.app` SaaS tenant |
| One or more workspace IDs | Created via canvas or `POST /workspaces` (see [External Agent Registration](/docs/guides/external-agent-registration)) |
| The workspace bearer token | Shown once when the workspace is created — save it from the canvas modal |
| Claude Code | `claude` CLI ≥ the version that supports `--channels` |
| `bun` | The plugin runs under bun for fast startup; `bun install` is invoked automatically by `start` |
> **Note:** The platform must be running molecule-core ≥ PR #2300, which shipped the `?since_secs=` query parameter on `GET /workspaces/:id/activity`. Available on all staging-onward and self-hosted main builds after 2026-04-29.
---
## Step 1 — Create the workspace
In your Molecule canvas:
1. Click **+ New workspace**
2. Choose **External** runtime
3. Set tier as needed; click **Create**
4. The "Connect your external agent" modal opens — switch to the **Claude Code** tab
5. Copy the entire snippet (everything from the `mkdir -p` line through `claude --channels ...`)
Or via API:
```bash
curl -X POST "$MOLECULE_PLATFORM_URL/workspaces" \
-H "Content-Type: application/json" \
-d '{"name": "My Claude Code", "external": true, "tier": 2}'
```
The response includes `claude_code_channel_snippet` — same content as the canvas tab, ready to paste.
## Step 2 — Set up the channel config
Run the snippet from Step 1. It does two things:
```bash
mkdir -p ~/.claude/channels/molecule
cat > ~/.claude/channels/molecule/.env <<'EOF'
MOLECULE_PLATFORM_URL=https://your-tenant.staging.moleculesai.app
MOLECULE_WORKSPACE_IDS=ws-uuid-1
MOLECULE_WORKSPACE_TOKENS=<paste auth_token from create response>
EOF
chmod 600 ~/.claude/channels/molecule/.env
```
Replace the token placeholder with the workspace bearer from Step 1.
## Step 3 — Launch Claude Code
```bash
claude --channels plugin:molecule@Molecule-AI/molecule-mcp-claude-channel
```
You should see on stderr (use `--debug` to surface):
```
molecule channel: connected — watching 1 workspace(s) at https://your-tenant.staging.moleculesai.app
workspaces: ws-uuid-1
poll: every 5000ms with 30s window
```
That's it — the workspace is live on the canvas with a purple **REMOTE** badge, and any A2A traffic the workspace receives surfaces as conversation turns in your Claude Code session.
---
## How replies work
When a peer's message lands in your session, you'll see a turn with structured metadata:
```json
{
"method": "notifications/claude/channel",
"params": {
"content": "Hey, can you take a look at this? <issue body>",
"meta": {
"source": "molecule",
"workspace_id": "ws-uuid-1",
"peer_id": "ws-uuid-pm-coordinator",
"method": "user_message",
"activity_id": "act-...",
"ts": "2026-04-29T..."
}
}
}
```
Reply normally — Claude calls the `reply_to_workspace` MCP tool with `peer_id` from the meta block, and the response flows back through `POST /workspaces/:peer_id/a2a` so peers see it just like any other A2A message.
---
## Multi-workspace setup
Watch multiple workspaces from a single Claude Code session by comma-separating the lists. Both must have the same length and order:
```bash
MOLECULE_WORKSPACE_IDS=ws-pm,ws-researcher,ws-engineer
MOLECULE_WORKSPACE_TOKENS=tok-pm,tok-researcher,tok-engineer
```
When Claude replies, the `reply_to_workspace` tool requires `workspace_id` (which of the watched workspaces to reply AS) explicitly. With a single workspace it's implicit.
---
## Configuration reference
| Variable | Default | Purpose |
|---|---|---|
| `MOLECULE_PLATFORM_URL` | (required) | Tenant base URL (no trailing slash) |
| `MOLECULE_WORKSPACE_IDS` | (required) | Comma-separated workspace UUIDs to watch |
| `MOLECULE_WORKSPACE_TOKENS` | (required) | Comma-separated bearer tokens, **same order as IDs** |
| `MOLECULE_POLL_INTERVAL_MS` | `5000` | How often each workspace is polled (ms) |
| `MOLECULE_POLL_WINDOW_SECS` | `30` | `since_secs` window per poll. Wider than interval to recover from missed ticks |
| `MOLECULE_STATE_DIR` | `~/.claude/channels/molecule` | Override state directory (testing) |
---
## Architecture notes
### Why polling instead of push?
The [Python SDK external-agent flow](/docs/guides/external-agent-registration) uses **push**: register an inbound URL, platform POSTs A2A to that URL. Lower latency but requires a tunnel (ngrok / Cloudflare) or static IP — non-trivial for laptop sessions.
This plugin uses **polling** as the default because it works through every NAT/firewall with zero infra. Cost: up to `MOLECULE_POLL_INTERVAL_MS` of inbound latency. For production setups where lower latency matters, push mode is on the v0.2 roadmap.
### Why the 30s window over a 5s interval?
A single missed tick (transient network blip, GC pause, laptop sleep) shouldn't lose messages. The plugin re-fetches the last 30 seconds on every poll and dedups by `activity_id`, so 25 seconds of overlap is the recovery margin. Increase `MOLECULE_POLL_WINDOW_SECS` for noisier networks.
### Singleton lock
Only one channel server runs per host — multiple instances would race the dedup state and double-deliver. The plugin maintains a PID file at `~/.claude/channels/molecule/bot.pid` and on startup kills any stale predecessor. This mirrors the [`@claude-plugins-official/telegram`](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/telegram) pattern.
---
## Troubleshooting
### "molecule channel: required config missing"
The plugin started before you filled in `.env`. Re-run the snippet from Step 2, then re-launch Claude Code.
### "molecule channel: poll `<ws-id>` returned 401"
Bearer token mismatch. Two common causes:
- The token in `MOLECULE_WORKSPACE_TOKENS` doesn't match the workspace whose ID is in the corresponding position of `MOLECULE_WORKSPACE_IDS`. Verify same-order pairing.
- The workspace was rotated and the token was revoked. Generate a new token from the canvas Settings tab (or `POST /admin/workspaces/:id/tokens`).
### "molecule channel: poll `<ws-id>` returned 404"
Either the workspace doesn't exist or the `MOLECULE_PLATFORM_URL` is wrong. Confirm:
```bash
curl -fsS "$MOLECULE_PLATFORM_URL/workspaces/$WS_ID" \
-H "Authorization: Bearer $WS_TOKEN" | jq '.workspace.id'
```
### A2A messages aren't surfacing
Check that the watched workspace is actually receiving them — the plugin only pulls `activity_logs` rows whose `activity_type = a2a_receive`. If peers aren't sending to this workspace, there's nothing to surface. Verify with:
```bash
curl -fsS "$MOLECULE_PLATFORM_URL/workspaces/$WS_ID/activity?type=a2a_receive&limit=10" \
-H "Authorization: Bearer $WS_TOKEN" | jq
```
If that returns events but Claude doesn't see them, file an issue at [`Molecule-AI/molecule-mcp-claude-channel`](https://github.com/Molecule-AI/molecule-mcp-claude-channel/issues) with the workspace_id + sample event.
---
## Limitations (v0.1)
- **Polling-only inbound.** No push mode yet; latency floor is `MOLECULE_POLL_INTERVAL_MS`.
- **No pairing flow.** Tokens are configured manually via `.env`; no canvas-side approval handshake.
- **No file-attachment download.** URLs surface in the meta block; the host fetches on-demand.
- **No outbound channel-init.** The plugin only sends replies (in response to inbound A2A); starting a fresh A2A conversation initiated FROM the Claude Code side requires a future `start_workspace_chat` tool.
Track the v0.2 roadmap on the [plugin repo's README](https://github.com/Molecule-AI/molecule-mcp-claude-channel#limitations-v01).
---
## See also
- [External Agent Registration](/docs/guides/external-agent-registration) — full A2A wire-shape reference + Python SDK + curl flow
- [External Workspace Quickstart](/docs/guides/external-workspace-quickstart) — 5-min guide for any HTTP-speaking agent
- [Remote Workspaces FAQ](/docs/guides/remote-workspaces-faq) — production hardening notes
- [`Molecule-AI/molecule-mcp-claude-channel`](https://github.com/Molecule-AI/molecule-mcp-claude-channel) — plugin source code, issues, v0.2 roadmap

View File

@ -9,6 +9,8 @@ Run an agent on your laptop, a home server, a cloud VM, or any machine with inte
> **Looking for the operator-focused reference?** See [External Agent Registration](/docs/guides/external-agent-registration) for full capability + auth details, or [Remote Workspaces FAQ](/docs/guides/remote-workspaces-faq) for hardening + production notes. This doc is the fast path.
> **Running Claude Code on your laptop?** Skip this guide — use the [Claude Code Channel Plugin](/docs/guides/claude-code-channel-plugin) instead. It's polling-based and needs no tunnel, so your laptop session shows up on the canvas in under a minute.
---
## What is an "external workspace"?
@ -158,7 +160,7 @@ The `id` field is your workspace ID — remember it.
|---|---|
| "Failed to send message — agent may be unreachable" | The tenant couldn't POST to your URL. Verify `curl https://<your-tunnel>/health` returns 200 from another machine. |
| Response takes > 30s | Canvas times out around 30s. Keep initial implementations simple. For long-running work, return a placeholder and use [polling mode](#next-step-polling-mode-preview) (once available). |
| Agent duplicated in chat | Known canvas bug where WebSocket + HTTP responses both render. Fixed in [molecule-core #1517](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1517). |
| Agent duplicated in chat | Known canvas bug where WebSocket + HTTP responses both render. Fixed in [molecule-core #1517](https://github.com/Molecule-AI/molecule-core/pull/1517). |
| Agent replies but canvas shows "Agent unreachable" | Check the tenant can reach your URL. Cloudflare quick tunnels rotate — the URL in your canvas may point at a dead tunnel after restart. |
| Getting 404 when POSTing to tenant | Add `X-Molecule-Org-Id` header. The tenant's security layer 404s unmatched origin requests by design. |
@ -220,7 +222,7 @@ Push mode (this guide) works today but requires an inbound-reachable URL — whi
Your agent makes only outbound HTTPS calls to the platform, pulling messages from an inbox queue and posting replies back. Works behind any NAT/firewall, tolerates offline laptops, no tunnel needed.
See the [design doc](https://git.moleculesai.app/molecule-ai/internal/src/branch/main/product/external-workspaces-polling.md) (internal) and the implementation tracking issue (search `polling+mode` on the [molecule-core issue tracker](https://git.moleculesai.app/molecule-ai/molecule-core/issues)).
See the [design doc](https://github.com/Molecule-AI/internal/blob/main/product/external-workspaces-polling.md) (internal) and [implementation tracking issue](https://github.com/Molecule-AI/molecule-core/issues?q=polling+mode) once opened.
---
@ -260,11 +262,11 @@ If all four pass and canvas still shows your agent as unreachable, see the [remo
## Feedback
This is a new path. Tell us what broke:
- Open an issue: https://git.moleculesai.app/molecule-ai/molecule-core/issues/new?labels=external-workspace
- Open an issue: https://github.com/Molecule-AI/molecule-core/issues/new?labels=external-workspace
- Submit a PR improving this doc if something tripped you up — the faster we can make the quickstart, the more developers we bring in
---
*Last updated 2026-04-23*
(`molecule-core` [#1760](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1760))
(`molecule-core` [#1760](https://github.com/Molecule-AI/molecule-core/pull/1760))

View File

@ -78,7 +78,7 @@ Every log entry automatically includes MCP request context (tool name, request I
Set `LOG_LEVEL=debug` (level 20) to trace all tool calls and request IDs. Set `LOG_LEVEL=error` (level 50) in CI to suppress informational output.
See [`molecule-mcp-server` PR #6](https://git.moleculesai.app/molecule-ai/molecule-mcp-server/pull/6) for implementation details.
See [`molecule-mcp-server` PR #6](https://github.com/Molecule-AI/molecule-mcp-server/pull/6) for implementation details.
## Tool Reference

View File

@ -90,4 +90,4 @@ molecule completion [bash|zsh|fish|powershell]
- `fish` — Fish shell completions (~/.config/fish/completions)
- `powershell` — PowerShell completions ($PROFILE)
See [`molecule-cli` PR #5](https://git.moleculesai.app/molecule-ai/molecule-cli/pull/5) for implementation details.
See [`molecule-cli` PR #5](https://github.com/Molecule-AI/molecule-cli/pull/5) for implementation details.

View File

@ -148,5 +148,5 @@ The agent appears on the canvas with a **purple REMOTE badge** within seconds. F
## Next Steps
- **[External Agent Registration Guide →](/docs/guides/external-agent-registration)** — full endpoint reference, Python + Node.js examples, troubleshooting
- **[molecule-sdk-python →](https://git.moleculesai.app/molecule-ai/molecule-sdk-python)** — SDK source, `RemoteAgentClient` API docs
- **[SDK Examples →](https://git.moleculesai.app/molecule-ai/molecule-sdk-python/src/branch/main/examples/remote-agent)** — `run.py` demo script, annotated walkthrough
- **[molecule-sdk-python →](https://github.com/Molecule-AI/molecule-sdk-python)** — SDK source, `RemoteAgentClient` API docs
- **[SDK Examples →](https://github.com/Molecule-AI/molecule-sdk-python/tree/main/examples/remote-agent)** — `run.py` demo script, annotated walkthrough

View File

@ -65,7 +65,7 @@ molecule skills install arxiv-research --from community
Community skills are reviewed by the Molecule AI team before being
listed. Submit a skill for review by opening a PR against
`molecule-ai/skills` (repo location TBD post-2026-05-06 GitHub-org-suspension; check the [internal issue tracker](https://git.moleculesai.app/molecule-ai/internal/issues) for the canonical submission path).
[`molecule-ai/skills`](https://github.com/Molecule-AI/skills).
## Installing via config.yaml
@ -171,7 +171,7 @@ molecule skills bundle my-custom-skill --output ./org-templates/my-role/
```
**Publishing to the community:** Open a PR against
`molecule-ai/skills` (repo location TBD post-2026-05-06 GitHub-org-suspension; check the [internal issue tracker](https://git.moleculesai.app/molecule-ai/internal/issues) for the canonical submission path) with a
[`molecule-ai/skills`](https://github.com/Molecule-AI/skills) with a
complete skill package. Community skills are reviewed for security and
correctness before listing.

View File

@ -339,7 +339,7 @@ If you are routing a Gemini model through a key that triggers the compat shim (e
- [Concepts — Workspaces](/docs/concepts#workspaces)
- [API Reference — POST /workspaces](/docs/api-reference#post-workspaces)
- [Google ADK Runtime](/docs/google-adk) — Gemini-native alternative to Hermes for ADK-first workflows
- PR #240: [Phase 2a — native Anthropic dispatch](https://git.moleculesai.app/molecule-ai/molecule-core/pull/240)
- PR #255: [Phase 2b — native Gemini dispatch](https://git.moleculesai.app/molecule-ai/molecule-core/pull/255)
- PR #267: [Phase 2c — multi-turn history on all paths](https://git.moleculesai.app/molecule-ai/molecule-core/pull/267)
- Issue [#513](https://git.moleculesai.app/molecule-ai/molecule-core/issues/513)
- PR #240: [Phase 2a — native Anthropic dispatch](https://github.com/Molecule-AI/molecule-core/pull/240)
- PR #255: [Phase 2b — native Gemini dispatch](https://github.com/Molecule-AI/molecule-core/pull/255)
- PR #267: [Phase 2c — multi-turn history on all paths](https://github.com/Molecule-AI/molecule-core/pull/267)
- Issue [#513](https://github.com/Molecule-AI/molecule-core/issues/513)

View File

@ -165,14 +165,14 @@ ticket if a future revival of this BFG procedure is needed.
**Step 2 — Clean origin/main:**
```bash
git clone --mirror https://git.moleculesai.app/molecule-ai/molecule-core /tmp/molecule-main-mirror
git clone --mirror https://github.com/Molecule-AI/molecule-core /tmp/molecule-main-mirror
java -jar bfgr.jar --replace-text creds.txt --rewrite-not-committed-by-oss --no-blob-protection /tmp/molecule-main-mirror
cd /tmp/molecule-main-mirror && git push --mirror
```
**Step 3 — Clean origin/staging:**
```bash
git clone --mirror https://git.moleculesai.app/molecule-ai/molecule-core /tmp/molecule-staging-mirror
git clone --mirror https://github.com/Molecule-AI/molecule-core /tmp/molecule-staging-mirror
java -jar bfgr.jar --replace-text creds.txt --rewrite-not-committed-by-oss --no-blob-protection /tmp/molecule-staging-mirror
cd /tmp/molecule-staging-mirror && git push --mirror
```
@ -584,7 +584,7 @@ Core-BE — delegated to Dev Lead (A2A failed). Core-BE sub-team: please pick up
### Fix PR
[PR #1336](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1336) filed — `fix(orchestrator): fail-fast if WORKSPACE_ID env var is unset/empty`. Targets staging. Labels: bug, needs-work, area:backend-engineer, area:dev-lead.
[PR #1336](https://github.com/Molecule-AI/molecule-core/pull/1336) filed — `fix(orchestrator): fail-fast if WORKSPACE_ID env var is unset/empty`. Targets staging. Labels: bug, needs-work, area:backend-engineer, area:dev-lead.
---

View File

@ -0,0 +1,166 @@
---
title: Marketplace
description: A tiered library of plugins, agents, and bundles you can mount into any Molecule workspace.
---
## Overview
The Molecule **Marketplace** is the distribution surface for reusable agent
infrastructure. It surfaces three tiers of artifacts — from a single MCP
plugin to a full team topology — and the same governance, memory, and audit
substrate runs underneath each one.
You browse and install via the Marketplace UI at
[`https://moleculesai.app`](https://moleculesai.app), or pin entries from
your `workspace.yaml` for reproducible deployments.
---
## Three Tiers
| Tier | Name | Granularity | Mount as |
|------|------|-------------|----------|
| **L1** | Plugins | A single MCP server / tool pack | Tool capability on an agent or workspace |
| **L2** | Agents | A prebuilt single-agent skill (prompts + tools + policy) | Workspace member |
| **L3** | Bundles | A full team topology (root + children with their own scopes) | Workspace |
The tier model is intentionally additive — an L3 Bundle is composed of L2
Agents, which in turn use L1 Plugins. Forking a Bundle gives you the lineage
to swap any constituent piece without rewiring the operating model.
### L1 — Plugins
Plugins are MCP servers or agentskills.io packs. Examples:
- `postgres` — read/write Postgres with role-scoped credentials
- `slack` — post and search Slack with workspace-scoped tokens
- `linear` — create / triage / comment on Linear issues
- `gh-actions` — query and dispatch GitHub Actions runs
- `sentry` — read incident timeline, ack alerts
Plugins follow the [two-axis source/shape model](/docs/plugins) and install
from either a curated `local://` source or a pinned `github://owner/repo#tag`.
### L2 — Agents
Agents are single-purpose skills mounted as a workspace member. They ship with:
- A **system prompt** baked in
- A **tool manifest** specifying which L1 plugins they require
- A **policy** declaring scope reads/writes and approval requirements
Examples:
- `code-reviewer` — five-axis review, posts inline comments via `gh-actions`
- `oncall-triager` — reads Sentry, drafts a runbook step, requests approval before paging
- `churn-analyst` — periodic Postgres + Stripe rollup, posts a weekly Slack summary
Mount an agent via the workspace UI or `workspace.yaml`:
```yaml
members:
- kind: agent
source: marketplace://l2/code-reviewer
version: ^1.2.0
scopes:
- read: pull_requests
- write: pull_request_comments
```
### L3 — Bundles
Bundles are complete team topologies. A bundle ships:
- A **root agent** that coordinates the team
- One or more **child agents**, each with its own scope, memory, and tool
list
- A **policy graph** declaring which scopes the root can write through and
which approvals route to humans
Examples:
- `growth-team` — root strategist + content-writer + analytics-rollup +
experiment-designer
- `platform-ops` — root SRE + on-call triager + change-reviewer +
incident-scribe
- `revenue-pod` — root commercial lead + churn-analyst + cs-summarizer +
expansion-prospector
Mount a bundle as a workspace:
```yaml
workspace:
bundle: marketplace://l3/platform-ops
bundle_version: ^0.4.0
overrides:
members:
change-reviewer:
scopes:
- read: ["github:Molecule-AI/*", "linear:eng"]
```
Forking is encouraged — the bundle author publishes the operating model;
your team tunes it for your processes without rebuilding the substrate.
---
## Trust Tiers
Every Marketplace entry carries a **trust tier** that signals review depth
and supply-chain provenance:
| Trust | Vetting | Provenance |
|-------|---------|------------|
| **Verified** | Reviewed by Molecule for safety, prompt-injection resistance, and policy correctness | Published from a Molecule-controlled identity |
| **Partner** | Reviewed by a Marketplace partner; carries the partner's identity badge | Published from a verified partner account |
| **Community** | Self-published; static analysis + sandbox runtime; no human review | Pinned to a specific commit SHA |
The trust tier is shown on every listing card and gated by enterprise
policy: organizations on the Enterprise plan can restrict installs to
Verified-only via `policy.marketplace.min_trust = verified`.
---
## Installing from the Marketplace
Browse listings at [`https://moleculesai.app`](https://moleculesai.app).
Each card shows tier (L1/L2/L3), trust badge, runtime compatibility, and
required scopes. The "Install" flow:
1. Picks a workspace (or creates a new one) to mount into.
2. Surfaces required scopes for review and approval.
3. Pins to a specific version (semver range, exact tag, or commit SHA).
4. Writes the entry into your `workspace.yaml` and triggers a workspace
redeploy.
You can also install non-interactively:
```bash
curl -X POST https://app.moleculesai.app/cp/orgs/$ORG/marketplace/install \
-H "Authorization: Bearer $CP_ADMIN_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tier": "l2",
"slug": "code-reviewer",
"version": "^1.2.0",
"workspace_id": "ws_abc123"
}'
```
---
## Listing on the Marketplace
If you have built reusable agent infrastructure — a plugin, agent, or
bundle — you can list it on the Marketplace and reach every Molecule
organization. See [Listing on the Marketplace](/docs/marketplace/creators)
for the full builder workflow.
---
## See also
- [Plugins](/docs/plugins) — L1 source/shape model and install mechanics
- [External Agents](/docs/external-agents) — bringing a non-Molecule agent runtime
- [Workspace Configuration](/docs/workspace-config) — `workspace.yaml` reference
- [Listing on the Marketplace](/docs/marketplace/creators) — builder workflow

View File

@ -0,0 +1,164 @@
---
title: Listing on the Marketplace
description: How builders ship plugins, agents, and bundles to every Molecule organization.
---
## Overview
The Marketplace is open to external builders. If you have authored reusable
agent infrastructure — an MCP plugin, a single-agent skill, or a full team
bundle — you can list it and reach every Molecule organization. We handle
distribution, billing, and policy; you keep the IP and the upgrade cadence.
This page walks through the three-step workflow: **Build · List · Earn**.
---
## 1. Build
You author your artifact against the open Molecule SDK. The same primitives
we use internally are available to you:
- **Workspace** — the durable boundary for memory, members, and policy
- **A2A** — agent-to-agent messaging, used to talk to runtimes you don't
own (LangGraph, CrewAI, etc.)
- **Memory scopes** — hierarchical, governance-aware persistence
- **Audit** — every action is captured at the orchestration layer
Pick the tier that matches your artifact's granularity:
### L1 — Plugins
A plugin is an MCP server (or an agentskills.io pack). The
[two-axis source/shape model](/docs/plugins) describes how the workspace
runtime loads it. Authoring requirements:
- A `plugin.yaml` manifest declaring tools, required scopes, and runtime
compatibility.
- A README documenting the tool surface and side effects.
- For MCP plugins: an HTTP or stdio MCP server pinned to a tagged commit.
A reference plugin lives at
[`Molecule-AI/molecule-ai-plugin-template`](https://github.com/Molecule-AI/molecule-ai-plugin-template).
### L2 — Agents
An agent is a single workspace member with a baked-in prompt + tools +
policy. Authoring requirements:
- An `agent.yaml` manifest declaring system prompt, required L1 plugins,
scope reads/writes, and approval triggers.
- A `prompts/` directory with the system prompt and any reusable templates.
- A `tests/` directory exercising the prompt against canned scenarios.
Reference: [`Molecule-AI/molecule-ai-agent-template`](https://github.com/Molecule-AI/molecule-ai-agent-template).
### L3 — Bundles
A bundle ships a complete team topology — a root agent plus children, each
with its own scope and memory. Authoring requirements:
- A `bundle.yaml` declaring members, their scopes, and the policy graph
(which scopes the root can write through, which approvals route to
humans).
- A `members/` directory containing member-specific overrides if any
member is a fork of an L2 agent.
- A `topology.svg` diagram (auto-rendered from `bundle.yaml`, but you can
override).
Reference: [`Molecule-AI/molecule-ai-bundle-template`](https://github.com/Molecule-AI/molecule-ai-bundle-template).
---
## 2. List
Submit through the **Creator Portal** at
[`https://moleculesai.app/creators`](https://moleculesai.app/creators).
The submission flow:
1. **Connect** — link the GitHub repository hosting your artifact. We pull
from tagged releases; we never re-tag or modify your code.
2. **Manifest check** — we validate `plugin.yaml` / `agent.yaml` /
`bundle.yaml` against the schema for your tier and surface any gaps.
3. **Static analysis** — credential-shape scan, prompt-injection-pattern
scan, and dependency vulnerability check on every tagged release.
4. **Sandbox boot** — your artifact is mounted into a throwaway workspace
to verify it boots, declares its scopes correctly, and surfaces a
reasonable error path.
5. **Trust tier** — every artifact starts at **Community**. Apply for
**Partner** or **Verified** review once you have a couple of releases
under your belt.
Pricing is configured at submission:
- **Free** — no charge to install.
- **Per-seat** — a flat monthly amount per workspace member that mounts
the artifact.
- **Per-use** — metered against a unit you define (token calls, runs,
alerts handled).
- **Hybrid** — base seat fee plus metered overages.
You can change pricing on subsequent releases; existing installs are
grandfathered to the version they pinned.
---
## 3. Earn
Once your listing is live, you receive:
- **Distribution** — every Molecule organization sees your listing in the
Marketplace UI, gated only by their policy (`min_trust`, region, etc.).
- **Billing** — Molecule handles the charge to the installing
organization, deducts the platform fee (15% as of writing; check the
current rate in the Creator Portal), and pays out monthly.
- **Audit visibility** — you see install counts, version distribution,
and aggregated usage metrics in the Creator Portal. You do **not** see
per-organization data.
- **Upgrade cadence** — semver: bump tags, organizations on a `^range`
pin pull updates on their next workspace redeploy. Major bumps require
re-approval of any new scopes.
---
## Policy & Safety
By listing, you agree to:
- **No exfiltration** — your code does not transmit organization data
outside the scopes it declares.
- **Pinned releases** — every version is pinned to an immutable commit;
retagging is not permitted.
- **Disclose model usage** — if your agent calls an LLM API, declare the
provider and model so enterprise plans can route through their own
keys.
- **Respect approval triggers** — if your `agent.yaml` declares a scope
that requires human approval (e.g. `write: pull_request_merge`), you
must call the approval API before acting.
Listings that violate these terms are de-listed; refunds for affected
installs are paid from your account.
---
## Maintenance
Once a listing is live, you can:
- Push new tagged releases — they enter the static-analysis + sandbox
flow automatically.
- Mark older versions as **deprecated** to nudge installs to upgrade.
- File **security advisories** that surface to every organization on a
vulnerable pinned version.
- Yank a release in the rare case of a critical bug; organizations
pinned to the yanked tag are notified and offered the next safe version.
---
## See also
- [Marketplace](/docs/marketplace) — tier model and installation overview
- [Plugins](/docs/plugins) — L1 plugin source/shape mechanics
- [Workspace Configuration](/docs/workspace-config) — pinning marketplace
entries in `workspace.yaml`
- [Security &raquo; OWASP Agentic Top 10](/docs/security/owasp-agentic-top-10) — supply-chain considerations relevant to bundle authors

View File

@ -20,6 +20,9 @@
"self-hosting/admin-token",
"observability",
"troubleshooting",
"---Marketplace---",
"marketplace",
"marketplace/creators",
"---Security---",
"security/index",
"security/safe-mcp-advisory",

View File

@ -163,11 +163,11 @@ not expose.
| `molecule-skill-update-docs` | `[claude_code]` | `[claude_code, hermes]` |
Companion PRs:
- [molecule-ai-plugin-ecc#2](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-ecc/pull/2)
- [molecule-ai-plugin-superpowers#2](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-superpowers/pull/2)
- [molecule-ai-plugin-molecule-dev#2](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-molecule-dev/pull/2)
- [molecule-ai-plugin-molecule-skill-cron-learnings#2](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-molecule-skill-cron-learnings/pull/2)
- [molecule-ai-plugin-molecule-skill-update-docs#2](https://git.moleculesai.app/molecule-ai/molecule-ai-plugin-molecule-skill-update-docs/pull/2)
- [molecule-ai-plugin-ecc#2](https://github.com/Molecule-AI/molecule-ai-plugin-ecc/pull/2)
- [molecule-ai-plugin-superpowers#2](https://github.com/Molecule-AI/molecule-ai-plugin-superpowers/pull/2)
- [molecule-ai-plugin-molecule-dev#2](https://github.com/Molecule-AI/molecule-ai-plugin-molecule-dev/pull/2)
- [molecule-ai-plugin-molecule-skill-cron-learnings#2](https://github.com/Molecule-AI/molecule-ai-plugin-molecule-skill-cron-learnings/pull/2)
- [molecule-ai-plugin-molecule-skill-update-docs#2](https://github.com/Molecule-AI/molecule-ai-plugin-molecule-skill-update-docs/pull/2)
Security note: Security Auditor was offline at time of change. Self-assessed
as non-security-impacting — adding `hermes` to a string list in `plugin.yaml`

View File

@ -11,7 +11,7 @@ Get a Molecule AI workspace running in under five minutes.
## 1. Install Molecule AI
```bash
git clone https://git.moleculesai.app/molecule-ai/molecule-core.git
git clone https://github.com/Molecule-AI/molecule-core.git
cd molecule-core
docker compose up -d
```
@ -78,4 +78,4 @@ Or type `/ask what's our deployment status?` in your connected Discord channel.
- [Review the REST API reference](/docs/guides/org-api-keys)
- [Browse all guides](/docs/guides)
Explore the [Gitea repo](https://git.moleculesai.app/molecule-ai/molecule-core) for self-hosting options, or visit [moleculesai.app](https://moleculesai.app) for the hosted platform.
Explore the [GitHub repo](https://github.com/Molecule-AI/molecule-core) for self-hosting options, or visit [moleculesai.app](https://moleculesai.app) for the hosted platform.

View File

@ -104,14 +104,15 @@ 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`:
Four additional env vars control how your workspace appears on the
canvas and how the wheel's inbound-delivery contract behaves:
| Env var | What it sets | Default |
|---|---|---|
| `MOLECULE_AGENT_NAME` | Display name on the canvas card | `molecule-mcp-{id[:8]}` |
| `MOLECULE_AGENT_DESCRIPTION` | One-line description in Details/Skills tabs | empty |
| `MOLECULE_AGENT_SKILLS` | Comma-separated skill names — e.g. `research,code-review,memory-curation` | `[]` |
| `MOLECULE_MCP_POLL_TIMEOUT_SECS` | How long the agent blocks on `wait_for_message` per turn (the universal poll path). `0` disables polling for push-only mode (Claude Code with `--dangerously-load-development-channels`). Above 60 clamps to 60. | `2` |
Skills are surfaced two places:
@ -158,7 +159,7 @@ status. If the workspace is still offline after ~30s, check
| `delegate_task` | Send a task to a peer and wait for the reply |
| `delegate_task_async` | Fire-and-forget delegation; result lands in inbox |
| `check_task_status` | Poll an async delegation |
| `wait_for_message` | Block until the next inbound A2A message arrives |
| `wait_for_message` | Block until the next inbound A2A message arrives — the universal inbound-delivery primitive (see [Inbound delivery](#inbound-delivery-universal-poll-optional-push)) |
| `inbox_peek` / `inbox_pop` | Inspect / acknowledge queued inbound messages |
| `send_message_to_user` | Push a chat bubble to the user's canvas |
| `commit_memory` / `recall_memory` | Persistent KV (local / team / global scope) |
@ -168,29 +169,63 @@ External runtimes can't accept inbound HTTP, so the wheel polls
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
### Inbound delivery: universal poll, optional push
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.
Inbound messages reach the agent via one of two paths. The wheel
exposes both; which one fires depends on the host's capabilities.
Both paths converge on the same `inbox_pop` ack so dedup is automatic.
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.
**Poll path (universal default — works on every spec-compliant MCP
client).** The wheel's `initialize` handshake includes an `instructions`
field telling the agent: *"At the start of every turn, before producing
your final response, call `wait_for_message(timeout_secs=N)` to check
for inbound messages."* Every MCP client surfaces `instructions` to
the agent's system prompt automatically, so Claude Code, Cursor, Cline,
OpenCode, hermes-agent, and codex all receive the polling contract
without any per-client wiring. The 2-second default is tuned for the
"peer A2A landed seconds before my turn started" common case; tune
via the `MOLECULE_MCP_POLL_TIMEOUT_SECS` env var
(see "Optional — declare your identity & capabilities" above).
**Push path (Claude Code with channel push enabled — strictly
better when available).** On top of the poll path, the wheel emits a
JSON-RPC notification (`notifications/claude/channel`) on every new
inbound message and declares the matching `experimental.claude/channel`
capability in `initialize`. Claude Code with channel push enabled
turns the notification into an inline `<channel source="molecule"
...>` synthetic user turn — zero agent-side polling cost, zero
per-turn stall.
**Today (research preview), Claude Code's channel push requires
either the `--dangerously-load-development-channels` launch flag OR
an entry on Claude Code's approved channel-server allowlist.** The
wheel ships the wire shape correctly, but a standard `claude` launch
without the flag silently drops the notification — which is why the
poll path has to be the floor.
Set `MOLECULE_MCP_POLL_TIMEOUT_SECS=0` to disable polling entirely
when you're running Claude Code with the dev-channels flag and don't
want the per-turn stall. The instructions adapt automatically: with
polling disabled, the agent is told push is the only delivery path.
| Client | Push path | Poll path |
|---|---|---|
| Claude Code with `--dangerously-load-development-channels` | ✅ inline tag | ✅ also works |
| Claude Code (standard launch) | ❌ silently dropped | ✅ via instructions |
| Cursor / Cline / OpenCode / codex | ❌ method ignored | ✅ via instructions |
| hermes-agent | ❌ method ignored | ✅ naturally polls every cycle |
### 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:
JSON-RPC. It declares the standard `tools` capability plus the
`experimental.claude/channel` capability for the optional push path
(see [Inbound delivery](#inbound-delivery-universal-poll-optional-push)).
It implements the standard request methods and nothing client-specific:
| MCP method | Behavior |
|---|---|
| `initialize` | Echoes `protocolVersion: "2024-11-05"`, `serverInfo`, declares `tools` capability |
| `initialize` | Echoes `protocolVersion: "2024-11-05"`, `serverInfo`, declares `tools` + `experimental.claude/channel` capabilities, returns the dual-path delivery `instructions` |
| `notifications/initialized` | No-op (no response — per spec) |
| `tools/list` | Returns all exposed tools in one response (no pagination cursor — surface is small) |
| `tools/call` | Dispatches by name, returns `content: [{ type: "text", text: ... }]` |
@ -198,8 +233,10 @@ standard request methods and nothing client-specific:
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.
that don't handle it discard it per JSON-RPC semantics. The poll path
(via the standard `instructions` field) carries delivery for those
clients, so no part of the wheel's tool surface depends on a client
recognizing the notification.
This means **any spec-compliant MCP client** can drive the wheel:
Claude Code, Cursor, Cline, OpenCode, hermes-agent, or anything else
@ -274,7 +311,7 @@ MCP config and restart your runtime.
### `Workspace <id> was deleted on the platform...` from `get_workspace_info`
Since [#2429](https://git.moleculesai.app/molecule-ai/molecule-core/pull/2449),
Since [#2429](https://github.com/Molecule-AI/molecule-core/pull/2449),
`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:

View File

@ -12,7 +12,7 @@ This page documents security fixes shipped in the Molecule AI platform. Each ent
## 2026-04-20 — CWE-22: Path Traversal in `copyFilesToContainer`
**Severity:** High (CWE-22)
**PRs:** [#1271](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1271), [#1270](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1270), [#1267](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1267)
**PRs:** [#1271](https://github.com/Molecule-AI/molecule-core/pull/1271), [#1270](https://github.com/Molecule-AI/molecule-core/pull/1270), [#1267](https://github.com/Molecule-AI/molecule-core/pull/1267)
**Affected:** `workspace-server/internal/handlers/container_files.go``TemplatesHandler.copyFilesToContainer`
### Vulnerability
@ -37,7 +37,7 @@ File writes to workspace containers now validate all paths before writing to the
## 2026-04-20 — CWE-78: Shell Injection in `deleteViaEphemeral`
**Severity:** High (CWE-78)
**PR:** [#1310](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1310)
**PR:** [#1310](https://github.com/Molecule-AI/molecule-core/pull/1310)
**Affected:** `workspace-server/internal/handlers/container_files.go``TemplatesHandler.deleteViaEphemeral`
### Vulnerability
@ -69,9 +69,9 @@ Workspace file deletion operations now use safe argument-passing and validate al
## 2026-04-21 — CWE-918: SSRF in MCP / A2A Proxy Endpoints (Updated: Regression Fix)
**Severity:** High (CWE-918)
**Original PRs:** [#1274](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1274), [#1302](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1302)
**Regression Fix PR:** [#1430](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1430)
**Regression introduced by:** [#1363](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1363)
**Original PRs:** [#1274](https://github.com/Molecule-AI/molecule-core/pull/1274), [#1302](https://github.com/Molecule-AI/molecule-core/pull/1302)
**Regression Fix PR:** [#1430](https://github.com/Molecule-AI/molecule-core/pull/1430)
**Regression introduced by:** [#1363](https://github.com/Molecule-AI/molecule-core/pull/1363)
**Affected:** `workspace-server/internal/handlers/mcp.go``isSafeURL`, `isPrivateOrMetadataIP`; `workspace-server/internal/handlers/a2a_proxy.go`; `workspace-server/internal/handlers/a2a_proxy_helpers.go`
### Vulnerability
@ -105,9 +105,9 @@ In **SaaS mode** (`saasMode()` returns true), cross-EC2 traffic to RFC-1918 addr
### Regression (2026-04-21)
PR [#1363](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1363) (handler refactor) moved `isPrivateOrMetadataIP` into `a2a_proxy_helpers.go` but kept a **pre-SaaS version** that unconditionally blocked RFC-1918 addresses, breaking cross-EC2 communication in SaaS. The old version also **returned `false` for all IPv6 inputs**, fully bypassing SSRF protection for IPv6 targets.
PR [#1363](https://github.com/Molecule-AI/molecule-core/pull/1363) (handler refactor) moved `isPrivateOrMetadataIP` into `a2a_proxy_helpers.go` but kept a **pre-SaaS version** that unconditionally blocked RFC-1918 addresses, breaking cross-EC2 communication in SaaS. The old version also **returned `false` for all IPv6 inputs**, fully bypassing SSRF protection for IPv6 targets.
PR [#1430](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1430) restores the correct SaaS-gated logic and adds proper IPv6 coverage to the A2A proxy path.
PR [#1430](https://github.com/Molecule-AI/molecule-core/pull/1430) restores the correct SaaS-gated logic and adds proper IPv6 coverage to the A2A proxy path.
### User-facing summary
@ -118,7 +118,7 @@ Platform outbound requests from workspaces (MCP tool calls, A2A proxy routing) v
## 2026-04-21 — Audit Ledger HMAC Chain Guard
**Severity:** Low (denial-of-service / data integrity)
**PRs:** [#1339](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1339), [#1352](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1352), [#1354](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1354) (backport to `main`)
**PRs:** [#1339](https://github.com/Molecule-AI/molecule-core/pull/1339), [#1352](https://github.com/Molecule-AI/molecule-core/pull/1352), [#1354](https://github.com/Molecule-AI/molecule-core/pull/1354) (backport to `main`)
**Affected:** `workspace-server/internal/handlers/audit.go`
### Vulnerability
@ -144,7 +144,7 @@ Audit chain verification now handles short or malformed HMAC values gracefully,
## 2026-04-21 — Credential Scrub: `err.Error()` Leak Prevention
**Severity:** Medium (information disclosure)
**PRs:** [#1282](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1282), [#1355](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1355), [#1359](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1359)
**PRs:** [#1282](https://github.com/Molecule-AI/molecule-core/pull/1282), [#1355](https://github.com/Molecule-AI/molecule-core/pull/1355), [#1359](https://github.com/Molecule-AI/molecule-core/pull/1359)
**Affected:** `workspace-server/internal/handlers/plugins_install_pipeline.go`, `workspace-server/internal/handlers/workspace_provision.go`, `content/docs/incidents/INCIDENT_LOG.md`
### Vulnerability

View File

@ -17,7 +17,7 @@ description: Run the full Molecule AI stack on your own infrastructure.
The fastest way to get Molecule AI running locally:
```bash
git clone https://git.moleculesai.app/molecule-ai/molecule-core.git
git clone https://github.com/Molecule-AI/molecule-core.git
cd molecule-core
./scripts/dev-start.sh
# Canvas: http://localhost:3000

View File

@ -88,8 +88,8 @@ Fly Machines start in milliseconds and run in 35+ regions. Provisioning agent wo
## Related
- PR #501: [feat(platform): Fly Machines provisioner](https://git.moleculesai.app/molecule-ai/molecule-core/pull/501)
- PR #481: [feat(ci): deploy to Fly after image push](https://git.moleculesai.app/molecule-ai/molecule-core/pull/481)
- PR #501: [feat(platform): Fly Machines provisioner](https://github.com/Molecule-AI/molecule-core/pull/501)
- PR #481: [feat(ci): deploy to Fly after image push](https://github.com/Molecule-AI/molecule-core/pull/481)
- [Fly Machines API docs](https://fly.io/docs/machines/api/)
- [Platform API reference](../api-reference.md)
- Issue [#525](https://git.moleculesai.app/molecule-ai/molecule-core/issues/525)
- Issue [#525](https://github.com/Molecule-AI/molecule-core/issues/525)

View File

@ -64,6 +64,6 @@ The real power surfaces when you mix runtimes on the same Molecule AI tenant. Yo
## Related
- PR #379: [feat(adapters): add gemini-cli runtime adapter](https://git.moleculesai.app/molecule-ai/molecule-core/pull/379)
- PR #379: [feat(adapters): add gemini-cli runtime adapter](https://github.com/Molecule-AI/molecule-core/pull/379)
- [Multi-provider Hermes docs](../architecture/hermes.md)
- [Workspace runtimes reference](../reference/runtimes.md)

View File

@ -71,7 +71,7 @@ ADK workspaces participate in the same A2A network as Claude Code, Gemini CLI, H
## Related
- PR #550: [feat(adapters): add google-adk runtime adapter](https://git.moleculesai.app/molecule-ai/molecule-core/pull/550)
- PR #550: [feat(adapters): add google-adk runtime adapter](https://github.com/Molecule-AI/molecule-core/pull/550)
- [Google ADK (adk-python)](https://github.com/google/adk-python)
- [Gemini CLI runtime tutorial](./gemini-cli-runtime.md)
- [Platform API reference](../api-reference.md)

View File

@ -179,9 +179,9 @@ What is on the roadmap for Phase 2d (not yet shipped):
## Related
- PR #240: [Phase 2a — native Anthropic dispatch](https://git.moleculesai.app/molecule-ai/molecule-core/pull/240)
- PR #255: [Phase 2b — native Gemini dispatch](https://git.moleculesai.app/molecule-ai/molecule-core/pull/255)
- PR #267: [Phase 2c — multi-turn history on all paths](https://git.moleculesai.app/molecule-ai/molecule-core/pull/267)
- PR #240: [Phase 2a — native Anthropic dispatch](https://github.com/Molecule-AI/molecule-core/pull/240)
- PR #255: [Phase 2b — native Gemini dispatch](https://github.com/Molecule-AI/molecule-core/pull/255)
- PR #267: [Phase 2c — multi-turn history on all paths](https://github.com/Molecule-AI/molecule-core/pull/267)
- [Hermes adapter design](../adapters/hermes-adapter-design.md)
- [Platform API reference](../api-reference.md)
- Issue [#513](https://git.moleculesai.app/molecule-ai/molecule-core/issues/513)
- Issue [#513](https://github.com/Molecule-AI/molecule-core/issues/513)

View File

@ -93,6 +93,6 @@ Molecule AI canvas without code changes.
## Related
- PR #480: [feat(channels): Lark / Feishu channel adapter](https://git.moleculesai.app/molecule-ai/molecule-core/pull/480)
- PR #480: [feat(channels): Lark / Feishu channel adapter](https://github.com/Molecule-AI/molecule-core/pull/480)
- [Social channels architecture](../agent-runtime/social-channels.md)
- [Channel adapter reference](../api-reference.md#channels)

View File

@ -246,4 +246,4 @@ For the API reference, see [`docs/api-reference`](/docs/api-reference) — the `
*SaaS federation is available for all Molecule AI platform operators. Contact the Molecule AI team to enable federation on your control plane.*
(`molecule-core` [#1700](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1700))
(`molecule-core` [#1700](https://github.com/Molecule-AI/molecule-core/pull/1700))

View File

@ -145,7 +145,7 @@ Key push + tunnel + write took longer than 30 s. Common causes: slow AWS EIC in
## Source PR
PR [#1702](https://git.moleculesai.app/molecule-ai/molecule-core/pull/1702) — `feat(files-api): SSH-backed write for SaaS workspaces (fixes 500 docker not available)`
PR [#1702](https://github.com/Molecule-AI/molecule-core/pull/1702) — `feat(files-api): SSH-backed write for SaaS workspaces (fixes 500 docker not available)`
Key files in `molecule-core`:
- `workspace-server/internal/handlers/template_files_eic.go` — EIC write logic

View File

@ -237,4 +237,4 @@ Once your agent is connected to MCP, it stops being a chatbot with a scrollable
---
*Have questions or want to share what you're building with MCP? File an issue with the `enhancement` label on the [molecule-core issue tracker](https://git.moleculesai.app/molecule-ai/molecule-core/issues).*
*Have questions or want to share what you're building with MCP? Open a discussion on [GitHub Discussions](https://github.com/Molecule-AI/molecule-core/discussions) or file an issue with the `enhancement` label.*