---
name: agents-sdk
description: >-
  Build 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. Use when the user mentions "build an agent," "AI agent," "Agents SDK," "WebSocket AI," agent state management, scheduled tasks, tool calling, callable RPC, Workflows integration, or MCP servers on Cloudflare.
enabled: false
source: github:JuanJoseGonGi/skills
imported-from: github:JuanJoseGonGi/skills
---

# Cloudflare Agents SDK

**STOP.** Your knowledge of the Agents SDK may be outdated. Prefer retrieval over pre-training for any Agents SDK task.

## Documentation

Fetch current docs from `https://github.com/cloudflare/agents/tree/main/docs` before implementing.

| Topic | Doc | Use for |
|-------|-----|---------|
| Getting started | `docs/getting-started.md` | First agent, project setup |
| State | `docs/state.md` | `setState`, `validateStateChange`, persistence |
| Routing | `docs/routing.md` | URL patterns, `routeAgentRequest`, `basePath` |
| Callable methods | `docs/callable-methods.md` | `@callable`, RPC, streaming, timeouts |
| Scheduling | `docs/scheduling.md` | `schedule()`, `scheduleEvery()`, cron |
| Workflows | `docs/workflows.md` | `AgentWorkflow`, durable multi-step tasks |
| HTTP/WebSockets | `docs/http-websockets.md` | Lifecycle hooks, hibernation |
| Email | `docs/email.md` | Email routing, secure reply resolver |
| MCP client | `docs/mcp-client.md` | Connecting to MCP servers |
| MCP server | `docs/mcp-servers.md` | Building MCP servers with `McpAgent` |
| Client SDK | `docs/client-sdk.md` | `useAgent`, `useAgentChat`, React hooks |
| Human-in-the-loop | `docs/human-in-the-loop.md` | Approval flows, pausing workflows |
| Resumable streaming | `docs/resumable-streaming.md` | Stream recovery on disconnect |

Cloudflare docs: https://developers.cloudflare.com/agents/

## Quick Start

```bash
npm create cloudflare@latest -- my-agent --template=cloudflare/agents-starter
cd my-agent
npm start        # http://localhost:8787
npx wrangler deploy  # Production
```

## What is an Agent?

An Agent is a stateful, persistent AI service that:
- Maintains state across requests and reconnections (SQLite-backed)
- Communicates via WebSockets or HTTP
- Runs on Cloudflare's edge via Durable Objects
- Can schedule tasks and call tools
- Scales horizontally (each user/session gets own instance)

## Agent Lifecycle

```
Client connects → Agent.onConnect() → Agent processes messages
                                    → Agent.onMessage()
                                    → Agent.setState() (persists + syncs)
Client disconnects → State persists → Client reconnects → State restored
```

## Verify Installation

```bash
npm ls agents  # Should show agents package
```

If not installed:
```bash
npm install agents
```

## Wrangler Configuration

```jsonc
// wrangler.jsonc
{
  "durable_objects": {
    "bindings": [{ "name": "MyAgent", "class_name": "MyAgent" }]
  },
  "migrations": [{ "tag": "v1", "new_sqlite_classes": ["MyAgent"] }]
}
```

For Workers AI add:
```jsonc
{
  "ai": { "binding": "AI" }
}
```

## Agent Class

```typescript
import { Agent, Connection, routeAgentRequest, callable } from "agents";

interface Env { AI: Ai; }

type State = {
  messages: Array<{ role: string; content: string }>;
  count: number;
};

export class MyAgent extends Agent<Env, State> {
  initialState: State = { messages: [], count: 0 };

  // Validation hook — sync, throwing rejects the update
  validateStateChange(nextState: State, source: Connection | "server") {
    if (nextState.count < 0) throw new Error("Count cannot be negative");
  }

  // Notification hook — async, non-blocking
  onStateUpdate(state: State, source: Connection | "server") {
    console.log("State updated:", state);
  }

  async onConnect(connection: Connection) {
    connection.send(JSON.stringify({
      type: "welcome",
      history: this.state.messages,
    }));
  }

  async onMessage(connection: Connection, message: string) {
    const data = JSON.parse(message);
    if (data.type === "chat") {
      await this.handleChat(connection, data.content);
    }
  }

  @callable()
  increment() {
    this.setState({ ...this.state, count: this.state.count + 1 });
    return this.state.count;
  }

  private async handleChat(connection: Connection, userMessage: string) {
    const messages = [
      ...this.state.messages,
      { role: "user", content: userMessage },
    ];
    const response = await this.env.AI.run("@cf/meta/llama-3-8b-instruct", {
      messages,
    });
    this.setState({
      ...this.state,
      messages: [
        ...messages,
        { role: "assistant", content: response.response },
      ],
    });
    connection.send(JSON.stringify({
      type: "response",
      content: response.response,
    }));
  }
}

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 |
|-------|-----|
| `MyAgent` | `/agents/my-agent/user-123` |
| `ChatRoom` | `/agents/chat-room/lobby` |

## 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)` |
| Broadcast | `this.broadcast(message)` |

## Chat Agent (AI-Powered)

For chat-focused agents, extend `AIChatAgent`:

```typescript
import { AIChatAgent } from "agents/ai-chat-agent";

export class ChatBot extends AIChatAgent<Env> {
  async onChatMessage(onFinish) {
    const result = streamText({
      model: openai("gpt-4o"),
      messages: await convertToModelMessages(this.messages),
      onFinish,
    });
    return result.toUIMessageStreamResponse();
  }
}
```

Features: automatic message history, resumable streaming, built-in `saveMessages()`.

## React Client

```tsx
import { useAgent } from "agents/react";

function App() {
  const [state, setLocalState] = useState({ count: 0 });

  const agent = useAgent({
    agent: "MyAgent",
    name: "my-instance",
    onStateUpdate: (newState) => setLocalState(newState),
  });

  return (
    <button onClick={() => agent.setState({ count: state.count + 1 })}>
      Count: {state.count}
    </button>
  );
}
```

## Vanilla JavaScript Client

```javascript
const ws = new WebSocket("wss://my-agent.workers.dev/agents/MyAgent/user123");
ws.onmessage = (e) => console.log("Received:", JSON.parse(e.data));
ws.send(JSON.stringify({ type: "chat", content: "Hello!" }));
```

## Deployment

```bash
npx wrangler deploy     # Deploy
wrangler tail            # View logs
curl https://my-agent.workers.dev/agents/MyAgent/test-user  # Test
```

## References

### SDK Features
- **[references/callable.md](references/callable.md)** — RPC methods, streaming, timeouts
- **[references/state-scheduling.md](references/state-scheduling.md)** — State persistence, scheduling
- **[references/streaming-chat.md](references/streaming-chat.md)** — AIChatAgent, resumable streams
- **[references/workflows.md](references/workflows.md)** — Durable Workflows integration
- **[references/mcp.md](references/mcp.md)** — MCP server/client integration
- **[references/email.md](references/email.md)** — Email routing and handling
- **[references/codemode.md](references/codemode.md)** — Code Mode (experimental)

### Building & Patterns
- **[references/agent-patterns.md](references/agent-patterns.md)** — Tool calling, RAG, multi-agent orchestration, human-in-the-loop
- **[references/state-patterns.md](references/state-patterns.md)** — Hybrid state/SQL, queues, migration, conflict resolution, per-connection state
- **[references/examples.md](references/examples.md)** — Official templates, starter projects, reference implementations
- **[references/troubleshooting.md](references/troubleshooting.md)** — Connection, state, SQL, scheduling, deployment issues
