Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
bagelhole avatar

Cloudflare Workers

  • 76 installs
  • 44 repo stars
  • Updated May 22, 2026
  • bagelhole/devops-security-agent-skills

cloudflare-workers is a Claude Code skill that builds and deploys edge functions (APIs, cron jobs, middleware) with Cloudflare Workers and Wrangler.

About

This skill builds and deploys edge functions with Cloudflare Workers. It covers Wrangler project setup and commands, wrangler.toml config, API routers, middleware like rate limiting, cron jobs, and KV, D1, and R2 storage bindings. A developer uses it to build lightweight edge APIs, middleware, and scheduled jobs without managing servers. It matters for running low-latency serverless logic at the edge.

  • Builds and deploys edge functions with Cloudflare Workers and Wrangler
  • Covers APIs, middleware, cron jobs, and KV/D1/R2 storage bindings
  • Includes Wrangler config, secrets, rate limiting, and tail logging

Cloudflare Workers by the numbers

  • 76 all-time installs (skills.sh)
  • Ranked #633 of 1,039 Cloud & Infrastructure skills by installs in the Skillselion catalog
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
At a glance

cloudflare-workers capabilities & compatibility

Free plan supports 100,000 requests/day; needs wrangler login or CLOUDFLARE_API_TOKEN

Capabilities
cloudflare pages · cloudflare r2 · cdn setup
Works with
cloudflare
Use cases
api development · devops
Platforms
macOS · Linux · Windows
Pricing
Freemium
From the docs

What cloudflare-workers says it does

Deploy JavaScript and TypeScript functions to Cloudflare's global edge network with sub-millisecond cold starts.
SKILL.md
Cloudflare account (free plan supports 100,000 requests/day).
SKILL.md
npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill cloudflare-workers

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs76
repo stars44
Last updatedMay 22, 2026
Repositorybagelhole/devops-security-agent-skills

What it does

Build and deploy edge functions (APIs, middleware, cron jobs) with Cloudflare Workers and Wrangler.

Who is it for?

Building lightweight edge APIs, middleware, and cron jobs on Cloudflare Workers with storage bindings

Skip if: Heavy, stateful, long-running backend workloads that exceed edge runtime limits

When should I use this skill?

Building edge APIs or microservices, adding middleware, running cron jobs, or serving from KV/D1/R2

What you get

Serverless edge functions deployed globally with storage bindings and secrets managed via Wrangler.

  • Deployed Worker
  • wrangler.toml config
  • Edge API router or middleware

By the numbers

  • Free plan supports 100,000 requests/day
  • Covers 3 storage bindings: KV, D1, R2

Files

SKILL.mdMarkdownGitHub ↗

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 login or set CLOUDFLARE_API_TOKEN.

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 deploy

Essential Wrangler Commands

# Local development with remote bindings (KV, D1, R2)
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 rollback

Wrangler 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" },
  });
}

Middleware: Rate Limiting with KV

// 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(env.ORIGIN_URL + new URL(request.url).pathname, request);
    return fetch(originRequest);
  },
};

KV Storage Binding

# wrangler.toml
[[kv_namespaces]]
binding = "MY_KV"
id = "abc123def456"

# Preview namespace for local dev
[[kv_namespaces]]
binding = "MY_KV"
id = "abc123def456"
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", "alice@example.com")
      .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" --json

Cron 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;
    count++;
    await this.state.storage.put("count", count);
    return Response.json({ count });
  }
}

// src/index.ts — route to Durable Object
interface Env {
  COUNTER: DurableObjectNamespace;
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const id = env.COUNTER.idFromName("global-counter");
    const stub = env.COUNTER.get(id);
    return stub.fetch(request);
  },
};

Custom Routing

# Route to specific zones
routes = [
  { pattern = "api.example.com/v1/*", zone_name = "example.com" },
  { pattern = "api.example.com/v2/*", zone_name = "example.com" },
]

# Or use custom domains (automatic SSL)
# Dashboard: Workers > your-worker > Triggers > Custom Domains

Troubleshooting

SymptomCauseFix
Error 1101: Worker threw exceptionUnhandled error in fetch handlerWrap handler in try/catch; check wrangler tail for stack trace
exceeded CPU time limitWorker exceeds 10ms CPU (free) or 30s (paid)Optimize code; offload work with ctx.waitUntil()
KV reads return stale dataKV is eventually consistent (~60s)Use cacheTtl option or switch to Durable Objects for strong consistency
wrangler dev binding errorsLocal bindings not configuredUse --remote flag or configure preview_id in wrangler.toml
Secret not found in WorkerSecret set for wrong environmentVerify with wrangler secret list --env <env>
CORS errors from browserMissing CORS headers in responseAdd Access-Control-Allow-Origin headers; handle OPTIONS preflight
Route not matchingPattern does not include /* suffixAdd /* to catch all paths: api.example.com/*

Related Skills

  • cloudflare-pages - Frontend deployments with Pages Functions
  • cloudflare-r2 - Object storage at the edge
  • cloudflare-zero-trust - Protect Worker endpoints with Access

Related skills

FAQ

What can Workers connect to?

KV, D1, and R2 storage bindings, plus secrets managed with wrangler secret put.

Does it support scheduled jobs?

Yes. It covers running cron jobs on a schedule without maintaining infrastructure.

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.