Skip to content

Cf Agentic CLI Guide: Cloudflare API Hands-On

Cf is the open-beta agentic CLI for 2,900+ Cloudflare API ops. Install on Node 22.18+, wire search → schema → dry-run, migrate from Wrangler, and avoid the exit-0 abort trap.

7 min readBeginner

48% of Wrangler usage is already agents – up from about 25% in March 2026, per Cloudflare’s cf launch post (open beta called for September 28, 2026 / Birthday Week). Those agents fire almost 2× the distinct commands humans do per day and are ~4× more likely to chain six or more. Wrangler still tops out near 280 operations. The rest of the API was the gap.

If your coding agent touches Workers, DNS, D1, Access, WAF, or Registrar, you’ve been writing raw fetch wrappers or watching the model invent flags. cf is one binary for you and the agent: the public Cloudflare API surface plus Workers projects, shipped as open beta.

What cf is (and what it isn’t yet)

More than 2,900 commands – over 3,000 API operations – most generated from the same OpenAPI schemas behind the docs and SDKs. That’s the number on the cf docs homepage, not a marketing round-up. JSON is default output: pretty on a TTY, tight on a pipe, so agents spend fewer tokens. You stop guessing which old Wrangler subcommands secretly take --json.

cloudflare.config.ts (typed defineConfig, bindings.*, triggers.*) becomes the Workers config path. Vite is the default local toolchain. cf cli search does a local natural-language lookup (up to five matches, no credentials). Auth is separate from Wrangler: cf auth login does not inherit wrangler login.

Resource commands can sit beside an existing Wrangler repo. Project commands – cf dev / build / deploy – expect the new config. After open beta ends, a final Wrangler major redirects toward cf; Wrangler then gets 18 months of maintenance. cf itself is free open source (Apache-2.0/MIT) on GitHub cloudflare/cf. Beta commands, config shape, and Build Output can still change – treat timelines below as of that launch announcement unless docs say otherwise.

Setup that doesn’t fight you

Hard requirements from Get started: a Cloudflare account and Node.js 22.18 or later. Bun is unsupported. Anything that loads cloudflare.config.ts fails under Bun as of the current beta docs – don’t “try it anyway” in an agent image.

  1. Install: npm install --global cf
  2. cf --version
  3. cf auth login – browser + one-time code. On SSH/containers: --no-browser.
  4. Quick check: cf auth whoami, then cf zones list (JSON on stdout; status on stderr).
cf cli search "add an A record"
# local NL → up to five command matches as JSON

cf zones list > zones.json

CI / headless agents: set CLOUDFLARE_API_TOKEN. If that token can see more than one account, also set CLOUDFLARE_ACCOUNT_ID (or a saved project account) – missing account context fails instead of prompting. Credential order is token, then profile, then default.

Pro tip: one line in user-level AGENTS.md or CLAUDE.md kills Wrangler muscle memory: “When interacting with Cloudflare, use the cf CLI unless the project has a Wrangler configuration file.”

Wire it once. Most sessions stop reinventing curl. Deeper agent notes: Use cf with coding agents.

Here’s the odd part about “agentic” CLIs: the win isn’t a smarter binary. It’s boring, stable shapes – JSON default, local search, schema dump, dry-run without creds – so the model stops hallucinating flags you then spend twenty minutes unscrewing.

Advanced usage agents actually need

Three thousand routes will drown a context window. The loop that actually works: search → schema → dry-run → execute.

cf cli search "provision D1"
cf schema d1 create
cf d1 create --name my-db --dry-run
cf d1 create --name my-db

cf schema prints operationId, method, path, params, body fields. Path/query names follow the API (often account_id). Flag-mapped body fields show up in the dump; when the body is still incomplete, pass --body with full JSON from the API reference. Dry-run needs no credentials and prints the request.

The catch is identifiers. Wrangler often accepted a D1 name. cf wants the database ID the API uses. Same pattern on a lot of products. Agents that skip search/schema invent flags that never existed.

Task Wrangler-ish habit cf reality
List / page Often auto-paged tables One API page per call; pass cursor yourself
Environments --env staging --mode staging from config
Local data Many commands default local Remote by default; --local only for limited KV / D1 raw+migrations / R2
Output Tables + optional –json JSON default

New Worker: cf init scaffolds Vite + cloudflare.config.ts. Existing Wrangler app: cf migrate --dry-run, then cf migrate. Vite conversions tend to be the smooth path; esbuild-centered pipelines still lean on Wrangler for builds until you change that. Static sites can cf deploy with almost no config. Named profiles (cf auth create work + cf auth activate work) split personal vs company without env-var spaghetti.

Honest limitations of the beta

Docs for Wrangler users spell the gaps out. Consequences matter more than the feature list.

  • No live Worker log stream.npx wrangler tail <WORKER_NAME> – no global Wrangler install required.
  • No single-secret put. Bulk with --secrets-file on cf deploy / cf workers versions create, or npx wrangler secret put.
  • Migrate is not zero-touch. Durable Object migrations, Workflows, Containers, and similar land as TODO(@cloudflare) comments plus a throw at the top of the generated config. cf dev / build / deploy fail until you resolve those items and delete the throw.
  • Destructive + non-interactive. Without --force, some deletes print Aborted. to stderr and exit 0. Success code ≠ resource gone. Check stderr; prefer dry-run first.
  • Multi-account CI. Token sees several accounts and no CLOUDFLARE_ACCOUNT_ID (or saved project account) → hard fail, no prompt.
  • List pagination. One page per call; you own the cursor.
  • --local scope. Only limited KV / D1 / R2 paths – remote is the default mindset.

Actually, --force is worse than it looks: on some calls it’s also an API parameter (for example deleting a Worker other Workers still reference). Review before an agent passes it on every mutate.

Will training data “catch up” before your team standardizes on cf? Maybe. Search + a one-line AGENTS.md preference already beats stuffing 2,900 names into a system prompt – so the waiting-for-weights argument is thinner than it sounds. Still: which gap blocks you this week, tail or secrets or migrate TODOs?

FAQ

Does cf replace Wrangler today?

No. Broad API and new or migrated projects → cf. Tail, single secrets, and anything still on the unsupported list → Wrangler via npx until beta closes those holes.

How do I point Claude Code (or similar) at cf without invented commands?

You install and finish cf auth login yourself. Add the prefer-cf line to CLAUDE.md / AGENTS.md. Example session instruction that works in practice: “For Cloudflare, run cf cli search "...", then cf schema ..., then --dry-run before any mutating call.” That three-step path is what the agents docs walk through – cheaper and safer than pasting the whole catalog into the system prompt.

Will migrate break my production Worker?

Not if you treat migrate as a config rewrite on a branch. Start with cf migrate --dry-run, clear every TODO(@cloudflare), remove the throw, keep old Wrangler files until you truly don’t need tail or secret put, and verify on a non-production deploy. Vite-based apps usually convert cleaner than custom esbuild pipelines – diff package.json and deploy scripts either way. Cloudflare has not published an open-beta end date; the 18-month Wrangler maintenance clock starts only after beta ends (per the launch materials).

Throwaway directory. npm install --global cf && cf auth login && cf init. Ask the agent to list zones, then create a disposable D1 through search → schema → dry-run. Ten minutes. You’ll know if cf fits your agent loop faster than another feature roundup will tell you.