Cloudflare Agents SDK skill
Build, debug, or review Cloudflare Agents SDK applications using the agents package.
by cloudflare·Apache-2.0 license·★ 2,976 Stars on the repo·GitHub ↗
npx degit cloudflare/skills/skills/agents-sdk#main ~/.claude/skills/agents-sdkChecked ·commit main
Files of Cloudflare Agents SDK
Show the full text203 lines
Cloudflare Agents SDK
Your knowledge of the Agents SDK may be outdated. Prefer retrieval over pre-training for any Agents SDK task.
Retrieval Sources
Cloudflare docs: https://developers.cloudflare.com/agents/index.md
| Topic | Docs URL | Use for |
|---|---|---|
| Getting started | Quick start | First agent, project setup |
| Adding to existing project | Add to existing project | Install into existing Workers app |
| Configuration | Configuration | wrangler.jsonc, bindings, assets, deployment |
| Agent class | Agents API | Agent lifecycle, patterns, pitfalls |
| State | Store and sync state | setState, validateStateChange, persistence |
| Routing | Routing | URL patterns, routeAgentRequest |
| Callable methods | Callable methods | @callable, RPC, streaming, timeouts |
| Scheduling | Schedule tasks | schedule(), scheduleEvery(), cron |
| Workflows | Run workflows | AgentWorkflow, durable multi-step tasks |
| HTTP/WebSockets | WebSockets | Lifecycle hooks, hibernation |
| Chat agents | Chat agents | AIChatAgent, streaming, tools, persistence |
| Client SDK | Client SDK | useAgent, AgentClient, state, RPC, HTTP |
| Client tools | Client tools | Client-side tools, autoContinueAfterToolResult |
| Server-driven messages | Autonomous responses | saveMessages, waitUntilStable, server-initiated turns |
| Resumable streaming | Chat agents | Stream recovery on disconnect |
| Email routing, secure reply resolver | ||
| MCP client | MCP client | Connecting to MCP servers |
| MCP server | MCP server | Building MCP servers with createMcpHandler |
| MCP transports | MCP transports | Streamable HTTP, SSE, RPC transport options |
| Securing MCP servers | Securing MCP | OAuth, proxy MCP, hardening |
| Human-in-the-loop | Human-in-the-loop | Workflow approvals, elicitation, timeout handling |
| Durable execution | Durable execution | runFiber(), stash(), surviving DO eviction |
| Queue | Queue | Built-in FIFO queue, queue() |
| Retries | Retries | this.retry(), backoff/jitter |
| Observability | Observability | Diagnostics-channel events |
| Push notifications | Push notifications | Web Push + VAPID from agents |
| Webhooks | Webhooks | Receiving external webhooks |
| Cross-domain auth | Cross-domain auth | WebSocket auth, tokens, CORS |
| Readonly connections | Readonly | shouldConnectionBeReadonly |
| Voice | Voice | Experimental STT/TTS, withVoice |
| Browse the web | Browser tools | Experimental CDP browser automation |
| Think | Think | Experimental higher-level chat agent class |
| Migrations | AI SDK v5, AI SDK v6 | Upgrading @cloudflare/ai-chat |
Capabilities
The Agents SDK provides:
- Persistent state — SQLite-backed, auto-synced to clients via
setState - Callable RPC —
@callable()methods invoked over WebSocket - Scheduling — One-time, recurring (
scheduleEvery), and cron tasks - Workflows — Durable multi-step background processing via
AgentWorkflow - Durable execution —
runFiber()/stash()for work that survives DO eviction - Queue — Built-in FIFO queue with retries via
queue() - Retries —
this.retry()with exponential backoff and jitter - MCP integration — Connect to MCP servers or build your own with
createMcpHandler - Email handling — Receive and reply to emails with secure routing
- Streaming chat —
AIChatAgentwith resumable streams, message persistence, tools - Server-driven messages —
saveMessages,waitUntilStablefor proactive agent turns - React hooks —
useAgent,useAgentChatfor client apps - Observability —
diagnostics_channelevents for state, RPC, schedule, lifecycle - Push notifications — Web Push + VAPID delivery from agents
- Webhooks — Receive and verify external webhooks
- Voice (experimental) — STT/TTS via
@cloudflare/voice - Browser tools (experimental) — CDP-powered browsing via
agents/browser - Think (experimental) — Higher-level chat agent via
@cloudflare/think
FIRST: Verify Installation
npm ls agents # Should show agents package
If not installed:
npm install agents
For chat agents:
npm install agents @cloudflare/ai-chat ai @ai-sdk/react
Wrangler Configuration
{
"compatibility_flags": ["nodejs_compat"],
"durable_objects": {
"bindings": [{ "name": "MyAgent", "class_name": "MyAgent" }]
},
"migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyAgent"] }]
}
Gotchas:
- Do NOT enable
experimentalDecoratorsin tsconfig (breaks@callable) - Never edit old migrations — always add new tags
- Each agent class needs its own DO binding + migration entry
- Add
"ai": { "binding": "AI" }for Workers AI
Agent Class
import { Agent, routeAgentRequest, callable } from "agents";
type State = { count: number };
export class Counter extends Agent<Env, State> {
initialState = { count: 0 };
validateStateChange(nextState: State, source: Connection | "server") {
if (nextState.count < 0) throw new Error("Count cannot be negative");
}
onStateUpdate(state: State, source: Connection | "server") {
console.log("State updated:", state);
}
@callable()
increment() {
this.setState({ count: this.state.count + 1 });
return this.state.count;
}
}
export default {
fetch: (req, env) => routeAgentRequest(req, env) ?? new Response("Not found", { status: 404 })
};
Routing
Requests route to /agents/{agent-name}/{instance-name}:
| Class | URL |
|---|---|
Counter |
/agents/counter/user-123 |
ChatRoom |
/agents/chat-room/lobby |
Client: useAgent({ agent: "Counter", name: "user-123" })
Custom routing: use getAgentByName(env.MyAgent, "instance-id") then agent.fetch(request).
Core APIs
| Task | API |
|---|---|
| Read state | this.state.count |
| Write state | this.setState({ count: 1 }) |
| SQL query | this.sql`SELECT * FROM users WHERE id = ${id}` |
| Schedule (delay) | await this.schedule(60, "task", payload) |
| Schedule (cron) | await this.schedule("0 * * * *", "task", payload) |
| Schedule (interval) | await this.scheduleEvery(30, "poll") |
| RPC method | @callable() myMethod() { ... } |
| Streaming RPC | @callable({ streaming: true }) stream(res) { ... } |
| Start workflow | await this.runWorkflow("ProcessingWorkflow", params) |
| Durable fiber | await this.runFiber("name", async (ctx) => { ... }) |
| Enqueue work | this.queue("handler", payload) |
| Retry with backoff | await this.retry(fn, { maxAttempts: 5 }) |
| Broadcast to clients | this.broadcast(message) |
| Get connections | this.getConnections(tag?) |
React Client
Read client-sdk.md for client selection and current connection examples. For chat UI and tools, also read streaming-chat.md.
References
Core
- references/state-scheduling.md — State persistence, scheduling, SQL
- references/callable.md — RPC methods, streaming, timeouts
- references/routing.md — URL patterns, custom routing,
getAgentByName - references/configuration.md — Wrangler config, bindings, Vite setup
Chat & Streaming
- references/streaming-chat.md — AIChatAgent, resumable streams, tools
- references/client-sdk.md —
useAgent,useAgentChat,AgentClient - references/server-driven-messages.md — Trigger patterns,
saveMessages - references/human-in-the-loop.md — Approval flows,
needsApproval
Background Processing
- references/workflows.md — Durable Workflows integration
- references/durable-execution.md —
runFiber,stash, surviving eviction - references/queue-retries.md — Built-in queue, retry with backoff
Integrations
- references/mcp.md — MCP client and server, transports, securing
- references/email.md — Email routing and handling
- references/webhooks-push.md — Webhooks, push notifications
- references/observability.md — Diagnostics-channel events
Experimental
- references/think.md —
@cloudflare/thinkhigher-level chat agent - references/voice.md —
@cloudflare/voiceSTT/TTS - references/codemode.md — Code Mode for tool orchestration
- references/browse-the-web.md — CDP browser tools
| 1 | |
| 2 | name agents-sdk |
| 3 | description Build, debug, or review Cloudflare Agents SDK applications using the agents package. |
| 4 | |
| 5 | |
| 6 | # Cloudflare Agents SDK |
| 7 | |
| 8 | Your knowledge of the Agents SDK may be outdated. **Prefer retrieval over pre-training** for any Agents SDK task. |
| 9 | |
| 10 | ## Retrieval Sources |
| 11 | |
| 12 | Cloudflare docs: https://developers.cloudflare.com/agents/index.md |
| 13 | |
| 14 | | Topic | Docs URL | Use for | |
| 15 | |-------|----------|---------| |
| 16 | | Getting started | [Quick start] | First agent, project setup | |
| 17 | | Adding to existing project | [Add to existing project] | Install into existing Workers app | |
| 18 | | Configuration | [Configuration] | `wrangler.jsonc`, bindings, assets, deployment | |
| 19 | | Agent class | [Agents API] | Agent lifecycle, patterns, pitfalls | |
| 20 | | State | [Store and sync state] | `setState`, `validateStateChange`, persistence | |
| 21 | | Routing | [Routing] | URL patterns, `routeAgentRequest` | |
| 22 | | Callable methods | [Callable methods] | `@callable`, RPC, streaming, timeouts | |
| 23 | | Scheduling | [Schedule tasks] | `schedule()`, `scheduleEvery()`, cron | |
| 24 | | Workflows | [Run workflows] | `AgentWorkflow`, durable multi-step tasks | |
| 25 | | HTTP/WebSockets | [WebSockets] | Lifecycle hooks, hibernation | |
| 26 | | Chat agents | [Chat agents] | `AIChatAgent`, streaming, tools, persistence | |
| 27 | | Client SDK | [Client SDK] | `useAgent`, `AgentClient`, state, RPC, HTTP | |
| 28 | | Client tools | [Client tools] | Client-side tools, `autoContinueAfterToolResult` | |
| 29 | | Server-driven messages | [Autonomous responses] | `saveMessages`, `waitUntilStable`, server-initiated turns | |
| 30 | | Resumable streaming | [Chat agents] | Stream recovery on disconnect | |
| 31 | | Email | [Email] | Email routing, secure reply resolver | |
| 32 | | MCP client | [MCP client] | Connecting to MCP servers | |
| 33 | | MCP server | [MCP server] | Building MCP servers with `createMcpHandler` | |
| 34 | | MCP transports | [MCP transports] | Streamable HTTP, SSE, RPC transport options | |
| 35 | | Securing MCP servers | [Securing MCP] | OAuth, proxy MCP, hardening | |
| 36 | | Human-in-the-loop | [Human-in-the-loop] | Workflow approvals, elicitation, timeout handling | |
| 37 | | Durable execution | [Durable execution] | `runFiber()`, `stash()`, surviving DO eviction | |
| 38 | | Queue | [Queue] | Built-in FIFO queue, `queue()` | |
| 39 | | Retries | [Retries] | `this.retry()`, backoff/jitter | |
| 40 | | Observability | [Observability] | Diagnostics-channel events | |
| 41 | | Push notifications | [Push notifications] | Web Push + VAPID from agents | |
| 42 | | Webhooks | [Webhooks] | Receiving external webhooks | |
| 43 | | Cross-domain auth | [Cross-domain auth] | WebSocket auth, tokens, CORS | |
| 44 | | Readonly connections | [Readonly] | `shouldConnectionBeReadonly` | |
| 45 | | Voice | [Voice] | Experimental STT/TTS, `withVoice` | |
| 46 | | Browse the web | [Browser tools] | Experimental CDP browser automation | |
| 47 | | Think | [Think] | Experimental higher-level chat agent class | |
| 48 | | Migrations | [AI SDK v5], [AI SDK v6] | Upgrading `@cloudflare/ai-chat` | |
| 49 | |
| 50 | ## Capabilities |
| 51 | |
| 52 | The Agents SDK provides: |
| 53 | |
| 54 | **Persistent state** — SQLite-backed, auto-synced to clients via `setState` |
| 55 | **Callable RPC** — `@callable()` methods invoked over WebSocket |
| 56 | **Scheduling** — One-time, recurring (`scheduleEvery`), and cron tasks |
| 57 | **Workflows** — Durable multi-step background processing via `AgentWorkflow` |
| 58 | **Durable execution** — `runFiber()` / `stash()` for work that survives DO eviction |
| 59 | **Queue** — Built-in FIFO queue with retries via `queue()` |
| 60 | **Retries** — `this.retry()` with exponential backoff and jitter |
| 61 | **MCP integration** — Connect to MCP servers or build your own with `createMcpHandler` |
| 62 | **Email handling** — Receive and reply to emails with secure routing |
| 63 | **Streaming chat** — `AIChatAgent` with resumable streams, message persistence, tools |
| 64 | **Server-driven messages** — `saveMessages`, `waitUntilStable` for proactive agent turns |
| 65 | **React hooks** — `useAgent`, `useAgentChat` for client apps |
| 66 | **Observability** — `diagnostics_channel` events for state, RPC, schedule, lifecycle |
| 67 | **Push notifications** — Web Push + VAPID delivery from agents |
| 68 | **Webhooks** — Receive and verify external webhooks |
| 69 | **Voice** (experimental) — STT/TTS via `@cloudflare/voice` |
| 70 | **Browser tools** (experimental) — CDP-powered browsing via `agents/browser` |
| 71 | **Think** (experimental) — Higher-level chat agent via `@cloudflare/think` |
| 72 | |
| 73 | ## FIRST: Verify Installation |
| 74 | |
| 75 | |
| 76 | npm ls agents # Should show agents package |
| 77 | |
| 78 | |
| 79 | If not installed: |
| 80 | |
| 81 | npm install agents |
| 82 | |
| 83 | |
| 84 | For chat agents: |
| 85 | |
| 86 | npm install agents @cloudflare/ai-chat ai @ai-sdk/react |
| 87 | |
| 88 | |
| 89 | ## Wrangler Configuration |
| 90 | |
| 91 | |
| 92 | { |
| 93 | "compatibility_flags": ["nodejs_compat"], |
| 94 | "durable_objects": { |
| 95 | "bindings": [{ "name": "MyAgent", "class_name": "MyAgent" }] |
| 96 | }, |
| 97 | "migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyAgent"] }] |
| 98 | } |
| 99 | |
| 100 | |
| 101 | **Gotchas:** |
| 102 | Do NOT enable `experimentalDecorators` in tsconfig (breaks `@callable`) |
| 103 | Never edit old migrations — always add new tags |
| 104 | Each agent class needs its own DO binding + migration entry |
| 105 | Add `"ai": { "binding": "AI" }` for Workers AI |
| 106 | |
| 107 | ## Agent Class |
| 108 | |
| 109 | |
| 110 | import { Agent, routeAgentRequest, callable } from "agents"; |
| 111 | |
| 112 | type State = { count: number }; |
| 113 | |
| 114 | export class Counter extends Agent<Env, State> { |
| 115 | initialState = { count: 0 }; |
| 116 | |
| 117 | validateStateChange(nextState: State, source: Connection | "server") { |
| 118 | if (nextState.count < 0) throw new Error("Count cannot be negative"); |
| 119 | } |
| 120 | |
| 121 | onStateUpdate(state: State, source: Connection | "server") { |
| 122 | console.log("State updated:", state); |
| 123 | } |
| 124 | |
| 125 | @callable() |
| 126 | increment() { |
| 127 | this.setState({ count: this.state.count + 1 }); |
| 128 | return this.state.count; |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | export default { |
| 133 | fetch: (req, env) => routeAgentRequest(req, env) ?? new Response("Not found", { status: 404 }) |
| 134 | }; |
| 135 | |
| 136 | |
| 137 | ## Routing |
| 138 | |
| 139 | Requests route to `/agents/{agent-name}/{instance-name}`: |
| 140 | |
| 141 | | Class | URL | |
| 142 | |-------|-----| |
| 143 | | `Counter` | `/agents/counter/user-123` | |
| 144 | | `ChatRoom` | `/agents/chat-room/lobby` | |
| 145 | |
| 146 | Client: `useAgent({ agent: "Counter", name: "user-123" })` |
| 147 | |
| 148 | Custom routing: use `getAgentByName(env.MyAgent, "instance-id")` then `agent.fetch(request)`. |
| 149 | |
| 150 | ## Core APIs |
| 151 | |
| 152 | | Task | API | |
| 153 | |------|-----| |
| 154 | | Read state | `this.state.count` | |
| 155 | | Write state | `this.setState({ count: 1 })` | |
| 156 | | SQL query | `` this.sql`SELECT * FROM users WHERE id = ${id}` `` | |
| 157 | | Schedule (delay) | `await this.schedule(60, "task", payload)` | |
| 158 | | Schedule (cron) | `await this.schedule("0 * * * *", "task", payload)` | |
| 159 | | Schedule (interval) | `await this.scheduleEvery(30, "poll")` | |
| 160 | | RPC method | `@callable() myMethod() { ... }` | |
| 161 | | Streaming RPC | `@callable({ streaming: true }) stream(res) { ... }` | |
| 162 | | Start workflow | `await this.runWorkflow("ProcessingWorkflow", params)` | |
| 163 | | Durable fiber | `await this.runFiber("name", async (ctx) => { ... })` | |
| 164 | | Enqueue work | `this.queue("handler", payload)` | |
| 165 | | Retry with backoff | `await this.retry(fn, { maxAttempts: 5 })` | |
| 166 | | Broadcast to clients | `this.broadcast(message)` | |
| 167 | | Get connections | `this.getConnections(tag?)` | |
| 168 | |
| 169 | ## React Client |
| 170 | |
| 171 | Read [client-sdk.md] for client selection and current connection examples. For chat UI and tools, also read [streaming-chat.md]. |
| 172 | |
| 173 | ## References |
| 174 | |
| 175 | ### Core |
| 176 | **[references/state-scheduling.md]** — State persistence, scheduling, SQL |
| 177 | **[references/callable.md]** — RPC methods, streaming, timeouts |
| 178 | **[references/routing.md]** — URL patterns, custom routing, `getAgentByName` |
| 179 | **[references/configuration.md]** — Wrangler config, bindings, Vite setup |
| 180 | |
| 181 | ### Chat & Streaming |
| 182 | **[references/streaming-chat.md]** — AIChatAgent, resumable streams, tools |
| 183 | **[references/client-sdk.md]** — `useAgent`, `useAgentChat`, `AgentClient` |
| 184 | **[references/server-driven-messages.md]** — Trigger patterns, `saveMessages` |
| 185 | **[references/human-in-the-loop.md]** — Approval flows, `needsApproval` |
| 186 | |
| 187 | ### Background Processing |
| 188 | **[references/workflows.md]** — Durable Workflows integration |
| 189 | **[references/durable-execution.md]** — `runFiber`, `stash`, surviving eviction |
| 190 | **[references/queue-retries.md]** — Built-in queue, retry with backoff |
| 191 | |
| 192 | ### Integrations |
| 193 | **[references/mcp.md]** — MCP client and server, transports, securing |
| 194 | **[references/email.md]** — Email routing and handling |
| 195 | **[references/webhooks-push.md]** — Webhooks, push notifications |
| 196 | **[references/observability.md]** — Diagnostics-channel events |
| 197 | |
| 198 | ### Experimental |
| 199 | **[references/think.md]** — `@cloudflare/think` higher-level chat agent |
| 200 | **[references/voice.md]** — `@cloudflare/voice` STT/TTS |
| 201 | **[references/codemode.md]** — Code Mode for tool orchestration |
| 202 | **[references/browse-the-web.md]** — CDP browser tools |
| 203 |
Discussion
Alternatives
Browse more free Claude skills or everything in Development.