Open-source managed agents without cloud lock-in.
OpenMaple is an open-source managed-agent control plane for teams that want the Anthropic Managed Agents operating model without binding their stack to one cloud. It gives you sessions, sandboxes, runtime pools, vault-backed tools, model configs, SDKs, CLIs, and audit logs behind stable interfaces.
OpenMaple 是开放的 managed agent 控制面:把 Session、Sandbox、Runtime Pool、Vault、Tool、模型接入点、SDK、CLI 和审计事件流放进同一套可二开的工程栈。
OpenMaple is not an Anthropic official product. It implements the same platform idea in an open stack: decouple the brain from the hands, persist session state, isolate computation, and keep agent harnesses replaceable.
Website · Evaluation guide · Provider readiness · 中文 README · Roadmap · Contributing · Support · Code of Conduct · Security · Latest release · Launch discussion · npm CLI · npm SDK
Screenshots are public-safe captures from the running OpenMaple console. Local Docker proof shots use demo/local test identities only and do not expose secret keys.
Feedback wanted: join the launch discussion to challenge the resource model, provider priorities, and first proof you would need before trying OpenMaple inside an engineering team.
Fastest trial path: run ./scripts/setup-local-docker.sh locally, or open GitHub Codespaces and run the same setup command. You get the web console on http://127.0.0.1:8080/, API, MySQL, local dev login, local Docker runtime pools, and local Docker sandbox pools without E2B, veFaaS, or OAuth credentials. Model keys are only needed when you run real model-backed loops.
Evaluating for an internal platform spike? Start with the 30-minute evaluation guide.
Prefer video first?
The 2-minute OpenMaple platform tour plays on the project site and is also available on YouTube. It is built from the running console and real end-to-end screenshots. The local Docker walkthrough focuses on the one-command setup, workspace settings, runtime/sandbox pools, sessions, and quickstart UI.
| Need to verify | Start here |
|---|---|
| It is a real product surface, not only architecture copy | Watch the 2-minute product tour and inspect real console screenshots. |
| A local managed-agent path can start without cloud credentials | ./scripts/setup-local-docker.sh, then open http://127.0.0.1:8080/. The local stack uses local_docker for both runtime and sandbox pools. |
| The local Docker path is visible end to end | Watch the local Docker walkthrough and inspect the proof screenshots below. |
| It has a coherent managed-agent model | Follow the 30-minute evaluation guide. |
| It keeps provider claims honest | Check provider readiness before assuming an adapter is production-ready. |
| It exposes UI, API, SDK, and CLI paths | Check the SDK, CLI, and API surface below. |
- For platform teams: build a self-hostable managed-agent platform instead of wiring one-off agent demos.
- For enterprise IT: keep cloud identity, runtime, sandbox, storage, and model access behind replaceable provider adapters.
- For engineering teams: start from the web console, automate through REST, then package repeatable workflows with
maple-agent-sdkandmaple-agent-cli. - For local evaluation: run the console, API, MySQL, local Docker runtime pool, and local Docker sandbox pool with Docker Compose before connecting cloud credentials.
- For long-running agents: keep session state outside the model context window and isolate tool execution from credentials.
- For contributors: the public repo includes the console, API, SDK, CLI, provider contracts, and deployable runtime adapters.
Start the control plane, web console, local MySQL database, and local dev login with one command:
./scripts/setup-local-docker.shThe script checks Docker, installs missing macOS packages when possible, creates .env.local, starts the stack, waits for health checks, and prints the URLs.
Open:
Web console: http://127.0.0.1:8080/
Local login: http://127.0.0.1:8080/?dev_login=1
API health: http://127.0.0.1:27951/health
The local stack is self-contained for evaluation: it builds OpenMaple, starts separate web, api, and mysql services, enables local dev login, and persists data in the mysql_data volume. It defaults both the agent runtime provider and sandbox provider to local_docker, mounts the host Docker socket into the API service, and prewarms runtime/sandbox pools without E2B or veFaaS credentials. OAuth/SSO providers are hidden in local Docker mode; model keys are only needed when you run real model-backed agent loops.
Local Docker mode starts with an empty model pool and does not read host provider keys implicitly. To show a default model, copy config/local-model.example.json to config/local-model.json, set base_url, model_name, and api_key_env, then rerun setup. The bundled VolcoEngine presets are not seeded in local Docker mode unless you explicitly set MAPLE_SEED_DEFAULT_MODELS=true.
Optional demo data lives in docker/local-demo-data.sql. Set MAPLE_SEED_DEMO_DATA=true before running the setup script, or set it in .env.local, to import two demo tenants, users, agents, runtime/sandbox pool rows, and sessions.
For host-side tests or scripts, the stack also exposes the API on 127.0.0.1:27951 and MySQL on 127.0.0.1:${MAPLE_MYSQL_HOST_PORT:-3307}.
No local Docker setup? Open GitHub Codespaces, wait for the devcontainer to finish, then run ./scripts/setup-local-docker.sh and npm run smoke:local. Codespaces forwards the web console and API ports for you.
OpenMaple uses different configuration files for local evaluation and cloud deployment:
| File or source | Purpose |
|---|---|
.env.local |
Generated by ./scripts/setup-local-docker.sh. Local Docker evaluation reads this file. Do not use it as a cloud deployment template. |
.env.example |
Minimal local Docker sample plus optional model-key placeholders. Online-only OAuth, veFaaS, TOS, E2B, and MCP client variables are intentionally omitted. |
.env |
Host-side development or self-hosted deployment overrides. Keep service-level database, storage, OAuth, VPC, and registry settings here or in your deployment secret manager. Do not commit this file. Tenant cloud AK/SK normally comes from onboarding, not this file. |
| Deployment environment | Production services can set the same variables through systemd, Kubernetes, Docker Compose, GitHub Actions secrets, or another secret manager. Runtime pool provisioning reads the process environment of the control-plane API. |
Runtime pool provisioning creates Agent Loop Runtime functions. These are not sandbox functions. Runtime pool members run the agent loop (claude_code, codex_open_source, or direct model adapters). Sandbox pool members isolate tool execution and files. Configure and troubleshoot the two pools separately.
Source mode is the default. Leave MAPLE_VEFAAS_IMAGE unset or empty in the control-plane deployment environment:
# MAPLE_VEFAAS_IMAGE=During tenant onboarding, fill Volcengine VOLCENGINE_ACCESS_KEY, VOLCENGINE_SECRET_KEY, and VEFAAS_REGION in the cloud access step. The control plane stores those tenant credentials and passes them to runtime pool provisioning. Do not duplicate tenant AK/SK in the root .env for normal workspace creation.
In source mode the control plane uploads infra/vefaas/runtime-app as a zip package for each runtime pool member. The generated function uses runtime=native-python3.12/v1 and command=./run.sh. run.sh starts app.py; the app listens on _FAAS_RUNTIME_PORT, then SERVER_PORT, then 8000, and installs Python requirements at startup when the base runtime does not already contain them.
Source mode is more portable because users do not need a container registry before first deployment. It can be slower than image mode because every function must upload source and resolve runtime dependencies.
Set MAPLE_VEFAAS_IMAGE only when the cloud account that creates veFaaS functions can read the target container image:
MAPLE_VEFAAS_IMAGE=<registry-domain>/<namespace>/maple-runtime:<version-or-git-sha>In image mode the generated function uses source_type=image, runtime=native/v1, command=/opt/maple-runtime/run.sh, and port=8000. During workspace onboarding, the control plane tries image mode first when MAPLE_VEFAAS_IMAGE is present. If veFaaS rejects the image, for example because the image does not exist or the account has no registry permission, provisioning falls back to source zip mode for that pool member and records the image error in the member config.
Runtime pool members are provisioned concurrently. Tune the fan-out with:
MAPLE_VEFAAS_RUNTIME_PROVISION_CONCURRENCY=4Build and publish a runtime image before setting MAPLE_VEFAAS_IMAGE:
docker build -t maple-vefaas-runtime:ark infra/vefaas/runtime-app
export MAPLE_LOCAL_IMAGE=maple-vefaas-runtime:ark
export MAPLE_VEFAAS_IMAGE=<registry-domain>/<namespace>/maple-runtime:20260622-a1b2c3d4
docker tag "$MAPLE_LOCAL_IMAGE" "$MAPLE_VEFAAS_IMAGE"
docker push "$MAPLE_VEFAAS_IMAGE"Use the full image reference accepted by veFaaS CreateFunction as MAPLE_VEFAAS_IMAGE. The final value has this shape:
<registry-domain>/<namespace>/<repository>:<tag>
Prefer immutable tags such as a release version, build timestamp plus git SHA, or runtime Dockerfile hash. Avoid latest for shared deployments because tenants may create runtime functions against different runtime builds over time.
If you use Volcengine CR, log in to the registry domain before docker push. The helper script infra/vefaas/push_and_release_runtime.py contains the CR login, tag, push, and existing-function release flow. Its release step is for updating existing runtime function IDs; first-time workspace onboarding only needs the image to exist and be readable.
For normal workspace onboarding, set tenant Volcengine credentials in the UI/API onboarding flow. Configure runtime-pool networking with runtime-scoped variables in the control-plane API process environment:
MAPLE_VEFAAS_RUNTIME_VPC_ID=vpc-...
MAPLE_VEFAAS_RUNTIME_SUBNET_IDS=subnet-...,subnet-...
MAPLE_VEFAAS_RUNTIME_SECURITY_GROUP_IDS=sg-...
MAPLE_VEFAAS_RUNTIME_ENABLE_SHARED_INTERNET_ACCESS=trueThe MAPLE_VEFAAS_BACKEND_* variables are for infra/vefaas/deploy_vefaas_application.py, which deploys the OpenMaple control-plane backend to veFaaS. Do not use those names as runtime pool configuration. If the deployed backend must reach MySQL through a different private endpoint, set that backend function's MAPLE_MYSQL_HOST during application deployment rather than duplicating host values in the root .env.
When you run infra/vefaas/deploy_vefaas_runtime.py directly outside tenant/workspace onboarding, provide Volcengine credentials in that shell or CI job:
VOLCENGINE_ACCESS_KEY=...
VOLCENGINE_SECRET_KEY=...
MAPLE_VEFAAS_REGION=cn-beijingRuntime pool min/max instances come from the runtime pool configuration selected during workspace creation. The control plane passes them to veFaaS resource updates for each generated function. When you run infra/vefaas/deploy_vefaas_runtime.py directly outside workspace onboarding, these variables provide the script fallback values:
MAPLE_RUNTIME_FUNCTION_MIN_INSTANCES=0
MAPLE_RUNTIME_FUNCTION_MAX_INSTANCES=10Use one MAPLE_MYSQL_HOST per process. A local control-plane process usually needs a public/VPN-reachable host. A deployed veFaaS control-plane backend can use a private MySQL host, but inject it as that backend process's MAPLE_MYSQL_HOST.
These HD screenshots come from the same running local Docker stack used for the current E2E proof: setup script, dashboard, workspace settings, local runtime/sandbox pools, sessions, and quickstart. Each image is captured at 5120x2880 from the real product UI.
| Setup + smoke | Demo workspace |
|---|---|
![]() |
![]() |
| Settings overview | Runtime provider |
![]() |
![]() |
| Runtime pool members | Sandbox provider |
![]() |
![]() |
| Sandbox pool members | Sessions list |
![]() |
![]() |
| Session timeline | Quickstart |
![]() |
![]() |
Clone the repo, fill a workspace API key plus one agent/environment pair, then run one managed-agent session through the repo SDK source:
cp examples/minimal-sdk-run/.env.example examples/minimal-sdk-run/.env
node examples/minimal-sdk-run/index.mjsSee examples/minimal-sdk-run for required variables and expected output.
Anthropic Managed Agents turns agent deployment into a platform problem: keep the model loop, tool execution, state, credentials, sandboxing, and orchestration behind stable interfaces. OpenMaple takes that operating model and makes the control plane open, self-hostable, and provider-portable.
| Managed-agent concern | OpenMaple primitive | Why it matters |
|---|---|---|
| Define what the agent is | Agent |
Model, system prompt, tools, MCP servers, skills, and loop type are versioned as a managed resource. |
| Decide where it runs | Environment |
Separates AgentRuntime from SandboxRuntime, so reasoning and tool execution can move independently. |
| Keep work durable | Session + event log |
User messages, tool calls, status changes, artifacts, and failures become replayable state, not terminal scrollback. |
| Keep secrets scoped | Vault + secret_ref |
Agents receive credential references instead of raw secrets; workspaces decide which vaults sessions can use. |
| Operate repeatably | Deployment |
Persist an agent, environment, initial message, and schedule into a reusable launch template. |
| Expose stable interfaces | Console, REST API, SDK, CLI | Users can start in the UI, automate with API calls, then package repeatable workflows through maple-agent-cli. |
flowchart LR
subgraph Interfaces
Console[Web Console]
CLI[Maple CLI]
SDK[Node SDK]
REST[REST API]
end
subgraph Control["Control Plane"]
API[Express API]
DB[(Remote MySQL)]
Vault[Vault + Secret Store]
Events[Session Event Log]
end
subgraph Runtime["Runtime Plane"]
Claude[Claude Code Loop]
Codex[Codex Loop]
Direct[Direct Provider Loop]
Pool[Runtime Pool]
end
subgraph Sandbox["Sandbox Plane"]
E2B[E2B]
VeFaaS[veFaaS Sandbox]
Docker[Local Docker]
end
Console --> API
CLI --> API
SDK --> API
REST --> API
API --> DB
API --> Vault
API --> Events
API --> Pool
Pool --> Claude
Pool --> Codex
Pool --> Direct
Claude --> Sandbox
Codex --> Sandbox
Direct --> Sandbox
Sandbox --> E2B
Sandbox --> VeFaaS
Sandbox --> Docker
- Create an agent:
POST /v1/agentsstores the model, prompt, tools, MCP servers, skills, and loop adapter. - Attach an environment:
POST /v1/environmentschooses runtime provider, sandbox provider, networking, and runtime pool behavior. - Add tool credentials:
POST /v1/vaults/:vaultId/credentialswrites encrypted secret material and returns credential references. - Start a session:
POST /v1/sessionsbindsagent,environment_id, optionalvault_ids, resources, and metadata. - Send and stream work:
POST /v1/sessions/:sessionId/eventswrites user/tool events;GET /v1/sessions/:sessionId/events/streamexposes the live timeline. - Operate repeatably:
POST /v1/deploymentssaves the same launch path as a manual or scheduled run template.
| Area | Endpoints | Notes |
|---|---|---|
| Auth/bootstrap | /v1/auth/*, /v1/bootstrap, /v1/console_snapshot |
Cookie or API-key auth; list endpoints are workspace-scoped. |
| Agents | /v1/agents, /v1/agents/:agentId/versions, /v1/agents/:agentId/runtime |
Agent configs are versioned and runtime state is inspectable. |
| Environments | /v1/environments, /v1/workspaces/:workspaceId/runtime_pool, /v1/workspaces/:workspaceId/sandbox_pool |
Runtime pool members provision in the background. |
| Sessions | /v1/sessions, /v1/sessions/:sessionId/events, /v1/sessions/:sessionId/events/stream |
Durable event log for user, agent, tool, artifact, and failure records. |
| Vaults + MCP | /v1/vaults, /v1/vaults/:vaultId/credentials, /v1/mcp_servers, /v1/mcp_servers/:mcpId/oauth/start |
OAuth and API-key credentials stay workspace-scoped. |
| Deployments | /v1/deployments, /v1/deployments/:deploymentId/run, /v1/deployments/:deploymentId/invoke |
Reusable launch templates with manual and scheduled execution. |
| Files + artifacts | /v1/files, /v1/sessions/:sessionId/files, /v1/sessions/:sessionId/artifacts |
Session file uploads and downloadable artifacts. |
| Skills + memory | /v1/skills, /v1/memory_stores, /v1/memory_stores/:memoryStoreId/memories/*path |
Packaged instructions and workspace-scoped persistent memory. |
| Claim | Evidence |
|---|---|
| Control plane is implemented | Express routes under apps/control-plane-api/src/routes/ and typed SDK calls in packages/sdk/. |
| Runtime and sandbox are separate | Environment and runtime pool contracts, veFaaS/E2B/Docker provider paths, and session event streaming. |
| API, SDK, and CLI are first-class | maple-agent-sdk, maple-agent-cli, route contracts, and package tests. |
| Provider lock-in is not the model | Runtime, sandbox, storage, model, and cloud identity are represented as provider choices. |
- Brain/hands split: agent loops run through runtime adapters; commands, files, and network access run through sandbox providers.
- Secret isolation: secrets are stored through
secret_refrecords; agents receive references and scoped tool access, not plaintext keys in config. - Workspace scoping: every list route must filter through the user's accessible workspaces. No global table scans in user-facing APIs.
- Remote MySQL: the control-plane data store uses a MySQL worker bridge with pooled remote connections.
- Provider portability: veFaaS, E2B, Docker, and future Lambda/FC-style runtimes can sit behind the same session contract.
| Quickstart builder | Agents registry |
|---|---|
![]() |
![]() |
| Runtime environments | Credential vaults |
![]() |
![]() |
- Quickstart: generate an agent draft, bind an environment, attach vaults, and start a session.
- Agents: version agent configs, tools, MCP servers, skills, models, and loop type.
- Deployments: persist reusable launch templates and invoke them through API/CLI/SDK paths.
- Sessions: inspect transcript, event log, status, runtime metadata, files, and artifacts.
- Environments: configure runtime provider, sandbox provider, pool behavior, and workspace defaults.
- Vaults: attach credentials by reference without exposing raw secret material in API responses.
apps/admin-web/ React console, docs view, route sync, design system
apps/control-plane-api/ Express API, auth, storage, runtime orchestration
packages/sdk/ Node SDK: MapleClient and typed API helpers
packages/cli/ Maple CLI: init, build, deploy, api, session, vault
agents/ Packaged agent skills and runtime-facing assets
tests/contracts/ Contract tests for docs, routes, branding, runtime behavior
bun install
bun run devOpen:
Web Console: http://127.0.0.1:8080/
API Server: http://127.0.0.1:27951/
Verify:
bun run typecheck
bun run lint
bun run buildLocal Docker stack:
./scripts/setup-local-docker.sh
npm run smoke:local -- --base http://127.0.0.1:27951
curl http://127.0.0.1:27951/health
curl http://127.0.0.1:8080/healthThe local stack runs web, api, and mysql as separate services. .env.example contains only local Docker settings and optional model keys; online-only OAuth, veFaaS, TOS, E2B, and MCP client variables are intentionally omitted from the default local setup.
npm install -g maple-agent-cli
maple config set api.baseUrl http://127.0.0.1:27951
maple config login --api-key <maple_ws_...>
maple init --name repo-auditor --loop codex_open_source --runtime e2b --yes
maple build --project ./repo-auditor
maple deploy --project ./repo-auditor --jsonnpm install maple-agent-sdkimport { MapleClient } from "maple-agent-sdk";
const client = new MapleClient({
baseUrl: process.env.MAPLE_BASE_URL,
apiKey: process.env.MAPLE_API_KEY
});
const { session, done } = await client.createSessionAndStream({
agent: "agent_...",
environment_id: "env_...",
vault_ids: ["vault_..."],
message: "Audit this repository and summarize the risky files."
});
await client.sendSessionMessage(session.id, "Focus on auth and storage code paths.");
await done;- Managed Agents platform pattern: Anthropic engineering essay














