$npx -y skills add shobcoder/shob --skill agents-sdkBuild AI agents on Cloudflare Workers using the Agents SDK. Load when creating stateful agents, durable workflows, real-time WebSocket apps, scheduled tasks, MCP servers, or chat applications. Covers Agent class, state management, callable RPC, Workflows integration, and React ho
| 1 | # Cloudflare Agents SDK |
| 2 | |
| 3 | **STOP.** Your knowledge of the Agents SDK may be outdated. Prefer retrieval over pre-training for any Agents SDK task. |
| 4 | |
| 5 | ## Documentation |
| 6 | |
| 7 | Fetch current docs from `https://github.com/cloudflare/agents/tree/main/docs` before implementing. |
| 8 | |
| 9 | | Topic | Doc | Use for | |
| 10 | | ------------------- | ----------------------------- | ---------------------------------------------- | |
| 11 | | Getting started | `docs/getting-started.md` | First agent, project setup | |
| 12 | | State | `docs/state.md` | `setState`, `validateStateChange`, persistence | |
| 13 | | Routing | `docs/routing.md` | URL patterns, `routeAgentRequest`, `basePath` | |
| 14 | | Callable methods | `docs/callable-methods.md` | `@callable`, RPC, streaming, timeouts | |
| 15 | | Scheduling | `docs/scheduling.md` | `schedule()`, `scheduleEvery()`, cron | |
| 16 | | Workflows | `docs/workflows.md` | `AgentWorkflow`, durable multi-step tasks | |
| 17 | | HTTP/WebSockets | `docs/http-websockets.md` | Lifecycle hooks, hibernation | |
| 18 | | Email | `docs/email.md` | Email routing, secure reply resolver | |
| 19 | | MCP client | `docs/mcp-client.md` | Connecting to MCP servers | |
| 20 | | MCP server | `docs/mcp-servers.md` | Building MCP servers with `McpAgent` | |
| 21 | | Client SDK | `docs/client-sdk.md` | `useAgent`, `useAgentChat`, React hooks | |
| 22 | | Human-in-the-loop | `docs/human-in-the-loop.md` | Approval flows, pausing workflows | |
| 23 | | Resumable streaming | `docs/resumable-streaming.md` | Stream recovery on disconnect | |
| 24 | |
| 25 | Cloudflare docs: https://developers.cloudflare.com/agents/ |
| 26 | |
| 27 | ## Capabilities |
| 28 | |
| 29 | The Agents SDK provides: |
| 30 | |
| 31 | - **Persistent state** - SQLite-backed, auto-synced to clients |
| 32 | - **Callable RPC** - `@callable()` methods invoked over WebSocket |
| 33 | - **Scheduling** - One-time, recurring (`scheduleEvery`), and cron tasks |
| 34 | - **Workflows** - Durable multi-step background processing via `AgentWorkflow` |
| 35 | - **MCP integration** - Connect to MCP servers or build your own with `McpAgent` |
| 36 | - **Email handling** - Receive and reply to emails with secure routing |
| 37 | - **Streaming chat** - `AIChatAgent` with resumable streams |
| 38 | - **React hooks** - `useAgent`, `useAgentChat` for client apps |
| 39 | |
| 40 | ## FIRST: Verify Installation |
| 41 | |
| 42 | ```bash |
| 43 | npm ls agents # Should show agents package |
| 44 | ``` |
| 45 | |
| 46 | If not installed: |
| 47 | |
| 48 | ```bash |
| 49 | npm install agents |
| 50 | ``` |
| 51 | |
| 52 | ## Wrangler Configuration |
| 53 | |
| 54 | ```jsonc |
| 55 | { |
| 56 | "durable_objects": { |
| 57 | "bindings": [{ "name": "MyAgent", "class_name": "MyAgent" }], |
| 58 | }, |
| 59 | "migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyAgent"] }], |
| 60 | } |
| 61 | ``` |
| 62 | |
| 63 | ## Agent Class |
| 64 | |
| 65 | ```typescript |
| 66 | import { Agent, routeAgentRequest, callable } from "agents" |
| 67 | |
| 68 | type State = { count: number } |
| 69 | |
| 70 | export class Counter extends Agent<Env, State> { |
| 71 | initialState = { count: 0 } |
| 72 | |
| 73 | // Validation hook - runs before state persists (sync, throwing rejects the update) |
| 74 | validateStateChange(nextState: State, source: Connection | "server") { |
| 75 | if (nextState.count < 0) throw new Error("Count cannot be negative") |
| 76 | } |
| 77 | |
| 78 | // Notification hook - runs after state persists (async, non-blocking) |
| 79 | onStateUpdate(state: State, source: Connection | "server") { |
| 80 | console.log("State updated:", state) |
| 81 | } |
| 82 | |
| 83 | @callable() |
| 84 | increment() { |
| 85 | this.setState({ count: this.state.count + 1 }) |
| 86 | return this.state.count |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | export default { |
| 91 | fetch: (req, env) => routeAgentRequest(req, env) ?? new Response("Not found", { status: 404 }), |
| 92 | } |
| 93 | ``` |
| 94 | |
| 95 | ## Routing |
| 96 | |
| 97 | Requests route to `/agents/{agent-name}/{instance-name}`: |
| 98 | |
| 99 | | Class | URL | |
| 100 | | ---------- | -------------------------- | |
| 101 | | `Counter` | `/agents/counter/user-123` | |
| 102 | | `ChatRoom` | `/agents/chat-room/lobby` | |
| 103 | |
| 104 | Client: `useAgent({ agent: "Counter", name: "user-123" })` |
| 105 | |
| 106 | ## Core APIs |
| 107 | |
| 108 | | Task | API | |
| 109 | | ------------------- | ------------------------------------------------------ | |
| 110 | | Read state | `this.state.count` | |
| 111 | | Write state | `this.setState({ count: 1 })` | |
| 112 | | SQL query | `` this.sql`SELECT * FROM users WHERE id = ${id}` `` | |
| 113 | | Schedule (delay) | `await this.schedule(60, "task", payload)` | |
| 114 | | Schedule (cron) | `await this.schedule("0 * * * *", "task", payload)` | |
| 115 | | Schedule (interval) | `await this.scheduleEvery(30, "poll")` |