MCPcopy Index your code
hub / github.com/cloudflare/claude-managed-agents

github.com/cloudflare/claude-managed-agents @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
1,238 symbols 2,126 edges 84 files 131 documented · 11%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Claude Managed Agents on Cloudflare

Run Claude Managed Agents (CMA) on Cloudflare.

This repo provides a customizable control plane that allows you to: - Run CMA sandboxes on both full containers and light-weight isolates - Customize the container size and image your agents use - Get better observability into agent sandboxes - Apply custom egress controls for zero-trust credential injection and connectivity to private services over Workers VPC - Extend your Agents with Browser Run, Email, and any other custom tools using the Cloudflare Developer Platform your needs.

Follow the Onboarding Guide to get started. Two deployment styles are supported: a one-click Deploy to Cloudflare button (git-based, runs in Workers Builds) and a terminal-based npm run deploy flow from your laptop.

[!IMPORTANT] You need a Paid or Enterprise Cloudflare account to run Managed Agents. Cloudflare Containers (used by the MicroVM sandbox) and Worker Loader bindings (used by the Isolate sandbox's code-execution and egress proxy tools) are Workers Paid plan and above.

Overview

This repository deploys a Workers-based control plane for running Claude Managed Agents on Cloudflare.

Claude Managed Agents will send a webhook to your Worker when an agent session begin or ends. The control plane spins up a sandbox for each session, syncs state across session sleeps, and shuts down the sandbox when the session ends.

Sandboxes can be Cloudflare Containers or Isolate sandboxes using the AgentsSDK. This allows you to get either the full functionality of a Linux VM or a lightweight isolate that can hit massive scales without the resource overhead or cost of a microVM.

You can configure policies to restrict agent access to specific domains, inject credentials into outgoing requests without the agent ever accessing secrets, or write arbitrary proxy code to modify, reroute, or log egress traffic.

Additionally, you can connect Workers VPC and Mesh resources to your sandboxes. This allows you to easily access private resources, on any cloud or on-prem, without them ever being exposed to the public internet.

Lastly, this codebase can be easily extended to add custom tools to your agent's sandbox. Tools are picked up automatically by both backends and run with direct access to Worker bindings so they can take advantage of the whole Cloudflare Developer Platform.

The repo provides built-in tools for: - Email Sending - Private Service Access - Browser Automation - Image Generation

All of this is accessible via a UI and API that gets deployed to your Cloudflare account.

With the repository you should be able to get a Cloudflare-based self-managed environment up and running quickly. Then you can fork it, customize it to suit your needs, and redeploy. This repository is meant as a starting point.

[!IMPORTANT] You should consider this repository alpha software. It is not yet stable and may contain bugs.

Onboarding guide

Order matters — work through the steps top to bottom.

[!IMPORTANT] Step 8 is vital to securing your workload in production. Until you add auth, anybody with access to your Workers URL can start sessions via the Claude Platform.

Pick a deployment style

There are two ways to deploy. Pick one and stick with it for the whole onboarding:

  • Git-based. Click the Deploy to Cloudflare button. Cloudflare forks this repo into your GitHub account, deploys your control plane and then future pushes to this GitHub repo will deploy updates automatically.
  • Terminal-based. Run npm run deploy from your laptop. Requires Docker (for the container image build) and a wrangler login session.

Steps 1 and 3 differ between the two tracks — each has separate sub-sections below. Steps 2 and 4 through 9 are identical regardless of how you deployed.


Step 1. Initial deploy

Git-based

The Deploy to Cloudflare button forks this repo into your GitHub account, provisions the D1 database, KV namespaces, R2 bucket, and Durable Objects automatically, prompts you for the required secrets (see Step 2), and deploys the Worker via Workers Builds.

After the deploy finishes you'll have a https://<your-worker>.workers.dev URL you'll need in step 2.

Deploy to Cloudflare

⚠️ You must rename one of the two KV namespaces in the deploy form. The "Configure resources" step pre-fills both SECRETS and EGRESS_POLICIES with the same default name, and the deploy will fail with Cannot provision a KV Namespace ... because it already exists if you don't change one. Suggested names: <worker-name>-secrets and <worker-name>-egress-policies.

The worker won't function until you finish the remaining steps.

Terminal-based

npm run deploy

npm run deploy builds your base sandbox container image (Docker required), deploys the Worker, and applies D1 migrations via the postdeploy hook. The committed wrangler.jsonc deliberately leaves KV id fields and the D1 database_id empty — scripts/ensure-kv.mjs and scripts/ensure-d1.mjs run on prebuild and patch the real IDs in (adopting any namespaces / databases that already exist by name, creating fresh ones otherwise). R2 buckets are bound by name (no ID lookup needed) and are auto-created by wrangler.

If you're on a Cloudflare login that has access to more than one account, set CLOUDFLARE_ACCOUNT_ID before running so the ensure scripts know which account to talk to:

export CLOUDFLARE_ACCOUNT_ID=<your-account-id>
npm run deploy

The worker won't function until you finish the remaining steps, but the deploy gives you the https://<your-worker>.workers.dev URL you'll need for the webhook.


Step 2. Create an Anthropic environment and webhook

Create a "Self-managed" environment in the Claude Platform Console and save the environment secret key. Then, in the Webhooks settings, set the webhook URL to https://<your-worker>.workers.dev/webhooks and save the generated Webhook Secret.

You will need the following values:

  • ENVIRONMENT_ID — the ID of your new self-managed environment
  • ANTHROPIC_ENVIRONMENT_KEY — environment secret key used by the control plane to authenticate calls from the specified Claude agent environment
  • ANTHROPIC_API_KEY — used by the Worker to make calls to Anthropic
  • WEBHOOK_SECRET — Standard Webhooks signing secret. Anthropic posts events to your Worker; we verify the signature before doing anything with them.

Step 3. Set the secrets

Git-based

The Deploy to Cloudflare form prompted for the core secrets when you deployed, so ENVIRONMENT_ID, ANTHROPIC_ENVIRONMENT_KEY, and ANTHROPIC_API_KEY are already on your Worker. If not, add them with npx wrangler secret put as well.

Two follow-ups:

  1. Re-add WEBHOOK_SECRET. The webhook didn't exist yet when you deployed (you created it in step 2), so whatever placeholder you supplied in the form is wrong. Push the real value now:

sh npx wrangler secret put WEBHOOK_SECRET

  1. Copy the secret values into .dev.vars for local development. Workers Builds doesn't sync your form inputs back to the repo, so wrangler dev won't see them otherwise.

sh cp .dev.vars.example .dev.vars # Edit .dev.vars and paste the values you supplied in the form, # plus the real WEBHOOK_SECRET from step 2.

Terminal-based

Set up local dev:

cp .dev.vars.example .dev.vars
# Edit with your real values

In production, every entry in .dev.vars needs a matching wrangler secret put NAME. The four core secrets are:

npx wrangler secret put ENVIRONMENT_ID
npx wrangler secret put ANTHROPIC_ENVIRONMENT_KEY
npx wrangler secret put ANTHROPIC_API_KEY
npx wrangler secret put WEBHOOK_SECRET

Step 4. Apply D1 migrations

The postdeploy hook runs wrangler d1 migrations apply DB --remote automatically after every npm run deploy (including the Deploy to Cloudflare button's deploy), so there's nothing to do here for production. For local dev:

npm run db:migrate          # local

Step 5. Provision R2 snapshot credentials

The R2 bucket itself was auto-created in step 1. The presigned-URL path used in production still needs an access key. If you provided R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY / BACKUP_BUCKET_NAME / CLOUDFLARE_ACCOUNT_ID during the Deploy to Cloudflare form, you can skip ahead — they're already set.

This is required unless you're exclusively using Isolate sandboxes or running stateless agent sessions. Isolate sessions persist through Durable Object SQLite storage and don't need R2 — if you're certain you'll never run a MicroVM agent, you can skip this step (and drop the r2_buckets block from wrangler.jsonc).

Anyone running the MicroVM backend should treat this as core onboarding.

Mint an R2 access key with read+write on the claude-managed-agents-snapshots bucket (Cloudflare dashboard → R2 → Manage R2 API Tokens → Create token), copy the Access Key ID and Secret Access Key, then push the following secrets:

npx wrangler secret put R2_ACCESS_KEY_ID
npx wrangler secret put R2_SECRET_ACCESS_KEY
npx wrangler secret put BACKUP_BUCKET_NAME # same as bucket_name in wrangler.jsonc (IE: claude-managed-agents-snapshots)
npx wrangler secret put CLOUDFLARE_ACCOUNT_ID # found in your dashboard URL

See Snapshots & state persistence for more information.


Step 6. (Optional) Turn on the extras

Browser Rendering, Workers AI, and Email send are wired up out of the box — disable in wrangler.jsonc if you don't want them. VPC bindings are opt-in.

Capability Default Bindings Secrets to add Setup steps
Browser Rendering tools on browser in wrangler.jsonc CLOUDFLARE_API_TOKEN (for REST tools) none
Workers AI image gen on ai in wrangler.jsonc none none
Email send + inbox on send_email in wrangler.jsonc; set EMAIL_DOMAIN + EMAIL_FROM (Deploy to Cloudflare prompts for these, or vars in wrangler.jsonc locally) none Email docs
VPC private services off add vpc_services blocks in wrangler.jsonc none Workers VPC docs

Step 7. Visit the dashboard

https://<your-worker>.workers.dev/. Create an agent (the form lets you pick MicroVM or Isolate backend), kick off a session, watch the logs.


Step 8. Secure the dashboard

Your control plane is not secured by default!

Once you have set things up, you will want to secure the dashboard by setting up Cloudflare Access.

See Cloudflare Access docs for more information.


Step 9. Customize the control plane (optional)

Fork this repo and modify it to suit your needs or add custom tools.

Going deeper

Once the control plane is up and a first session has run end-to-end, you can go futher:

Configuration reference

Required secrets & vars:

Name Description
ENVIRONMENT_ID Environment to poll for work
ANTHROPIC_ENVIRONMENT_KEY Anthropic environment key (sk-ant-oat01-...). The single credential the control plane uses for poll, ack, heartbeat, force-stop, and the session event stream. Renamed from ANTHROPIC_ENV_KEY in the 0.96 SDK / ant 1.8 CLI.
ANTHROPIC_API_KEY Anthropic API key (sk-ant-...)
WEBHOOK_SECRET HMAC secret for verifying webhook signatures
CLOUDFLARE_ACCOUNT_ID R2 snapshots (pr

Extension points exported contracts — how you extend this code

ServiceWorkerGlobalScope (Interface)
* The **`ServiceWorkerGlobalScope`** interface of the Service Worker API represents the global execution context of a se
worker-configuration.d.ts
FetcherLike (Interface)
(no doc) [1 implementers]
src/egress/handler.ts
Toast (Interface)
(no doc)
frontend/src/toasts.tsx
VpcBinding (Interface)
(no doc)
src/vpc.ts
HeartbeatLoopOpts (Interface)
(no doc)
src/heartbeat.ts
ForwardableEmailMessage (Interface)
(no doc)
src/email-handler.ts
WebhookEvent (Interface)
(no doc)
src/storage.ts
Env (Interface)
(no doc)
src/env.d.ts

Core symbols most depended-on inside this repo

json
called by 88
worker-configuration.d.ts
get
called by 74
src/egress/handler.ts
warn
called by 62
worker-configuration.d.ts
makeEnv
called by 56
tests/helpers.ts
log
called by 54
worker-configuration.d.ts
error
called by 36
worker-configuration.d.ts
request
called by 34
frontend/src/api.ts
replace
called by 32
worker-configuration.d.ts

Shape

Interface 502
Function 351
Method 288
Class 97

Languages

TypeScript100%

Modules by API surface

worker-configuration.d.ts766 symbols
src/storage.ts36 symbols
src/isolate/runner.ts22 symbols
frontend/src/api.ts21 symbols
frontend/src/App.tsx19 symbols
frontend/src/views/EgressView.tsx18 symbols
src/isolate/custom-dispatch.ts17 symbols
src/email-handler.ts17 symbols
tests/helpers.ts16 symbols
src/microvm/sandbox.ts16 symbols
frontend/src/utils.ts14 symbols
src/tools/cf/shared.ts13 symbols

For agents

$ claude mcp add claude-managed-agents \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact