Cloudflare released cf, a CLI that mirrors their entire API surface and supports TypeScript configuration-as-code. They also open-sourced Forge, the internal SDK generator that makes it possible. The design philosophy is explicit: build tools that work equally well for humans typing commands and agents executing programmatic workflows.
This is not a curated subset of common operations. It is the full API surface, generated from OpenAPI specs, with type-safe bindings and programmatic configuration. The shift reveals a broader pattern in infrastructure tooling: CLIs are being redesigned with AI agents as first-class users.
Traditional CLIs optimize for human discoverability. You type --help, scan flags, and compose commands interactively. Agentic CLIs optimize for programmatic consumption while maintaining human usability.
Key differences:
Cloudflare's implementation lets you write configuration files in TypeScript that the CLI executes. An agent can generate these files programmatically, version them, and execute them without string interpolation or shell escaping.
// TypeScript config file for cf CLI
import { cf } from '@cloudflare/cf';
export default cf.configure({
zone: {
id: process.env.ZONE_ID,
settings: {
ssl: 'strict',
minify: {
js: true,
css: true,
html: false
}
}
},
workers: {
scripts: [{
name: 'api-gateway',
content: await Deno.readTextFile('./worker.js'),
bindings: {
KV: { namespace_id: process.env.KV_NAMESPACE }
}
}]
}
});
This is executable configuration. The agent does not need to know Cloudflare's flag syntax. It imports the library, calls typed functions, and gets compile-time validation.
Forge is Cloudflare's internal tool for generating SDKs from OpenAPI specs. They open-sourced it alongside the CLI. The workflow:
This approach solves the maintenance problem. When Cloudflare adds a new API endpoint, the OpenAPI spec updates, Forge regenerates the SDK, and the CLI automatically supports the new operation. No manual documentation or CLI flag design required.
Trade-offs:
| Aspect | Generated CLI | Hand-Written CLI |
|---|---|---|
| API coverage | Complete, automatic | Curated, manual |
| Maintenance burden | Low (regenerate on spec change) | High (update code, docs, tests) |
| Discoverability | Poor (too many commands) | Good (focused on common tasks) |
| Type safety | Full (generated from spec) | Partial (depends on discipline) |
| Agent usability | Excellent (programmatic API) | Poor (string parsing required) |
| Human usability | Mixed (overwhelming options) | Excellent (guided workflows) |
Cloudflare chose completeness over curation. The CLI has hundreds of commands because the API has hundreds of endpoints. This is a bet that agents will handle the complexity through programmatic interfaces, while humans will use IDE autocomplete and type hints to navigate.
The cf CLI is not a standalone binary that makes HTTP requests. It is a Node.js package that imports the generated SDK and adds a command-line interface layer.
Execution flow:
For TypeScript config files, the flow is simpler:
This architecture means the CLI and SDK share the same code paths. An agent using the SDK directly gets identical behavior to the CLI, just without the terminal formatting layer.
Cloudflare's API is RESTful, so state management happens server-side. The CLI does not maintain local state beyond authentication tokens. Each command is a stateless API call.
Idempotency handling:
This is critical for agent workflows. An agent can repeatedly execute the same configuration file without side effects. The CLI calculates what changed and only applies deltas.
// Agent workflow: apply config with diff preview
const config = await generateConfig(requirements);
const diff = await cf.plan(config); // Fetch current state, calculate diff
if (diff.changes.length > 0) {
await cf.apply(config); // Apply only the changes
}
The CLI inherits Cloudflare's API security model:
CLOUDFLARE_API_TOKEN for CI/CD environments.
For agent workflows, the security boundary is the API token scope. An agent with a read-only token cannot modify infrastructure, even if it has full CLI access. This is better than SSH-based automation, where the agent typically has full shell access.
Risk: TypeScript config execution
TypeScript config files are executable code. If an agent generates a malicious config file, it can execute arbitrary code when the CLI loads it. Mitigation strategies:
The CLI supports structured logging and tracing:
For agent workflows, JSON output mode is essential. The agent can parse responses programmatically without regex scraping terminal output.
cf zones list --output json | jq -r '.[] | select(.name == "example.com") | .id'
The CLI is distributed as an npm package. This is unusual for infrastructure CLIs, which typically ship as standalone binaries (Terraform, kubectl, etc.). The npm distribution model has implications:
Advantages:
npm install @cloudflare/cf and import it directly.
Disadvantages:
For agent harnesses, the npm distribution is a net positive. Most agent runtimes already include Node.js, and the ability to import the CLI as a library outweighs the startup cost.
1. API spec drift
If Cloudflare's OpenAPI spec diverges from actual API behavior, the generated CLI will have bugs. This is a risk with any code generation approach. Mitigation: comprehensive integration tests that run against production API.
2. Rate limiting
Agents executing many CLI commands in parallel can hit Cloudflare's rate limits. The CLI does not implement automatic retry with backoff. Agents must handle this at the orchestration layer.
3. TypeScript config errors
Syntax errors in config files cause runtime failures. The CLI does not pre-validate configs before execution. Agents should lint generated configs before passing them to the CLI.
4. Token expiration
API tokens can expire or be revoked. The CLI does not refresh tokens automatically. Agents must implement token rotation logic.
Good fit:
Poor fit:
The Cloudflare approach works because they already had comprehensive OpenAPI specs and a large API surface. For smaller projects, the overhead of maintaining specs and running a code generator may not be worth it.
Use Cloudflare's cf CLI when:
Avoid it when:
Use the Forge pattern (generated CLI from OpenAPI) when:
Avoid Forge when:
The agentic CLI pattern is emerging across infrastructure tooling. Cloudflare's implementation shows the plumbing: OpenAPI as source of truth, code generation for SDK coverage, TypeScript for executable configuration, and npm distribution for programmatic access. The trade-off is clear: you sacrifice human discoverability for agent usability. Whether that trade-off makes sense depends on who your primary user is.