Cloudflare Agents SDK — a framework for building stateful AI agents on Cloudflare Workers. This is a monorepo containing the core SDK packages, examples, guides, sites, and documentation.
packages/ # Published npm packages (need changesets for changes)
agents/ # Core SDK (see packages/agents/AGENTS.md)
ai-chat/ # @cloudflare/ai-chat — higher-level AI chat agent
hono-agents/ # Hono framework integration
codemode/ # @cloudflare/codemode — experimental code generation
examples/ # Self-contained demo apps (see examples/AGENTS.md)
playground/ # Main showcase app — all SDK features in one UI (uses Kumo design system)
mcp/ # MCP server example
mcp-client/ # MCP client example
... # ~20 examples total
experimental/ # Work-in-progress experiments (not published, no stability guarantees)
site/ # Deployed websites
agents/ # agents.cloudflare.com (Astro)
ai-playground/ # Workers AI playground (React + Vite)
guides/ # In-depth pattern tutorials with narrative READMEs (see guides/AGENTS.md)
anthropic-patterns/
human-in-the-loop/
openai-sdk/ # Examples using @openai/agents SDK
basic/ chess-app/ handoffs/ human-in-the-loop/ ...
docs/ # Markdown docs for developers.cloudflare.com (see docs/AGENTS.md)
design/ # Architecture and design decision records (see design/AGENTS.md)
scripts/ # Repo-wide tooling (typecheck, export checks, update checks)
Some directories have their own AGENTS.md with deeper guidance:
| File | Scope |
|---|---|
packages/agents/AGENTS.md |
Core SDK internals — exports, source layout, build, testing, architecture |
examples/AGENTS.md |
Example conventions — required structure, consistency rules, known issues |
guides/AGENTS.md |
Guide conventions — how guides differ from examples, README expectations |
docs/AGENTS.md |
Writing user-facing docs — Diátaxis framework, upstream sync, style |
design/AGENTS.md |
Design records and RFCs — format, workflow, relationship to docs |
npm install # installs all workspaces; postinstall runs patch-package + playwrightNode 24+ required. Uses npm workspaces with Nx for task orchestration, caching, and affected detection.
Run from the repo root:
| Command | What it does |
|---|---|
npm run build |
Builds all packages via Nx (cached, dependency-ordered) |
npm run check |
Full CI check: sherif + export checks + oxfmt + oxlint + typecheck |
npm run test |
Runs all tests via Nx (cached) |
npm run test:react |
Runs Playwright-based React hook tests for agents |
npm run typecheck |
TypeScript type checking across the repo (custom script) |
npm run format |
Oxfmt format all files |
npm run check:exports |
Verifies package.json exports match actual build output |
npx nx affected -t build |
Build only packages affected by current changes |
npx nx affected -t test |
Test only packages affected by current changes |
npx nx run <project>:build |
Build a single project (and its dependencies) |
Run an example locally:
cd examples/playground # or any example
npm run dev # starts Vite dev server + Workers runtime via @cloudflare/vite-plugin- Strict mode enabled (
agents/tsconfig) - Target: ES2021, module: ES2022, moduleResolution: bundler
verbatimModuleSyntax: true— use explicitimport typefor type-only imports- JSX:
react-jsx
Config in .oxlintrc.json. Plugins: react, jsx-a11y, typescript, react-hooks. Key rules:
no-explicit-any: "error"— never useany, useunknownand narrowno-unused-vars: "error"— withvarsIgnorePattern: "^_"andargsIgnorePattern: "^_"correctnesscategory set to"error"— catches common mistakesjsx-a11yrules enabled — accessibility violations are errorsreact-hooks/exhaustive-deps: "warn"— warns on missing hook dependencies
Oxlint does not handle formatting — Oxfmt does.
- Run
npm run formator rely on lint-staged (auto-formats on commit via husky) - Config in
.oxfmtrc.json(trailingComma: "none",printWidth: 80)
- Always TypeScript, always ES modules
wrangler.jsonc(not.toml) for configuration- All wrangler configs use
compatibility_date: "2026-01-28"andcompatibility_flags: ["nodejs_compat"] - Never hardcode secrets — use
wrangler secret putor.dev.vars - No native/FFI dependencies (must run in Workers runtime)
Tests use vitest with @cloudflare/vitest-pool-workers for running inside the Workers runtime.
npm run test # agents + ai-chat unit/integration tests
npm run test:react # Playwright-based React hook tests (agents package)Test locations:
packages/agents/src/tests/— core SDK testspackages/agents/src/react-tests/— React hook tests (Playwright + vitest-browser-react)packages/ai-chat/src/tests/— AI chat testspackages/agents/src/tests-d/— type-level tests (.test-d.ts)
Each test directory has its own vitest.config.ts and (for Workers tests) a wrangler.jsonc.
Changes to packages/ that affect the public API or fix bugs need a changeset:
npx changeset # interactive prompt — pick packages, semver bump, descriptionThis creates a markdown file in .changeset/ that gets consumed during release.
Examples, guides, and sites don't need changesets.
CI runs on every PR (npm ci && npm run build && npm run check && npm run test). All checks must pass. The workflow is in .github/workflows/pullrequest.yml.
env.d.tsfiles are generated bywrangler types— regenerate withnpx wrangler typesinside the relevant example/package, don't hand-editpackage-lock.json— regenerated bynpm install, don't hand-edit
packages/shell/is published as@cloudflare/shell— an experimental sandboxed JS execution and filesystem runtime for agents, built on the same dynamic Worker loader machinery as@cloudflare/codemode.- To run code against a
Workspace: importstateToolsfrom@cloudflare/shell/workersandDynamicWorkerExecutor/resolveProviderfrom@cloudflare/codemode; useexecutor.execute(code, [resolveProvider(stateTools(workspace))]).
- Keep
Workspaceas a pure durable filesystem — do not embed execution or session logic inside it. Execution is a caller concern wired via@cloudflare/codemode+stateTools. - When a package boundary feels wrong (e.g., a helper package depending on a larger package just for an adapter), prefer moving the adapter out rather than carrying the dependency.
Always:
- Run
npm run checkbefore considering work done - Use
import typefor type-only imports (enforced byverbatimModuleSyntax) - Keep examples simple and self-contained — they're user-facing learning material
- Use Cloudflare Workers APIs (KV, D1, R2, Durable Objects, etc.) over third-party equivalents
- Use Workers AI for LLM calls in examples — not third-party APIs like OpenAI or Anthropic
Ask first:
- Adding new dependencies to
packages/(these ship to users) - Changing
wrangler.jsonccompatibility dates across the repo - Modifying CI workflows
Never:
- Hardcode secrets or API keys
- Add native/FFI/C-binding dependencies
- Use
any— Oxlint will reject it - Use CommonJS or Service Worker format — ES modules only
- Modify
node_modules/ordist/directories - Force push to main