cloudflare/agents-starter: a Workers template for chat agents with tools, scheduling and Durable Object state
A starter kit for building ai agents on Cloudflare
At a glance
- What is it?
- This is a Cloudflare-maintained starter kit for AI chat agents, built on the Agents SDK, Workers AI and Durable Objects. It is worth adopting if you want the agent runtime and deployment path handed to you, and worth skipping if you need a provider-agnostic or fully local development loop.
- Who is it for?
- Adopt it if you are already deploying to Cloudflare Workers and want the agent loop, WebSocket transport, message persistence and tool wiring supplied rather than assembled. Do not adopt it if you need offline local development or a provider you cannot reach from a Worker, because Workers AI has no local simulator and the template requires Cloudflare authentication just to run the dev server.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 28 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem it removes: wiring an agent loop before you have an agent
Building a chat agent involves a lot of plumbing that has nothing to do with the agent's actual job. You need a streaming response path, a transport that survives page reloads, somewhere to persist conversation history, a way to declare tools, and a way for the browser to answer questions the server cannot answer. The README describes this template as a starter for building AI chat agents on Cloudflare, powered by the Agents SDK, and the included feature list reads like an inventory of exactly that plumbing: streaming responses via AIChatAgent, a WebSocket connection with automatic reconnection and message persistence, three distinct tool patterns, scheduling, and a debug toggle that shows raw message JSON.
The intended audience is narrow and specific. You are expected to be deploying to Cloudflare Workers, to be comfortable editing TypeScript in a small src directory, and to accept Workers AI as the default model provider. The repository layout is four files: server.ts holds the chat agent with its tools and scheduling, app.tsx holds the chat UI built with Kumo components, client.tsx is the React entry point, and styles.css carries Tailwind plus Kumo styles. That is a small surface to read before you decide. It is also the whole application, so there is no framework abstraction to learn on top of the SDK itself.
How the pieces connect: Durable Object state, WebSocket transport, three tool routes
The architecture follows from the topics attached to the repository: agents, ai, cloudflare, durable-objects. The agent class extends AIChatAgent from the agents package, and the README shows state being read through this.messages and written through this.setState() and this.state, with a documented behaviour that state syncs to all connected clients. Message persistence and the WebSocket connection are described as part of the same real-time layer, which is why a reload does not lose the conversation.
The tool system is the part worth studying before you write anything. There are three patterns, and they differ in where execution happens. A server-side tool has an execute function and runs automatically, which is what the weather demo does. A client-side tool has an inputSchema and no execute function at all; the browser supplies the result, and app.tsx handles it through an onToolCall callback. The timezone demo uses this route, which makes sense because only the browser knows the answer. The third pattern adds needsApproval to a tool that does have an execute function, so execution is gated; the README shows it returning true, and notes it can hold conditional logic instead. The calculate demo is the example.
Scheduling is a separate mechanism layered on the same agent. When a scheduled task fires, executeTask runs on the server, does its work, and then calls this.broadcast() to notify connected clients, which the UI renders as a toast. The README explains why broadcast is used rather than saveMessages: injecting a notification into chat history can cause the model to read it as new context and re-trigger the same task in a loop. That is a concrete design constraint, and it is the kind of detail that is easy to get wrong when you write your own scheduler.
Getting it running, and the authentication step people will miss
The quick start is four commands. Run npx create-cloudflare@latest --template cloudflare/agents-starter, then cd agents-starter, npm install, and npm run dev. The dev server serves the UI at http://localhost:5173.
The constraint that catches people is stated in the README as a blockquote: Cloudflare authentication is required to run locally. The template sets "ai": { "remote": true } in wrangler.jsonc, and Workers AI has no local simulator, so npm run dev opens a remote proxy session against Cloudflare. You either run wrangler login once in an interactive terminal or set a CLOUDFLARE_API_TOKEN environment variable, for example in a .env file. No OpenAI or Anthropic key is needed, but a Cloudflare login is. If you are used to templates that boot fully offline, this one will not, and the failure will look like an auth error rather than a missing dependency.
Renaming is two edits. Change the name in package.json and in wrangler.jsonc, and the name in wrangler.jsonc becomes the deployed Worker URL in the form <name>.<subdomain>.workers.dev. The README calls the system string in server.ts the most impactful single change you can make, which is a fair description for a template whose demo tools return placeholder data. It also documents removing scheduling entirely by deleting scheduleTask, getScheduledTasks and cancelScheduledTask from the tools object, removing the executeTask method, and dropping the getSchedulePrompt, scheduleSchema and Schedule imports. That is a clean subtraction path, which is not always true of starter kits.
Three ways to extend it, and one that is typed RPC rather than a tool
Beyond editing the system prompt, the README gives three extension routes. The first is replacing demo tools with real implementations; the example swaps the random-data getWeather for a fetch against a real endpoint. The second is adding callable methods. Marking a method with the callable decorator from the agents package exposes it as typed RPC, and the client calls it with agent.call("getStats"), where the example returns a message count from this.messages. That is a different channel from tools: the model does not decide when it runs, your UI does.
The third is MCP. The README shows connecting to an external MCP server inside onChatMessage with await this.mcp.connect("https://my-mcp-server.example/sse"), then spreading this.mcp.getAITools() into the tools object alongside your own. This is the most consequential extension point in the template, because it means the tool surface is not fixed at deploy time. It also means the model's available actions depend on a network call that can fail, and the README does not describe what happens to the chat turn when the MCP connection does not come up. That is a gap worth testing yourself rather than assuming.
Provider swapping is documented for OpenAI. Install @ai-sdk/openai, import openai, and replace the model inside onChatMessage with openai("gpt-5.2"), then put OPENAI_API_KEY in a .env file. The README's section on this is cut off after the OpenAI heading, so I cannot confirm from the supplied material which other providers are covered or whether the Workers AI binding is expected to stay in place alongside them.
Where this template is the wrong choice
The remote-only development loop is the clearest limitation. Every local run of npm run dev depends on reaching Cloudflare and on your credentials being valid, because the AI binding is configured with remote set to true and there is no local Workers AI simulator. On a plane, behind a restrictive network, or in a CI job that should not hold a Cloudflare token, this is a real obstacle rather than a preference.
Provider lock-in is the second. The template is built around Workers AI and the Agents SDK, and the documented escape hatch is an AI SDK provider, not a generic interface. If your stack is built on a different agent framework, adopting this means adopting the Cloudflare runtime model, Durable Objects and all, rather than dropping in a library.
The demo tools are also a trap for the impatient. getWeather returns random data and calculate does basic arithmetic. The README states this plainly, but a template that looks like it works end to end while returning fake weather is easy to demo and easy to ship by accident.
Finally, the README does not document limits on scheduling, on message history size, or on how many concurrent WebSocket clients a single agent instance handles. Those are the numbers you would want before putting this in front of real users, and they are not in the material I have.
The alternative: assembling the AI SDK yourself
The natural comparison is the Vercel AI SDK used directly, without the Agents SDK and without Durable Objects. The difference is not features, it is where the state lives. With the AI SDK on its own, you write the streaming endpoint, you choose the persistence layer, and you own the reconnect logic. The template's value is that the chat agent, its message history, its WebSocket transport and its reconnection behaviour are all one object with a documented lifecycle, and state written with setState() reaches every connected client without you building a fan-out.
The trade is control. A hand-rolled AI SDK setup runs against any provider the SDK supports and can run entirely on your own machine, which is exactly what this template cannot do because of the remote Workers AI binding. It also lets you pick a database you already operate instead of accepting Durable Object storage. If your agent is a thin wrapper over one model call, the Agents SDK may be more machinery than the problem needs. If your agent holds conversations across sessions, answers tool calls from the browser, and fires scheduled tasks, the Durable Object model is doing work you would otherwise write yourself, badly, at first.
Maintenance, upgrade cost and the MIT licence
The repository is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is the standard permissive arrangement, and it does not by itself tell you anything about the licence terms of the Agents SDK, Kumo, Tailwind or Workers AI, which are separate dependencies with their own terms. Check those independently; this is not legal advice.
The maintenance question is harder to answer from the material. There are no retrieved releases, so there is no version history to read for breaking-change cadence. The last push date is 2026-08-19, and the repository is not archived. The template is small, four source files, so the surface you own after forking is small too. The dependency that will actually move is the agents package and its SDK docs at developers.cloudflare.com/agents, which the README links for state, callable methods and the MCP client API.
Upgrade cost concentrates in the parts you customise. The three tool patterns, the executeTask broadcast contract and the callable RPC signatures are the interfaces most likely to shift, and they are the ones you will have rewritten. Because the template has no test suite in the supplied material, verifying an upgrade means exercising the demo prompts by hand: the weather prompt for server tools, the timezone prompt for client tools, the calculate prompt for approval, the reminder prompt for scheduling, and an image drop for vision.
Editorial conclusion
Adopt it if you are already deploying to Cloudflare Workers and want the agent loop, WebSocket transport, message persistence and tool wiring supplied rather than assembled. Do not adopt it if you need offline local development or a provider you cannot reach from a Worker, because Workers AI has no local simulator and the template requires Cloudflare authentication just to run the dev server. Before committing, run the quick start once, then read server.ts to confirm the three tool patterns and the executeTask broadcast behaviour match how your own tools and notifications are supposed to work.
Community notes