repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources16d ago| #1 | # Moltbot on Cloudflare Workers |
| #2 | |
| #3 | Run [Moltbot](https://molt.bot/) personal AI assistant in a [Cloudflare Sandbox](https://developers.cloudflare.com/sandbox/). |
| #4 | |
| #5 | > **Experimental:** This is a proof of concept demonstrating that Moltbot can run in Cloudflare Sandbox. It is not officially supported and may break without notice. Use at your own risk. |
| #6 | |
| #7 | [](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/moltworker) |
| #8 | |
| #9 |  |
| #10 | |
| #11 | ## Requirements |
| #12 | |
| #13 | - [Workers Paid plan](https://www.cloudflare.com/plans/developer-platform/) ($5 USD/month) — required for Cloudflare Sandbox containers |
| #14 | - [Anthropic API key](https://console.anthropic.com/) — for Claude access, or you can AI Gateway's [Unified Billing](https://developers.cloudflare.com/ai-gateway/features/unified-billing/) |
| #15 | |
| #16 | The following Cloudflare features used by this project have free tiers: |
| #17 | - Cloudflare Access (authentication) |
| #18 | - Browser Rendering (for browser navigation) |
| #19 | - AI Gateway (optional, for API routing/analytics) |
| #20 | - R2 Storage (optional, for persistence) |
| #21 | |
| #22 | ## What is Moltbot? |
| #23 | |
| #24 | [Moltbot](https://molt.bot/) is a personal AI assistant with a gateway architecture that connects to multiple chat platforms. Key features: |
| #25 | |
| #26 | - **Control UI** - Web-based chat interface at the gateway |
| #27 | - **Multi-channel support** - Telegram, Discord, Slack |
| #28 | - **Device pairing** - Secure DM authentication requiring explicit approval |
| #29 | - **Persistent conversations** - Chat history and context across sessions |
| #30 | - **Agent runtime** - Extensible AI capabilities with workspace and skills |
| #31 | |
| #32 | This project packages Moltbot to run in a [Cloudflare Sandbox](https://developers.cloudflare.com/sandbox/) container, providing a fully managed, always-on deployment without needing to self-host. Optional R2 storage enables persistence across container restarts. |
| #33 | |
| #34 | ## Architecture |
| #35 | |
| #36 |  |
| #37 | |
| #38 | ## Quick Start |
| #39 | |
| #40 | _Cloudflare Sandboxes are available on the [Workers Paid plan](https://dash.cloudflare.com/?to=/:account/workers/plans)._ |
| #41 | |
| #42 | ```bash |
| #43 | # Install dependencies |
| #44 | npm install |
| #45 | |
| #46 | # Set your API key (direct Anthropic access) |
| #47 | npx wrangler secret put ANTHROPIC_API_KEY |
| #48 | |
| #49 | # Or use AI Gateway instead (see "Optional: Cloudflare AI Gateway" below) |
| #50 | # npx wrangler secret put AI_GATEWAY_API_KEY |
| #51 | # npx wrangler secret put AI_GATEWAY_BASE_URL |
| #52 | |
| #53 | # Generate and set a gateway token (required for remote access) |
| #54 | # Save this token - you'll need it to access the Control UI |
| #55 | export MOLTBOT_GATEWAY_TOKEN=$(openssl rand -base64 32 | tr -d '=+/' | head -c 32) |
| #56 | echo "Your gateway token: $MOLTBOT_GATEWAY_TOKEN" |
| #57 | echo "$MOLTBOT_GATEWAY_TOKEN" | npx wrangler secret put MOLTBOT_GATEWAY_TOKEN |
| #58 | |
| #59 | # Deploy |
| #60 | npm run deploy |
| #61 | ``` |
| #62 | |
| #63 | After deploying, open the Control UI with your token: |
| #64 | |
| #65 | ``` |
| #66 | https://your-worker.workers.dev/?token=YOUR_GATEWAY_TOKEN |
| #67 | ``` |
| #68 | |
| #69 | Replace `your-worker` with your actual worker subdomain and `YOUR_GATEWAY_TOKEN` with the token you generated above. |
| #70 | |
| #71 | **Note:** The first request may take 1-2 minutes while the container starts. |
| #72 | |
| #73 | > **Important:** You will not be able to use the Control UI until you complete the following steps. You MUST: |
| #74 | > 1. [Set up Cloudflare Access](#setting-up-the-admin-ui) to protect the admin UI |
| #75 | > 2. [Pair your device](#device-pairing) via the admin UI at `/_admin/` |
| #76 | |
| #77 | You'll also likely want to [enable R2 storage](#persistent-storage-r2) so your paired devices and conversation history persist across container restarts (optional but recommended). |
| #78 | |
| #79 | ## Setting Up the Admin UI |
| #80 | |
| #81 | To use the admin UI at `/_admin/` for device management, you need to: |
| #82 | 1. Enable Cloudflare Access on your worker |
| #83 | 2. Set the Access secrets so the worker can validate JWTs |
| #84 | |
| #85 | ### 1. Enable Cloudflare Access on workers.dev |
| #86 | |
| #87 | The easiest way to protect your worker is using the built-in Cloudflare Access integration for workers.dev: |
| #88 | |
| #89 | 1. Go to the [Workers & Pages dashboard](https://dash.cloudflare.com/?to=/:account/workers-and-pages) |
| #90 | 2. Select your Worker (e.g., `moltbot-sandbox`) |
| #91 | 3. In **Settings**, under **Domains & Routes**, in the `workers.dev` row, click the meatballs menu (`...`) |
| #92 | 4. Click **Enable Cloudflare Access** |
| #93 | 5. Click **Manage Cloudflare Access** to configure who can access: |
| #94 | - Add your email address to the allow list |
| #95 | - Or configure other identity providers (Google, GitHub, etc.) |
| #96 | 6. Copy the **Application Audience (AUD)** tag from the Access application settings. This will be your `CF_ACCESS_AUD` in Step 2 below |
| #97 | |
| #98 | ### 2. Set Access Secrets |
| #99 | |
| #100 | After enabling Cloudflare Access, set the secrets so the worker can validate JWTs: |
| #101 | |
| #102 | ```bash |
| #103 | # Your Cloudflare Access team domain (e.g., "myteam.cloudflareaccess.com") |
| #104 | npx wrangler secret put CF_ACCESS_TEAM_DOMAIN |
| #105 | |
| #106 | # The Application Audience (AUD) tag from your Access application that you copied in the step above |
| #107 | npx wrangler secret put CF_ACCESS_AUD |
| #108 | ``` |
| #109 | |
| #110 | You can find your team domain in the [Zero Trust Dashboard](https://one.dash.cloudflare.com/) under **Settings** > **Custom Pages** (it's the subdomain before `.cloudflareaccess.com`). |
| #111 | |
| #112 | ### 3. Redeploy |
| #113 | |
| #114 | ```bash |
| #115 | npm run deploy |
| #116 | ``` |
| #117 | |
| #118 | Now visit `/_admin/` and you'll be prompted to authenticate via Cloudflare Access before accessing the admin UI. |
| #119 | |
| #120 | ### Alternative: Manual Access Application |
| #121 | |
| #122 | If you prefer more control, you can manually create an Access application: |
| #123 | |
| #124 | 1. Go to [Cloudflare Zero Trust Dashboard](https://one.dash.cloudflare.com/) |
| #125 | 2. Navigate to **Access** > **Applications** |
| #126 | 3. Create a new **Self-hosted** application |
| #127 | 4. Set the application domain to your Worker URL (e.g., `moltbot-sandbox.your-subdomain.workers.dev`) |
| #128 | 5. Add paths to protect: `/_admin/*`, `/api/*`, `/debug/*` |
| #129 | 6. Configure your desired identity providers (e.g., email OTP, Google, GitHub) |
| #130 | 7. Copy the **Application Audience (AUD)** tag and set the secrets as shown above |
| #131 | |
| #132 | ### Local Development |
| #133 | |
| #134 | For local development, create a `.dev.vars` file with: |
| #135 | |
| #136 | ```bash |
| #137 | DEV_MODE=true # Skip Cloudflare Access auth + bypass device pairing |
| #138 | DEBUG_ROUTES=true # Enable /debug/* routes (optional) |
| #139 | ``` |
| #140 | |
| #141 | ## Authentication |
| #142 | |
| #143 | By default, moltbot uses **device pairing** for authentication. When a new device (browser, CLI, etc.) connects, it must be approved via the admin UI at `/_admin/`. |
| #144 | |
| #145 | ### Device Pairing |
| #146 | |
| #147 | 1. A device connects to the gateway |
| #148 | 2. The connection is held pending until approved |
| #149 | 3. An admin approves the device via `/_admin/` |
| #150 | 4. The device is now paired and can connect freely |
| #151 | |
| #152 | This is the most secure option as it requires explicit approval for each device. |
| #153 | |
| #154 | ### Gateway Token (Required) |
| #155 | |
| #156 | A gateway token is required to access the Control UI when hosted remotely. Pass it as a query parameter: |
| #157 | |
| #158 | ``` |
| #159 | https://your-worker.workers.dev/?token=YOUR_TOKEN |
| #160 | wss://your-worker.workers.dev/ws?token=YOUR_TOKEN |
| #161 | ``` |
| #162 | |
| #163 | **Note:** Even with a valid token, new devices still require approval via the admin UI at `/_admin/` (see Device Pairing above). |
| #164 | |
| #165 | For local development only, set `DEV_MODE=true` in `.dev.vars` to skip Cloudflare Access authentication and enable `allowInsecureAuth` (bypasses device pairing entirely). |
| #166 | |
| #167 | ## Persistent Storage (R2) |
| #168 | |
| #169 | By default, moltbot data (configs, paired devices, conversation history) is lost when the container restarts. To enable persistent storage across sessions, configure R2: |
| #170 | |
| #171 | ### 1. Create R2 API Token |
| #172 | |
| #173 | 1. Go to **R2** > **Overview** in the [Cloudflare Dashboard](https://dash.cloudflare.com/) |
| #174 | 2. Click **Manage R2 API Tokens** |
| #175 | 3. Create a new token with **Object Read & Write** permissions |
| #176 | 4. Select the `moltbot-data` bucket (created automatically on first deploy) |
| #177 | 5. Copy the **Access Key ID** and **Secret Access Key** |
| #178 | |
| #179 | ### 2. Set Secrets |
| #180 | |
| #181 | ```bash |
| #182 | # R2 Access Key ID |
| #183 | npx wrangler secret put R2_ACCESS_KEY_ID |
| #184 | |
| #185 | # R2 Secret Access Key |
| #186 | npx wrangler secret put R2_SECRET_ACCESS_KEY |
| #187 | |
| #188 | # Your Cloudflare Account ID |
| #189 | npx wrangler secret put CF_ACCOUNT_ID |
| #190 | ``` |
| #191 | |
| #192 | To find your Account ID: Go to the [Cloudflare Dashboard](https://dash.cloudflare.com/), click the three dots menu next to your account name, and select "Copy Account ID". |
| #193 | |
| #194 | ### How It Works |
| #195 | |
| #196 | R2 storage uses a backup/restore approach for simplicity: |
| #197 | |
| #198 | **On container startup:** |
| #199 | - If R2 is mounted and contains backup data, it's restored to the moltbot config directory |
| #200 | - Moltbot uses its default paths (no special configuration needed) |
| #201 | |
| #202 | **During operation:** |
| #203 | - A cron job runs every 5 minutes to sync the moltbot config to R2 |
| #204 | - You can also trigger a manual backup from the admin UI at `/_admin/` |
| #205 | |
| #206 | **In the admin UI:** |
| #207 | - When R2 is configured, you'll see "Last backup: [timestamp]" |
| #208 | - Click "Backup Now" to trigger an immediate sync |
| #209 | |
| #210 | Without R2 credentials, moltbot still works but uses ephemeral storage (data lost on container restart). |
| #211 | |
| #212 | ## Container Lifecycle |
| #213 | |
| #214 | By default, the sandbox container stays alive indefinitely (`SANDBOX_SLEEP_AFTER=never`). This is recommended because cold starts take 1-2 minutes. |
| #215 | |
| #216 | To reduce costs for infrequently used deployments, you can configure the container to sleep after a period of inactivity: |
| #217 | |
| #218 | ```bash |
| #219 | npx wrangler secret put SANDBOX_SLEEP_AFTER |
| #220 | # Enter: 10m (or 1h, 30m, etc.) |
| #221 | ``` |
| #222 | |
| #223 | When the container sleeps, the next request will trigger a cold start. If you have R2 storage configured, your paired devices and data will persist across restarts. |
| #224 | |
| #225 | ## Admin UI |
| #226 | |
| #227 |  |
| #228 | |
| #229 | Access the admin UI at `/_admin/` to: |
| #230 | - **R2 Storage Status** - Shows if R2 is configured, last backup time, and a "Backup Now" button |
| #231 | - **Restart Gateway** - Kill and restart the moltbot gateway process |
| #232 | - **Device Pairing** - View pending requests, approve devices individually or all at once, view paired devices |
| #233 | |
| #234 | The admin UI requires Cloudflare Access authentication (or `DEV_MODE=true` for local development). |
| #235 | |
| #236 | ## Debug Endpoints |
| #237 | |
| #238 | Debug endpoints are available at `/debug/*` when enabled (requires `DEBUG_ROUTES=true` and Cloudflare Access): |
| #239 | |
| #240 | - `GET /debug/processes` - List all container processes |
| #241 | - `GET /debug/logs?id=<process_id>` - Get logs for a specific process |
| #242 | - `GET /debug/version` - Get container and moltbot version info |
| #243 | |
| #244 | ## Optional: Chat Channels |
| #245 | |
| #246 | ### Telegram |
| #247 | |
| #248 | ```bash |
| #249 | npx wrangler secret put TELEGRAM_BOT_TOKEN |
| #250 | npm run deploy |
| #251 | ``` |
| #252 | |
| #253 | ### Discord |
| #254 | |
| #255 | ```bash |
| #256 | npx wrangler secret put DISCORD_BOT_TOKEN |
| #257 | npm run deploy |
| #258 | ``` |
| #259 | |
| #260 | ### Slack |
| #261 | |
| #262 | ```bash |
| #263 | npx wrangler secret put SLACK_BOT_TOKEN |
| #264 | npx wrangler secret put SLACK_APP_TOKEN |
| #265 | npm run deploy |
| #266 | ``` |
| #267 | |
| #268 | ## Optional: Browser Automation (CDP) |
| #269 | |
| #270 | This worker includes a Chrome DevTools Protocol (CDP) shim that enables browser automation capabilities. This allows Moltbot to control a headless browser for tasks like web scraping, screenshots, and automated testing. |
| #271 | |
| #272 | ### Setup |
| #273 | |
| #274 | 1. Set a shared secret for authentication: |
| #275 | |
| #276 | ```bash |
| #277 | npx wrangler secret put CDP_SECRET |
| #278 | # Enter a secure random string |
| #279 | ``` |
| #280 | |
| #281 | 2. Set your worker's public URL: |
| #282 | |
| #283 | ```bash |
| #284 | npx wrangler secret put WORKER_URL |
| #285 | # Enter: https://your-worker.workers.dev |
| #286 | ``` |
| #287 | |
| #288 | 3. Redeploy: |
| #289 | |
| #290 | ```bash |
| #291 | npm run deploy |
| #292 | ``` |
| #293 | |
| #294 | ### Endpoints |
| #295 | |
| #296 | | Endpoint | Description | |
| #297 | |----------|-------------| |
| #298 | | `GET /cdp/json/version` | Browser version information | |
| #299 | | `GET /cdp/json/list` | List available browser targets | |
| #300 | | `GET /cdp/json/new` | Create a new browser target | |
| #301 | | `WS /cdp/devtools/browser/{id}` | WebSocket connection for CDP commands | |
| #302 | |
| #303 | All endpoints require the `CDP_SECRET` header for authentication. |
| #304 | |
| #305 | ## Built-in Skills |
| #306 | |
| #307 | The container includes pre-installed skills in `/root/clawd/skills/`: |
| #308 | |
| #309 | ### cloudflare-browser |
| #310 | |
| #311 | Browser automation via the CDP shim. Requires `CDP_SECRET` and `WORKER_URL` to be set (see [Browser Automation](#optional-browser-automation-cdp) above). |
| #312 | |
| #313 | **Scripts:** |
| #314 | - `screenshot.js` - Capture a screenshot of a URL |
| #315 | - `video.js` - Create a video from multiple URLs |
| #316 | - `cdp-client.js` - Reusable CDP client library |
| #317 | |
| #318 | **Usage:** |
| #319 | ```bash |
| #320 | # Screenshot |
| #321 | node /root/clawd/skills/cloudflare-browser/scripts/screenshot.js https://example.com output.png |
| #322 | |
| #323 | # Video from multiple URLs |
| #324 | node /root/clawd/skills/cloudflare-browser/scripts/video.js "https://site1.com,https://site2.com" output.mp4 --scroll |
| #325 | ``` |
| #326 | |
| #327 | See `skills/cloudflare-browser/SKILL.md` for full documentation. |
| #328 | |
| #329 | ## Optional: Cloudflare AI Gateway |
| #330 | |
| #331 | You can route API requests through [Cloudflare AI Gateway](https://developers.cloudflare.com/ai-gateway/) for caching, rate limiting, analytics, and cost tracking. AI Gateway supports multiple providers — configure your preferred provider in the gateway and use these env vars: |
| #332 | |
| #333 | ### Setup |
| #334 | |
| #335 | 1. Create an AI Gateway in the [AI Gateway section](https://dash.cloudflare.com/?to=/:account/ai/ai-gateway/create-gateway) of the Cloudflare Dashboard. |
| #336 | 2. Add a provider (e.g., Anthropic) to your gateway |
| #337 | 3. Set the gateway secrets: |
| #338 | |
| #339 | You'll find the base URL on the Overview tab of your newly created gateway. At the bottom of the page, expand the **Native API/SDK Examples** section and select "Anthropic". |
| #340 | |
| #341 | ```bash |
| #342 | # Your provider's API key (e.g., Anthropic API key) |
| #343 | npx wrangler secret put AI_GATEWAY_API_KEY |
| #344 | |
| #345 | # Your AI Gateway endpoint URL |
| #346 | npx wrangler secret put AI_GATEWAY_BASE_URL |
| #347 | # Enter: https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/anthropic |
| #348 | ``` |
| #349 | |
| #350 | 4. Redeploy: |
| #351 | |
| #352 | ```bash |
| #353 | npm run deploy |
| #354 | ``` |
| #355 | |
| #356 | The `AI_GATEWAY_*` variables take precedence over `ANTHROPIC_*` if both are set. |
| #357 | |
| #358 | ## All Secrets Reference |
| #359 | |
| #360 | | Secret | Required | Description | |
| #361 | |--------|----------|-------------| |
| #362 | | `AI_GATEWAY_API_KEY` | Yes* | API key for your AI Gateway provider (requires `AI_GATEWAY_BASE_URL`) | |
| #363 | | `AI_GATEWAY_BASE_URL` | Yes* | AI Gateway endpoint URL (required when using `AI_GATEWAY_API_KEY`) | |
| #364 | | `ANTHROPIC_API_KEY` | Yes* | Direct Anthropic API key (fallback if AI Gateway not configured) | |
| #365 | | `ANTHROPIC_BASE_URL` | No | Direct Anthropic API base URL (fallback) | |
| #366 | | `OPENAI_API_KEY` | No | OpenAI API key (alternative provider) | |
| #367 | | `CF_ACCESS_TEAM_DOMAIN` | Yes* | Cloudflare Access team domain (required for admin UI) | |
| #368 | | `CF_ACCESS_AUD` | Yes* | Cloudflare Access application audience (required for admin UI) | |
| #369 | | `MOLTBOT_GATEWAY_TOKEN` | Yes | Gateway token for authentication (pass via `?token=` query param) | |
| #370 | | `DEV_MODE` | No | Set to `true` to skip CF Access auth + device pairing (local dev only) | |
| #371 | | `DEBUG_ROUTES` | No | Set to `true` to enable `/debug/*` routes | |
| #372 | | `SANDBOX_SLEEP_AFTER` | No | Container sleep timeout: `never` (default) or duration like `10m`, `1h` | |
| #373 | | `R2_ACCESS_KEY_ID` | No | R2 access key for persistent storage | |
| #374 | | `R2_SECRET_ACCESS_KEY` | No | R2 secret key for persistent storage | |
| #375 | | `CF_ACCOUNT_ID` | No | Cloudflare account ID (required for R2 storage) | |
| #376 | | `TELEGRAM_BOT_TOKEN` | No | Telegram bot token | |
| #377 | | `TELEGRAM_DM_POLICY` | No | Telegram DM policy: `pairing` (default) or `open` | |
| #378 | | `DISCORD_BOT_TOKEN` | No | Discord bot token | |
| #379 | | `DISCORD_DM_POLICY` | No | Discord DM policy: `pairing` (default) or `open` | |
| #380 | | `SLACK_BOT_TOKEN` | No | Slack bot token | |
| #381 | | `SLACK_APP_TOKEN` | No | Slack app token | |
| #382 | | `CDP_SECRET` | No | Shared secret for CDP endpoint authentication (see [Browser Automation](#optional-browser-automation-cdp)) | |
| #383 | | `WORKER_URL` | No | Public URL of the worker (required for CDP) | |
| #384 | |
| #385 | ## Security Considerations |
| #386 | |
| #387 | ### Authentication Layers |
| #388 | |
| #389 | Moltbot in Cloudflare Sandbox uses multiple authentication layers: |
| #390 | |
| #391 | 1. **Cloudflare Access** - Protects admin routes (`/_admin/`, `/api/*`, `/debug/*`). Only authenticated users can manage devices. |
| #392 | |
| #393 | 2. **Gateway Token** - Required to access the Control UI. Pass via `?token=` query parameter. Keep this secret. |
| #394 | |
| #395 | 3. **Device Pairing** - Each device (browser, CLI, chat platform DM) must be explicitly approved via the admin UI before it can interact with the assistant. This is the default "pairing" DM policy. |
| #396 | |
| #397 | ## Troubleshooting |
| #398 | |
| #399 | **`npm run dev` fails with an `Unauthorized` error:** You need to enable Cloudflare Containers in the [Containers dashboard](https://dash.cloudflare.com/?to=/:account/workers/containers) |
| #400 | |
| #401 | **Gateway fails to start:** Check `npx wrangler secret list` and `npx wrangler tail` |
| #402 | |
| #403 | **Config changes not working:** Edit the `# Build cache bust:` comment in `Dockerfile` and redeploy |
| #404 | |
| #405 | **Slow first request:** Cold starts take 1-2 minutes. Subsequent requests are faster. |
| #406 | |
| #407 | **R2 not mounting:** Check that all three R2 secrets are set (`R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `CF_ACCOUNT_ID`). Note: R2 mounting only works in production, not with `wrangler dev`. |
| #408 | |
| #409 | **Access denied on admin routes:** Ensure `CF_ACCESS_TEAM_DOMAIN` and `CF_ACCESS_AUD` are set, and that your Cloudflare Access application is configured correctly. |
| #410 | |
| #411 | **Devices not appearing in admin UI:** Device list commands take 10-15 seconds due to WebSocket connection overhead. Wait and refresh. |
| #412 | |
| #413 | **WebSocket issues in local development:** `wrangler dev` has known limitations with WebSocket proxying through the sandbox. HTTP requests work but WebSocket connections may fail. Deploy to Cloudflare for full functionality. |
| #414 | |
| #415 | ## Links |
| #416 | |
| #417 | - [Moltbot](https://molt.bot/) |
| #418 | - [Moltbot Docs](https://docs.molt.bot) |
| #419 | - [Cloudflare Sandbox Docs](https://developers.cloudflare.com/sandbox/) |
| #420 | - [Cloudflare Access Docs](https://developers.cloudflare.com/cloudflare-one/policies/access/) |
| #421 |