cloudflare-agents

IndexedCommit: 8cfe15e0 pullsUpdated Jan 29, 2026

Cloudflare Agents provides a comprehensive framework for building stateful AI agents that persist, think, and evolve at the edge. Built on Cloudflare's Durable Objects, it enables agents to maintain p

Install this reference
Reference

Cloudflare Agents

Cloudflare Agents provides a comprehensive framework for building stateful AI agents that persist, think, and evolve at the edge. Built on Cloudflare's Durable Objects, it enables agents to maintain persistent state across sessions, communicate via WebSockets and HTTP, integrate with LLMs through the AI SDK, and execute scheduled tasks—all with global scale and automatic hibernation for cost efficiency.

Quick References

FilePurpose
packages/agents/src/index.tsMain Agent class and core framework
packages/agents/src/index.tsPublic API exports and core abstractions
packages/ai-chat/src/index.tsAIChatAgent for chat-enabled agents
packages/hono-agents/src/index.tsHono middleware for agent routing
README.mdOfficial documentation and overview

Packages

Packagenpm nameDescription
packages/agentsagentsCore agent framework with state management, RPC, scheduling, and MCP client
packages/ai-chat@cloudflare/ai-chatAI chat agent with automatic message persistence and AI SDK v6 integration
packages/codemode@cloudflare/codemodeCode mode for LLM-generated executable tool code
packages/hono-agentshono-agentsHono middleware for integrating agents into Hono apps

When to Use

  • Stateful AI Chatbots: Build chatbots that remember conversation history across sessions and connections
  • Multi-user Collaborative Agents: Create agents with shared state synchronized across multiple clients in real-time
  • Scheduled Task Automation: Implement agents that execute scheduled workflows via cron, delayed execution, or one-time events
  • Human-in-the-Loop Workflows: Request human approval before executing sensitive operations
  • Tool-Enabled AI Agents: Connect AI agents to external tools via Model Context Protocol (MCP)
  • Email-Responsive Agents: Handle incoming emails and reply programmatically
  • Event-Driven Automation: React to external events and take autonomous actions

Installation

# Core agents framework
npm install agents

# AI chat functionality
npm install @cloudflare/ai-chat ai react

# Hono integration
npm install hono-agents hono

# Code mode for LLM-generated tools
npm install @cloudflare/codemode

Best Practices

  1. Always define SQL migrations in wrangler.jsonc: Agents require SQLite storage for state persistence. Add your agent class to new_sqlite_classes in the migrations section.

  2. Use the @callable decorator for RPC methods: Mark public methods with @callable() to expose them via WebSocket RPC. Optionally enable streaming responses with @callable({ streaming: true }).

  3. Initialize agent state with initialState: Set default state in the initialState property to avoid undefined state values on first access.

  4. Use getCurrentAgent() for context access: AsyncLocalStorage provides access to the current agent, connection, request, and email from anywhere in your code without passing parameters.

  5. Batch SQL operations when possible: For multiple database writes, consider batching them to reduce transaction overhead.

  6. Use schedule() instead of setAlarm() directly: Agent's schedule() method handles multiple schedules internally using a single alarm.

  7. Handle errors in onError(): Override the onError() method to gracefully handle connection and server errors.

  8. Clean up with destroy() when needed: Call await this.destroy() to wipe all tables, clear storage, and remove alarms when an agent should be terminated.

Common Patterns

Basic Agent with HTTP Handler:

import { Agent } from "agents";

export class MyAgent extends Agent<{ OPENAI_API_KEY: string }> {
  initialState = { count: 0 };

  async onRequest(request: Request) {
    return Response.json({ count: this.state.count });
  }

  increment() {
    this.setState({ count: this.state.count + 1 });
  }
}

Agent with WebSocket RPC:

import { Agent, callable } from "agents";

export class CalculatorAgent extends Agent {
  @callable({ description: "Add two numbers" })
  async add(a: number, b: number) {
    return a + b;
  }

  @callable({ description: "Multiply two numbers" })
  async multiply(a: number, b: number) {
    return a * b;
  }
}

Agent with Scheduled Tasks:

export class ScheduledAgent extends Agent {
  async onStart() {
    // Run daily at midnight
    this.schedule("0 0 * * *", "dailyCleanup", { type: "logs" });
    // Run in 10 seconds
    this.schedule(10, "quickCheck");
    // Run at specific date
    this.schedule(new Date("2025-12-25"), "holidayMessage");
  }

  async dailyCleanup(payload: { type: string }) {
    console.log(`Cleaning up ${payload.type}`);
  }
}

Agent with Queue:

export class QueueAgent extends Agent {
  async onConnect() {
    this.queue("process", { userId: "123" });
  }

  async process(payload: { userId: string }) {
    console.log(`Processing user ${payload.userId}`);
    await this.dequeue();
  }
}

AI Chat Agent:

import { AIChatAgent } from "@cloudflare/ai-chat";
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";

export class ChatBot extends AIChatAgent<{ OPENAI_API_KEY: string }> {
  async onChatMessage(onFinish) {
    return streamText({
      model: openai("gpt-4"),
      messages: this.messages,
      onFinish
    }).toDataStreamResponse();
  }
}

React Client Connection:

import { useAgent } from "agents/react";

function Component() {
  const agent = useAgent({ 
    agent: "my-agent",
    name: "user-123" 
  });

  const increment = () => agent.call("increment");

  return <button onClick={increment}>Increment</button>;
}

React Chat Interface:

import { useAgentChat } from "@cloudflare/ai-chat/react";

function ChatInterface() {
  const agent = useAgent({ agent: "chatbot", name: "session-1" });
  const { messages, sendMessage } = useAgentChat({ agent });

  return (
    <div>
      {messages.map(m => <p key={m.id}>{m.content}</p>)}
      <button onClick={() => sendMessage("Hello!")}>Send</button>
    </div>
  );
}

Human-in-the-Loop Approval:

export class ApprovalAgent extends AIChatAgent {
  async onChatMessage(onFinish) {
    // Use needsApproval on tools to require human confirmation
    return streamText({
      model: openai("gpt-4"),
      messages: this.messages,
      tools: {
        dangerousAction: tool({
          description: "Execute dangerous action",
          inputSchema: z.object({}),
          needsApproval: true
        })
      },
      onFinish
    }).toDataStreamResponse();
  }
}

MCP Integration:

import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

export class MyMcp extends McpAgent {
  server = new McpServer({ name: "demo", version: "1.0.0" });

  async init() {
    this.server.registerTool(
      "getData",
      { description: "Fetch data", inputSchema: z.object({ id: z.string() }) },
      async ({ id }) => ({ content: [{ type: "text", text: `Data for ${id}` }] })
    );
  }
}

API Quick Reference

ExportTypeDescription
AgentClassBase class for creating agents with state persistence, RPC, scheduling, and WebSocket support
AIChatAgentClassExtension of Agent with AI chat capabilities and automatic message persistence
McpAgentClassAgent extension for creating MCP servers with tool registration
@callableDecoratorMarks methods as callable via WebSocket RPC
callable()FunctionDecorator factory for callable methods
useAgentHookReact hook for connecting to an agent with WebSocket support
useAgentChatHookReact hook for AI chat interfaces with message persistence
AgentClientClassWebSocket client for agent communication
agentFetchFunctionMake HTTP requests to an agent
routeAgentRequestFunctionRoute HTTP/WebSocket requests to the appropriate agent
getAgentByNameFunctionGet an agent stub by name
getCurrentAgentFunctionAccess current agent, connection, request, and email context
SqlErrorClassError class for SQL query failures

Agent Class Methods

MethodReturnsDescription
setState(state)voidUpdate agent state and persist to storage
onStateUpdate(state, source)voidCalled when state is updated (override in subclass)
schedule(when, callback, payload?)Promise<Schedule>Schedule a one-time, delayed, or recurring task
cancelSchedule(id)Promise<boolean>Cancel a scheduled task
getSchedule(id)Promise<Schedule|undefined>Get a specific scheduled task
getSchedules(criteria?)Schedule[]Get scheduled tasks matching criteria
queue(callback, payload)Promise<string>Queue a task for deferred execution
dequeue(id)voidRemove a specific queued task
dequeueAll()voidRemove all queued tasks
getQueue(id)Promise<QueueItem|undefined>Get a specific queued task
getQueues(key, value)Promise<QueueItem[]>Get queued tasks by key/value filter
destroy()Promise<void>Destroy the agent, dropping all tables and clearing storage
replyToEmail(email, options)Promise<void>Reply to an incoming email
runWorkflow(name, params, options?)Promise<string>Start a Cloudflare Workflow and track it
sendWorkflowEvent(name, id, event)Promise<void>Send an event to a running workflow
approveWorkflow(id, data?)Promise<void>Approve a waiting workflow
rejectWorkflow(id, data?)Promise<void>Reject a waiting workflow

Agent Lifecycle Hooks

HookParametersDescription
onStart(props?)PropsCalled when the agent starts up
onRequest(request)RequestHandle HTTP requests to the agent
onConnect(connection, ctx)Connection, ConnectionContextCalled when a WebSocket connects
onMessage(connection, message)Connection, WSMessageHandle incoming WebSocket messages
onClose(connection, code, reason, wasClean)Connection, number, string, booleanCalled when a WebSocket closes
onEmail(email)AgentEmailHandle incoming emails

Hono Integration

ExportTypeDescription
agentsMiddlewareFunctionCreate Hono middleware for handling agent WebSocket and HTTP requests

MCP Integration

ExportTypeDescription
McpAgentClassBase class for creating MCP servers
MCPClientManagerClassClient for connecting to MCP servers

Utility Types

TypeDescription
QueueItem<T>Type for a queued task with payload, callback, and timestamp
Schedule<T>Type for a scheduled task with type (scheduled/delayed/cron), time, and payload
AgentContextType for agent constructor context
AgentEmailType for incoming email messages
ConnectionType for WebSocket connection (from partyserver)
ConnectionContextType for connection context with request

“Explore distant worlds.”

© 2026 Oscar Gabriel