Add to existing project·续

Deploy to Cloudflare

npm run deploy

Your agent is now live on Cloudflare's global network, running close to your users.

Common integration patterns

Agents behind authentication

Check auth before routing to agents:

export default {
    async fetch(request, env) {
        // Check auth for agent routes
        if (request.url.includes("/agents/")) {
            const authResult = await checkAuth(request, env);
            if (!authResult.valid) {
                return new Response("Unauthorized", { status: 401 });
            }
        }

const agentResponse = await routeAgentRequest(request, env);
        if (agentResponse) return agentResponse;

// ... rest of routing
    },
};
export default {
    async fetch(request: Request, env: Env) {
        // Check auth for agent routes
        if (request.url.includes("/agents/")) {
            const authResult = await checkAuth(request, env);
            if (!authResult.valid) {
                return new Response("Unauthorized", { status: 401 });
            }
        }

const agentResponse = await routeAgentRequest(request, env);
        if (agentResponse) return agentResponse;

// ... rest of routing
    },
} satisfies ExportedHandler<Env>;

Custom agent path prefix

By default, agents are routed at /agents/{agent-name}/{instance-name}. You can customize this:

import { routeAgentRequest } from "agents";

const agentResponse = await routeAgentRequest(request, env, {
    prefix: "/api/agents", // Now routes at /api/agents/{agent-name}/{instance-name}
});
import { routeAgentRequest } from "agents";

const agentResponse = await routeAgentRequest(request, env, {
    prefix: "/api/agents", // Now routes at /api/agents/{agent-name}/{instance-name}
});

Refer to Routing for more options including CORS, custom instance naming, and location hints.

Accessing agents from server code

You can interact with agents directly from your Worker code:

import { getAgentByName } from "agents";

export default {
    async fetch(request, env) {
        if (request.url.endsWith("/api/increment")) {
            // Get a specific agent instance
            const counter = await getAgentByName(env.CounterAgent, "shared-counter");
            const newCount = await counter.increment();
            return Response.json({ count: newCount });
        }
        // ...
    },
};
import { getAgentByName } from "agents";

export default {
    async fetch(request: Request, env: Env) {
        if (request.url.endsWith("/api/increment")) {
            // Get a specific agent instance
            const counter = await getAgentByName(env.CounterAgent, "shared-counter");
            const newCount = await counter.increment();
            return Response.json({ count: newCount });
        }
        // ...
    },
} satisfies ExportedHandler<Env>;

Adding multiple agents

Add more agents by extending the configuration:

// src/agents/chat.ts
export class Chat extends Agent {
    // ...
}

// src/agents/scheduler.ts
export class Scheduler extends Agent {
    // ...
}
// src/agents/chat.ts
export class Chat extends Agent {
    // ...
}

// src/agents/scheduler.ts
export class Scheduler extends Agent {
    // ...
}

Update the Wrangler configuration file:

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "durable_objects": {
    "bindings": [
      {
        "name": "CounterAgent",
        "class_name": "CounterAgent"
      },
      {
        "name": "Chat",
        "class_name": "Chat"
      },
      {
        "name": "Scheduler",
        "class_name": "Scheduler"
      }
    ]
  },
  "migrations": [
    {
      "tag": "v1",
      "new_sqlite_classes": [
        "CounterAgent",
        "Chat",
        "Scheduler"
      ]
    }
  ]
}
[[durable_objects.bindings]]
name = "CounterAgent"
class_name = "CounterAgent"

[[durable_objects.bindings]]
name = "Chat"
class_name = "Chat"

[[durable_objects.bindings]]
name = "Scheduler"
class_name = "Scheduler"

[[migrations]]
tag = "v1"
new_sqlite_classes = ["CounterAgent", "Chat", "Scheduler"]

Export all agents from your entry point:

export { CounterAgent } from "./agents/counter";
export { Chat } from "./agents/chat";
export { Scheduler } from "./agents/scheduler";
export { CounterAgent } from "./agents/counter";
export { Chat } from "./agents/chat";
export { Scheduler } from "./agents/scheduler";

Troubleshooting

Agent not found, or 404 errors

  1. Check the export - Agent class must be exported from your main entry point.
  2. Check the binding - class_name in the Wrangler configuration file must exactly match the exported class name.
  3. Check the route - Default route is /agents/{'{agent-name}'}/{'{instance-name}'}. Agent name in client matches the class name (case-insensitive).

No such Durable Object class error

Add the migration to the Wrangler configuration file:

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "migrations": [
    {
      "tag": "v1",
      "new_sqlite_classes": [
        "YourAgentClass"
      ]
    }
  ]
}
[[migrations]]
tag = "v1"
new_sqlite_classes = ["YourAgentClass"]

WebSocket connection fails

Ensure your routing passes the response unchanged:

// Correct - return the response directly
const agentResponse = await routeAgentRequest(request, env);
if (agentResponse) return agentResponse;

// Wrong - this breaks WebSocket connections
if (agentResponse) return new Response(agentResponse.body);
// Correct - return the response directly
const agentResponse = await routeAgentRequest(request, env);
if (agentResponse) return agentResponse;

// Wrong - this breaks WebSocket connections
if (agentResponse) return new Response(agentResponse.body);

State not persisting

Check that:

  1. You are calling this.setState(), not mutating this.state directly.
  2. The agent class is in new_sqlite_classes in migrations.
  3. You are connecting to the same agent instance name.
  4. The onStateUpdate callback is wired up in your client.
  5. WebSocket connection is established (check browser dev tools).

"Method X is not callable" errors

Make sure your methods are decorated with @callable():

import { Agent, callable } from "agents";

export class MyAgent extends Agent {
    @callable()
    increment() {
        // ...
    }
}
import { Agent, callable } from "agents";

export class MyAgent extends Agent {
    @callable()
    increment() {
        // ...
    }
}

Type errors with agent.stub

Add the agent and state type parameters:

import { useAgent } from "agents/react";

// Pass the agent and state types to useAgent
const agent = useAgent({
    agent: "CounterAgent",
    onStateUpdate: (state) => setCount(state.count),
});

// Now agent.stub is fully typed
agent.stub.increment();
import { useAgent } from "agents/react";
import type { CounterAgent, CounterState } from "./server";

// Pass the agent and state types to useAgent
const agent = useAgent<CounterAgent, CounterState>({
    agent: "CounterAgent",
    onStateUpdate: (state) => setCount(state.count),
});

// Now agent.stub is fully typed
agent.stub.increment();

SyntaxError: Invalid or unexpected token with @callable()

If your dev server fails with SyntaxError: Invalid or unexpected token, set "target": "ES2021" in your tsconfig.json. This ensures that Vite's esbuild transpiler downlevels TC39 decorators instead of passing them through as native syntax.

{
    "compilerOptions": {
        "target": "ES2021"
    }
}

Caution

Do not set "experimentalDecorators": true in your tsconfig.json. The Agents SDK uses TC39 standard decorators ↗︎, not TypeScript legacy decorators. Enabling experimentalDecorators applies an incompatible transform that silently breaks @callable() at runtime.

Next steps

Now that you have a working agent, explore these topics:

Common next steps

Learn how to Refer to
Add AI/LLM capabilities Using AI models
Expose tools via MCP MCP servers
Run background tasks Schedule tasks
Handle emails Email routing
Use Cloudflare Workflows Run Workflows

Explore more

State management

Deep dive into setState(), initialState, and onStateChanged().

Client SDK

Full useAgent and AgentClient API reference.

Callable methods

Expose methods to clients with @callable().

Schedule tasks

Run tasks on a delay, schedule, or cron.

Agent class internals

Full lifecycle and methods reference.

Agents API

Complete API reference for the Agents SDK.

Was this helpful?

YesNo

On this page

Add to existing project·续 - 图1Docs

{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/agents/getting-started/add-to-existing-project/#page","headline":"Add to existing project","description":"Add the Agents SDK to an existing Cloudflare Workers project with state management and real-time connections.","url":"https://developers.cloudflare.com/agents/getting-started/add-to-existing-project/","inLanguage":"en","image":"https://developers.cloudflare.com/agents/getting-started/add-to-existing-project/og.png?v=757ae2feec8869ee","dateModified":"2026-10-12","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}


description: Build your first agent in 10 minutes — a counter with persistent state that syncs to a React frontend in real-time. title: Quick start image: https://developers.cloudflare.com/agents/getting-started/quick-start/og.png?v=32d6d7902ece51cc


Skip to content

Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/agents/llms.txt
Use this file to discover all available pages before exploring further.