docs: clarify multi external workspace config
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Waiting to run
Block internal-flavored paths / Block forbidden paths (push) Successful in 9s
CI / Python Lint & Test (push) Successful in 7s
CI / Detect changes (push) Successful in 11s
E2E API Smoke Test / detect-changes (push) Successful in 15s
Handlers Postgres Integration / detect-changes (push) Successful in 11s
E2E Chat / detect-changes (push) Successful in 22s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 15s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 11s
Lint no tenant GITEA or GITHUB token write / Scan for repo-host token write into tenant workspace surface (push) Successful in 10s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 9s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 11s
CI / Shellcheck (E2E scripts) (push) Successful in 20s
E2E Chat / E2E Chat (push) Successful in 13s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 18s
Sweep stale e2e-* orgs (staging) / Sweep e2e orgs (push) Successful in 8s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 2m59s
publish-workspace-server-image / build-and-push (push) Successful in 6m24s
CI / Platform (Go) (push) Successful in 6m9s
CI / Canvas (Next.js) (push) Successful in 7m3s
CI / all-required (push) Successful in 7m55s
CI / Canvas Deploy Reminder (push) Successful in 2s
publish-workspace-server-image / Production auto-deploy (push) Successful in 4m19s
Staging SaaS smoke (every 30 min) / Staging SaaS smoke (push) Successful in 8m47s
Continuous synthetic E2E (staging) / Synthetic E2E against staging (push) Successful in 10m10s
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (push) Waiting to run
Block internal-flavored paths / Block forbidden paths (push) Successful in 9s
CI / Python Lint & Test (push) Successful in 7s
CI / Detect changes (push) Successful in 11s
E2E API Smoke Test / detect-changes (push) Successful in 15s
Handlers Postgres Integration / detect-changes (push) Successful in 11s
E2E Chat / detect-changes (push) Successful in 22s
E2E Staging Canvas (Playwright) / detect-changes (push) Successful in 15s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (push) Successful in 11s
Lint no tenant GITEA or GITHUB token write / Scan for repo-host token write into tenant workspace surface (push) Successful in 10s
Secret scan / Scan diff for credential-shaped strings (push) Successful in 9s
E2E API Smoke Test / E2E API Smoke Test (push) Successful in 11s
CI / Shellcheck (E2E scripts) (push) Successful in 20s
E2E Chat / E2E Chat (push) Successful in 13s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (push) Successful in 18s
Sweep stale e2e-* orgs (staging) / Sweep e2e orgs (push) Successful in 8s
Handlers Postgres Integration / Handlers Postgres Integration (push) Successful in 2m59s
publish-workspace-server-image / build-and-push (push) Successful in 6m24s
CI / Platform (Go) (push) Successful in 6m9s
CI / Canvas (Next.js) (push) Successful in 7m3s
CI / all-required (push) Successful in 7m55s
CI / Canvas Deploy Reminder (push) Successful in 2s
publish-workspace-server-image / Production auto-deploy (push) Successful in 4m19s
Staging SaaS smoke (every 30 min) / Staging SaaS smoke (push) Successful in 8m47s
Continuous synthetic E2E (staging) / Synthetic E2E against staging (push) Successful in 10m10s
This commit was merged in pull request #1640.
This commit is contained in:
+18
-1
@@ -127,7 +127,11 @@ cd workspace-server && go test -race ./...
|
||||
cd canvas && npm test
|
||||
|
||||
# Workspace runtime (Python)
|
||||
cd workspace && python -m pytest -v
|
||||
# Runtime code is SSOT in molecule-ai-workspace-runtime, not molecule-core/workspace.
|
||||
cd ../molecule-ai-workspace-runtime
|
||||
python -m venv .venv && source .venv/bin/activate
|
||||
pip install --index-url https://git.moleculesai.app/api/packages/molecule-ai/pypi/simple/ -e . pytest pytest-asyncio
|
||||
pytest -q
|
||||
|
||||
# E2E API tests (requires running platform)
|
||||
bash tests/e2e/test_api.sh
|
||||
@@ -159,6 +163,19 @@ and run CI manually.
|
||||
| review-check-tests | `review-check.sh` evaluator regression suite (13 scenarios) |
|
||||
| ops-scripts | Python unittest suite for `scripts/*.py` |
|
||||
|
||||
### Workspace runtime SSOT
|
||||
|
||||
Runtime code lives in
|
||||
[`molecule-ai-workspace-runtime`](https://git.moleculesai.app/molecule-ai/molecule-ai-workspace-runtime).
|
||||
Do not reintroduce `molecule-core/workspace/` or vendored `molecule_runtime/`
|
||||
copies in consumers. Core and templates consume the published runtime package
|
||||
from the Gitea package registry.
|
||||
|
||||
For local external MCP agents, multi-workspace config is
|
||||
`MOLECULE_WORKSPACES=[{"id":"...","token":"...","platform_url":"..."}]`.
|
||||
`platform_url` selects the tenant; `org_id` is not part of this config.
|
||||
Workspace IDs can differ across orgs.
|
||||
|
||||
## Local Testing
|
||||
|
||||
### review-check.sh
|
||||
|
||||
@@ -285,6 +285,39 @@ Canvas requests (no `X-Workspace-ID` header) and system callers
|
||||
|
||||
---
|
||||
|
||||
## Multiple Workspaces From One Local MCP Bridge
|
||||
|
||||
The standalone runtime package includes `molecule-mcp`, a local MCP bridge for
|
||||
external agents such as Claude Code, Codex, Hermes, and other tools that run
|
||||
outside the platform container fleet. One local bridge can serve multiple
|
||||
external workspaces by setting `MOLECULE_WORKSPACES`:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "workspace-id-local-to-hongming-org",
|
||||
"token": "...",
|
||||
"platform_url": "https://hongming.moleculesai.app"
|
||||
},
|
||||
{
|
||||
"id": "different-workspace-id-local-to-agents-team-org",
|
||||
"token": "...",
|
||||
"platform_url": "https://agents-team.moleculesai.app"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
`platform_url` is the tenant routing key. The bridge registers, heartbeats,
|
||||
polls inboxes, and sends outbound A2A calls against the URL attached to the
|
||||
workspace that is doing the work.
|
||||
|
||||
Do not add `org_id` to this config. The tenant already comes from
|
||||
`platform_url`, and the bearer token is issued by that tenant. Workspace IDs
|
||||
also do not need to be shared across orgs; each tenant can return its own
|
||||
workspace ID and token for the same local agent process.
|
||||
|
||||
---
|
||||
|
||||
## Canvas Appearance
|
||||
|
||||
External workspaces appear on the canvas with a purple **REMOTE** badge
|
||||
|
||||
@@ -135,6 +135,33 @@ The `id` field is your workspace ID — remember it.
|
||||
|
||||
---
|
||||
|
||||
## Optional — one local MCP bridge, multiple tenants
|
||||
|
||||
If your local agent runtime uses `molecule-mcp`, one process can serve more
|
||||
than one external workspace:
|
||||
|
||||
```bash
|
||||
export MOLECULE_WORKSPACES='[
|
||||
{
|
||||
"id": "workspace-id-local-to-you-org",
|
||||
"token": "...",
|
||||
"platform_url": "https://you.moleculesai.app"
|
||||
},
|
||||
{
|
||||
"id": "different-workspace-id-local-to-team-org",
|
||||
"token": "...",
|
||||
"platform_url": "https://team.moleculesai.app"
|
||||
}
|
||||
]'
|
||||
molecule-mcp
|
||||
```
|
||||
|
||||
Use the workspace ID and token returned by each tenant. The IDs may differ
|
||||
across orgs. `org_id` is not required here because `platform_url` selects the
|
||||
tenant and the token is tenant-scoped.
|
||||
|
||||
---
|
||||
|
||||
## Step 4 — Chat with it
|
||||
|
||||
1. Open your Molecule canvas at `https://<TENANT>`
|
||||
|
||||
@@ -125,6 +125,33 @@ The agent appears on the canvas with a **purple REMOTE badge** within seconds. F
|
||||
|
||||
---
|
||||
|
||||
## Multi-Tenant Local MCP Bridge
|
||||
|
||||
For local MCP-driven agents, use the standalone runtime's `molecule-mcp`
|
||||
entrypoint. A single local bridge can serve multiple external workspaces by
|
||||
setting `MOLECULE_WORKSPACES`:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "workspace-id-local-to-acme",
|
||||
"token": "...",
|
||||
"platform_url": "https://acme.moleculesai.app"
|
||||
},
|
||||
{
|
||||
"id": "different-workspace-id-local-to-ops",
|
||||
"token": "...",
|
||||
"platform_url": "https://ops.moleculesai.app"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
`platform_url` selects the tenant for registration, heartbeat, inbox polling,
|
||||
and outbound A2A routing. `org_id` is not required in this config, and the
|
||||
workspace IDs do not need to match across tenants.
|
||||
|
||||
---
|
||||
|
||||
## What Phase 30 Covers
|
||||
|
||||
| Phase | What shipped | Endpoint |
|
||||
|
||||
Reference in New Issue
Block a user