Blue Orchid.
    Case StudiesOpportunitiesWork With Us
    Newsletter
    Back to main guide
    Cloud deployment

    Deploy OpenClaw on Cloudflare

    Run your AI agent on Cloudflare's edge network.
    No hardware to manage, built-in auth, persistent storage.

    You (browser / Telegram / Discord)
    |
    Cloudflare Worker (routing, auth, admin UI)
    |
    Cloudflare Sandbox (Ubuntu VM running OpenClaw)
    |
    Cloudflare R2 (persistent config, conversations, files)
    1-2 hours for full setup~$5/month base costTerminal required

    A guide from Blue Orchid Society by Manas Takalpati. Built from a working deployment.

    1Prerequisites

    Cloudflare account

    • Workers Paid plan ($5/month), required for Sandbox containers. dash.cloudflare.com

    Local tools

    Install Node.js 18+ and Wrangler
    # Check Node.js version (need 18+)
    node --version
    
    # Install Wrangler (Cloudflare's deployment tool)
    npm install -g wrangler
    
    # Authenticate with Cloudflare
    wrangler login

    Create R2 buckets

    Go to R2 Object Storage > Create bucket in the Cloudflare Dashboard:

    1. 1.moltbot-data: Stores OpenClaw config, conversation history, device pairings, workspace files
    2. 2.obsidian-vault (optional): Stores your Obsidian vault for AI-accessible knowledge base

    Create R2 API credentials

    Go to R2 Object Storage > Manage R2 API Tokens > Create API Token:

    • Token name: moltbot-rclone
    • Permissions: Object Read & Write
    • Scope: Apply to specific buckets (select moltbot-data and obsidian-vault)

    Save the Access Key ID and Secret Access Key. You'll need them later.

    Use R2 API Tokens (under R2 settings), not the general Cloudflare API tokens. They're different systems. Find them at: Dashboard > R2 Object Storage > Manage R2 API Tokens.

    Note your account ID

    Your Cloudflare Account ID is in the URL when viewing the dashboard: dash.cloudflare.com/{account-id}/... You'll also find it on the Workers & Pages overview page in the right sidebar.

    2Project setup

    Clone and install

    Moltworker is Cloudflare's official wrapper for running OpenClaw in Sandbox containers.

    git clone https://github.com/cloudflare/moltworker.git
    cd moltworker
    npm install

    Project structure

    moltworker/
    ├── src/
    │   ├── index.ts              # Main Worker entry point
    │   ├── types.ts              # Environment variable types
    │   ├── auth/                 # Cloudflare Access JWT verification
    │   ├── gateway/              # OpenClaw process lifecycle
    │   ├── routes/               # Admin UI, API, vault, debug endpoints
    │   └── client/               # React admin UI source
    ├── Dockerfile                # Container image (Ubuntu + Node.js + OpenClaw)
    ├── start-openclaw.sh         # Container startup script
    ├── skills/                   # Custom skills (SKILL.md files)
    ├── wrangler.jsonc            # Cloudflare Worker configuration
    └── package.json

    Key config: wrangler.jsonc

    This file defines your Worker's bindings. The important sections:

    wrangler.jsonc
    {
      "name": "moltbot-sandbox",
      "main": "src/index.ts",
      "compatibility_date": "2025-05-06",
      "compatibility_flags": ["nodejs_compat"],
    
      // Sandbox container configuration
      "containers": [{
        "class_name": "Sandbox",
        "image": "./Dockerfile",
        "instance_type": "standard-1",  // 1/2 vCPU, 4GB RAM, 8GB disk
        "max_instances": 1
      }],
    
      // R2 storage buckets
      "r2_buckets": [
        { "binding": "MOLTBOT_BUCKET", "bucket_name": "moltbot-data" },
        { "binding": "OBSIDIAN_VAULT", "bucket_name": "obsidian-vault" }
      ],
    
      // Admin UI static assets
      "assets": {
        "directory": "./dist/client",
        "binding": "ASSETS",
        "html_handling": "single-page-application"
      }
    }

    3Configure secrets

    Gateway token (required)

    Protects the Control UI. Generate a random token and set it:

    # Generate a random token
    openssl rand -hex 32
    
    # Set it as a secret
    npx wrangler secret put MOLTBOT_GATEWAY_TOKEN

    AI provider (pick one)

    Option A: Cloudflare AI Gateway (recommended): Routes through Cloudflare with caching, rate limiting, and analytics. Supports Anthropic, OpenAI, and Workers AI backends.

    npx wrangler secret put CLOUDFLARE_AI_GATEWAY_API_KEY  # API key for your backend
    npx wrangler secret put CF_AI_GATEWAY_ACCOUNT_ID       # Your Cloudflare account ID
    npx wrangler secret put CF_AI_GATEWAY_GATEWAY_ID       # Gateway ID (create in Dashboard > AI > AI Gateway)
    npx wrangler secret put CF_AI_GATEWAY_MODEL             # e.g., "anthropic/claude-sonnet-4-5"
    ModelValue
    Claude Sonnet 4.5anthropic/claude-sonnet-4-5
    GPT-4oopenai/gpt-4o
    Llama 3.3 70B (Workers AI)workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast
    Qwen3 30B (Workers AI)workers-ai/@cf/qwen/qwen3-30b-a3b-fp8

    Workers AI models are cheaper (some have free tiers) but lower quality than Claude or GPT-4o. Start cheap to verify everything works, then upgrade.

    Option B: Direct Anthropic API key

    npx wrangler secret put ANTHROPIC_API_KEY

    Option C: Direct OpenAI API key

    npx wrangler secret put OPENAI_API_KEY

    R2 persistence (strongly recommended)

    Without R2, all configuration, conversations, and device pairings are lost when the container restarts.

    npx wrangler secret put R2_ACCESS_KEY_ID       # From R2 API token creation
    npx wrangler secret put R2_SECRET_ACCESS_KEY   # From R2 API token creation
    npx wrangler secret put CF_ACCOUNT_ID          # Your Cloudflare account ID

    Verify your secrets

    npx wrangler secret list

    You should see your configured secrets listed (values are hidden).

    4Deploy to Cloudflare

    # Build the admin UI and deploy everything
    npm run deploy

    This builds the React admin UI with Vite, builds the Docker container image (installs Node.js 22, OpenClaw, rclone, git, gh), pushes the image to Cloudflare's registry, and deploys the Worker.

    First deploy takes 5-10 minutes because it builds the Docker image from scratch. Subsequent deploys are faster due to layer caching.

    Verify deployment

    curl https://your-worker.your-subdomain.workers.dev/api/status

    Your Worker URL follows the pattern: https://{worker-name}.{subdomain}.workers.dev. Find it in the Wrangler output or in Dashboard > Workers & Pages.

    5Set up Cloudflare Access (Zero Trust auth)

    Cloudflare Access protects the admin UI and API endpoints with identity-provider login (Google, GitHub, email OTP, etc.).

    Create an Access application

    1. 1.Go to Cloudflare Zero Trust Dashboard
    2. 2.Navigate to Access > Applications > Add an application
    3. 3.Choose Self-hosted
    4. 4.Set your Worker URL as the application domain, leave path empty
    5. 5.Add a policy: Allow > Emails > your email address
    6. 6.Save and note the Application Audience (AUD) tag from the overview page

    Set Access secrets

    # Your Zero Trust team domain (e.g., myteam.cloudflareaccess.com)
    npx wrangler secret put CF_ACCESS_TEAM_DOMAIN
    
    # Application Audience tag (the long hex string from step 6)
    npx wrangler secret put CF_ACCESS_AUD

    How auth works

    Three layers of authentication:

    1.

    Cloudflare Access

    JWT verification via JWKS endpoint. Protects /_admin/*, /api/*, /debug/*

    2.

    Gateway token

    Injected server-side into WebSocket connections after CF Access validates the user

    3.

    Device pairing

    Each new client (browser, app) must be approved via the admin UI before it can chat

    6First boot and device pairing

    1. 1.Open your Worker URL: https://your-worker.workers.dev/_admin/
    2. 2.Authenticate through Cloudflare Access
    3. 3.The admin UI loads, showing the Control UI
    4. 4.Pair your device (you may need to add ?token=YOUR_GATEWAY_TOKEN to the URL)

    First boot takes ~80 seconds (cold start). The container needs to start, run the startup script, restore from R2, and launch the OpenClaw gateway.

    Admin API endpoints

    EndpointMethodPurpose
    /api/admin/devicesGETList paired/pending devices
    /api/admin/devicesPOSTApprove device
    /api/admin/storagePOSTTrigger manual R2 backup
    /api/admin/gateway/restartPOSTRestart OpenClaw process

    7AI model configuration

    Switching models

    Change the CF_AI_GATEWAY_MODEL secret and restart the container (via admin UI or redeploy).

    npx wrangler secret put CF_AI_GATEWAY_MODEL
    # Enter: anthropic/claude-sonnet-4-5

    Model comparison

    ModelCostQualityBest for
    Claude Sonnet 4.5~$3/1M inputExcellentGeneral assistant, coding
    GPT-4o~$2.50/1M inputExcellentBroad knowledge, creative
    Qwen3 30BVery cheapGoodBudget-friendly, basic tasks
    Llama 3.3 70BCheap (free tier)DecentTesting, simple queries

    Start with a Workers AI model to verify everything works, then upgrade to Claude or GPT-4o.

    Monitoring costs

    • AI Gateway: Dashboard > AI > AI Gateway > Analytics
    • Workers AI: Dashboard > AI > Workers AI (shows usage and costs)
    • Direct API keys: Check your provider's dashboard (Anthropic Console, OpenAI Usage)

    8R2 persistent storage

    How persistence works

    The container is ephemeral. When it restarts, everything is lost. R2 persistence solves this:

    1.

    On startup

    start-openclaw.sh uses rclone to restore from R2: config, workspace files, and custom skills

    2.

    Background sync

    Every 30 seconds, changed files are synced back to R2 (excludes lock files, logs, .git, node_modules)

    3.

    Manual backup

    Available via admin API: POST /api/admin/storage

    What's stored in R2

    R2 pathContainer pathContents
    openclaw//root/.openclaw/Config, device records
    workspace//root/clawd/SOUL.md, USER.md, AGENTS.md
    skills//root/clawd/skills/Custom SKILL.md files

    9Obsidian vault sync (Second Brain)

    Optional step that syncs your Obsidian vault to R2 so the AI can search your notes.

    Install Remotely Save plugin

    1. 1.In Obsidian: Settings > Community Plugins > Browse > search “Remotely Save”
    2. 2.Install and enable the plugin

    Configure S3-compatible storage

    In Remotely Save settings:

    • Remote service: S3 or S3-compatible
    • Endpoint: https://{your-account-id}.r2.cloudflarestorage.com
    • Region: auto
    • Access Key ID: Your R2 API token access key
    • Secret Access Key: Your R2 API token secret key
    • Bucket name: obsidian-vault

    Add exclusion patterns in Remotely Save for any private folders you don't want synced.

    10Vault MCP server with semantic search

    This deploys a separate Cloudflare Worker that provides MCP access to your Obsidian vault with AI-powered semantic search.

    Create the project

    # In a separate directory from moltworker
    npm create cloudflare@latest vault-mcp -- --template cloudflare/ai-mcp-demo
    cd vault-mcp

    Create the Vectorize index

    npx wrangler vectorize create vault-embeddings \
      --dimensions 768 \
      --metric cosine

    768 dimensions matches the BGE Base English embedding model (@cf/baai/bge-base-en-v1.5).

    Set auth token

    npx wrangler secret put VAULT_TOKEN

    Available MCP tools

    ToolDescription
    list_filesList vault files, optionally filtered by prefix
    read_fileRead a single file's contents
    searchKeyword search across all text files
    semantic_searchAI-powered meaning-based search using embeddings
    index_vaultBuild/rebuild the semantic search index

    How semantic search works

    1.

    Each markdown file is split into ~500-character chunks by paragraph boundaries

    2.

    Chunks are converted to 768-dimensional vectors using @cf/baai/bge-base-en-v1.5

    3.

    Vectors stored in Vectorize with metadata (file path, chunk index, preview)

    4.

    Queries get embedded and matched via cosine similarity

    5.

    Cron job re-indexes modified files every 15 minutes

    Cost: Workers AI embeddings are ~$0.011 per 1M tokens. There's a free tier of 10,000 neurons/day. A typical vault of 500-1000 files costs fractions of a cent to index.

    Deploy and connect

    npx wrangler deploy

    Then add the MCP server to your client's configuration:

    MCP client config
    {
      "mcpServers": {
        "second-brain": {
          "url": "https://vault-mcp.your-subdomain.workers.dev/mcp",
          "headers": {
            "Authorization": "Bearer YOUR_VAULT_TOKEN"
          }
        }
      }
    }

    11GitHub integration (PR creation)

    This lets the OpenClaw agent clone repos, make changes, and create pull requests.

    Create a fine-grained GitHub PAT

    1. 1.Go to GitHub Fine-grained PAT settings
    2. 2.Repository access: “Only select repositories” > choose the repos you want
    3. 3.Permissions: Contents (Read & write), Pull requests (Read & write), Metadata (Read-only)

    Set secrets

    npx wrangler secret put GITHUB_TOKEN       # Your fine-grained PAT
    
    # Optional: override the default git identity
    npx wrangler secret put GIT_USER_NAME      # Default: "Gravemind"
    npx wrangler secret put GIT_USER_EMAIL     # Default: "gravemind@blueorchid.world"

    Then redeploy: npm run deploy

    How it works inside the container

    When the container starts with GITHUB_TOKEN set, the startup script configures git, authenticates gh CLI, and rewrites HTTPS URLs to use the token automatically.

    A github-dev skill teaches the agent the workflow: clone to /tmp/REPO, create a feature branch, make changes, commit with conventional messages, push and create a PR via gh pr create.

    12Chat channel setup

    Telegram (easiest)

    1. 1.Message @BotFather on Telegram, send /newbot
    2. 2.Copy the bot token
    3. 3.Set secrets and redeploy
    npx wrangler secret put TELEGRAM_BOT_TOKEN    # Bot token from BotFather
    npx wrangler secret put TELEGRAM_DM_POLICY    # "pairing" (secure) or "open"
    npm run deploy

    If using “pairing” policy: approve the device in /_admin/ after messaging the bot.

    Discord

    npx wrangler secret put DISCORD_BOT_TOKEN
    npx wrangler secret put DISCORD_DM_POLICY    # "pairing" or "open"
    npm run deploy

    Create a bot at the Discord Developer Portal.

    Slack

    npx wrangler secret put SLACK_BOT_TOKEN
    npx wrangler secret put SLACK_APP_TOKEN
    npm run deploy

    Create a Slack app at api.slack.com and enable Socket Mode.

    13Workspace personality files

    OpenClaw loads workspace files from /root/clawd/ into every conversation's system prompt (max 24k characters). These define your agent's personality, context, and behavior.

    FilePurpose
    SOUL.mdPersonality, tone, boundaries
    USER.mdWho you are, your context
    AGENTS.mdOperating rules, priorities
    IDENTITY.mdName, branding
    HEARTBEAT.mdPeriodic check-in behavior
    TOOLS.mdNotes about available tools

    How to add workspace files

    Option A: Edit via the OpenClaw Control UI (changes sync to R2 automatically)

    Option B: Upload directly to R2:

    echo "You are Gravemind, a proactive AI assistant..." > /tmp/SOUL.md
    npx wrangler r2 object put moltbot-data/workspace/SOUL.md --file /tmp/SOUL.md

    Option C: Add to the skills/ directory in the moltworker repo and redeploy

    Files are restored from R2 on every container restart and synced back every 30 seconds when changed.

    14Troubleshooting

    IssueSolution
    502/503 after deployFirst cold start takes ~80 seconds. Wait and retry. Check logs: npx wrangler tail moltbot-sandbox
    401 or redirect loop on /_admin/Verify CF_ACCESS_TEAM_DOMAIN and CF_ACCESS_AUD secrets are set. Check your email is in the Access allow list. Clear cookies.
    Low-quality AI responsesYou're likely using a small model. Upgrade: npx wrangler secret put CF_AI_GATEWAY_MODEL > anthropic/claude-sonnet-4-5
    Config lost on restartVerify R2 secrets: R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, CF_ACCOUNT_ID. Trigger manual backup via POST /api/admin/storage.
    Remotely Save errors in ObsidianPress Cmd+P > “Reload app without saving”. This rebuilds the file index.
    Device pairing stuckTry approving via API: POST /api/admin/devices with { "action": "approve-all" }. Check gateway is running via GET /api/status.

    15Architecture reference

    Environment variables

    VariableRequiredDescription
    MOLTBOT_GATEWAY_TOKENYesProtects Control UI access
    CLOUDFLARE_AI_GATEWAY_API_KEYOne AI providerAI Gateway API key
    CF_AI_GATEWAY_ACCOUNT_IDWith AI GatewayCloudflare account ID
    CF_AI_GATEWAY_GATEWAY_IDWith AI GatewayAI Gateway instance ID
    CF_AI_GATEWAY_MODELWith AI Gatewayprovider/model-id
    ANTHROPIC_API_KEYAlt providerDirect Anthropic key
    CF_ACCESS_TEAM_DOMAINFor admin authZero Trust team domain
    CF_ACCESS_AUDFor admin authApplication audience tag
    R2_ACCESS_KEY_IDFor persistenceR2 API token access key
    R2_SECRET_ACCESS_KEYFor persistenceR2 API token secret key
    CF_ACCOUNT_IDFor persistenceCloudflare account ID
    TELEGRAM_BOT_TOKENFor TelegramBot token from BotFather
    DISCORD_BOT_TOKENFor DiscordDiscord bot token
    GITHUB_TOKENFor GitHubFine-grained PAT
    SANDBOX_SLEEP_AFTERNo (default: never)never, 10m, 1h: sleep to save costs
    DEV_MODENotrue to skip all auth (dev only)

    Request flow

    Incoming Request
      │
      ├─ Public routes (no auth): /api/status, /sandbox-health, static assets
      │
      ├─ CDP routes (secret auth): /cdp/* - browser automation
      │
      └─ Protected routes (CF Access JWT required):
          │
          ├─ /_admin/* → Admin SPA (React)
          ├─ /api/admin/* → Device, storage, gateway, vault APIs
          ├─ /debug/* → Diagnostics (if DEBUG_ROUTES=true)
          │
          └─ /* (catch-all) → Proxy to OpenClaw Gateway in container
              ├─ HTTP requests → Direct proxy
              └─ WebSocket → Bidirectional relay with token injection

    Container startup sequence

    1. Git/GitHub setup (if GITHUB_TOKEN set)
    2. Rclone configuration (if R2 credentials set)
    3. Restore from R2 (config, workspace, skills)
    4. OpenClaw onboard (if no config exists)
    5. Config patching (channels, gateway auth, AI model, trusted proxies)
    6. Background sync loop (every 30 seconds)
    7. Start OpenClaw Gateway (port 18789)

    Useful links

    OpenClaw docsCloudflare WorkersCloudflare SandboxCloudflare R2Cloudflare AI GatewayCloudflare VectorizeCloudflare Access (Zero Trust)MCP Protocol

    Want more AI systems?

    Join the newsletter for weekly guides on building personal AI systems.

    Get it in your inbox

    Free weekly newsletter. AI workflows, technical deep-dives, and lessons from building in public.

    No spam. Unsubscribe anytime.

    Frequently asked questions

    Get more

    Main guide: Back to the full personal AI assistant guide

    Questions? DM me on Instagram or Twitter

    Weekly insights: Be Superpowered Newsletter

    Guide created from a working deployment. Last updated: February 2026.

    Blue Orchid.

    A collective that builds things with people.

    Built by Manas

    Resources
    • Tools
    • Articles
    • Workflows
    • Glossary
    Popular tools
    • ChatGPT
    • Claude
    • Perplexity
    • Cursor
    • All comparisons
    ADHD hub
    • ADHD resources
    • Getting started
    • AI workflow guide
    • Productivity tools
    Company
    • About
    • Consulting
    • Opportunities
    • Newsletter
    • Contact

    © 2026 Blue Orchid World. All rights reserved.

    Best AI chatbotsSolopreneur stackWhat is an LLM?AI prompts guide