Bringing Outerbase’s Data Explorer into the Cloudflare Dashboard
We’ll also tie some of Starbase’s features directly into Cloudflare’s platform, so you can tap into its unique offerings like pre- and post-query hooks or row-level security right from your existing D1 databases and Durable Objects:
\n
const beforeQuery = ({ sql, params }) => {\n // Prevent unauthorized queries\n if (!isAllowedQuery(sql)) throw new Error('Query not allowed');\n};\n\nconst afterQuery = ({ sql, result }) => {\n // Basic PII masking example\n for (const row of result) {\n if ('email' in row) row.email = '[redacted]';\n }\n};\n\n// Execute the query with pre- and post- query hooks\nconst { results } = await env.DB.prepare("SELECT * FROM users;", beforeQuery, afterQuery);
\n
Define hooks on your D1 queries that can be re-used, shared and automatically executed before or after your queries run.
This should give you more clarity and control over your data, as well as new ways to secure and optimize it.
\n \n \n
Rethinking the Durable Objects getting started experience
We have even begun optimizing the Cloudflare dashboard experience around Durable Objects and D1 to improve the empty state, provide more Getting Started resources, and overall, make managing and tracking your database resources even easier.\n\nFor those of you who’ve supported us, given us feedback, and stuck with us as we grew: thank you. You have helped shape Outerbase into what it is today. This acquisition means we can pour even more resources and attention into building the data experience we’ve always wanted to deliver. Our hope is that, by working as part of Cloudflare, we can help reach even more developers by building intuitive experiences, accelerating the speed of innovation, and creating tools that naturally fit into your workflows.
This is a big step for Outerbase, and we couldn’t be more excited. Thank you for being part of our journey so far. We can’t wait to show you what we’ve got in store as we continue to make data more accessible, intuitive, and powerful — together with Cloudflare.
We’re planning to get to work on some of the big changes to how you interact with your data on Cloudflare, starting with D1 and Durable Objects.
We’ll also be ensuring we bring a great developer experience to the broader database & storage platform on Cloudflare, including how you access data in Workers KV, R2, Workflows and even your AI Agents (just to name a few).
"],"published_at":[0,"2025-04-07T14:00+00:00"],"updated_at":[0,"2025-04-08T09:55:07.382Z"],"feature_image":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5MvFdMXLBUAHvXJjVcSSJJ/f956f874b1e62e667b3f2457c68b1762/image3.png"],"tags":[1,[[0,{"id":[0,"2xCnBweKwOI3VXdYsGVbMe"],"name":[0,"Developer Week"],"slug":[0,"developer-week"]}],[0,{"id":[0,"UKt2GEAUQsbObsNqZ3Pr7"],"name":[0,"D1"],"slug":[0,"d1"]}],[0,{"id":[0,"5v2UZdTRX1Rw9akmhexnxs"],"name":[0,"Durable Objects"],"slug":[0,"durable-objects"]}],[0,{"id":[0,"3JAY3z7p7An94s6ScuSQPf"],"name":[0,"Developer Platform"],"slug":[0,"developer-platform"]}],[0,{"id":[0,"6hbkItfupogJP3aRDAq6v8"],"name":[0,"Cloudflare Workers"],"slug":[0,"workers"]}]]],"relatedTags":[0],"authors":[1,[[0,{"name":[0,"Brandon Strittmatter"],"slug":[0,"brandon-strittmatter"],"bio":[0],"profile_image":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3viCDHdRdgbirjk7W1OqS5/10437b1d8ddeadc34fee3796dbfefa7e/Brandon_Strittmatter.webp"],"location":[0],"website":[0],"twitter":[0],"facebook":[0]}],[0,{"name":[0,"Matt Silverlock"],"slug":[0,"silverlock"],"bio":[0,"Director of Product at Cloudflare."],"profile_image":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7xP5qePZD9eyVtwIesXYxh/e714aaa573161ec9eb48d59bd1aa6225/silverlock.jpeg"],"location":[0,null],"website":[0,null],"twitter":[0,"@elithrar"],"facebook":[0,null]}]]],"meta_description":[0,"Cloudflare has acquired Outerbase, expanding our database and agent developer experience capabilities."],"primary_author":[0,{}],"localeList":[0,{"name":[0,"blog-english-only"],"enUS":[0,"English for Locale"],"zhCN":[0,"No Page for Locale"],"zhHansCN":[0,"No Page for Locale"],"zhTW":[0,"No Page for Locale"],"frFR":[0,"No Page for Locale"],"deDE":[0,"No Page for Locale"],"itIT":[0,"No Page for Locale"],"jaJP":[0,"No Page for Locale"],"koKR":[0,"No Page for Locale"],"ptBR":[0,"No Page for Locale"],"esLA":[0,"No Page for Locale"],"esES":[0,"No Page for Locale"],"enAU":[0,"No Page for Locale"],"enCA":[0,"No Page for Locale"],"enIN":[0,"No Page for Locale"],"enGB":[0,"No Page for Locale"],"idID":[0,"No Page for Locale"],"ruRU":[0,"No Page for Locale"],"svSE":[0,"No Page for Locale"],"viVN":[0,"No Page for Locale"],"plPL":[0,"No Page for Locale"],"arAR":[0,"No Page for Locale"],"nlNL":[0,"No Page for Locale"],"thTH":[0,"No Page for Locale"],"trTR":[0,"No Page for Locale"],"heIL":[0,"No Page for Locale"],"lvLV":[0,"No Page for Locale"],"etEE":[0,"No Page for Locale"],"ltLT":[0,"No Page for Locale"]}],"url":[0,"https://blog.cloudflare.com/cloudflare-acquires-outerbase-database-dx"],"metadata":[0,{"title":[0,"Cloudflare acquires Outerbase to expand database and agent developer experience capabilities"],"description":[0,"Cloudflare has acquired Outerbase, expanding our database and agent developer experience capabilities."],"imgPreview":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5MvFdMXLBUAHvXJjVcSSJJ/f956f874b1e62e667b3f2457c68b1762/image3.png"]}]}],[0,{"id":[0,"2JjYf004DWQEOykF435HA3"],"title":[0,"Introducing AutoRAG: fully managed Retrieval-Augmented Generation on Cloudflare"],"slug":[0,"introducing-autorag-on-cloudflare"],"excerpt":[0,"AutoRAG is here: fully managed Retrieval-Augmented Generation (RAG) pipelines powered by Cloudflare's global network and powerful developer ecosystem. "],"featured":[0,false],"html":[0,"
Today we’re excited to announce AutoRAG in open beta, a fully managed Retrieval-Augmented Generation (RAG) pipeline powered by Cloudflare, designed to simplify how developers integrate context-aware AI into their applications. RAG is a method that improves the accuracy of AI responses by retrieving information from your own data, and providing it to the large language model (LLM) to generate more grounded responses.
Building a RAG pipeline is a patchwork of moving parts. You have to stitch together multiple tools and services — your data storage, a vector database, an embedding model, LLMs, and custom indexing, retrieval, and generation logic — all just to get started. Maintaining it is even harder. As your data changes, you have to manually reindex and regenerate embeddings to keep the system relevant and performant. What should be a simple “ask a question, get a smart answer” experience becomes a brittle pipeline of glue code, fragile integrations, and constant upkeep.
AutoRAG removes that complexity. With just a few clicks, it delivers a fully-managed RAG pipeline end-to-end: from ingesting your data and automatically chunking and embedding it, to storing vectors in Cloudflare’s Vectorize database, performing semantic retrieval, and generating high-quality responses using Workers AI. AutoRAG continuously monitors your data sources and indexes in the background so your AI stays fresh without manual effort. It abstracts away the mess, letting you focus on building smarter, faster applications on Cloudflare’s developer platform. Get started today in the Cloudflare Dashboard!
LLMs like Llama 3.3 from Meta are powerful, but they only know what they’ve been trained on. They often struggle to produce accurate answers when asked about new, proprietary, or domain-specific information. System prompts providing relevant information can help, but they bloat input size and are limited by context windows. Fine-tuning a model is expensive and requires ongoing retraining to keep up to date.
RAG solves this by retrieving relevant information from your data source at query time, combining it with the user’s input query, and feeding both into the LLM to generate responses grounded with your data. This makes RAG a great fit for AI-driven support bots, internal knowledge assistants, semantic search across documentation, and other use cases where the source of truth is always evolving.
AutoRAG sets up a RAG pipeline for you, using the building blocks of Cloudflare’s developer platform. Instead of you having to write code to create a RAG system using Workers AI, Vectorize, and AI Gateway, you just create an AutoRAG instance and point it at a data source, like an R2 storage bucket.
Behind the scenes, AutoRAG is powered by two processes: indexing and querying.
Indexing is an asynchronous process that runs in the background. It kicks off as soon as you create an AutoRAG, and automatically continues in cycles — reprocessing new or updated files after each previous job completes. During indexing, your content is transformed into vectors optimized for semantic search.
Querying is a synchronous process triggered when a user sends a search request. AutoRAG takes the query, retrieves the most relevant content from your vector database, and uses it to generate a context-aware response using an LLM.
Let’s take a closer look at how they work.
Indexing process
When you connect a data source, AutoRAG automatically ingests, transforms, and stores it as vectors, optimizing it for semantic search when querying:
File ingestion from data source: AutoRAG reads directly from your data source. Today, it supports integration with Cloudflare R2, where you can store documents like PDFs, images, text, HTML, CSV, and more for processing.\nCheck out the RAG to riches in 5 minutes tutorial below to learn how you can use Browser Rendering to parse webpages to use within your AutoRAG.
Markdown conversion: AutoRAG uses Workers AI’s Markdown Conversion to convert all files into structured Markdown. This ensures consistency across diverse file types. For images, Workers AI is used to perform object detection followed by vision-to-language transformation to convert images into Markdown text.
Chunking: The extracted text is chunked into smaller pieces to improve retrieval granularity.
Embedding: Each chunk is embedded using Workers AI’s embedding model to transform the content into vectors.
Vector storage: The resulting vectors, along with metadata like source location and file name, are stored in a Cloudflare’s Vectorize database created on your account.
\n \n \n
Querying process
When an end user makes a request, AutoRAG orchestrates the following:
Receive query from AutoRAG API: The query workflow begins when you send a request to either the AutoRAG’s AI Search or Search endpoint.
Query rewriting (optional): AutoRAG provides the option to rewrite the input query using one of Workers AI’s LLMs to improve retrieval quality by transforming the original query into a more effective search query.
Embedding the query: The rewritten (or original) query is transformed into a vector via the same embedding model used to embed your data so that it can be compared against your vectorized data to find the most relevant matches.
Vector search in Vectorize: The query vector is searched against stored vectors in the associated Vectorize database for your AutoRAG.
Metadata + content retrieval: Vectorize returns the most relevant chunks and their metadata. And the original content is retrieved from the R2 bucket. These are passed to a text-generation model.
Response generation: A text-generation model from Workers AI is used to generate a response using the retrieved content and the original user’s query.
The end result is an AI-powered answer grounded in your private data — accurate, and up to date.
Most of the time, getting started with AutoRAG is as simple as pointing it to an existing R2 bucket — just drop in your content, and you're ready to go. But what if your content isn’t already in a bucket? What if it’s still on a webpage or needs to first be rendered dynamically by a frontend UI? You're in luck, because with the Browser Rendering API, you can crawl your own websites to gather information that powers your RAG. The Browser Rendering REST API is now generally available, offering endpoints for common browser actions including extracting HTML content, capturing screenshots, and generating PDFs. Additionally, a crawl endpoint is coming soon, making it even easier to ingest websites.
In this walkthrough, we’ll show you how to take your website and feed it into AutoRAG for Q&A. We’ll use a Cloudflare Worker to render web pages in a headless browser, upload the content to R2, and hook that into AutoRAG for semantic search and generation.
Step 1. Create a Worker to fetch webpages and upload into R2
We’ll create a Cloudflare Worker that uses Puppeteer to visit your URL, render it, and store the full HTML in your R2 bucket. If you already have an R2 bucket with content you’d like to build a RAG for then you can skip this step.
Create a new Worker project named browser-r2-worker by running:
\n
npm create cloudflare@latest -- browser-r2-worker
\n
For setup, select the following options:
What would you like to start with? Choose Hello World Starter.
Which template would you like to use? Choose Worker only.
Which language do you want to use? Choose TypeScript.
\n2. Install @cloudflare/puppeteer, which allows you to control the Browser Rendering instance:
\n
npm i @cloudflare/puppeteer
\n
3. Create a new R2 bucket named html-bucket by running:
\n
npx wrangler r2 bucket create html-bucket
\n
4. Add the following configurations to your Wrangler configuration file, so your Worker can use browser rendering and your new R2 bucket:
5. Replace the contents of src/index.ts with the following skeleton script:
\n
import puppeteer from "@cloudflare/puppeteer";\n\n// Define our environment bindings\ninterface Env {\n\tMY_BROWSER: any;\n\tHTML_BUCKET: R2Bucket;\n}\n\n// Define request body structure\ninterface RequestBody {\n\turl: string;\n}\n\nexport default {\n\tasync fetch(request: Request, env: Env): Promise<Response> {\n\t\t// Only accept POST requests\n\t\tif (request.method !== 'POST') {\nreturn new Response('Please send a POST request with a target URL', { status: 405 });\n\t\t}\n\n\t\t// Get URL from request body\n\t\tconst body = await request.json() as RequestBody;\n\t\t// Note: Only use this parser for websites you own\n\t\tconst targetUrl = new URL(body.url); \n\n\t\t// Launch browser and create new page\n\t\tconst browser = await puppeteer.launch(env.MY_BROWSER);\n\t\tconst page = await browser.newPage();\n\n\t\t// Navigate to the page and fetch its html\n\t\tawait page.goto(targetUrl.href);\n\t\tconst htmlPage = await page.content();\n\n\t\t// Create filename and store in R2\n\t\tconst key = targetUrl.hostname + '_' + Date.now() + '.html';\n\t\tawait env.HTML_BUCKET.put(key, htmlPage);\n\n\t\t// Close browser\n\t\tawait browser.close();\n\n\t\t// Return success response\n\t\treturn new Response(JSON.stringify({\n\t\t\tsuccess: true,\n\t\t\tmessage: 'Page rendered and stored successfully',\n\t\t\tkey: key\n\t\t}), {\n\t\t\theaders: { 'Content-Type': 'application/json' }\n\t\t});\n\t}\n} satisfies ExportedHandler<Env>;
\n
6. Once the code is ready, you can deploy it to your Cloudflare account by running:
\n
npx wrangler deploy
\n
7. To test your Worker, you can use the following cURL request to fetch the HTML file of a page. In this example we are fetching this blog page to upload into the html-bucket bucket:
\n
curl -X POST https://browser-r2-worker.<YOUR_SUBDOMAIN>.workers.dev \\\n-H "Content-Type: application/json" \\\n-d '{"url": "https://blog.cloudflare.com/introducing-autorag-on-cloudflare"}'
\n
Step 2. Create your AutoRAG and monitor the indexing
Now that you have created your R2 bucket and filled it with your content that you’d like to query from, you are ready to create an AutoRAG instance:
Select Create AutoRAG and complete the setup process:
Select the R2 bucket which contains your knowledge base, in this case, select the html-bucket.
Select an embedding model used to convert your data to vector representation. It is recommended to use the Default.
Select an LLM to use to generate your responses. It is recommended to use the Default.
Select or create an AI Gateway to monitor and control your model usage.
Name your AutoRAG as my-rag.
Select or create a Service API token to grant AutoRAG access to create and access resources in your account.
Select Create to spin up your AutoRAG.
Once you’ve created your AutoRAG, it will automatically create a Vectorize database in your account and begin indexing the data. You can view the progress of your indexing job in the Overview page of your AutoRAG. The indexing time may vary depending on the number and type of files you have in your data source.
\n \n \n
Step 3. Test and add to your application
Once AutoRAG finishes indexing your content, you’re ready to start asking it questions. You can open up your AutoRAG instance, navigate to the Playground tab, and ask a question based on your uploaded content, like “What is AutoRAG?”.
Once you’re happy with the results in the Playground, you can integrate AutoRAG directly into the application that you are building. If you are using a Worker to build your application, then you can use the AI binding to directly call your AutoRAG:
Then, query your AutoRAG instance from your Worker code by calling the aiSearch() method. Alternatively you can use the Search() method to get a list of retrieved results without an AI generated response.
\n
const answer = await env.AI.autorag('my-rag').aiSearch({\n query: 'What is AutoRAG?'\n});
\n
For more information on how to add AutoRAG into your application, go to your AutoRAG then navigate to Use AutoRAG for more instructions.
During the open beta, AutoRAG is free to enable. Compute operations for indexing, retrieval and augmentation incur no additional cost during this phase.
AutoRAG is built entirely on top of Cloudflare’s Developer Platform, using the same tools you’d reach for if you were building a RAG pipeline yourself. When you create an AutoRAG instance, it provisions and runs on top of Cloudflare services within your own account, giving you full visibility into performance, cost, and behavior with fewer black boxes.
We’re just getting started with AutoRAG and we have more planned throughout 2025 to make it more powerful and flexible. Here are a few things we’re actively working on:
More data source integrations: We’re expanding beyond R2, with support for new input types like direct website URL parsing (powered by browser rendering) and structured data sources like Cloudflare D1.
Smarter, higher-quality responses: We’re exploring built-in reranking, recursive chunking, and other processing techniques to improve the quality and relevance of generated answers.
These features will roll out incrementally, and we’d love your feedback as we shape what’s next. AutoRAG is built to evolve with your use cases so stay tuned.
Get started with AutoRAG today by visiting the Cloudflare Dashboard, navigate to AI > AutoRAG, and select Create AutoRAG. Whether you’re building an AI-powered search experience, an internal knowledge assistant, or just experimenting with LLMs, AutoRAG gives you a fast and flexible way to get started with RAG on Cloudflare’s global network. For more details, refer to the Developer Docs. Also, try out the Browser Rendering API that is now generally available for your browser action needs.
We’re excited to see what you build and we’re here to help. Have questions or feedback? Join the conversation on the Cloudflare Developers Discord.
"],"published_at":[0,"2025-04-07T14:00+00:00"],"updated_at":[0,"2025-04-07T14:27:52.933Z"],"feature_image":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2SZ1fpLEMXLfjidRspvQ3p/35aaef41cf7231cf349019d54143c00e/Feature_Image.png"],"tags":[1,[[0,{"id":[0,"2xCnBweKwOI3VXdYsGVbMe"],"name":[0,"Developer Week"],"slug":[0,"developer-week"]}],[0,{"id":[0,"6Foe3R8of95cWVnQwe5Toi"],"name":[0,"AI"],"slug":[0,"ai"]}],[0,{"id":[0,"5p63yzKv4kkAVAioSAXDy7"],"name":[0,"Auto Rag"],"slug":[0,"auto-rag"]}],[0,{"id":[0,"glPl13W9trPo4l3ZVojXy"],"name":[0,"Browser Rendering"],"slug":[0,"browser-rendering"]}],[0,{"id":[0,"3JAY3z7p7An94s6ScuSQPf"],"name":[0,"Developer Platform"],"slug":[0,"developer-platform"]}],[0,{"id":[0,"4HIPcb68qM0e26fIxyfzwQ"],"name":[0,"Developers"],"slug":[0,"developers"]}]]],"relatedTags":[0],"authors":[1,[[0,{"name":[0,"Anni Wang"],"slug":[0,"anni"],"bio":[0,null],"profile_image":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3RnKI54hxLOIRs0QBSZgxa/e71b8f7a5ccadb45dd553c69f8ffe539/anni.png"],"location":[0,null],"website":[0,"https://www.linkedin.com/in/a248wang/"],"twitter":[0,null],"facebook":[0,null]}]]],"meta_description":[0,"AutoRAG is here: fully managed Retrieval-Augmented Generation (RAG) pipelines powered by Cloudflare's global network and powerful developer ecosystem. Simplify how you build and scale RAG pipelines to power your context-aware AI chatbots and search applications."],"primary_author":[0,{}],"localeList":[0,{"name":[0,"blog-english-only"],"enUS":[0,"English for Locale"],"zhCN":[0,"No Page for Locale"],"zhHansCN":[0,"No Page for Locale"],"zhTW":[0,"No Page for Locale"],"frFR":[0,"No Page for Locale"],"deDE":[0,"No Page for Locale"],"itIT":[0,"No Page for Locale"],"jaJP":[0,"No Page for Locale"],"koKR":[0,"No Page for Locale"],"ptBR":[0,"No Page for Locale"],"esLA":[0,"No Page for Locale"],"esES":[0,"No Page for Locale"],"enAU":[0,"No Page for Locale"],"enCA":[0,"No Page for Locale"],"enIN":[0,"No Page for Locale"],"enGB":[0,"No Page for Locale"],"idID":[0,"No Page for Locale"],"ruRU":[0,"No Page for Locale"],"svSE":[0,"No Page for Locale"],"viVN":[0,"No Page for Locale"],"plPL":[0,"No Page for Locale"],"arAR":[0,"No Page for Locale"],"nlNL":[0,"No Page for Locale"],"thTH":[0,"No Page for Locale"],"trTR":[0,"No Page for Locale"],"heIL":[0,"No Page for Locale"],"lvLV":[0,"No Page for Locale"],"etEE":[0,"No Page for Locale"],"ltLT":[0,"No Page for Locale"]}],"url":[0,"https://blog.cloudflare.com/introducing-autorag-on-cloudflare"],"metadata":[0,{"title":[0,"Introducing AutoRAG: fully managed Retrieval-Augmented Generation on Cloudflare"],"description":[0,"AutoRAG is here: fully managed Retrieval-Augmented Generation (RAG) pipelines powered by Cloudflare's global network and powerful developer ecosystem. Simplify how you build and scale RAG pipelines to power your context-aware AI chatbots and search applications."],"imgPreview":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/C49lgxZjPye4ttsdldEQj/dcd8bfcd9e47a7b7d9bd98e656dbf26f/OG_Share_2024__28_.png"]}]}],[0,{"id":[0,"7ju3oFGzR3iR8gO2TmMleF"],"title":[0,"Cloudflare Workflows is now GA: production-ready durable execution"],"slug":[0,"workflows-ga-production-ready-durable-execution"],"excerpt":[0,"Workflows — a durable execution engine built directly on top of Workers — is now Generally Available. We’ve landed new human-in-the-loop capabilities, more scale, and more metrics."],"featured":[0,false],"html":[0,"
Betas are useful for feedback and iteration, but at the end of the day, not everyone is willing to be a guinea pig or can tolerate the occasional sharp edge that comes along with beta software. Sometimes you need that big, shiny “Generally Available” label (or blog post), and now it’s Workflows’ turn.
Workflows, our serverless durable execution engine that allows you to build long-running, multi-step applications (some call them “step functions”) on Workers, is now GA.
In short, that means it’s production ready — but it also doesn’t mean Workflows is going to ossify. We’re continuing to scale Workflows (including more concurrent instances), bring new capabilities (like the new waitForEvent API), and make it easier to build AI agents with our Agents SDK and Workflows.
If you prefer code to prose, you can quickly install the Workflows starter project and start exploring the code and the API with a single command:
Workflows is a durable execution engine built on Cloudflare Workers that allows you to build resilient, multi-step applications.
At its core, Workflows implements a step-based architecture where each step in your application is independently retriable, with state automatically persisted between steps. This means that even if a step fails due to a transient error or network issue, Workflows can retry just that step without needing to restart your entire application from the beginning.
When you define a Workflow, you break your application into logical steps.
Each step can either execute code (step.do), put your Workflow to sleep (step.sleep or step.sleepUntil), or wait on an event (step.waitForEvent).
As your Workflow executes, it automatically persists the state returned from each step, ensuring that your application can continue exactly where it left off, even after failures or hibernation periods.
This durable execution model is particularly powerful for applications that coordinate between multiple systems, process data in sequence, or need to handle long-running tasks that might span minutes, hours, or even days.
Workflows are particularly useful at handling complex business processes that traditional stateless functions struggle with.
For example, an e-commerce order processing workflow might check inventory, charge a payment method, send an email confirmation, and update a database — all as separate steps. If the payment processing step fails due to a temporary outage, Workflows will automatically retry just that step when the payment service is available again, without duplicating the inventory check or restarting the entire process.
You can see how this works below: each call to a service can be modelled as a step, independently retried, and if needed, recovered from that step onwards:
\n
import { WorkflowEntrypoint, WorkflowStep, WorkflowEvent } from 'cloudflare:workers';\n\n// The params we expect when triggering this Workflow\ntype OrderParams = {\n\torderId: string;\n\tcustomerId: string;\n\titems: Array<{ productId: string; quantity: number }>;\n\tpaymentMethod: {\n\t\ttype: string;\n\t\tid: string;\n\t};\n};\n\n// Our Workflow definition\nexport class OrderProcessingWorkflow extends WorkflowEntrypoint<Env, OrderParams> {\n\tasync run(event: WorkflowEvent<OrderParams>, step: WorkflowStep) {\n\t\t// Step 1: Check inventory\n\t\tconst inventoryResult = await step.do('check-inventory', async () => {\n\t\t\tconsole.log(`Checking inventory for order ${event.payload.orderId}`);\n\n\t\t\t// Mock: In a real workflow, you'd query your inventory system\n\t\t\tconst inventoryCheck = await this.env.INVENTORY_SERVICE.checkAvailability(event.payload.items);\n\n\t\t\t// Return inventory status as state for the next step\n\t\t\treturn {\n\t\t\t\tinStock: true,\n\t\t\t\treservationId: 'inv-123456',\n\t\t\t\titemsChecked: event.payload.items.length,\n\t\t\t};\n\t\t});\n\n\t\t// Exit workflow if items aren't in stock\n\t\tif (!inventoryResult.inStock) {\n\t\t\treturn { status: 'failed', reason: 'out-of-stock' };\n\t\t}\n\n\t\t// Step 2: Process payment\n\t\t// Configure specific retry logic for payment processing\n\t\tconst paymentResult = await step.do(\n\t\t\t'process-payment',\n\t\t\t{\n\t\t\t\tretries: {\n\t\t\t\t\tlimit: 3,\n\t\t\t\t\tdelay: '30 seconds',\n\t\t\t\t\tbackoff: 'exponential',\n\t\t\t\t},\n\t\t\t\ttimeout: '2 minutes',\n\t\t\t},\n\t\t\tasync () => {\n\t\t\t\tconsole.log(`Processing payment for order ${event.payload.orderId}`);\n\n\t\t\t\t// Mock: In a real workflow, you'd call your payment processor\n\t\t\t\tconst paymentResponse = await this.env.PAYMENT_SERVICE.processPayment({\n\t\t\t\t\tcustomerId: event.payload.customerId,\n\t\t\t\t\torderId: event.payload.orderId,\n\t\t\t\t\tamount: calculateTotal(event.payload.items),\n\t\t\t\t\tpaymentMethodId: event.payload.paymentMethod.id,\n\t\t\t\t});\n\n\t\t\t\t// If payment failed, throw an error that will trigger retry logic\n\t\t\t\tif (paymentResponse.status !== 'success') {\n\t\t\t\t\tthrow new Error(`Payment failed: ${paymentResponse.message}`);\n\t\t\t\t}\n\n\t\t\t\t// Return payment info as state for the next step\n\t\t\t\treturn {\n\t\t\t\t\ttransactionId: 'txn-789012',\n\t\t\t\t\tamount: 129.99,\n\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t};\n\t\t\t},\n\t\t);\n\n\t\t// Step 3: Send email confirmation\n\t\tawait step.do('send-confirmation-email', async () => {\n\t\t\tconsole.log(`Sending confirmation email for order ${event.payload.orderId}`);\n\t\t\tconsole.log(`Including payment confirmation ${paymentResult.transactionId}`);\n\t\t\treturn await this.env.EMAIL_SERVICE.sendOrderConfirmation({ ... })\n\t\t});\n\n\t\t// Step 4: Update database\n\t\tconst dbResult = await step.do('update-database', async () => {\n\t\t\tconsole.log(`Updating database for order ${event.payload.orderId}`);\n\t\t\tawait this.updateOrderStatus(...)\n\n\t\t\treturn { dbUpdated: true };\n\t\t});\n\n\t\t// Return final workflow state\n\t\treturn {\n\t\t\torderId: event.payload.orderId,\n\t\t\tprocessedAt: new Date().toISOString(),\n\t\t};\n\t}\n}
\n
\nThis combination of durability, automatic retries, and state persistence makes Workflows ideal for building reliable distributed applications that can handle real-world failures gracefully.
Workflows are just code, and that makes them extremely powerful: you can define steps dynamically and on-the-fly, conditionally branch, and make API calls to any system you need. But sometimes you also need a Workflow to wait for something to happen in the real world.
For example:
Approval from a human to progress.
An incoming webhook, like from a Stripe payment or a GitHub event.
A state change, such as a file upload to R2 that triggers an Event Notification, and then pushes a reference to the file to the Workflow, so it can process the file (or run it through an AI model).
The new waitForEvent API in Workflows allows you to do just that:
\n
let event = await step.waitForEvent<IncomingStripeWebhook>("receive invoice paid webhook from Stripe", { type: "stripe-webhook", timeout: "1 hour" })
\n
You can then send an event to a specific instance from any external service that can make a HTTP request:
You can even wait for multiple events, using the type parameter, and/or race multiple events using Promise.race to continue on depending on which event was received first:
\n
export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {\n\tasync run(event: WorkflowEvent<Params>, step: WorkflowStep) {\n\t\tlet state = await step.do("get some data", () => { /* step call here /* })\n\t\t// Race the events, resolving the Promise based on which event\n// we receive first\n\t\tlet value = Promise.race([\nstep.waitForEvent("payment success", { type: "payment-success-webhook", timeout: "4 hours" ),\nstep.waitForEvent("payment failure", { type: "payment-failure-webhook", timeout: "4 hours" ),\n])\n// Continue on based on the value and event received\n\t}\n}
\n
To visualize waitForEvent in a bit more detail, let’s assume we have a Workflow that is triggered by a code review agent that watches a GitHub repository.
Without the ability to wait on events, our Workflow can’t easily get human approval to write suggestions back (or even submit a PR of its own). It could potentially poll for some state that was updated, but that means we have to call step.sleep for arbitrary periods of time, poll a storage service for an updated value, and repeat if it’s not there. That’s a lot of code and room for error:
\n \n \n
Without waitForEvent, it’s harder to send data to a Workflow instance that’s running
If we modified that same example to incorporate the new waitForEvent API, we could use it to wait for human approval before making a mutating change:
\n \n \n
Adding waitForEvent to our code review Workflow, so it can seek explicit approval.
You could even imagine an AI agent itself sending and/or acting on behalf of a human here: waitForEvent simply exposes a way for a Workflow to retrieve and pause on something in the world to change before it continues (or not).
Critically, you can call waitForEvent just like any other step in Workflows: you can call it conditionally, and/or multiple times, and/or in a loop. Workflows are just Workers: you have the full power of a programming language and are not restricted by a domain specific language (DSL) or config language.
Good news: we haven’t changed much since our original beta announcement! We’re adding storage pricing for state stored by your Workflows, and retaining our CPU-based and request (invocation) based pricing as follows:
Because the storage pricing is new, we will not actively bill for storage until September 15, 2025. We will notify users above the included 1 GB limit ahead of charging for storage, and by default, Workflows will expire stored state after three (3) days (Free plan) or thirty (30) days (Paid plan).
If you’re wondering what “CPU time” is here: it’s the time your Workflow is actively consuming compute resources. It doesn’t include time spent waiting on API calls, reasoning LLMs, or other I/O (like writing to a database). That might seem like a small thing, but in practice, it adds up: most applications have single digit milliseconds of CPU time, and multiple seconds of wall time: an API or two taking 100 - 250 ms to respond adds up!
\n \n \n
Bill for CPU, not for time spent when a Workflow is idle or waiting.
Workflow engines, especially, tend to spend a lot of time waiting: reading data from object storage (like Cloudflare R2), calling third-party APIs or LLMs like o3-mini or Claude 3.7, even querying databases like D1, Postgres, or MySQL. With Workflows, just like Workers: you don’t pay for time your application is just waiting.
And lastly, deploy the starter to your own Cloudflare account with a few clicks:
"],"published_at":[0,"2025-04-07T14:00+00:00"],"updated_at":[0,"2025-04-08T07:43:37.523Z"],"feature_image":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1JAXkncQezxjEeV0IHNG5b/944fcc20d602ce88e6c2f5dfebba1a56/Feature_Image.png"],"tags":[1,[[0,{"id":[0,"2xCnBweKwOI3VXdYsGVbMe"],"name":[0,"Developer Week"],"slug":[0,"developer-week"]}],[0,{"id":[0,"6hbkItfupogJP3aRDAq6v8"],"name":[0,"Cloudflare Workers"],"slug":[0,"workers"]}],[0,{"id":[0,"1KBFlaTf50eub8uvJ1pAt1"],"name":[0,"Workflows"],"slug":[0,"workflows"]}],[0,{"id":[0,"3JAY3z7p7An94s6ScuSQPf"],"name":[0,"Developer Platform"],"slug":[0,"developer-platform"]}]]],"relatedTags":[0],"authors":[1,[[0,{"name":[0,"Sid Chatterjee"],"slug":[0,"sid"],"bio":[0,null],"profile_image":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/66pIfBfhDUadwWztfEDfXe/66d41b9c01e48856fd1deb323d9007a9/sid.jpg"],"location":[0,"London, United Kingdom"],"website":[0,null],"twitter":[0,"@chatsidhartha"],"facebook":[0,null]}],[0,{"name":[0,"Matt Silverlock"],"slug":[0,"silverlock"],"bio":[0,"Director of Product at Cloudflare."],"profile_image":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7xP5qePZD9eyVtwIesXYxh/e714aaa573161ec9eb48d59bd1aa6225/silverlock.jpeg"],"location":[0,null],"website":[0,null],"twitter":[0,"@elithrar"],"facebook":[0,null]}]]],"meta_description":[0,"Workflows — a durable execution engine built directly on top of Workers — is now Generally Available. We’ve landed new human-in-the-loop capabilities, more scale, and more metrics: just what you need for a production-ready service."],"primary_author":[0,{}],"localeList":[0,{"name":[0,"blog-english-only"],"enUS":[0,"English for Locale"],"zhCN":[0,"No Page for Locale"],"zhHansCN":[0,"No Page for Locale"],"zhTW":[0,"No Page for Locale"],"frFR":[0,"No Page for Locale"],"deDE":[0,"No Page for Locale"],"itIT":[0,"No Page for Locale"],"jaJP":[0,"No Page for Locale"],"koKR":[0,"No Page for Locale"],"ptBR":[0,"No Page for Locale"],"esLA":[0,"No Page for Locale"],"esES":[0,"No Page for Locale"],"enAU":[0,"No Page for Locale"],"enCA":[0,"No Page for Locale"],"enIN":[0,"No Page for Locale"],"enGB":[0,"No Page for Locale"],"idID":[0,"No Page for Locale"],"ruRU":[0,"No Page for Locale"],"svSE":[0,"No Page for Locale"],"viVN":[0,"No Page for Locale"],"plPL":[0,"No Page for Locale"],"arAR":[0,"No Page for Locale"],"nlNL":[0,"No Page for Locale"],"thTH":[0,"No Page for Locale"],"trTR":[0,"No Page for Locale"],"heIL":[0,"No Page for Locale"],"lvLV":[0,"No Page for Locale"],"etEE":[0,"No Page for Locale"],"ltLT":[0,"No Page for Locale"]}],"url":[0,"https://blog.cloudflare.com/workflows-ga-production-ready-durable-execution"],"metadata":[0,{"title":[0,"Cloudflare Workflows is now GA: production-ready durable execution"],"description":[0,"Workflows — a durable execution engine built directly on top of Workers — is now Generally Available. We’ve landed new human-in-the-loop capabilities, more scale, and more metrics: just what you need for a production-ready service."],"imgPreview":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/57BfkxRQ9SaJw6uwKocEQk/85730493a2e4a386cad5d3b2df97465f/OG_Share_2024__29_.png"]}]}],[0,{"id":[0,"6lQQWDqELUkL4c1y13VL0V"],"title":[0,"Piecing together the Agent puzzle: MCP, authentication & authorization, and Durable Objects free tier"],"slug":[0,"building-ai-agents-with-mcp-authn-authz-and-durable-objects"],"excerpt":[0,"Cloudflare delivers toolkit for AI agents with new Agents SDK support for MCP (Model Context Protocol) clients, authentication/authorization/hibernation for MCP servers and Durable Objects free tier. "],"featured":[0,false],"html":[0,"
It’s not a secret that at Cloudflare we are bullish on the future of agents. We’re excited about a future where AI can not only co-pilot alongside us, but where we can actually start to delegate entire tasks to AI.
While it hasn’t been too long since we first announced our Agents SDK to make it easier for developers to build agents, building towards an agentic future requires continuous delivery towards this goal. Today, we’re making several announcements to help accelerate agentic development, including:
New Agents SDK capabilities: Build remote MCP clients, with transport and authentication built-in, to allow AI agents to connect to external services.
Hibernation for McpAgent: Automatically sleep stateful, remote MCP servers when inactive and wake them when needed. This allows you to maintain connections for long-running sessions while ensuring you’re not paying for idle time.
Durable Objects free tier: We view Durable Objects as a key component for building agents, and if you’re using our Agents SDK, you need access to it. Until today, Durable Objects was only accessible as part of our paid plans, and today we’re excited to include it in our free tier.
Workflows GA: Enables you to ship production-ready, long-running, multi-step actions in agents.
AutoRAG: Helps you integrate context-aware AI into your applications, in just a few clicks
AI agents can now connect to and interact with external services through MCP (Model Context Protocol). We’ve updated the Agents SDK to allow you to build a remote MCP client into your AI agent, with all the components — authentication flows, tool discovery, and connection management — built-in for you.
This allows you to build agents that can:
Prompt the end user to grant access to a 3rd party service (MCP server).
Use tools from these external services, acting on behalf of the end user.
Call MCP servers from Workflows, scheduled tasks, or any part of your agent.
Connect to multiple MCP servers and automatically discover new tools or capabilities presented by the 3rd party service.
\n \n \n
MCP (Model Context Protocol) — first introduced by Anthropic — is quickly becoming the standard way for AI agents to interact with external services, with providers like OpenAI, Cursor, and Copilot adopting the protocol.
We recently announced support for building remote MCP servers on Cloudflare, and added an McpAgent class to our Agents SDK that automatically handles the remote aspects of MCP: transport and authentication/authorization. Now, we’re excited to extend the same capabilities to agents acting as MCP clients.
\n \n \n
Want to see it in action? Use the button below to deploy a fully remote MCP client that can be used to connect to remote MCP servers.
\n\n
\n
AI Agents can now act as remote MCP clients, with transport and auth included
AI agents need to connect to external services to access tools, data, and capabilities beyond their built-in knowledge. That means AI agents need to be able to act as remote MCP clients, so they can connect to remote MCP servers that are hosting these tools and capabilities.
We’ve added a new class, MCPClientManager, into the Agents SDK to give you all the tooling you need to allow your AI agent to make calls to external services via MCP. The MCPClientManager class automatically handles:
Transport: Connect to remote MCP servers over SSE and HTTP, with support for Streamable HTTP coming soon.
Connection management: The client tracks the state of all connections and automatically reconnects if a connection is lost.
Capability discovery: Automatically discovers all capabilities, tools, resources, and prompts presented by the MCP server.
Real-time updates: When a server's tools, resources, or prompts change, the client automatically receives notifications and updates its internal state.
Namespacing: When connecting to multiple MCP servers, all tools and resources are automatically namespaced to avoid conflicts.
\n
\n
Granting agents access to tools with built-in auth check for MCP Clients
We've integrated the complete OAuth authentication flow directly into the Agents SDK, so your AI agents can securely connect and authenticate to any remote MCP server without you having to build authentication flow from scratch.
This allows you to give users a secure way to log in and explicitly grant access to allow the agent to act on their behalf by automatically:
Supporting the OAuth 2.1 protocol.
Redirecting users to the service’s login page.
Generating the code challenge and exchanging an authorization code for an access token.
Using the access token to make authenticated requests to the MCP server.
Here is an example of an agent that can securely connect to MCP servers by initializing the client manager, adding the server, and handling the authentication callbacks:
\n
async onStart(): Promise<void> {\n // initialize MCPClientManager which manages multiple MCP clients with optional auth\n this.mcp = new MCPClientManager("my-agent", "1.0.0", {\n baseCallbackUri: `${serverHost}/agents/${agentNamespace}/${this.name}/callback`,\n storage: this.ctx.storage,\n });\n}\n\nasync addMcpServer(url: string): Promise<string> {\n // Add one MCP client to our MCPClientManager\n const { id, authUrl } = await this.mcp.connect(url);\n // Return authUrl to redirect the user to if the user is unauthorized\n return authUrl\n}\n\nasync onRequest(req: Request): Promise<void> {\n // handle the auth callback after being finishing the MCP server auth flow\n if (this.mcp.isCallbackRequest(req)) {\n await this.mcp.handleCallbackRequest(req);\n return new Response("Authorized")\n }\n \n // ...\n}
\n
Connecting to multiple MCP servers and discovering what capabilities they offer
You can use the Agents SDK to connect an MCP client to multiple MCP servers simultaneously. This is particularly useful when you want your agent to access and interact with tools and resources served by different service providers.
The MCPClientManager class maintains connections to multiple MCP servers through the mcpConnections object, a dictionary that maps unique server names to their respective MCPClientConnection instances.
When you register a new server connection using connect(), the manager:
Creates a new connection instance with server-specific authentication.
Initializes the connections and registers for server capability notifications.
\n
async onStart(): Promise<void> {\n // Connect to an image generation MCP server\n await this.mcp.connect("https://image-gen.example.com/mcp/sse");\n \n // Connect to a code analysis MCP server\n await this.mcp.connect("https://code-analysis.example.org/sse");\n \n // Now we can access tools with proper namespacing\n const allTools = this.mcp.listTools();\n console.log(`Total tools available: ${allTools.length}`);\n}
\n
Each connection manages its own authentication context, allowing one AI agent to authenticate to multiple servers simultaneously. In addition, MCPClientManager automatically handles namespacing to prevent collisions between tools with identical names from different servers.
For example, if both an “Image MCP Server” and “Code MCP Server” have a tool named “analyze”, they will both be independently callable without any naming conflicts.
\n
\n
Use Stytch, Auth0, and WorkOS to bring authentication & authorization to your MCP server
With MCP, users will have a new way of interacting with your application, no longer relying on the dashboard or API as the entrypoint. Instead, the service will now be accessed by AI agents that are acting on a user’s behalf. To ensure users and agents can connect to your service securely, you’ll need to extend your existing authentication and authorization system to support these agentic interactions, implementing login flows, permissions scopes, consent forms, and access enforcement for your MCP server.
We’re adding integrations with Stytch, Auth0, and WorkOS to make it easier for anyone building an MCP server to configure authentication & authorization for their MCP server.
You can leverage our MCP server integration with Stytch, Auth0, and WorkOS to:
Allow users to authenticate to your MCP server through email, social logins, SSO (single sign-on), and MFA (multi-factor authentication).
Define scopes and permissions that directly map to your MCP tools.
Present users with a consent page corresponding with the requested permissions.
Enforce the permissions so that agents can only invoke permitted tools.
\n \n \n
Get started with the examples below by using the “Deploy to Cloudflare” button to deploy the demo MCP servers in your Cloudflare account. These demos include pre-configured authentication endpoints, consent flows, and permission models that you can tailor to fit your needs. Once you deploy the demo MCP servers, you can use the Workers AI playground, a browser-based remote MCP client, to test out the end-to-end user flow.
Get started with a remote MCP server that uses Stytch to allow users to sign in with email, Google login or enterprise SSO and authorize their AI agent to view and manage their company’s OKRs on their behalf. Stytch will handle restricting the scopes granted to the AI agent based on the user’s role and permissions within their organization. When authorizing the MCP Client, each user will see a consent page that outlines the permissions that the agent is requesting that they are able to grant based on their role.
\n
For more consumer use cases, deploy a remote MCP server for a To Do app that uses Stytch for authentication and MCP client authorization. Users can sign in with email and immediately access the To Do lists associated with their account, and grant access to any AI assistant to help them manage their tasks.
\n
Regardless of use case, Stytch allows you to easily turn your application into an OAuth 2.0 identity provider and make your remote MCP server into a Relying Party so that it can easily inherit identity and permissions from your app. To learn more about how Stytch is enabling secure authentication to remote MCP servers, read their blog post.
“One of the challenges of realizing the promise of AI agents is enabling those agents to securely and reliably access data from other platforms. Stytch Connected Apps is purpose-built for these agentic use cases, making it simple to turn your app into an OAuth 2.0 identity provider to enable secure access to remote MCP servers. By combining Cloudflare Workers with Stytch Connected Apps, we're removing the barriers for developers, enabling them to rapidly transition from AI proofs-of-concept to secure, deployed implementations.” — Julianna Lamb, Co-Founder & CTO, Stytch.
Get started with a remote MCP server that uses Auth0 to authenticate users through email, social logins, or enterprise SSO to interact with their todos and personal data through AI agents. The MCP server securely connects to API endpoints on behalf of users, showing exactly which resources the agent will be able to access once it gets consent from the user. In this implementation, access tokens are automatically refreshed during long running interactions.
To set it up, first deploy the protected API endpoint:
\n
Then, deploy the MCP server that handles authentication through Auth0 and securely connects AI agents to your API endpoint.
\n
"Cloudflare continues to empower developers building AI products with tools like AI Gateway, Vectorize, and Workers AI. The recent addition of Remote MCP servers further demonstrates that Cloudflare Workers and Durable Objects are a leading platform for deploying serverless AI. We’re very proud that Auth0 can help solve the authentication and authorization needs for these cutting-edge workloads." — Sandrino Di Mattia, Auth0 Sr. Director, Product Architecture.
Get started with a remote MCP server that uses WorkOS's AuthKit to authenticate users and manage the permissions granted to AI agents. In this example, the MCP server dynamically exposes tools based on the user's role and access rights. All authenticated users get access to the add tool, but only users who have been assigned the image_generation permission in WorkOS can grant the AI agent access to the image generation tool. This showcases how MCP servers can conditionally expose capabilities to AI agents based on the authenticated user's role and permission.
\n
“MCP is becoming the standard for AI agent integration, but authentication and authorization are still major gaps for enterprise adoption. WorkOS Connect enables any application to become an OAuth 2.0 authorization server, allowing agents and MCP clients to securely obtain tokens for fine-grained permission authorization and resource access. With Cloudflare Workers, developers can rapidly deploy remote MCP servers with built-in OAuth and enterprise-grade access control. Together, WorkOS and Cloudflare make it easy to ship secure, enterprise-ready agent infrastructure.” — Michael Grinich, CEO of WorkOS.
\n
\n
Hibernate-able WebSockets: put AI agents to sleep when they’re not in use
Starting today, a new improvement is landing in the McpAgent class: support for the WebSockets Hibernation API that allows your MCP server to go to sleep when it’s not receiving requests and instantly wake up when it’s needed. That means that you now only pay for compute when your agent is actually working.
We recently introduced the McpAgent class, which allows developers to build remote MCP servers on Cloudflare by using Durable Objects to maintain stateful connections for every client session. We decided to build McpAgent to be stateful from the start, allowing developers to build servers that can remember context, user preferences, and conversation history. But maintaining client connections means that the session can remain active for a long time, even when it’s not being used.
You don’t need to change your code to take advantage of hibernation. With our latest SDK update, all McpAgent instances automatically include hibernation support, allowing your stateful MCP servers to sleep during inactive periods and wake up with their state preserved when needed.
When a request comes in on the Server-Sent Events endpoint, /sse, the Worker initializes a WebSocket connection to the appropriate Durable Object for the session and returns an SSE stream back to the client. All responses flow over this stream.
The implementation leverages the WebSocket Hibernation API within Durable Objects. When periods of inactivity occur, the Durable Object can be evicted from memory while keeping the WebSocket connection open. If the WebSocket later receives a message, the runtime recreates the Durable Object and delivers the message to the appropriate handler.
To help you build AI agents on Cloudflare, we’re making Durable Objects available on the free tier, so you can start with zero commitment. With Agents SDK, your AI agents deploy to Cloudflare running on Durable Objects.
Durable Objects offer compute alongside durable storage, that when combined with Workers, unlock stateful, serverless applications. Each Durable Object is a stateful coordinator for handling client real-time interactions, making requests to external services like LLMs, and creating agentic “memory” through state persistence in zero-latency SQLite storage — all tasks required in an AI agent. Durable Objects scale out to millions of agents effortlessly, with each agent created near the user interacting with their agent for fast performance, all managed by Cloudflare.
Zero-latency SQLite storage in Durable Objects was introduced in public beta September 2024 for Birthday Week. Since then, we’ve focused on missing features and robustness compared to pre-existing key-value storage in Durable Objects. We are excited to make SQLite storage generally available, with a 10 GB SQLite database per Durable Object, and recommend SQLite storage for all new Durable Object classes. Durable Objects free tier can only access SQLite storage.
Cloudflare’s free tier allows you to build real-world applications. On the free plan, every Worker request can call a Durable Object. For usage-based pricing, Durable Objects incur compute and storage usage with the following free tier limits.
We realize this is a lot of information to take in, but don’t worry. Whether you’re new to agents as a whole, or looking to learn more about how Cloudflare can help you build agents, today we launched a new site to help get you started — agents.cloudflare.com.
Let us know what you build!
"],"published_at":[0,"2025-04-07T14:10+01:00"],"updated_at":[0,"2025-04-08T08:06:59.562Z"],"feature_image":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3TwoHmJacmESFWbUsT8gG3/5dcc9efc89b275ccd1ec887eed06245f/Feature_Image.png"],"tags":[1,[[0,{"id":[0,"2xCnBweKwOI3VXdYsGVbMe"],"name":[0,"Developer Week"],"slug":[0,"developer-week"]}],[0,{"id":[0,"6Foe3R8of95cWVnQwe5Toi"],"name":[0,"AI"],"slug":[0,"ai"]}],[0,{"id":[0,"22RkiaggH3NV4u6qyMmC42"],"name":[0,"Agents"],"slug":[0,"agents"]}],[0,{"id":[0,"4HIPcb68qM0e26fIxyfzwQ"],"name":[0,"Developers"],"slug":[0,"developers"]}],[0,{"id":[0,"6Wqde8DfPQiDn7CAhj6lu2"],"name":[0,"Model Context Protocol,"],"slug":[0,"model-context-protocol"]}],[0,{"id":[0,"6Lfy7VaNvl5G8gOYMKFiux"],"name":[0,"MCP"],"slug":[0,"mcp"]}]]],"relatedTags":[0],"authors":[1,[[0,{"name":[0,"Rita Kozlov"],"slug":[0,"rita"],"bio":[0,null],"profile_image":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/56u5zfWi9255rUocOgksl0/5eb2eb16e26893d259f7b00af85e8417/rita.png"],"location":[0,null],"website":[0,null],"twitter":[0,"@ritakozlov_"],"facebook":[0,null]}],[0,{"name":[0,"Dina Kozlov"],"slug":[0,"dina"],"bio":[0,null],"profile_image":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/bY78cK0burCjZbD6jOgAH/a8479b5ea6dd8fb3acb41227c1a4ad0e/dina.jpg"],"location":[0,null],"website":[0,null],"twitter":[0,"@dinasaur_404"],"facebook":[0,null]}],[0,{"name":[0,"Vy Ton"],"slug":[0,"vy"],"bio":[0,"Product Manager at Cloudflare."],"profile_image":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/47vp9vXZx8EXsnBFmCK8NS/2f7f46cdadaa4545e2b61d9c674d1e5a/vy.png"],"location":[0,null],"website":[0,null],"twitter":[0,"@vaiton13"],"facebook":[0,null]}]]],"meta_description":[0,"Cloudflare delivers the toolkit for AI agents with new Agents SDK support for MCP (Model Context Protocol) clients, authentication/authorization/hibernation for MCP servers, and Durable Objects free tier."],"primary_author":[0,{}],"localeList":[0,{"name":[0,"blog-english-only"],"enUS":[0,"English for Locale"],"zhCN":[0,"No Page for Locale"],"zhHansCN":[0,"No Page for Locale"],"zhTW":[0,"No Page for Locale"],"frFR":[0,"No Page for Locale"],"deDE":[0,"No Page for Locale"],"itIT":[0,"No Page for Locale"],"jaJP":[0,"No Page for Locale"],"koKR":[0,"No Page for Locale"],"ptBR":[0,"No Page for Locale"],"esLA":[0,"No Page for Locale"],"esES":[0,"No Page for Locale"],"enAU":[0,"No Page for Locale"],"enCA":[0,"No Page for Locale"],"enIN":[0,"No Page for Locale"],"enGB":[0,"No Page for Locale"],"idID":[0,"No Page for Locale"],"ruRU":[0,"No Page for Locale"],"svSE":[0,"No Page for Locale"],"viVN":[0,"No Page for Locale"],"plPL":[0,"No Page for Locale"],"arAR":[0,"No Page for Locale"],"nlNL":[0,"No Page for Locale"],"thTH":[0,"No Page for Locale"],"trTR":[0,"No Page for Locale"],"heIL":[0,"No Page for Locale"],"lvLV":[0,"No Page for Locale"],"etEE":[0,"No Page for Locale"],"ltLT":[0,"No Page for Locale"]}],"url":[0,"https://blog.cloudflare.com/building-ai-agents-with-mcp-authn-authz-and-durable-objects"],"metadata":[0,{"title":[0,"Piecing together the Agent puzzle: MCP, authentication & authorization, and Durable Objects free tier"],"description":[0,"Cloudflare delivers the toolkit for AI agents with new Agents SDK support for MCP (Model Context Protocol) clients, authentication/authorization/hibernation for MCP servers, and Durable Objects free tier."],"imgPreview":[0,"https://cf-assets.www.cloudflare.com/zkvhlag99gkb/30VRQmv0JPpGZ42NwvLTbR/5ddff55f644d394f2b952287d0801faf/OG_Share_2024__27_.png"]}]}]]],"locale":[0,"en-us"],"translations":[0,{"posts.by":[0,"By"],"footer.gdpr":[0,"GDPR"],"lang_blurb1":[0,"This post is also available in {lang1}."],"lang_blurb2":[0,"This post is also available in {lang1} and {lang2}."],"lang_blurb3":[0,"This post is also available in {lang1}, {lang2} and {lang3}."],"footer.press":[0,"Press"],"header.title":[0,"The Cloudflare Blog"],"search.clear":[0,"Clear"],"search.filter":[0,"Filter"],"search.source":[0,"Source"],"footer.careers":[0,"Careers"],"footer.company":[0,"Company"],"footer.support":[0,"Support"],"footer.the_net":[0,"theNet"],"search.filters":[0,"Filters"],"footer.our_team":[0,"Our team"],"footer.webinars":[0,"Webinars"],"page.more_posts":[0,"More posts"],"posts.time_read":[0,"{time} min read"],"search.language":[0,"Language"],"footer.community":[0,"Community"],"footer.resources":[0,"Resources"],"footer.solutions":[0,"Solutions"],"footer.trademark":[0,"Trademark"],"header.subscribe":[0,"Subscribe"],"footer.compliance":[0,"Compliance"],"footer.free_plans":[0,"Free plans"],"footer.impact_ESG":[0,"Impact/ESG"],"posts.follow_on_X":[0,"Follow on X"],"footer.help_center":[0,"Help center"],"footer.network_map":[0,"Network Map"],"header.please_wait":[0,"Please Wait"],"page.related_posts":[0,"Related posts"],"search.result_stat":[0,"Results {search_range} of {search_total} for {search_keyword}"],"footer.case_studies":[0,"Case Studies"],"footer.connect_2024":[0,"Connect 2024"],"footer.terms_of_use":[0,"Terms of Use"],"footer.white_papers":[0,"White Papers"],"footer.cloudflare_tv":[0,"Cloudflare TV"],"footer.community_hub":[0,"Community Hub"],"footer.compare_plans":[0,"Compare plans"],"footer.contact_sales":[0,"Contact Sales"],"header.contact_sales":[0,"Contact Sales"],"header.email_address":[0,"Email Address"],"page.error.not_found":[0,"Page not found"],"footer.developer_docs":[0,"Developer docs"],"footer.privacy_policy":[0,"Privacy Policy"],"footer.request_a_demo":[0,"Request a demo"],"page.continue_reading":[0,"Continue reading"],"footer.analysts_report":[0,"Analyst reports"],"footer.for_enterprises":[0,"For enterprises"],"footer.getting_started":[0,"Getting Started"],"footer.learning_center":[0,"Learning Center"],"footer.project_galileo":[0,"Project Galileo"],"pagination.newer_posts":[0,"Newer Posts"],"pagination.older_posts":[0,"Older Posts"],"posts.social_buttons.x":[0,"Discuss on X"],"search.icon_aria_label":[0,"Search"],"search.source_location":[0,"Source/Location"],"footer.about_cloudflare":[0,"About Cloudflare"],"footer.athenian_project":[0,"Athenian Project"],"footer.become_a_partner":[0,"Become a partner"],"footer.cloudflare_radar":[0,"Cloudflare Radar"],"footer.network_services":[0,"Network services"],"footer.trust_and_safety":[0,"Trust & Safety"],"header.get_started_free":[0,"Get Started Free"],"page.search.placeholder":[0,"Search Cloudflare"],"footer.cloudflare_status":[0,"Cloudflare Status"],"footer.cookie_preference":[0,"Cookie Preferences"],"header.valid_email_error":[0,"Must be valid email."],"search.result_stat_empty":[0,"Results {search_range} of {search_total}"],"footer.connectivity_cloud":[0,"Connectivity cloud"],"footer.developer_services":[0,"Developer services"],"footer.investor_relations":[0,"Investor relations"],"page.not_found.error_code":[0,"Error Code: 404"],"search.autocomplete_title":[0,"Insert a query. Press enter to send"],"footer.logos_and_press_kit":[0,"Logos & press kit"],"footer.application_services":[0,"Application services"],"footer.get_a_recommendation":[0,"Get a recommendation"],"posts.social_buttons.reddit":[0,"Discuss on Reddit"],"footer.sse_and_sase_services":[0,"SSE and SASE services"],"page.not_found.outdated_link":[0,"You may have used an outdated link, or you may have typed the address incorrectly."],"footer.report_security_issues":[0,"Report Security Issues"],"page.error.error_message_page":[0,"Sorry, we can't find the page you are looking for."],"header.subscribe_notifications":[0,"Subscribe to receive notifications of new posts:"],"footer.cloudflare_for_campaigns":[0,"Cloudflare for Campaigns"],"header.subscription_confimation":[0,"Subscription confirmed. Thank you for subscribing!"],"posts.social_buttons.hackernews":[0,"Discuss on Hacker News"],"footer.diversity_equity_inclusion":[0,"Diversity, equity & inclusion"],"footer.critical_infrastructure_defense_project":[0,"Critical Infrastructure Defense Project"]}],"localesAvailable":[1,[]],"footerBlurb":[0,"Cloudflare's connectivity cloud protects entire corporate networks, helps customers build Internet-scale applications efficiently, accelerates any website or Internet application, wards off DDoS attacks, keeps hackers at bay, and can help you on your journey to Zero Trust.
Visit 1.1.1.1 from any device to get started with our free app that makes your Internet faster and safer.
To learn more about our mission to help build a better Internet, start here. If you're looking for a new career direction, check out our open positions."]}" client="load" opts="{"name":"Post","value":true}" await-children="">
Introducing The Serverlist: Cloudflare's New Serverless Newsletter
At Cloudflare, we've been digging our heels into serverless, so we created The Serverlist newsletter, enabling us to share interesting content in the serverless space with the developer community. The Serverlist newsletter highlights all things serverless, with content that covers news from the serverless world, tutorials to learn how to get involved yourself, and different events you can attend.
Check out our first edition of The Serverlist below and sign up here to have this newsletter delivered to your inbox.
Visit 1.1.1.1 from any device to get started with our free app that makes your Internet faster and safer.
To learn more about our mission to help build a better Internet, start here. If you're looking for a new career direction, check out our open positions.
AutoRAG is here: fully managed Retrieval-Augmented Generation (RAG) pipelines powered by Cloudflare's global network and powerful developer ecosystem. ...
Workflows — a durable execution engine built directly on top of Workers — is now Generally Available. We’ve landed new human-in-the-loop capabilities, more scale, and more metrics....
Cloudflare delivers toolkit for AI agents with new Agents SDK support for MCP (Model Context Protocol) clients, authentication/authorization/hibernation for MCP servers and Durable Objects free tier. ...