cloudflare-workers – DevOps & Infrastructure skill for AI agents
Build and deploy edge functions with Cloudflare Workers and Wrangler. Use for APIs, cron jobs, and edge middleware.
Install the cloudflare-workers skill with one command
Pick the tool you use, copy the command and paste it in your terminal. The skill lands in that tool's skills folder and is ready in your next session.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/cloudflare-workers-4ce36.tgz | tar xz -C ~/.claude/skills
Call it in Claude Code: /cloudflare-workers – then describe the task you want done.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/cloudflare-workers-4ce36.tgz | tar xz -C ~/.codex/skills
Call it in Codex: $cloudflare-workers – then describe the task you want done.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/cloudflare-workers-4ce36.tgz | tar xz -C ~/.hermes/skills
Call it in Hermes Agent: /cloudflare-workers – then describe the task you want done.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/cloudflare-workers-4ce36.tgz | tar xz -C ~/.deepcode/skills
Call it in DeepSeek: /cloudflare-workers – then describe the task you want done.
SKILL.md content
Cloudflare Workers
Deploy JavaScript and TypeScript functions to Cloudflare's global edge network with sub-millisecond cold starts.
When to Use
- Building lightweight APIs and microservices at the edge.
- Adding middleware (auth, rate limiting, header injection) in front of origin servers.
- Running cron jobs on a schedule without maintaining infrastructure.
- Processing webhooks, image transformations, or A/B testing logic.
- Serving dynamic content from KV, D1, or R2 storage bindings.
Prerequisites
- Node.js 18+ installed locally.
- Wrangler CLI:
npm install -g wrangler. - Cloudflare account (free plan supports 100,000 requests/day).
- Authenticated:
wrangler loginor setCLOUDFLARE_API_TOKEN.
Verify Node/Wrangler support, plan quotas and CPU limits for the actual account; historical numbers below are not current entitlement guarantees. Choose target account/environment/routes explicitly before deploy, rollback or remote dev. KV read-modify-write is non-atomic and eventually consistent; concurrent increments lose updates, repeated puts hit write limits, and TTL resets make this a sliding approximation. Use an authoritative rate limiter for security. Increasing cacheTtl does not make KV strongly consistent. waitUntil is bounded background work, not a durable job queue and does not bypass CPU limits. Bind only approved origins, strip unexpected credentials before proxying and validate incoming data before analytics egress. Inline KV/D1 examples mutate on every request and must be isolated or authenticated. Scheduled helpers and analytics endpoints are placeholders, the third cron has no handler, and the Durable Object class must be re-exported from the configured entrypoint with a compatible migration type.
Quick Start
# Scaffold a new Worker project
npm create cloudflare@latest my-worker
cd my-worker
# Login to Cloudflare
npx wrangler login
# Start local development server (port 8787)
npx wrangler dev
# Deploy to production
npx wrangler deployEssential Wrangler Commands
# Remote development: executes in Cloudflare and can affect bound remote resources
npx wrangler dev --remote
# Deploy to a specific environment
npx wrangler deploy --env staging
# Set a secret (prompts for value)
npx wrangler secret put API_TOKEN
npx wrangler secret put API_TOKEN --env staging
# List secrets
npx wrangler secret list
# Tail production logs in real time
npx wrangler tail
# Tail with filters
npx wrangler tail --status=error --search="timeout"
# View deployment versions
npx wrangler deployments list
# Rollback to a previous deployment
npx wrangler rollbackWrangler Configuration
# wrangler.toml
name = "my-api"
main = "src/index.ts"
compatibility_date = "2024-09-01"
compatibility_flags = ["nodejs_compat"]
# Custom routes
routes = [
{ pattern = "api.example.com/*", zone_name = "example.com" }
]
# Or use a workers.dev subdomain
# workers_dev = true
# Environment variables (non-secret)
[vars]
ENVIRONMENT = "production"
API_VERSION = "v2"
# Staging environment override
[env.staging]
name = "my-api-staging"
routes = [
{ pattern = "api-staging.example.com/*", zone_name = "example.com" }
]
[env.staging.vars]
ENVIRONMENT = "staging"Worker Examples
Basic API Router
// src/index.ts
export interface Env {
ENVIRONMENT: string;
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
switch (url.pathname) {
case "/":
return new Response("OK", { status: 200 });
case "/api/health":
return Response.json({
status: "healthy",
env: env.ENVIRONMENT,
timestamp: new Date().toISOString(),
});
case "/api/data":
if (request.method !== "POST") {
return new Response("Method Not Allowed", { status: 405 });
}
const body = await request.json();
// Process in the background after returning response
ctx.waitUntil(logToAnalytics(body));
return Response.json({ received: true });
default:
return new Response("Not Found", { status: 404 });
}
},
};
async function logToAnalytics(data: unknown): Promise<void> {
await fetch("https://analytics.example.com/ingest", {
method: "POST",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" },
});
}Approximate KV Counter (not an enforcement-grade rate limiter)
// src/rate-limiter.ts
interface Env {
RATE_LIMIT_KV: KVNamespace;
ORIGIN_URL: string;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const ip = request.headers.get("CF-Connecting-IP") || "unknown";
const key = `ratelimit:${ip}`;
const window = 60; // seconds
const maxRequests = 100;
const current = parseInt((await env.RATE_LIMIT_KV.get(key)) || "0");
if (current >= maxRequests) {
return new Response("Too Many Requests", {
status: 429,
headers: { "Retry-After": String(window) },
});
}
await env.RATE_LIMIT_KV.put(key, String(current + 1), {
expirationTtl: window,
});
// Forward to origin
const originRequest = new Request(new URL(new URL(request.url).pathname + new URL(request.url).search, env.ORIGIN_URL), request);
return fetch(originRequest);
},
};KV Storage Binding
# wrangler.toml
[[kv_namespaces]]
binding = "MY_KV"
id = "abc123def456"
# Optional preview namespace on the same binding:
# preview_id = "preview789"// KV operations in a Worker
interface Env {
MY_KV: KVNamespace;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Write with TTL
await env.MY_KV.put("session:abc", JSON.stringify({ user: "alice" }), {
expirationTtl: 3600,
});
// Read
const session = await env.MY_KV.get("session:abc", "json");
// List keys by prefix
const list = await env.MY_KV.list({ prefix: "session:", limit: 100 });
// Delete
await env.MY_KV.delete("session:abc");
return Response.json({ session, keys: list.keys.length });
},
};# KV CLI operations
npx wrangler kv namespace create MY_KV
npx wrangler kv namespace list
npx wrangler kv key put --namespace-id=abc123 "config:feature-flags" '{"darkMode":true}'
npx wrangler kv key get --namespace-id=abc123 "config:feature-flags"
npx wrangler kv key list --namespace-id=abc123 --prefix="config:"D1 Database Binding
# wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "my-app"
database_id = "xxxx-yyyy-zzzz"// D1 SQL queries in a Worker
interface Env {
DB: D1Database;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Parameterized query
const { results } = await env.DB.prepare(
"SELECT id, name, email FROM users WHERE active = ? LIMIT ?"
)
.bind(1, 50)
.all();
// Insert
await env.DB.prepare("INSERT INTO users (name, email) VALUES (?, ?)")
.bind("Alice", "[email protected]")
.run();
// Batch multiple statements
await env.DB.batch([
env.DB.prepare("UPDATE users SET active = 0 WHERE last_login < ?").bind("2024-01-01"),
env.DB.prepare("DELETE FROM sessions WHERE expires_at < ?").bind(Date.now()),
]);
return Response.json(results);
},
};# D1 CLI operations
npx wrangler d1 create my-app
npx wrangler d1 list
npx wrangler d1 execute my-app --command="CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, active INTEGER DEFAULT 1)"
npx wrangler d1 execute my-app --file=./migrations/001_init.sql
npx wrangler d1 execute my-app --command="SELECT * FROM users" --jsonCron Triggers
# wrangler.toml
[triggers]
crons = [
"0 */6 * * *", # Every 6 hours
"0 0 * * MON", # Every Monday at midnight
"*/15 * * * *", # Every 15 minutes
]// src/index.ts — scheduled handler
export default {
async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext): Promise<void> {
switch (event.cron) {
case "0 */6 * * *":
ctx.waitUntil(cleanupExpiredSessions(env));
break;
case "0 0 * * MON":
ctx.waitUntil(generateWeeklyReport(env));
break;
}
},
async fetch(request: Request, env: Env): Promise<Response> {
return new Response("OK");
},
};Durable Objects
# wrangler.toml
[durable_objects]
bindings = [
{ name = "COUNTER", class_name = "Counter" }
]
[[migrations]]
tag = "v1"
new_classes = ["Counter"]// src/counter.ts — Durable Object class
export class Counter {
state: DurableObjectState;
constructor(state: DurableObjectState) {
this.state = state;
}
async fetch(request: Request): Promise<Response> {
let count = (await this.state.storage.get<number>("count")) || 0;
c… (full content is in the download package)
Related skills
- cloudformation – Deploy AWS resources with CloudFormation templates. Create stacks, use nested stacks…
- cloudish – Deploy a Dockerfile, source folder, or existing image to Cloudish as a running container…
- quantized-export – Export a promoted fine-tuned model in the right deployment format — merged safetensors…
- kubernetes-operator – Use when building a Kubernetes Operator — custom controllers that reconcile CRD state…
- kubernetes-operator – Use when building a Kubernetes Operator — custom controllers that reconcile CRD state…
- product-price-monitor – Watch product, flight, or listing prices; alert on target.
- risk-metrics-calculation – Calculate portfolio risk metrics including VaR, CVaR, Sharpe, Sortino, and drawdown…
- publish-site – Versioned site deploys to GitHub/Cloudflare/Netlify Pages.