Cloudflare & Wrangler CLI
Manage Cloudflare infrastructure from the terminal: Pages, Workers, KV, R2, D1, Queues, Vectorize, and more.
Prerequisites
# Install
npm install -g wrangler
# Authenticate (opens browser OAuth flow)
wrangler login
# Verify
wrangler whoami
Environment variables (alternative to wrangler login):
CLOUDFLARE_API_TOKEN— scoped API token (recommended for CI/CD)CLOUDFLARE_ACCOUNT_ID— your account ID (found in dashboard URL)
Quick Start
# Deploy a static site to Cloudflare Pages
npm run build && wrangler pages deploy out --project-name mysite
Quick Reference
| Command | Purpose | Example |
|---|---|---|
wrangler pages deploy |
Deploy static site | wrangler pages deploy out --project-name mysite |
wrangler pages project list |
List Pages projects | wrangler pages project list |
wrangler deploy |
Deploy Worker | wrangler deploy |
wrangler dev |
Local dev server | wrangler dev |
wrangler tail |
Stream live logs | wrangler tail my-worker |
wrangler kv namespace list |
List KV namespaces | wrangler kv namespace list |
wrangler r2 bucket list |
List R2 buckets | wrangler r2 bucket list |
wrangler d1 list |
List D1 databases | wrangler d1 list |
wrangler secret put |
Set encrypted secret | wrangler secret put API_KEY |
wrangler whoami |
Check auth status | wrangler whoami |
Full CLI reference: references/wrangler-commands.md
Pages
Primary use case for static site deployment (Next.js output: 'export', Astro, etc.).
Deploy
# Direct deploy (no git integration needed)
npm run build
wrangler pages deploy out --project-name worldwarwatcher
# With commit tracking
wrangler pages deploy out --project-name mysite --commit-hash $(git rev-parse HEAD) --commit-message "$(git log -1 --format=%s)"
# Preview deploy (non-production branch)
wrangler pages deploy out --project-name mysite --branch staging
Project Management
wrangler pages project create mysite --production-branch main
wrangler pages project list
wrangler pages project delete mysite
Deployment History & Rollback
wrangler pages deployment list --project-name mysite
wrangler pages deployment tail --project-name mysite # Stream logs
To rollback: redeploy a previous build directory, or use the dashboard to promote an earlier deployment.
Custom Domains
Custom domain management is dashboard-only — wrangler cannot add/remove custom domains for Pages projects. Use the Cloudflare dashboard:
- Workers & Pages → project → Custom Domains → Add
- CF auto-creates DNS records and provisions TLS
Pages Config Files
Place _headers and _redirects in your static assets directory (e.g., public/ for Next.js, Astro, Vite) — the build process copies them to the output root.
Details: references/pages-config.md — _headers format, _redirects format, framework presets, preview deploys.
Workers
# Create new Worker project (C3 scaffolding)
npm create cloudflare@latest my-worker
# Local development (with hot reload)
wrangler dev
# Deploy to production
wrangler deploy
# Stream live logs
wrangler tail my-worker
Note: wrangler init is deprecated — use npm create cloudflare@latest instead.
Agents SDK & Code Mode
Build stateful AI agents on Cloudflare Workers with durable state, chat persistence, voice, sub-agents, durable execution, MCP tools, and sandboxed code execution. SDK at agents@0.13.2 (May 2026).
Quick Start
# Scaffold with the starter (includes chat, tools, HITL, scheduling)
npx create-cloudflare@latest --template cloudflare/agents-starter
# Or install packages individually
npm install agents @cloudflare/ai-chat @cloudflare/think @cloudflare/voice @cloudflare/codemode
Class Hierarchy
| Class | Package | Purpose |
|---|---|---|
Agent<Env, State> |
agents |
Base: state, scheduling, fibers, sub-agents, RPC, MCP |
AIChatAgent |
@cloudflare/ai-chat |
Chat: message persistence, streaming, tool approval, data parts |
Think |
@cloudflare/think |
Opinionated chat: full agentic loop, extensions, auto-continuation |
withVoice(Agent) |
@cloudflare/voice |
Mixin: real-time STT/TTS over WebSocket (beta) |
Key Concepts
| Concept | Description |
|---|---|
this.subAgent(Class, id) |
Spawn co-located child agents with typed RPC and isolated SQLite |
runAgentTool / agentTool |
Run sub-agents as retained, streaming tools from a parent |
runFiber() / stash() |
Durable execution — work survives DO eviction with checkpoint recovery |
needsApproval |
Human-in-the-loop tool approval (5 patterns available) |
this.schedule() / scheduleEvery() |
Persistent scheduling: delayed, cron, interval (survives restarts) |
this.retry() |
Built-in exponential backoff with jitter |
keepAlive() |
Prevent DO eviction during long-running work |
diagnostics_channel |
Structured observability across 7 typed event channels |
addMcpServer() |
Consume MCP tools via HTTP/SSE or RPC (DO binding, no HTTP overhead) |
createCodeTool() |
Code Mode: wraps tools into TypeScript API for LLM-generated code |
DynamicWorkerExecutor |
Runs LLM code in isolated V8 sandbox (Dynamic Workers, open beta) |
| Chat Recovery | Server turns survive client disconnect, resume on reconnect (v0.12.4+) |
codeMcpServer() |
Wrap an MCP server with Code Mode — all tools become typed sandbox APIs |
When to Use
| Need | Approach |
|---|---|
| Static API endpoint or cron | Standard Worker (wrangler deploy) |
| Custom protocol, non-chat agent | Agent base class |
| Chat with full control over agentic loop | AIChatAgent |
| Chat with minimal boilerplate | Think (handles everything) |
| Voice interaction | withVoice(Agent) or withVoice(AIChatAgent) |
| Orchestrating multiple agents | Agent + subAgent() |
| LLM composing multiple tools via code | Code Mode (@cloudflare/codemode) |
| Durable multi-step workflow | AgentWorkflow (Workflows integration) |
Full API references: references/agents-sdk-core.md, references/agents-sdk-chat-voice.md, references/codemode.md
Storage & Data Services
| Service | Purpose | Key Commands |
|---|---|---|
| KV | Key-value store | kv namespace create/list, kv key put/get/list/delete |
| R2 | Object storage (S3-compatible) | r2 bucket create/list, r2 object put/get/delete |
| D1 | SQLite database | d1 create/list, d1 execute --remote, d1 migrations apply --remote |
| Queues | Message queues between Workers | queues create/list/delete, queues consumer add/remove |
| Vectorize | Vector DB for AI/embeddings | vectorize create/list/delete, vectorize insert |
| Hyperdrive | Connection pooling for external DBs | hyperdrive create/list/delete |
Important: D1 commands default to the local dev database. Add --remote to target production:
wrangler d1 execute my-database --command "SELECT * FROM users" --remote
Full command reference with all flags: references/wrangler-commands.md
Secrets
wrangler secret put SECRET_NAME # Prompts for value
echo "value" | wrangler secret put SECRET_NAME # From stdin
wrangler secret list
wrangler secret bulk secrets.json # Bulk upload
Common Workflows
CI/CD with GitHub Actions
# .github/workflows/deploy.yml
- name: Deploy to Cloudflare Pages
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy out --project-name mysite
Note: In CI/CD (non-interactive), create the project first with wrangler pages project create — auto-creation only works interactively.
Tail Production Logs
wrangler tail my-worker --format pretty
wrangler pages deployment tail --project-name mysite
Troubleshooting
# Check auth
wrangler whoami
# Re-authenticate
wrangler logout && wrangler login
# Check wrangler version
wrangler --version
# Verbose output for debugging
WRANGLER_LOG=debug wrangler pages deploy out --project-name mysite
- "Authentication error" — Run
wrangler loginor setCLOUDFLARE_API_TOKEN - "Project not found" — Check project name:
wrangler pages project list - "Build output not found" — Verify build output directory exists. See
references/pages-config.mdfor framework-to-directory mapping. - Pages deploy hangs — Check
_headers/_redirectssyntax (no YAML, plain text format) - Deploy includes too many files — Ensure
--directorypoints to the build output only (e.g.,out/,dist/), not the project root
Browser Rendering (Web Scraping & Crawling)
Budget alternative to Firecrawl using Cloudflare's headless Chrome on the edge. Free tier: 10 min/day, 5 crawls/day, 100 pages/crawl. Static fetches (--no-render) are free during beta.
Quick Start
# Single page to markdown
python3 ~/.claude/skills/cloudflare/scripts/cf_browser.py markdown https://example.com
# Free static fetch (no JS rendering, free during beta)
python3 ~/.claude/skills/cloudflare/scripts/cf_browser.py markdown https://example.com --no-render
# With filter pipeline (same as Firecrawl)
python3 ~/.claude/skills/cloudflare/scripts/cf_browser.py markdown https://docs.example.com | \
python3 ~/.claude/skills/firecrawl/scripts/filter_web_results.py --sections "API" --max-chars 5000
# Multi-page crawl
python3 ~/.claude/skills/cloudflare/scripts/cf_browser.py crawl https://docs.example.com --limit 50
# Screenshot / PDF
python3 ~/.claude/skills/cloudflare/scripts/cf_browser.py screenshot https://example.com -o page.png
python3 ~/.claude/skills/cloudflare/scripts/cf_browser.py pdf https://example.com -o page.pdf
# AI-structured extraction (Workers AI, free tier included)
python3 ~/.claude/skills/cloudflare/scripts/cf_browser.py json https://example.com --prompt "Extract product names and prices"
# Extract links
python3 ~/.claude/skills/cloudflare/scripts/cf_browser.py links https://example.com
When to Use CF Browser Rendering vs Firecrawl vs Scrapling
| Need | Best Tool | Why |
|---|---|---|
| Clean markdown, reliable | firecrawl scrape --only-main-content |
Best markdown quality, optimized for LLMs |
| Cheap/free JS-rendered scrape | cf_browser.py markdown URL |
Free 10 min/day, $0.09/hr after |
| Free static page fetch | cf_browser.py markdown URL --no-render |
FREE during beta |
| Multi-page crawl on a budget | cf_browser.py crawl URL |
5 free crawls/day, 100 pages each |
| Incremental re-crawl | cf_browser.py crawl --modified-since |
Built-in cache, Firecrawl lacks this |
| Autonomous data finding (no URL) | firecrawl_api.py agent |
No CF equivalent |
| Anti-bot / Cloudflare bypass | scrapling --stealth |
Local, no API key |
| Web search + scrape | firecrawl search --scrape |
No CF search API |
| Twitter/X content | jina URL |
Only tool that works |
Subcommands
| Command | Description |
|---|---|
markdown |
Single page → markdown |
content |
Single page → rendered HTML |
crawl |
Multi-page async crawl (polls until done, or --async) |
status |
Check crawl job status |
cancel |
Cancel a running crawl |
screenshot |
Page screenshot (PNG) |
pdf |
Page → PDF |
links |
Extract all links |
scrape |
Extract elements via CSS selectors |
json |
AI-structured extraction (Workers AI) |
Auth
Uses CLOUDFLARE_ACCOUNT_ID + CLOUDFLARE_API_TOKEN (preferred) or CLOUDFLARE_GLOBAL_API_KEY + CLOUDFLARE_EMAIL (fallback). All in ~/.config/env/secrets.env.
Pricing
| Tier | Browser Hours | Crawl Limits |
|---|---|---|
| Free | 10 min/day | 5 jobs/day, 100 pages/job |
| Paid | 10 hr/month included, $0.09/hr after | 100,000 pages/job |
Full API reference: references/browser-rendering-api.md
Reference Documentation
| File | Contents |
|---|---|
references/wrangler-commands.md |
Full Wrangler CLI command reference with all flags |
references/pages-config.md |
Pages config: _headers, _redirects, build presets, env vars |
references/browser-rendering-api.md |
Browser Rendering REST API: endpoints, params, pricing, limits |
references/agents-sdk-core.md |
Agents SDK core: Agent class, scheduling, fibers, HITL, workflows, observability, MCP |
references/agents-sdk-chat-voice.md |
Chat (AIChatAgent, Think), Voice, sub-agents, agent tools, chat recovery |
references/codemode.md |
Code Mode, Dynamic Workers (open beta), sandbox security, MCP barrel export |