[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-77643":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":8,"htmlUrl":8,"language":9,"languages":8,"totalLinesOfCode":8,"stars":10,"forks":11,"watchers":12,"openIssues":12,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":12,"stars7d":14,"stars30d":15,"stars90d":13,"forks30d":13,"starsTrendScore":16,"compositeScore":17,"rankGlobal":8,"rankLanguage":8,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":21,"hasPages":19,"topics":22,"createdAt":8,"pushedAt":8,"updatedAt":23,"readmeContent":24,"aiSummary":25,"trendingCount":13,"starSnapshotCount":13,"syncStatus":26,"lastSyncTime":27,"discoverSource":28},77643,"claude-managed-agents","cloudflare\u002Fclaude-managed-agents","cloudflare",null,"TypeScript",215,30,1,0,16,157,7,4.47,"MIT License",false,"main",true,[],"2026-06-12 02:03:43","# Claude Managed Agents on Cloudflare\n\nRun Claude Managed Agents (CMA) on Cloudflare.\n\nThis repo provides a customizable control plane that allows you to:\n- Run CMA sandboxes on both full containers and light-weight isolates\n- Customize the container size and image your agents use\n- Get better observability into agent sandboxes\n- Apply custom egress controls for [zero-trust credential injection](https:\u002F\u002Fblog.cloudflare.com\u002Fsandbox-auth\u002F) and connectivity to private services over [Workers VPC](https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers-vpc\u002F)\n- Extend your Agents with [Browser Run](https:\u002F\u002Fdevelopers.cloudflare.com\u002Fbrowser-run), [Email](https:\u002F\u002Fdevelopers.cloudflare.com\u002Femail-service\u002F), and any other custom tools using the [Cloudflare Developer Platform](https:\u002F\u002Fworkers.cloudflare.com\u002Fproducts#all)\n your needs.\n\nFollow the [Onboarding Guide](#onboarding-guide) to get started. Two\ndeployment styles are supported: a one-click Deploy to Cloudflare\nbutton (git-based, runs in Workers Builds) and a terminal-based\n`npm run deploy` flow from your laptop.\n\n> **You need a Paid or Enterprise Cloudflare account to run Managed Agents.**\n> [Cloudflare Containers](https:\u002F\u002Fdevelopers.cloudflare.com\u002Fcontainers\u002F)\n> (used by the MicroVM sandbox) and Worker Loader bindings (used by the\n> Isolate sandbox's code-execution and egress proxy tools) are **Workers\n> Paid plan and above**.\n\n## Overview\n\nThis repository deploys a Workers-based control plane for running Claude Managed Agents on Cloudflare.\n\nClaude Managed Agents will send a webhook to your Worker when an agent session begin or ends. The\ncontrol plane spins up a sandbox for each session, syncs state across session sleeps, and shuts down\nthe sandbox when the session ends.\n\nSandboxes can be [Cloudflare Containers](https:\u002F\u002Fdevelopers.cloudflare.com\u002Fcontainers\u002F) or [Isolate](https:\u002F\u002Fdevelopers.cloudflare.com\u002Fdynamic-workers\u002F) sandboxes using the [AgentsSDK](https:\u002F\u002Fdevelopers.cloudflare.com\u002Fagents\u002F). This\nallows you to get either the full functionality of a Linux VM or a lightweight isolate\nthat can hit massive scales without the resource overhead or cost of a microVM.\n\nYou can configure policies to restrict agent access to specific domains, inject credentials into outgoing\nrequests without the agent ever accessing secrets, or write arbitrary proxy code to modify, reroute,\nor log egress traffic.\n\nAdditionally, you can connect [Workers VPC](https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers-vpc\u002F) and [Mesh](https:\u002F\u002Fdevelopers.cloudflare.com\u002Fworkers-vpc\u002Fexamples\u002Fconnect-to-cloudflare-mesh\u002F) resources to your sandboxes. This allows you\nto easily access private resources, on any cloud or on-prem, without them ever being exposed to the public internet.\n\nLastly, this codebase can be easily extended to add custom tools to your agent's sandbox. Tools are picked up\nautomatically by both backends and run with direct access to Worker bindings so they can take advantage of\nthe whole Cloudflare Developer Platform.\n\nThe repo provides built-in tools for:\n- Email Sending\n- Private Service Access\n- Browser Automation\n- Image Generation\n\nAll of this is accessible via a UI and API that gets deployed to your Cloudflare account.\n\nWith the repository you should be able to get a Cloudflare-based self-managed environment up and\nrunning quickly. Then you can fork it, customize it to suit your needs, and redeploy. This repository is\nmeant as a starting point.\n\n## Onboarding guide\n\nOrder matters — work through the steps top to bottom.\n\n### Pick a deployment style\nThere are two ways to deploy. Pick one and stick with it for the whole onboarding:\n\n- **Git-based**. Click the [Deploy to Cloudflare](#step-1-initial-deploy) button.\n  Cloudflare forks this repo into your GitHub account, deploys your control plane\n  and then future pushes to this GitHub repo will deploy updates automatically.\n- **Terminal-based**. Run `npm run deploy` from your laptop. Requires\n  Docker (for the container image build) and a `wrangler login`\n  session.\n\n**Steps 1 and 3 differ between the two tracks** — each has separate\nsub-sections below. Steps 2 and 4 through 9 are identical regardless\nof how you deployed.\n\n---\n\n### Step 1. Initial deploy\n\n#### Git-based\n\nThe Deploy to Cloudflare button forks this repo into your GitHub account,\nprovisions the D1 database, KV namespaces, R2 bucket, and Durable Objects\nautomatically, prompts you for the required secrets (see Step 2), and\ndeploys the Worker via Workers Builds.\n\nAfter the deploy finishes you'll have a `https:\u002F\u002F\u003Cyour-worker>.workers.dev`\nURL you'll need in step 2.\n\n[![Deploy to Cloudflare](https:\u002F\u002Fdeploy.workers.cloudflare.com\u002Fbutton)](https:\u002F\u002Fdeploy.workers.cloudflare.com\u002F?url=https:\u002F\u002Fgithub.com\u002Fcloudflare\u002Fclaude-managed-agents)\n\n> ⚠️ **You must rename one of the two KV namespaces in the deploy\n> form.** The \"Configure resources\" step pre-fills both `SECRETS`\n> and `EGRESS_POLICIES` with the same default name, and the deploy\n> will fail with `Cannot provision a KV Namespace ... because it\n> already exists` if you don't change one. Suggested names:\n> `\u003Cworker-name>-secrets` and `\u003Cworker-name>-egress-policies`.\n\nThe worker won't function until you finish the remaining steps.\n\n#### Terminal-based\n\n```sh\nnpm run deploy\n```\n\n`npm run deploy` builds your base sandbox container image (Docker\nrequired), deploys the Worker, and applies D1 migrations via the\n`postdeploy` hook. The committed `wrangler.jsonc` deliberately leaves\nKV `id` fields and the D1 `database_id` empty — `scripts\u002Fensure-kv.mjs`\nand `scripts\u002Fensure-d1.mjs` run on `prebuild` and patch the real IDs\nin (adopting any namespaces \u002F databases that already exist by name,\ncreating fresh ones otherwise). R2 buckets are bound by name (no ID\nlookup needed) and are auto-created by wrangler.\n\nIf you're on a Cloudflare login that has access to more than one\naccount, set `CLOUDFLARE_ACCOUNT_ID` before running so the ensure\nscripts know which account to talk to:\n\n```sh\nexport CLOUDFLARE_ACCOUNT_ID=\u003Cyour-account-id>\nnpm run deploy\n```\n\nThe worker won't function until you finish the remaining steps, but\nthe deploy gives you the `https:\u002F\u002F\u003Cyour-worker>.workers.dev` URL\nyou'll need for the webhook.\n\n---\n\n### Step 2. Create an Anthropic environment and webhook\n\nCreate a \"Self-managed\" environment in the\n[Claude Platform Console](https:\u002F\u002Fplatform.claude.com\u002Fworkspaces\u002Fdefault\u002Fenvironments)\nand save the environment secret key. Then, in the\n[Webhooks settings](https:\u002F\u002Fplatform.claude.com\u002Fsettings\u002Fworkspaces\u002Fdefault\u002Fwebhooks),\nset the webhook URL to `https:\u002F\u002F\u003Cyour-worker>.workers.dev\u002Fwebhooks`\nand save the generated Webhook Secret.\n\nYou will need the following values:\n\n- `ENVIRONMENT_ID` — the ID of your new self-managed environment\n- `ANTHROPIC_ENVIRONMENT_KEY` — environment secret key used by the\n  control plane to authenticate calls from the specified Claude agent\n  environment\n- `ANTHROPIC_API_KEY` — used by the Worker to make calls to Anthropic\n- `WEBHOOK_SECRET` — Standard Webhooks signing secret. Anthropic\n  posts events to your Worker; we verify the signature before doing\n  anything with them.\n\n---\n\n### Step 3. Set the secrets\n\n#### Git-based\n\nThe Deploy to Cloudflare form prompted for the core secrets when you\ndeployed, so `ENVIRONMENT_ID`, `ANTHROPIC_ENVIRONMENT_KEY`, and\n`ANTHROPIC_API_KEY` are already on your Worker. If not,\nadd them with `npx wrangler secret put` as well.\n\nTwo follow-ups:\n\n1. **Re-add `WEBHOOK_SECRET`.** The webhook didn't exist yet when\n   you deployed (you created it in step 2), so whatever placeholder\n   you supplied in the form is wrong. Push the real value now:\n\n   ```sh\n   npx wrangler secret put WEBHOOK_SECRET\n   ```\n\n2. **Copy the secret values into `.dev.vars` for local development.**\n   Workers Builds doesn't sync your form inputs back to the repo, so\n   `wrangler dev` won't see them otherwise.\n\n   ```sh\n   cp .dev.vars.example .dev.vars\n   # Edit .dev.vars and paste the values you supplied in the form,\n   # plus the real WEBHOOK_SECRET from step 2.\n   ```\n\n#### Terminal-based\n\nSet up local dev:\n\n```sh\ncp .dev.vars.example .dev.vars\n# Edit with your real values\n```\n\nIn production, every entry in `.dev.vars` needs a matching\n`wrangler secret put NAME`. The four core secrets are:\n\n```sh\nnpx wrangler secret put ENVIRONMENT_ID\nnpx wrangler secret put ANTHROPIC_ENVIRONMENT_KEY\nnpx wrangler secret put ANTHROPIC_API_KEY\nnpx wrangler secret put WEBHOOK_SECRET\n```\n\n---\n\n### Step 4. Apply D1 migrations\n\nThe `postdeploy` hook runs `wrangler d1 migrations apply DB --remote`\nautomatically after every `npm run deploy` (including the Deploy to\nCloudflare button's deploy), so there's nothing to do here for\nproduction. For local dev:\n\n```sh\nnpm run db:migrate          # local\n```\n\n---\n\n### Step 5. Provision R2 snapshot credentials\n\nThe R2 bucket itself was auto-created in step 1. The presigned-URL\npath used in production still needs an access key. If you provided\n`R2_ACCESS_KEY_ID` \u002F `R2_SECRET_ACCESS_KEY` \u002F `BACKUP_BUCKET_NAME` \u002F\n`CLOUDFLARE_ACCOUNT_ID` during the Deploy to Cloudflare form, you\ncan skip ahead — they're already set.\n\nThis is required unless you're exclusively using Isolate sandboxes\nor running stateless agent sessions. Isolate sessions persist through\nDurable Object SQLite storage and don't need R2 — if you're certain\nyou'll never run a MicroVM agent, you can skip this step (and drop\nthe `r2_buckets` block from `wrangler.jsonc`).\n\nAnyone running the MicroVM backend should treat this as core\nonboarding.\n\n[Mint an R2 access key](https:\u002F\u002Fdash.cloudflare.com?to=\u002F:account\u002Fr2\u002Fapi-tokens\u002Fcreate?type=user)\nwith read+write on the `claude-managed-agents-snapshots` bucket\n(Cloudflare dashboard → R2 → Manage R2 API Tokens → Create token),\ncopy the Access Key ID and Secret Access Key, then push the\nfollowing secrets:\n\n```sh\nnpx wrangler secret put R2_ACCESS_KEY_ID\nnpx wrangler secret put R2_SECRET_ACCESS_KEY\nnpx wrangler secret put BACKUP_BUCKET_NAME # same as bucket_name in wrangler.jsonc (IE: claude-managed-agents-snapshots)\nnpx wrangler secret put CLOUDFLARE_ACCOUNT_ID # found in your dashboard URL\n```\n\nSee [Snapshots & state persistence](.\u002Fdocs\u002Fsnapshots-and-state-persistence.md)\nfor more information.\n\n---\n\n### Step 6. (Optional) Turn on the extras\n\nBrowser Rendering, Workers AI, and Email send are wired up out of the\nbox — disable in `wrangler.jsonc` if you don't want them. VPC bindings\nare opt-in.\n\n| Capability | Default | Bindings | Secrets to add | Setup steps |\n|---|---|---|---|---|\n| Browser Rendering tools | on | `browser` in `wrangler.jsonc` | `CLOUDFLARE_API_TOKEN` (for REST tools) | none |\n| Workers AI image gen | on | `ai` in `wrangler.jsonc` | none | none |\n| 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](.\u002Fdocs\u002Fagent-email.md) |\n| VPC private services | off | add `vpc_services` blocks in `wrangler.jsonc` | none | [Workers VPC docs](.\u002Fdocs\u002Fconnecting-to-private-services.md) |\n\n---\n\n### Step 7. Visit the dashboard\n\n`https:\u002F\u002F\u003Cyour-worker>.workers.dev\u002F`. Create an agent (the form lets\nyou pick MicroVM or Isolate backend), kick off a session, watch the\nlogs.\n\n---\n\n### Step 8. Secure the dashboard\n\n**Your control plane is not secured by default!**\n\nOnce you have set things up, you will want to secure the dashboard\nby setting up Cloudflare Access.\n\nSee [Cloudflare Access docs](.\u002Fdocs\u002Fsecuring-access.md) for more\ninformation.\n\n---\n\n### Step 9. Customize the control plane (optional)\n\nFork this repo and modify it to suit your needs or add custom\ntools.\n\n## Going deeper\n\nOnce the control plane is up and a first session has run end-to-end,\nyou can go futher:\n\n- [Connect to Private Services](.\u002Fdocs\u002Fconnecting-to-private-services.md)\n  in other clouds or on-prem (or even on your laptop) with Workers VPC bindings.\n- [Inject credentials and lock down agent sessions](.\u002Fdocs\u002Fapplying-egress-policies.md)\n  with egress policies. Set up allow\u002Fdeny lists, header-injection, custom Worker proxies,\n  and VPC routing.\n- [Pick between Isolate and VM-based Sandboxes](.\u002Fdocs\u002Fisolate-vs-vm-sandboxes.md)\n  for the best agent execution environment.\n- [Set up Agent Email](.\u002Fdocs\u002Fagent-email.md) to give your\n  new agents email addresses and sending abilities.\n- [Use Browser Run](.\u002Fdocs\u002Fbrowser-rendering-tools.md) to get\n  powerful and observable and agent browser interactions.\n- [Add Custom Tools](.\u002Fdocs\u002Fadding-custom-tools.md) New tools are declared in a single\n  file — [`src\u002Ftools\u002Fcustom-tools.ts`](.\u002Fsrc\u002Ftools\u002Fcustom-tools.ts).\n- [Customize your Sandboxes](.\u002Fdocs\u002Fcustomizing-sandboxes.md) by changing\n  `Dockerfile` and `instance_type` knobs for the MicroVM backend.\n- [Learn about state persistence](.\u002Fdocs\u002Fsnapshots-and-state-persistence.md)\n  across both sandbox types.\n- [Explore the Architecture](.\u002Fdocs\u002Farchitecture.md) to learn about the request lifecycle\n  from webhook ingress through dispatch to either sandbox backend, and\n  inventories every Worker binding the control plane uses.\n- [Secure Access](.\u002Fdocs\u002Fsecuring-access.md) to your the new CMA control plane.\n\n## Configuration reference\n\nRequired secrets & vars:\n\n| Name | Description |\n|---|---|\n| `ENVIRONMENT_ID` | Environment to poll for work |\n| `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 \u002F ant 1.8 CLI. |\n| `ANTHROPIC_API_KEY` | Anthropic API key (`sk-ant-...`) |\n| `WEBHOOK_SECRET` | HMAC secret for verifying webhook signatures |\n| `CLOUDFLARE_ACCOUNT_ID` | R2 snapshots (presigned URL mode); also used by Browser Rendering REST tools |\n| `R2_ACCESS_KEY_ID` \u002F `R2_SECRET_ACCESS_KEY` | R2 snapshots (presigned URL mode) |\n| `BACKUP_BUCKET_NAME` | R2 snapshots (presigned URL mode) |\n\nThe snapshot-related values are required for production deploys that run\nMicroVM sandboxes. `wrangler dev` can run without them by falling back\nto the BACKUP_BUCKET binding directly, but the R2 bucket itself must\nexist (done in initial deploy). Deployments that exclusively use Isolate\nsandboxes can drop the snapshot secrets and the `r2_buckets` block\nentirely.\n\nOptional secrets:\n\n| Name | Used for |\n|---|---|\n| `CLOUDFLARE_API_TOKEN` | Browser Rendering REST tools |\n| `ANTHROPIC_BASE_URL` | Override (defaults to `https:\u002F\u002Fapi.anthropic.com`) |\n\nOptional vars:\n\n| Name | Used for |\n|---|---|\n| `EMAIL_DOMAIN` | Suffix for per-session inbox addresses |\n| `EMAIL_FROM` | Default sender for `cf_email_send` |\n| `EMAIL_FORWARD` | Fallback inbox for stray (non-session) email |\n\nOptional bindings (declare in `wrangler.jsonc`):\n\n| Binding | Used for |\n|---|---|\n| `BROWSER` | Isolate CDP browser tools |\n| `AI` | `cf_image_generate` |\n| `BACKUP_BUCKET` | Sandbox snapshots |\n| `SEND_EMAIL` | `cf_email_send` |\n| `vpc_services[]` | Private VPC service routing + `cf_call_service` |\n\n## Tests\n\n```sh\nnpm test\n```\n\nVitest covers the egress proxy, storage layer, and API surface. VPC and\nMesh test stubs are included but commented out — see the `describe.skip(...)`\nblocks at the bottom of `tests\u002Fegress.test.ts` for the planned shape.\n\n## Common pitfalls\n\nA handful of edge cases that bite people, most of them around the\nempty `id` \u002F `database_id` placeholders in `wrangler.jsonc`:\n\n- **Running `npx wrangler deploy` directly fails.** The committed\n  `wrangler.jsonc` has empty KV `id` and `database_id` fields by design;\n  wrangler refuses to load that without first running the patch\n  scripts. Use the `npm run …` wrappers (which trigger `prebuild`), or\n  run `npm run prebuild` once after cloning to populate the IDs in\n  your working tree. `npm run cf-typegen` has the same caveat — run\n  `prebuild` first if it complains about missing IDs.\n- **Don't commit the patched IDs.** After a local deploy the scripts\n  write real namespace \u002F database IDs into your working copy of\n  `wrangler.jsonc`. Those values are account-specific. If you're\n  contributing PRs back to the canonical repo, leave them out of the\n  commit (`git checkout wrangler.jsonc` or stage selectively). If\n  you're working on a personal fork, committing them is fine — your\n  Workers Builds rebuilds will no-op-fast on them.\n- **Switching Cloudflare accounts.** The prebuild fast path skips the\n  API check when IDs are already populated locally. If you switch the\n  `CLOUDFLARE_ACCOUNT_ID` you're deploying to, run\n  `git checkout wrangler.jsonc` first so the IDs reset to empty and\n  the scripts repopulate against the new account. Otherwise wrangler\n  will try the old account's IDs against the new account and fail with\n  permission errors.\n- **Multi-account local dev.** If your Cloudflare login has access to\n  more than one account, the prebuild scripts can't pick one in\n  non-interactive mode. Set `CLOUDFLARE_ACCOUNT_ID` (the script's\n  error message lists the candidates) before running `npm run deploy`\n  or `npm run dev`.\n- **Renaming the worker via the Deploy to Cloudflare form.** Safe to\n  do — Cloudflare's setup page lets you pick a Worker name to avoid\n  collisions with an existing one. The KV namespaces and D1 database\n  get the new name as their prefix because the ensure scripts read\n  `name` from `wrangler.jsonc` at build time. Just remember to use the\n  rewritten URL (`https:\u002F\u002F\u003Cyour-chosen-name>.\u003Caccount>.workers.dev`)\n  when configuring the Anthropic webhook in step 2.\n- **Deploy to Cloudflare form: you must rename at least one of the\n  two KV namespaces.** This repo declares two KV namespaces\n  (`SECRETS` and `EGRESS_POLICIES`) and the form's \"Configure\n  resources\" step pre-fills both name inputs with the worker name,\n  with no binding suffix — so the first create succeeds and the\n  second fails with `Cannot provision a KV Namespace with the title\n  \"\u003Cworker-name>\" because it already exists`. Before clicking deploy,\n  edit both inputs to be distinct, e.g. `\u003Cworker-name>-secrets` and\n  `\u003Cworker-name>-egress-policies`. `ensure-kv.mjs` will then\n  fuzzy-match those names back to the right bindings on every\n  subsequent build.\n\n## License\n\n[MIT](.\u002FLICENSE)\n","该项目旨在通过Cloudflare平台运行Claude Managed Agents (CMA)，提供一个可定制的控制平面，支持在全容器或轻量级隔离环境中执行代理任务。其核心功能包括自定义容器大小和镜像、增强对代理沙箱的可观测性、应用零信任凭证注入及与私有服务的连接等高级安全特性。此外，用户可以利用Browser Run、Email服务等扩展代理功能。项目特别适合需要在高度安全且可控环境下运行自动化任务的企业级应用场景，尤其是那些已经使用了Cloudflare付费或企业级服务的组织。通过灵活部署选项，无论是通过一键式部署还是本地终端命令行方式，都能快速启动并管理CMA实例。",2,"2026-06-11 03:55:41","CREATED_QUERY"]