
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Mon, 01 Jun 2026 20:10:08 GMT</lastBuildDate>
        <item>
            <title><![CDATA[How we built Cloudflare's data platform and an AI agent on top of it]]></title>
            <link>https://blog.cloudflare.com/our-unified-data-platform/</link>
            <pubDate>Thu, 28 May 2026 13:00:00 GMT</pubDate>
            <description><![CDATA[ Here’s how we built Town Lake, Cloudflare's unified analytics platform, alongside Skipper, an internal AI agent running on top of it. ]]></description>
            <content:encoded><![CDATA[ <p>Cloudflare processes more than a billion events every second. Our network spans 330+ cities in 120+ countries. Behind every HTTP request, every Worker invocation, every R2 read operation, there is data, and a lot of it.</p><p>For years, that data was not very easy to access. It lived in dozens of production databases, ClickHouse clusters, Kafka streams, Google Cloud buckets, BigQuery datasets, and a long tail of pipelines. To answer a simple question like "How many domains that signed up today are in the Top 100 by traffic?", an analyst at Cloudflare had to know which system to ask, what credentials to use, what query language to write, and whether the data they were looking at was sampled, fresh, or seven-days stale. As a result, it was difficult to glean informed insights from the data.</p><p>To solve this problem, we built two in-house tools: Town Lake, Cloudflare's unified data analytics platform, and Skipper, an AI data agent that runs on top of it. Town Lake is a single SQL interface to everything Cloudflare knows, and Skipper is how anyone at Cloudflare can ask questions in plain English and get correct, auditable answers back in seconds.</p><p>This is the story of how we built both.</p>
    <div>
      <h3>The shape of the problem</h3>
      <a href="#the-shape-of-the-problem">
        
      </a>
    </div>
    <p>If you have ever worked at a company that went through a hyper-growth period, you know what data sprawl looks like. Ours had a few specific symptoms:</p><ol><li><p><b>Too many disparate systems.</b> A product engineer who wanted to investigate a customer issue might need to query Postgres for account metadata, ClickHouse for analytics events, BigQuery for usage rollups, R2 for raw logs, and Kafka topics for real-time signals. Each system had its own credentials, its own language, and its own retention policy.</p></li><li><p><b>Sampled data.</b> This is fine for dashboards, but doesn’t work for domains like billing. Our <a href="https://blog.cloudflare.com/how-we-make-sense-of-too-much-data"><u>analytics pipeline</u></a> downsamples to handle 700M+ events per second. That is the right behavior when you want an analytics dashboard to load, but it’s exactly the wrong behavior when you are trying to compute someone’s usage required to issue an invoice.</p></li><li><p><b>External dependencies for internal data.</b> Parts of our previous internal reporting stack were powered by external vendors. Beyond the cost, we had a hard external dependency on another cloud for some of our critical data.</p></li><li><p><b>No one could find the data.</b> Even if you had all the right credentials, you needed to know that the right table for "Billable Workers requests by account" lived in a specific ClickHouse cluster, in a specific schema, joined to a specific Postgres dimension table, and that the join required an obscure customer ID translation. There was too much tribal knowledge.</p></li></ol><p>We had a cultural challenge too: data infrastructure had historically been treated as a back-office function that was in service of the business, rather than critical infrastructure in its own right.</p>
    <div>
      <h3>What we wanted</h3>
      <a href="#what-we-wanted">
        
      </a>
    </div>
    <p>We wanted to create one place where anyone at the company with appropriate permissions and a need to know could get answers to questions about Cloudflare: “Show me the top 100 customers by revenue in the last quarter”, “List all Bot Management ML scoring events with score &gt; 0.9 in the last 48 hours coming from a specific ASN”, “Find the Top 100 billing support tickets from customers who have spent &gt;$100”, etc.</p><p>We wanted that place to give fresh, accurate, unsampled data for the queries that need it (like billing or security investigations) and fast, downsampled data for the queries that don't (like dashboards or exploration).</p><p>We wanted security and governance baked in, with personally identifiable information (PII) detected automatically, and sensitive tables locked down by default. All access should be auditable, and have time-bounded permission grants so that users could only access data when they were actively working on tasks that required it.</p><p>We wanted it to be built on Cloudflare’s own platform: <a href="https://www.cloudflare.com/products/r2/"><u>R2</u></a> for storage, <a href="https://www.cloudflare.com/products/workers/"><u>Workers</u></a> for compute, <a href="https://www.cloudflare.com/products/access/"><u>Cloudflare Access</u></a> for authentication, <a href="https://www.cloudflare.com/products/workflows/"><u>Workflows</u></a> for orchestration. If we were going to make a major investment in our data infrastructure, it was going to be built on the same products we sell to customers.</p><p>And we wanted, eventually, an interface that did not require knowing any SQL. The goal was to empower anyone at the company with appropriate permissions and a need to know to look at the stream of data flowing through our network, not just analysts.</p><p>That last requirement is what became Skipper.</p>
    <div>
      <h3>Town Lake, the platform</h3>
      <a href="#town-lake-the-platform">
        
      </a>
    </div>
    <p>At its core, our data platform’s architecture is a <a href="https://en.wikipedia.org/wiki/Data_lakehouse"><u>data lakehouse</u></a>: a query engine that reads from object storage, with a metadata layer that makes the storage behave like a database. We call it Town Lake, after its namesake in Austin, Texas.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/47E8uC26eDC4XrOibNlGCi/4b1e083bb76de4f09404bdac07e5f03a/image5.png" />
            
            </figure><p>Its most important components are:</p><p><b>Query engine.</b> We chose Apache Trino for that: a single SQL query can join a Postgres table, a ClickHouse table, and an Iceberg table on R2 without a need to materialize the intermediate results into a different system. A query that asks "what are the top 100 paying customers by Workers requests this week" compiles into a plan that pushes filters into ClickHouse, joins against an account dimension in Postgres, and ranks against billing rollups in R2, all in one go.</p><p><b>R2 Data Catalog,</b> our managed Apache Iceberg service, is where the cold and warm data lives. Iceberg gives us schema evolution, time travel, partition evolution, and the ability to compact data as it ages. Per-minute usage from last week becomes hourly, hourly from last quarter becomes daily, etc. The storage cost decreases as recency does, while the data stays queryable. Parquet files in R2 are much cheaper compared to keeping the same data in an OLAP database.</p><p><b>DataHub</b> is our metadata catalog. Every table, column, owner, lineage edge, and glossary term lives there. When a user asks "what's in <code>townlake.dim.accounts</code>," DataHub provides an answer, including the table description, the column descriptions, the owning team, the upstream tables that feed it, and the downstream tables that consume it.</p><p><b>Lifeguard</b> is our access control service: it stores access rules in D1, dynamically pulls user and group membership from our internal access management system, and renders a combined JSON policy that Trino reads over HTTP. Lifeguard also feeds basic access information to Skipper and the Gateway, so users get blocked at the front door rather than at query time.</p><p><b>Skimmer</b> is a PII detection scanner. It runs continuously, samples rows from every column in every table, and uses Workers AI to classify whether each column contains PII. It does this in two passes: first, a fast per-column classifier; then, if anything is flagged, an agentic second pass that gets full table context and can query Trino directly to verify. Findings flow into DataHub and into Lifeguard's allowlist to allow human-in-the-loop review.</p><p><b>Transformer</b> is our ELT (extract, load, transform) engine built on Workflows. Users define a Directed Acyclic Graph (DAG) of SQL transformations with YAML frontmatter (target table, materialization mode, dependencies, schedule). Transformer compiles the graph and runs it on Trino, with state managed by Durable Objects, definitions stored in R2, and run history in D1.</p><p><b>Ingestion</b> is the bridge from operational systems into the lake. An orchestrator runs as a long-lived Kubernetes deployment, reads pipeline configs, and spawns short-lived worker jobs to extract from Postgres or ClickHouse, transform to Parquet, and load into R2 as Iceberg tables. Each pipeline runs as either full-replace or incremental-append.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3eVzLYLm870nH9S3qVmGD9/6c8d81f3c07a2edcec1d83648d1edb1f/image3.png" />
          </figure>
    <div>
      <h3>Default-closed: governance by construction</h3>
      <a href="#default-closed-governance-by-construction">
        
      </a>
    </div>
    <p>A real concern when you build a unified data platform is that you have just built a large sensitive-data surface. The traditional answer to this is: open by default, restrict by exception. Allow access to everything, then audit and lock down sensitive tables when someone notices.</p><p>Town Lake takes the opposite approach. Tables are inaccessible for querying until they have been reviewed. When a new database is connected to Trino or a new table is created, Skimmer scans it, classifies its columns, and registers it in the central allowlist as pending. Until a reviewer approves the table, and the specific columns within it, users can't query it. This sounds painful, and it would be, except for two things.</p><p>First, it's automated. Skimmer's classifier is reasonably good: it catches obvious PII (emails, IPs, names, phone numbers) and the long tail of non-obvious sensitive data (API tokens that match certain prefixes, opaque IDs that can be traced back to users). Reviewers see what was detected and either approve, override, or deny. Most reviews take seconds.</p><p>Second, the workflow is self-serve. If you query a table you don't have access to, the error message is not "permission denied." It's "this table needs review, click here to request one." Skipper, the AI agent, will even suggest the right <a href="https://www.cloudflare.com/learning/access-management/role-based-access-control-rbac/"><u>RBAC</u></a> group to request and link you straight to it.</p><p>We separate schema discovery from data access. Users can see what tables exist, but unreviewed columns are hidden from <code>DESCRIBE</code> and <code>SHOW COLUMNS</code> and from <code>SELECT *</code>. That subtle distinction matters: it means a new unreviewed column doesn't break existing dashboards built on the rest of an approved table.</p><p>PII is opt-in per session. By default, Trino redacts sensitive columns before they ever hit your screen. If you have a legitimate need for raw PII (e.g., fraud investigation), you flip the bit on the session, your permissions are checked, and the redaction is lifted. The flip and every query is logged.</p>
    <div>
      <h3>Skipper: the AI data agent</h3>
      <a href="#skipper-the-ai-data-agent">
        
      </a>
    </div>
    <p>A query engine alone isn’t enough these days. SQL is still a barrier, as is knowing which of tens of thousands of tables to query — you need to know the canonical schema.</p><p>Skipper is our take on a conversational AI agent that goes from natural-language question to validated answer, grounded in the company's actual data, code, and institutional knowledge. We built it on top of Town Lake and on top of our developer platform: Workers, Workers AI, Durable Objects, D1, R2, Workflows, KV.</p><p>The interface is a chat box. Ask a question:</p><blockquote><p><i>Show me the top 10 customers by R2 storage cost in the last 30 days, and the change versus the previous 30 days.</i></p></blockquote><p>Skipper finds the right tables (DataHub search), pulls their schemas and lineage, writes the SQL, submits it to Trino, polls for results, and shows you a table or a chart. Follow up:</p><blockquote><p><i>Now break it down by region, and ignore internal Cloudflare accounts.</i></p></blockquote><p>It carries the context, refines the query, and reruns it. If something looks wrong, e.g., a join produced zero rows or a filter excluded what you expected, then Skipper investigates, adjusts, and tries again, in the closed-loop reasoning. The hard part was having the right context.</p><p>Skipper can also package charts into dashboards that can be shared internally and embedded into other internal applications. It also has tools for building transformation graphs via Transformer and for checking access and permissions via Lifeguard.</p><p>Skipper meets its users wherever they are. All of these tools are available via a Worker backed by a built-in agentic harness powered by Workers AI. On the flip side, many of our internal users work via local agentic flows, and Skipper’s tools are additionally available via an MCP server.</p>
    <div>
      <h3>Layers of context</h3>
      <a href="#layers-of-context">
        
      </a>
    </div>
    <p>An LLM, given a SQL prompt and a list of table names, can hallucinate joins, misuse columns, and confidently produce a number that is completely wrong. We learned this the hard way during early experiments. The fix is multiple layers of grounded context that the model can pull from at retrieval time.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6IEpUwNgEVrmNBMeKjFqRY/84a83ec11b38fa6c7595db2dc4fcb334/image2.png" />
          </figure><p>Layer 1: Schema and usage metadata. DataHub knows every column, every type, every primary key, every foreign key for every table. It also knows which tables are commonly joined together based on historical query patterns. Skipper's <code>search_datasets</code> and <code>get_entity_details</code> tools surface this directly.</p><p>Layer 2: Human annotations. When the team that owns <code>dim.accounts</code> writes a description like <i>"Account-level entity. One row per account_id. Every account belongs to exactly one customer (via customer_id FK),"</i> that description lives in DataHub and ends up in Skipper's context. Tags like <code>curated</code> mark validated tables that Skipper should prefer over scratch space.</p><p>Layer 3: Code-derived knowledge. Some of the most valuable context is not in any catalog: it's in the SQL that produces the table. The Transformer pipeline emits per-node <code>.meta.json</code> documentation to DataHub on every successful run. So when Skipper looks at <code>fct.billings_allocated</code>, it doesn't just see the schema; it sees that this is a pre-joined fact table built from <code>dim.accounts</code>, <code>dim.customers</code>, and <code>seed.product_classification</code>, with its <code>alloc_amount</code> column computed as <code>billed_amount / 12 for annual; billed_amount for monthly</code>. That's the kind of nuance that separates a correct answer from a confidently wrong one.</p><p>Layer 4: Curated data models. We maintain a small set of "data model" pages: short, human-written documents that describe how to think about billing, customers, accounts, and zones. <i>"Prefer tables tagged 'curated'. Avoid </i><code><i>scratch_r2</i></code><i> and tables tagged 'internal'. Search with data model terms (e.g., 'billing product revenue') not natural language."</i> These are surfaced as MCP resources that the agent can pull when the question matches.</p><p>Layer 5: Runtime introspection. When everything else fails, Skipper can issue live queries to Trino: <code>DESCRIBE table, SELECT DISTINCT col LIMIT 20, SELECT COUNT(*)</code>. It uses these sparingly as runtime context is expensive, but it's the safety net that makes the rest of the system robust.</p>
    <div>
      <h3>Skipper as MCP: Code Mode</h3>
      <a href="#skipper-as-mcp-code-mode">
        
      </a>
    </div>
    <p>One specific implementation detail is worth pulling out, because it is uniquely a Cloudflare-shaped solution.</p><p>When you build an AI agent with tools, the standard pattern is to define the tools in your prompt, let the model call them one at a time, parse the response, execute, and return results. This is fine, but it is chatty: a five-tool workflow is five model round-trips, each of which has to re-establish context.</p><p>For our MCP server, we use <a href="https://blog.cloudflare.com/code-mode/"><u>Code Mode</u></a>. Instead of defining 30 individual tools, we expose two: <code>search</code> and <code>execute</code>. The model writes a JavaScript snippet that calls our entire toolset programmatically:</p>
            <pre><code>const datasets = await skipper.search_datasets({ query: "billing product revenue" })
const queryId = await skipper.start_query({ sql: "SELECT ..." })
const results = await skipper.fetch_results({ queryId, mode: "inject" })
return skipper.create_chart({ chartType: "bar", data: results.rows, ... })</code></pre>
            <p>That JavaScript runs in a sandboxed Dynamic Worker isolate via <a href="https://developers.cloudflare.com/workers/runtime-apis/bindings/worker-loader/"><u>WorkerLoader</u></a>. The model gets to express complex multi-step workflows in a single round-trip, in a language it already knows extremely well. It's faster, it's cheaper, and the workflows it produces are auditable as code.</p>
    <div>
      <h3>The security model is the data model</h3>
      <a href="#the-security-model-is-the-data-model">
        
      </a>
    </div>
    <p>Everything Skipper does runs as the calling user. If you don't have access to a table, Skipper can't query it for you. If you ask for PII, your permissions are checked. If a query you save is shared with a teammate, their access is checked at view time, not at save time, because group membership changes.</p><p>Shared dashboards have their own twist. They can be embedded in any internal Cloudflare tool with a single placeholder div and a script tag:</p>
            <pre><code>&lt;div data-skipper-dashboard="dash-123"&gt;&lt;/div&gt;
&lt;script src="https://skipper.cloudflare.com/embed.js" async&gt;&lt;/script&gt;</code></pre>
            <p>The iframe auto-resizes to fit content. Content Security Policy (CSP) <code>frame-ancestors</code> blocks embedding from anywhere outside the corporate domain. Cloudflare Access still gates the iframe contents, so an unauthenticated viewer hits the Access login page in the iframe rather than seeing the data. Non-owner viewers are checked against the underlying tables: if they don't have access, they get pointed at the right group to request.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/54J6Qyl8K77YAhOsuCRGEp/55e8090976b45ff77fdfa049731fe303/image4.png" />
          </figure>
    <div>
      <h3>What it powers: really fast answers</h3>
      <a href="#what-it-powers-really-fast-answers">
        
      </a>
    </div>
    <p><b>Billing.</b> This was the original use case. Our Billable Usage Dashboard, the customer-facing dashboard that shows pay-as-you-go users exactly what they owe, is powered by a metering pipeline whose source of truth is a set of Iceberg tables in R2, queried via Trino. The dashboard's API pulls the same compact <code>(date, account_id, metric_name, usage)</code> rows that the invoicing system uses, so the number on the dashboard matches the number on the bill.</p><p>Billing-related queries account for 53% of all queries Town Lake serves: 91,760 queries from 324 distinct Cloudflare employees in a recent measurement period. The 200–300 line legacy SQL queries that used to compute revenue rollups by customer are now five lines.</p><p><b>Business intelligence.</b> The "top 100 customers by revenue" question takes about three seconds in Skipper now. So does "how many domains that signed up today are in the top 100." So do most of the data-related questions we used to file Jira tickets for.</p><p><b>Security analytics.</b> Our Bot Management team uses Town Lake to query ML scoring events with score &gt; 0.9 in the last 48 hours filtered by ASN and geography. Threat researchers have built their own query toolkit on top of it. Trust &amp; Safety pulls signals to help police abuse.</p><p><b>Customer support.</b> "Find the top 100 billing support tickets from customers who have spent &gt;$100" used to be a multi-day project. Now it's a Skipper query.</p>
    <div>
      <h3>What we have learned</h3>
      <a href="#what-we-have-learned">
        
      </a>
    </div>
    <p>A few things have surprised us.</p><p>Less prompting is more. Early versions of Skipper had elaborate, prescriptive system prompts: <i>"First, use search_datasets. Then, use get_entity_details. Then, use list_schema_fields if needed..."</i> Quality went down. The model is good at reasoning about analytical workflows; it doesn't need to be micromanaged. We replaced the prescriptive prompts with high-level guidance and let the model pick its own path. Results got better.</p><p>Tool overlap is poison. We initially exposed every variant of every tool: three different "fetch results" tools, two "search" tools, several "list" tools. The model got confused and called the wrong one. We consolidated. Now <code>fetch_results</code> has a <code>mode</code> parameter <code>(inject / display / both)</code> instead of three separate tools. Every tool has a single reason to exist.</p><p>Code, not metadata, captures meaning. The biggest accuracy wins came when we started ingesting the actual SQL that produces a table, not just its schema. A <code>customer_type</code> column with values <code>contract</code>, <code>paygo</code>, <code>free</code> looks identical in either context, but the SQL tells you that <code>customer_type</code> defaults to <code>paygo</code> when Salesforce data is missing. That kind of context never lives in column descriptions.</p><p>Memory matters more than we expected. There is a long tail of corrections that look like "you have to filter for X like this" or "ignore tables tagged Y." Without a memory layer, the agent rediscovers and re-learns these every conversation. With one, it gets monotonically better at the recurring questions a team actually asks.</p><p>The boring infrastructure is the hard part. Trino + Iceberg is not new technology. The hard work is in the boring stuff: per-row access control, default-closed table allowlisting, query auditing, time-bound credentials, PII detection, idempotent ingestion, schema evolution. Those are the things that make a data platform safe to actually use.</p>
    <div>
      <h3>What's next</h3>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>We're expanding the agent surface. Skipper already integrates as an MCP server into any IDE that supports it. The next step is deeper integration with our own internal chat and ticketing systems, so that "ask the data" becomes the natural first move for anyone debugging an incident, scoping a project, or sanity-checking a hypothesis.</p><p>We're investing heavily in the Transformer pipeline. The goal is for any team at Cloudflare to be able to build a curated dataset with a few SQL files and a <code>.meta.json</code> description, deploy it as a Workflow, get it scheduled and monitored automatically, and have it surface in DataHub and Skipper without any additional work. The idea is self-serve data engineering, with the same shape as self-serve software engineering.</p><p><a href="https://developers.cloudflare.com/r2-sql/"><u>R2 SQL</u></a>, Cloudflare's serverless, distributed, analytics query engine, is getting more and more robust by the day. As its feature set expands, we plan to move many parts of Town Lake’s workflow over to it.</p><p>The bet we made — that the next breakthrough product comes from someone looking at the data and seeing something nobody else sees — is one we're still betting on. Town Lake is how we make sure they can find it.</p> ]]></content:encoded>
            <category><![CDATA[Engineering]]></category>
            <category><![CDATA[Analytics]]></category>
            <category><![CDATA[Developers Storage]]></category>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Data Platform]]></category>
            <guid isPermaLink="false">5kM0Nfgzw6beOD5mSzIqw4</guid>
            <dc:creator>Brian Brunner</dc:creator>
            <dc:creator>Dmitry Alexeenko</dc:creator>
            <dc:creator>Matt Moen</dc:creator>
        </item>
        <item>
            <title><![CDATA[Announcing Claude Managed Agents on Cloudflare]]></title>
            <link>https://blog.cloudflare.com/claude-managed-agents/</link>
            <pubDate>Tue, 19 May 2026 13:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare has integrated with Anthropic's Claude Managed Agents to provide a fast, isolated execution environment for autonomous code delivery. This means builders can scale agent workflows globally while strictly controlling access to private backends and easily customizing their agent’s tools and runtimes. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Cloudflare and Anthropic have collaborated to integrate Claude Managed Agents with Cloudflare Sandboxes. Our <a href="https://developers.cloudflare.com/sandbox/tutorials/claude-managed-agents/"><u>new integration</u></a> gives you more control over your agent sandboxes, secures connections to private services, and improves observability.</p><p>In the past year, Cloudflare’s Developer Platform has expanded to give more developers the tools they need to run agents at scale. This includes:</p><ul><li><p><a href="https://developers.cloudflare.com/sandbox/"><u>Sandboxes</u></a> for full stateful Linux microVMs at scale</p></li><li><p><a href="https://developers.cloudflare.com/agents/"><u>Agents SDK</u></a>, providing simple and customizable agent framework</p></li><li><p><a href="https://developers.cloudflare.com/browser-run/"><u>Browser Run</u></a>, which gives agents fully programmable and observable browsers</p></li><li><p><a href="https://developers.cloudflare.com/dynamic-workers/"><u>Dynamic Workers</u></a>, allowing for dynamic sandboxed code execution at massive scale</p></li></ul><p>Our goal is to make Cloudflare the simplest, most secure, and most programmable cloud for agents.</p><p>Integrating with Claude Managed Agents is another step in this direction. You can run your agent loop on the Claude Platform, while using Cloudflare to execute code, secure connections, and run custom tool calls.</p><p>To get going in just minutes, we’ve created a <a href="https://github.com/cloudflare/claude-managed-agents"><u>default deployment template </u></a>that gives you the following:</p><ul><li><p><b>Enhanced security</b> - Run all agent traffic through customizable proxies. This allows you to securely inject credentials, prevent data exfiltration, and better observe how your agents interact with the outside world.</p></li><li><p><b>Sandbox control and observability</b> - Get detailed sandbox metrics and logs. SSH into running machines. Customize sandbox images.</p></li><li><p><b>Lightweight sandboxes</b> - Writing and executing untrusted code can be done in a traditional microVM or a <a href="https://blog.cloudflare.com/dynamic-workers/"><u>lightweight isolate</u></a>. This lets you hit massive scale, boot sandboxes in milliseconds, and minimize infrastructure spend.</p></li><li><p><b>Private service connectivity</b> - Connect agents to private internal services without ever exposing them to the Internet.</p></li><li><p><b>Browser Control and Observability</b> - Get an audit trail of every agent’s browser sessions, including session recording and human-in-the-loop flows.</p></li><li><p><b>Email </b>- Give each of your agents its own email address and ability to send emails.</p></li><li><p><b>Custom tools</b> - Extend your agents with tools without needing additional infrastructure. Just write functions and deploy.</p></li></ul><p>You get all of this out of the box when deploying the integration, and you can easily customize if you need more.</p><p>Let’s take a brief look at Claude Managed Agents, see how to integrate a Cloudflare-based environment, then explore how to get the most out of Claude on Cloudflare.</p>
    <div>
      <h2>An overview of Claude Managed Agents</h2>
      <a href="#an-overview-of-claude-managed-agents">
        
      </a>
    </div>
    <p><a href="https://www.anthropic.com/engineering/managed-agents"><u>Claude Managed Agents</u></a> allow developers to easily define and run agents on the Anthropic platform. In these managed environments, Claude can read files, run commands, browse the web, and execute code. The harness supports built-in prompt caching, compaction, and various agent-first performance optimizations.</p><p>Until now, using Claude Managed Agents has meant running the entire stack on Anthropic-provided infrastructure. While this is great for some developers, others may need more control over their infrastructure choice, whether this is for security, compliance, or performance reasons. Self-managed environments for Claude Agents provide just that.</p><p>Anthropic describes this as “decoupling the brain from the hands.” The core agent loop runs in Anthropic (the “brain”), but the infrastructure for running and executing code (the “hands”) can be run anywhere, including Cloudflare.</p>
    <div>
      <h2>The Cloudflare environment</h2>
      <a href="#the-cloudflare-environment">
        
      </a>
    </div>
    <p>Our new integration gives your agents a Cloudflare-based environment for running and executing code within minutes.</p><p>Follow <a href="https://github.com/cloudflare/claude-managed-agents#onboarding-guide"><u>the onboarding guide</u></a> to get started. Then fork the repo and customize your integration as you see fit.</p><p>After setup, when a Claude Agent starts a session, it sends a message to your new Cloudflare-based control plane. The <a href="https://developers.cloudflare.com/workers/"><u>Workers</u></a>-based control plane gives each agent session a sandboxed environment for executing code, developing applications, running CLI tools, and more. State is automatically persisted across session sleeps.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6nYyreZYWyaKo6Xf2XjmtM/5cc21576a83e223a2cf67e8ed3fde928/image5.png" />
          </figure><p><sup><i>Sandboxes write files and execute code in response to the Claude-based Agent loop</i></sup></p><p>You can optionally configure sandbox instance sizes or customize the container image that runs within VM-based sandboxes. Each sandbox can be observed in the Cloudflare dashboard, sandbox logs can be queried or shipped to external providers like Datadog or Splunk, and the control plane ships with a built-in UI, making it easy to track the state of sandboxes or SSH into specific machines.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/46pEZh7MeAt27wLi7c9e6S/889b269b94db32c3188e3dff5b6cbd75/image3.png" />
          </figure><p><sup><i>Get interactive shell sessions into your agent’s sandbox</i></sup></p>
    <div>
      <h2>Enabling agents at Internet scale</h2>
      <a href="#enabling-agents-at-internet-scale">
        
      </a>
    </div>
    <p>What if your agent backend booted in a few milliseconds, and you didn’t have to pay for the resources of a full VM when running the agent?</p><p>The industry needs <a href="https://blog.cloudflare.com/dynamic-workers/#dynamic-worker-loader-a-lean-sandbox"><u>a lightweight primitive for sandboxing</u></a> as we adopt agents at scale, and we’re building just that.</p><p>But as models get better, we expect more and more workflows to be managed by agents. Each of your customers should be able to run many agents simultaneously; each of your employees should have tens of agents running at once. If we’re constantly running a full microVM per agent, we’ll be unnecessarily burning a ton of resources and money to enable this scale.</p><p>That’s why we’re providing a faster and cheaper sandbox for your Claude Agents. This sandbox is based on the <a href="https://developers.cloudflare.com/agents/"><u>AgentsSDK</u></a>. You can execute arbitrary code in <a href="https://developers.cloudflare.com/dynamic-workers/"><u>Dynamic Workers</u></a> using <a href="https://developers.cloudflare.com/agents/api-reference/codemode/"><u>Codemode</u></a>, and you still <a href="https://developers.cloudflare.com/sandbox/bridge/http-api/#workspace-persistence"><u>get a file system</u></a>, but your agent is doing all of this within a <a href="https://developers.cloudflare.com/workers/reference/how-workers-works/#isolates"><u>V8 isolate</u></a> instead of a microVM.</p><p>If you need agents to act as a developer, building full applications and running Linux-based tools, you can still reach for a microVM-based sandbox. For this, we provide <a href="https://developers.cloudflare.com/containers/"><u>Cloudflare Containers</u></a>, which Claude Managed Agents can also use.</p><p>But if you want a faster, cheaper, and more scalable alternative you can use isolates instead of microVMs easily. Just select “isolate” for backend type when setting up an Agent.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/MZ8cQ2UTYcbe2hFv7IUYw/f7b55a65b6a670651bf30a0e24a6f509/image1.png" />
          </figure><p><sup><i>Setting up an “isolate” backend gives you a lightweight V8 isolate sandbox instead of a microVM</i></sup></p><p>If you want to handle bursts of tens of thousands of concurrent agents or more, running with isolates will allow you to scale in a way that no VM-based solution allows.</p>
    <div>
      <h2>Securing your agentic workloads</h2>
      <a href="#securing-your-agentic-workloads">
        
      </a>
    </div>
    <p>Agents are far more powerful when they connect to your organization’s context. This usually means accessing private services and data.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1LXewj3QO0QZMiEYNEMVxk/08cf093a16e67c8fb48514b1ce744319/image9.png" />
          </figure><p>As <a href="https://blog.cloudflare.com/sandbox-auth/"><u>we’ve written before</u></a>, sandboxed workloads on Cloudflare can use an outbound proxy for fully dynamic, customizable, and zero-trust authentication between sandboxes and external services. This lets you inject secrets into requests outside the sandbox, so the agent never has access to them. This protects against exfiltration attacks.</p><p>And sometimes internal services shouldn’t ever be exposed to the open Internet. We recently launched <a href="https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-mesh/"><u>Cloudflare Mesh</u></a> and <a href="https://developers.cloudflare.com/workers-vpc/"><u>Cloudflare Workers VPC</u></a> to better connect to these private services, whether they’re running on a cloud provider like AWS or on-premises. This allows you to connect to internal services using post-quantum encrypted networking without a VPN or bastion host.</p><p>Claude Managed Agents can easily connect to private services with header injection or private VPC/Mesh tunnels. This is done via customizable outbound proxies. You can define egress policies that expose only the services you choose to the agent sandboxes that you choose. You can allowlist specific endpoints, perform zero-trust injection of encrypted credentials, access private services via Cloudflare Mesh, and even write custom proxy middleware.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2728IFBEK7MUx4YDuIldFj/2e28b1fd510abf49dd3a5ad6604b7709/image4.png" />
          </figure><p><sup><i>The integration uses outbound Workers to handle egress however you see fit</i></sup></p><p>You’re able to apply policies per tenant, per agent, or based on whatever metadata is useful. This gives you full control over how your agents connect to external services.</p>
    <div>
      <h2>Doing more with the Cloudflare Developer Platform</h2>
      <a href="#doing-more-with-the-cloudflare-developer-platform">
        
      </a>
    </div>
    <p>Agents need more than just a code execution environment. Cloudflare’s Developer Platform provides the tools you need by default to let your agents do more.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7GkOWWKBsbnBYeaIcrbHrm/e385f4fa3d8ca2fff13a92a92854f94d/image7.png" />
          </figure><p><sup><i>Sandboxes can make tool calls on Cloudflare and safely access external services.</i></sup></p><p>Here are a few of the tools you’ll find most useful as you deploy agents on Cloudflare:</p>
    <div>
      <h3>Browser Run via Claude</h3>
      <a href="#browser-run-via-claude">
        
      </a>
    </div>
    <p>One of the most common tools agents need is a browser. While <code>curl</code> can get you pretty far, when you want an agent to act like a human, this often means interacting with the web like one: rendering JS-heavy applications, taking screenshots for QA validation, filling out forms, etc. <a href="https://blog.cloudflare.com/browser-run-for-ai-agents/"><u>Browser Run</u></a> is Cloudflare’s tool to give agents browsers.</p><div>
  
</div>
<p></p><p><sup><i>A Browser Run session recording lets you watch how your agents used a browser. One of many built-in tools.</i></sup></p><p>The Claude Managed Agents integration ships with multiple browser-related tools that can be enabled immediately. These include <code>browser_search</code>, <code>browser_execute</code>, <code>screenshot</code>, <code>browse</code>, <code>fetch_to_markdown</code>, and a Cloudflare-specific implementation of <code>web_fetch</code> allows your agent to control a browser that runs on Cloudflare infrastructure. This not only lets your agent do more, but it also makes it easy to audit every action your agent’s browser is taking on the web, apply allowlists and denylist to browser sessions, and save recordings of browser sessions for future debugging.</p>
    <div>
      <h3>Agent inboxes</h3>
      <a href="#agent-inboxes">
        
      </a>
    </div>
    <p>The integration also comes with built-in support for email with the <code>send_email</code>, <code>email_read</code>, and <code>email_list</code> tools.</p><p>You can also kick off new sessions via email, or configure the agent to send emails using any domain and address configured with the <a href="https://blog.cloudflare.com/email-for-agents/"><u>Cloudflare Email Service</u></a>. This allows the agent to act on your behalf when it needs to, reply to context in forwarded emails, and autonomously interact with others via email.</p>
    <div>
      <h3>Custom tools and more</h3>
      <a href="#custom-tools-and-more">
        
      </a>
    </div>
    <p>Other built-in tools include <code>call_service</code>, which uses Cloudflare Mesh or Workers VPC to connect to private services, and <code>image_generate</code>, which uses <a href="https://www.cloudflare.com/developer-platform/products/workers-ai/"><u>Workers AI</u></a> to generate images on Cloudflare. This pairs well with Claude providing text-based inference.</p><p>Additionally, we encourage forking the repo to easily add customized tools. For example, you could add a custom tool to host a public file on <a href="https://www.cloudflare.com/developer-platform/r2/"><u>Cloudflare’s R2 object storage</u></a>. Just add the relevant binding in wrangler config, write a <a href="https://zod.dev/"><code><u>zod</u></code></a> definition, and short function in <code>custom-tools.js</code>:</p>
            <pre><code>defineTool({
  name: "r2_host_file",
  description: "Upload from sandbox to R2 and get a public URL.",
  inputSchema: z.object({
    key: z.string().describe("Object key"),
    content: z.string().describe("UTF-8 file body"),
    contentType: z.string().describe("MIME type"),
  }),
  run: async ({ key, content, contentType }, { env }) =&gt; {
    await env.PUBLIC_BUCKET.put(
      key, content, { httpMetadata: { contentType }}
    );
    return `${env.PUB_R2_URL.replace(/\/$/, "")}/${encodeURI(key)}`;
  }
}),</code></pre>
            <p>The Cloudflare Developer Platform provides all sorts of possibilities for extending your agents: give each agent session a git-backed repo with <a href="https://blog.cloudflare.com/artifacts-git-for-agents-beta/"><u>Artifacts</u></a>, run edge inference with <a href="https://workers.cloudflare.com/products/workers-ai/"><u>Workers AI</u></a>, host applications written on the fly with <a href="https://developers.cloudflare.com/dynamic-workers/"><u>Dynamic Workers</u></a>, and more.</p><p>You don’t have to worry about infrastructure or scaling – just write a few lines of code and hit deploy.</p>
    <div>
      <h2>Claude + Cloudflare</h2>
      <a href="#claude-cloudflare">
        
      </a>
    </div>
    <p>We’re excited to be working together with Anthropic to bring Cloudflare’s flexibility, scale, and security to more users. Whether you want to run tens of millions of agents using isolates, securely connect to private services with Workers VPC, or write custom tools that take advantage of all of Cloudflare, our new integration makes it easy.</p><p>See the <a href="https://developers.cloudflare.com/sandbox/claude-managed-agents/"><u>Getting Started with Managed Agents guide</u></a> to get Claude Managed Agents set up with Cloudflare in just minutes.</p> ]]></content:encoded>
            <category><![CDATA[AI]]></category>
            <category><![CDATA[Agents]]></category>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[Durable Objects]]></category>
            <category><![CDATA[Developers Storage]]></category>
            <guid isPermaLink="false">2atb0Whie0RvOXQHBoBrKH</guid>
            <dc:creator>Mike Nomitch</dc:creator>
        </item>
    </channel>
</rss>