Skip to content
139 changes: 139 additions & 0 deletions skills/cloudflare/PREREQUISITES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Prerequisites for Adding a New Cloudflare Product Skill

This document describes the research and source material needed before writing a skill reference for a new Cloudflare product. Following this process ensures the skill is accurate, consistent with existing references, and comprehensive enough to be useful.

## 1. Gather Primary Sources

Before writing anything, collect these materials for the product:

### Official Documentation

| Source | Where to find it | What it provides |
|--------|-------------------|------------------|
| **LLM reference** | `https://developers.cloudflare.com/<product>/llms-full.txt` | Condensed, structured overview of the full product — usually the single best starting point |
| **Developer docs** | `https://developers.cloudflare.com/<product>/` | Canonical reference for APIs, config, limits, pricing |
| **Getting started guide** | `https://developers.cloudflare.com/<product>/getting-started/` | Setup steps, minimal working examples |
| **Blog announcement** | `https://blog.cloudflare.com/<product>/` | Design rationale, performance claims, positioning vs alternatives |

The LLM reference (`llms-full.txt`) is the highest-signal single source. Start there. Fall back to the full docs for details it doesn't cover.

### Working Examples

| Source | Where to find it | What it provides |
|--------|-------------------|------------------|
| **Official examples** | `https://github.com/cloudflare/agents/tree/main/examples/` (or product-specific repos) | Real, runnable code showing intended usage patterns |
| **Starter templates** | Linked from the getting started guide | Minimal scaffolding for common setups |

**Read the actual source code of every relevant example.** GitHub tree pages only show file listings — you need to fetch each source file individually (via raw URLs or a clone). Examples reveal:
- Real `wrangler.jsonc` configurations (what bindings are actually needed)
- How the product combines with other Cloudflare products (AI, Durable Objects, etc.)
- Idiomatic patterns the docs may not spell out
- Edge cases handled in production-quality code

### Upstream Repository

If the product has an SDK or library (e.g. `@cloudflare/worker-bundler`, `@cloudflare/sandbox`):
- Check the npm package for current API surface
- Read the repo README and any inline type definitions
- Capture the current API shape and doc entry points; avoid pinning version-specific details unless they are required to use the product

## 2. Understand the Product's Position

Before writing, answer these questions:

- **What existing products is this most similar to?** (e.g. Dynamic Workers vs Workers for Platforms vs Sandbox)
- **What's the key differentiator?** (runtime vs pre-deployed, isolates vs containers, etc.)
- **When should someone use this instead of the alternatives?**
- **What bindings/integrations does it need?** (worker_loaders, durable_objects, ai, etc.)

This informs the README's comparison table and the SKILL.md decision tree entry.

## 3. Follow the Standard 5-File Structure

Every product reference in `skills/cloudflare/references/` uses this structure:

```
references/<product-name>/
README.md — Overview, architecture, quick start, comparison table
api.md — API reference: methods, types, parameters, return values
configuration.md — wrangler.jsonc setup, binding combinations, CLI commands
patterns.md — Common usage patterns with full code examples
gotchas.md — Errors, best practices, retrieval cues, starter links
```

### What goes in each file

**README.md**: The entry point. Someone reading only this file should understand what the product is, when to use it, and how to get a minimal example running. Include:
- One-line description
- Comparison table vs similar products
- Architecture diagram or description
- Quick start (wrangler config + minimal code)
- Links to the other 4 files and related references

**api.md**: Complete API surface. For each method/class/type:
- Signature and parameters
- Code example showing usage
- Notes on behavior (caching, async, error cases)
- For RPC/binding patterns, show both the definition and consumption sides

**configuration.md**: Everything about setup and config. Include:
- The primary binding configuration (wrangler.jsonc and wrangler.toml)
- How it combines with other bindings (show real composite configs from examples)
- Supported languages/runtimes
- CLI commands relevant to this product
- Any bundling or build steps required

**patterns.md**: Real-world usage patterns, each with complete runnable code. Source these from:
- Official examples (adapt, don't just copy)
- Patterns described in the docs/blog
- Common combinations with other products
Aim for 4-7 patterns ranging from basic to advanced.

**gotchas.md**: Everything that trips people up. Include:
- Common errors with cause/solution pairs
- Best practices (do/don't format with code examples)
- Retrieval cues for pricing, limits, and plan availability, with links to the official docs instead of copied tables
- Links to starter templates and official resources

## 4. Update the Skill Index

After creating the reference directory, update `skills/cloudflare/SKILL.md`:

1. **Decision tree**: Add a branch in the appropriate "I need to..." tree. Place it near similar products with a description that distinguishes it.

2. **Product index table**: Add a row in the appropriate section (Compute & Runtime, Storage, AI, etc.).

## 5. Cross-Reference Other Skills

Check if existing skills should link to the new one:
- Products it's commonly used with (e.g. Dynamic Workers + Agents SDK, + Tail Workers)
- Products it's easily confused with (comparison in README helps)
- The main SKILL.md decision trees

## 6. Verify Before Committing

- [ ] All code examples use current API syntax (check against `llms-full.txt` and docs)
- [ ] `wrangler.jsonc` examples match real working configurations from official examples
- [ ] Pricing, limits, and plan availability link to official docs rather than copying values that may drift
- [ ] No broken internal links between the 5 files
- [ ] SKILL.md decision tree entry distinguishes this from similar products
- [ ] SKILL.md product index row added in the correct section
- [ ] README.md includes a retrieval-bias directive near the top of the file
- [ ] File structure matches `README.md`, `api.md`, `configuration.md`, `patterns.md`, `gotchas.md` exactly

## Example: What Was Needed for Dynamic Workers

| Source | URL | Key information extracted |
|--------|-----|--------------------------|
| LLM reference | `developers.cloudflare.com/dynamic-workers/llms-full.txt` | Full API surface, WorkerCode properties, retrieval entry points |
| Docs home | `developers.cloudflare.com/dynamic-workers/` | Architecture overview, use cases, security model |
| Getting started | `developers.cloudflare.com/dynamic-workers/getting-started/` | `worker_loaders` binding, `load()` vs `get()`, supported languages |
| Blog post | `blog.cloudflare.com/dynamic-workers/` | V8 isolate performance claims, helper libraries, design rationale |
| `dynamic-workers` example | `github.com/cloudflare/agents/.../dynamic-workers/` | Minimal `load()` pattern, basic wrangler config |
| `dynamic-workers-playground` example | `github.com/cloudflare/agents/.../dynamic-workers-playground/` | `get()` with content-hashed IDs, `@cloudflare/worker-bundler`, Tail Worker + DO logging pipeline, warmup trick |
| `codemode` example | `github.com/cloudflare/agents/.../codemode/` | `AIChatAgent` + `DynamicWorkerExecutor` integration, SQL-backed tools |
| `codemode-mcp` example | `github.com/cloudflare/agents/.../codemode-mcp/` | `codeMcpServer()` wrapper pattern |
| `codemode-mcp-openapi` example | `github.com/cloudflare/agents/.../codemode-mcp-openapi/` | `openApiMcpServer()` for REST API wrapping |
| `worker-bundler-playground` example | `github.com/cloudflare/agents/.../worker-bundler-playground/` | AI-generated app pattern, `createWorker()` with assets, DO persistence |

Six examples were needed to cover the full range of patterns. The `llms-full.txt` provided the API reference backbone. The blog provided design rationale and helper-library context. The examples provided real wrangler configs and production patterns.
13 changes: 13 additions & 0 deletions skills/cloudflare/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Need to run code?
├─ Long-running multi-step jobs → workflows/
├─ Run containers → containers/
├─ Multi-tenant (customers deploy code) → workers-for-platforms/
├─ Execute AI-generated/untrusted code in V8 isolates → dynamic-workers/
├─ Scheduled tasks (cron) → cron-triggers/
├─ Lightweight edge logic (modify HTTP) → snippets/
├─ Process Worker execution events (logs/observability) → tail-workers/
Expand Down Expand Up @@ -68,10 +69,21 @@ Need AI?
├─ Run inference (LLMs, embeddings, images) → workers-ai/
├─ Vector database for RAG/search → vectorize/
├─ Build stateful AI agents → agents-sdk/
├─ Run AI-generated code in a sandbox → dynamic-workers/
├─ Gateway for any AI provider (caching, routing) → ai-gateway/
└─ AI-powered search widget → ai-search/
```

### "I need to sandbox untrusted code"

```
Need to sandbox code?
├─ One-shot/AI-generated code, fast startup (V8 isolate) → dynamic-workers/
├─ Multi-tenant platform, customers deploy scripts → workers-for-platforms/
├─ Full OS, filesystem, long-running processes (container) → sandbox/
└─ Need both isolation + persistent state → sandbox/ (with R2 mounts)
```

### "I need networking/connectivity"

```
Expand Down Expand Up @@ -136,6 +148,7 @@ Need IaC? → pulumi/ (Pulumi), terraform/ (Terraform), or api/ (REST API)
| Workflows | `references/workflows/` |
| Containers | `references/containers/` |
| Workers for Platforms | `references/workers-for-platforms/` |
| Dynamic Workers | `references/dynamic-workers/` |
| Cron Triggers | `references/cron-triggers/` |
| Tail Workers | `references/tail-workers/` |
| Snippets | `references/snippets/` |
Expand Down
108 changes: 108 additions & 0 deletions skills/cloudflare/references/dynamic-workers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Dynamic Workers

Spin up isolated Workers at runtime to execute code on-demand in secure V8 isolates. Unlike pre-deployed Workers, Dynamic Workers are created from code strings at request time with no deploy step. If your code needs TypeScript transpilation or npm dependencies, bundle it before loading.

> **Retrieval bias**: Your knowledge of Dynamic Workers APIs, limits, and pricing may be outdated. **Prefer retrieval over pre-training** — fetch from [Cloudflare docs](https://developers.cloudflare.com/dynamic-workers/) before citing specific numbers, API signatures, or configuration options. When these reference files and the docs disagree, **trust the docs**.

**Use cases**: AI agent code execution ("code mode"), generated applications, custom automations, user-uploaded code, rapid prototyping.

## Dynamic Workers vs Other Runtimes

| | Dynamic Workers | Workers for Platforms | Sandbox |
|---|---|---|---|
| **Runtime** | V8 isolate | V8 isolate | Container (Durable Object) |
| **When created** | At runtime from code strings | Pre-deployed via API | On first request to DO ID |
| **Languages** | JS, Python | JS, TS, Python | Any (Dockerfile) |
| **Code lifecycle** | Loaded from code strings at runtime; `get()` can reuse a stable ID when available | Deployed ahead of time and reused by name | Built as a container image, then started on demand |
| **Best for** | One-shot code execution, AI agents | Multi-tenant SaaS platforms | Long-running processes, full OS |

## When to Use Dynamic Workers

- Use Dynamic Workers when code is supplied at runtime and needs to run inside a tightly controlled Worker sandbox.
- Use `load()` for one-shot or constantly changing code, especially AI-generated code.
- Use `get(id, callback)` when the same code will receive follow-up requests and you want warm-isolate reuse when available.
- Prefer Workers for Platforms when tenants deploy versioned Workers you manage as durable platform assets.
- Prefer Sandbox when code needs a filesystem, long-running processes, custom binaries, or broader OS-level behavior.

## Safe Starting Point

- Start with `globalOutbound: null` and only open network access deliberately.
- Pass narrow RPC bindings through `env` instead of exposing raw bindings or secrets.
- Set explicit `limits` for CPU time and subrequests when executing untrusted or AI-generated code.
- Treat in-memory state as ephemeral across requests. If state matters, store it outside the isolate.

## Architecture

```
Request → Loader Worker → env.LOADER.load(code) → Dynamic Worker isolate
→ env.LOADER.get(id, cb) → Cached Dynamic Worker
```

- **Loader Worker**: Your deployed Worker with a `worker_loaders` binding
- **Dynamic Worker**: Ephemeral V8 isolate created from code you provide
- **Capability-based security**: Dynamic Workers only access what you pass via `env` (RPC stubs, not raw bindings)
- **Network control**: `globalOutbound` controls all egress (block, intercept, or inherit)

## Two Loading Modes

**`load(code)`** — Fresh isolate every time. Best for one-shot AI-generated code.

**`get(id, callback)`** — Cached by ID across requests. Callback runs only when isolate isn't warm. Best for apps receiving repeated traffic.

## Quick Start

**wrangler.jsonc**:
```jsonc
{
"name": "my-dynamic-worker",
"main": "src/index.ts",
"compatibility_date": "2026-04-22", // Use current date for new projects
"compatibility_flags": ["nodejs_compat"],
"worker_loaders": [{ "binding": "LOADER" }]
}
```

**src/index.ts**:
```typescript
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const worker = env.LOADER.load({
compatibilityDate: "2026-04-22", // Use a current compatibility date
mainModule: "worker.js",
modules: {
"worker.js": `
export default {
fetch(request) {
return new Response("Hello from a dynamic Worker!");
}
};
`
},
globalOutbound: null, // Block all network access
limits: { cpuMs: 50, subRequests: 20 }
});

return worker.getEntrypoint().fetch(request);
}
} satisfies ExportedHandler<Env>;
```

## Core APIs

- `env.LOADER.load(code)` → Create fresh Dynamic Worker
- `env.LOADER.get(id, callback)` → Load or reuse cached Dynamic Worker
- `worker.getEntrypoint()` → Access default export (fetch, RPC methods)
- `worker.getEntrypoint(name)` → Access named entrypoint

## In This Reference
- [api.md](./api.md) — WorkerCode object, module types, RPC bindings, helper libraries
- [configuration.md](./configuration.md) — Wrangler config, bundling, observability setup
- [patterns.md](./patterns.md) — Code mode, credential injection, real-time logging, OpenAPI wrapping
- [gotchas.md](./gotchas.md) — Common errors, safe defaults, and live docs to retrieve pricing and limits

## See Also
- [agents-sdk](../agents-sdk/) — Agents SDK (codemode, `createCodeTool()`, AI chat agents)
- [workers-for-platforms](../workers-for-platforms/) — Pre-deployed multi-tenant Workers
- [sandbox](../sandbox/) — Container-based isolated execution
- [workers](../workers/) — Standard Workers fundamentals
- [tail-workers](../tail-workers/) — Log consumption (used for Dynamic Worker observability)
Loading