# Cloudflare Artifacts: Git storage built for AI agents

> Learn how Cloudflare Artifacts gives AI agents isolated Git repositories, short-lived access tokens, forks, and a programmable Workers API.

Author: Flavio Copes | Published: 2026-07-10 | Canonical: https://flaviocopes.com/cloudflare-artifacts/

AI coding agents create a lot of files.

They edit code, generate configuration, run experiments, and produce results. We need a place where all this work can live.

A temporary folder works until the process disappears. Object storage keeps files, but it does not give us commits, branches, or diffs. GitHub gives us Git, but creating thousands of small repositories for short-lived agents is not its main job.

[Cloudflare Artifacts](https://www.cloudflare.com/products/artifacts/) is built for this problem.

It gives every agent a real Git repository, with standard `clone`, `pull`, and `push` commands. But those repositories are also programmable from a [Cloudflare Worker](https://flaviocopes.com/cloudflare-workers/) or the REST API.

Artifacts is currently in beta. You need [access enabled on your Cloudflare account](https://developers.cloudflare.com/artifacts/get-started/) before following this tutorial.

People are already using it at scale. Dillon Mulroy from Cloudflare says Artifacts is [nearing 50,000 new repositories per day](https://x.com/dillon_mulroy/status/2075386443283784146).

That's the interesting shift. A repository is no longer something a team creates occasionally. An application can create one for every agent, task, or experiment, then keep or delete it when the work is done.

## What is Cloudflare Artifacts?

Artifacts is versioned, Git-compatible storage.

Each repository has:

- its own Git history and branches
- a stable HTTPS remote
- separate read and write tokens
- durable storage replicated by Cloudflare

Repositories live inside **namespaces**. A namespace is a container you can use for an environment, a customer, or a group of agents.

For example:

```txt
agents/
  agent-001
  agent-002
  agent-003
```

You don't create the `agents` namespace separately. Artifacts creates it when you add the first repository.

## Create your first repository

The simplest way to start is through [Wrangler](https://flaviocopes.com/cloudflare-wrangler/).

First, log in:

```bash
npx wrangler login
```

Now create a repository called `agent-001` inside the `agents` namespace:

```bash
npx wrangler artifacts repos create agent-001 \
  --namespace agents \
  --default-branch main
```

You can inspect it with:

```bash
npx wrangler artifacts repos get agent-001 \
  --namespace agents
```

Wrangler prints the repository details, including its Git remote.

It looks like this:

```txt
https://<ACCOUNT_ID>.artifacts.cloudflare.net/git/agents/agent-001.git
```

## Create a write token

Every repository has its own tokens. A **read** token can clone, fetch, and pull. A **write** token can also push.

Let's create a write token that expires after one hour:

```bash
npx wrangler artifacts repos issue-token agent-001 \
  --namespace agents \
  --scope write \
  --ttl 3600
```

Copy the remote and token into two shell variables:

```bash
export ARTIFACTS_REMOTE='https://<ACCOUNT_ID>.artifacts.cloudflare.net/git/agents/agent-001.git'
export ARTIFACTS_TOKEN='art_v1_<TOKEN>?expires=<TIMESTAMP>'
```

Treat the token like a password. Do not commit it or print it in logs.

## Push a commit

Now let's create a small local repository:

```bash
mkdir agent-work
cd agent-work

git init -b main
printf '# Work produced by agent-001\n' > README.md

git add README.md
git commit -m "Add initial result"
git remote add origin "$ARTIFACTS_REMOTE"
```

Push the commit using the token:

```bash
git -c http.extraHeader="Authorization: Bearer $ARTIFACTS_TOKEN" \
  push -u origin main
```

This is a normal Git push. Artifacts speaks the Git smart HTTP protocol, so your existing Git client works without a plugin.

Notice that we did not put the token in the remote URL. The `http.extraHeader` option sends it only for this command.

You can clone the repository in the same way:

```bash
git -c http.extraHeader="Authorization: Bearer $ARTIFACTS_TOKEN" \
  clone "$ARTIFACTS_REMOTE" agent-work-copy
```

## Create repositories from a Worker

The CLI is useful for us. The Workers binding is useful when your application needs to create repositories automatically.

Create a Worker:

```bash
npm create cloudflare@latest artifacts-worker
cd artifacts-worker
```

Choose a Worker-only TypeScript project.

Add the Artifacts binding to `wrangler.jsonc`:

```jsonc
{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "name": "artifacts-worker",
  "main": "src/index.ts",
  "compatibility_date": "2026-07-10",
  "artifacts": [
    {
      "binding": "ARTIFACTS",
      "namespace": "agents"
    }
  ]
}
```

Generate the binding types:

```bash
npx wrangler types
```

Now replace `src/index.ts` with this:

```ts
interface Env {
  ARTIFACTS: Artifacts
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url)

    if (request.method !== 'POST' || url.pathname !== '/repos') {
      return new Response('Use POST /repos', { status: 404 })
    }

    const created = await env.ARTIFACTS.create('agent-002', {
      description: 'Workspace for agent-002',
      setDefaultBranch: 'main',
    })

    return Response.json({
      name: created.name,
      remote: created.remote,
      token: created.token,
    })
  },
} satisfies ExportedHandler<Env>
```

Start the Worker:

```bash
npx wrangler dev
```

Then create the repository from another terminal:

```bash
curl -X POST http://localhost:8787/repos
```

The response contains the repository name, remote URL, and initial write token:

```json
{
  "name": "agent-002",
  "remote": "https://<ACCOUNT_ID>.artifacts.cloudflare.net/git/agents/agent-002.git",
  "token": "art_v1_<TOKEN>?expires=<TIMESTAMP>"
}
```

The example returns a write token to keep the flow visible. **Do not expose this endpoint publicly without authentication.**

In production, verify the caller first. Create short-lived read tokens for clone operations, and only create write tokens when a client must push.

## Give every agent its own fork

One useful pattern is to keep a baseline repository, then fork it for every task.

The agent starts with the same files, but works in isolation:

```ts
const baseline = await env.ARTIFACTS.get('project-baseline')

const fork = await baseline.fork('agent-003', {
  description: 'Isolated workspace for agent-003',
  defaultBranchOnly: true,
})

console.log(fork.remote)
```

The fork gets its own history, tokens, and lifecycle. Changes made by `agent-003` do not affect the baseline.

When the work is done, your application can inspect the commits or diff the result. It can keep the repository as an audit trail, or delete it.

## Import an existing GitHub repository

You can also import a public Git repository:

```ts
const imported = await env.ARTIFACTS.import({
  source: {
    url: 'https://github.com/cloudflare/workers-sdk',
    branch: 'main',
    depth: 1,
  },
  target: {
    name: 'workers-sdk-copy',
  },
})

console.log(imported.remote)
```

A shallow import is useful when an agent needs the current code, but not the entire history.

## Where Artifacts fits

Artifacts is not a GitHub replacement.

GitHub is where people collaborate through issues, pull requests, reviews, and releases. Artifacts is a programmable Git storage layer for applications, automations, and agents.

It is a good fit when you need:

- one isolated repository per agent or task
- versioned generated content
- Git-backed configuration history
- temporary forks for code experiments
- repositories created from application code

If you only need to store files, [R2](https://flaviocopes.com/cloudflare-r2/) is simpler. Use Artifacts when commits, branches, diffs, and rollback are part of the data model.

## Current limits

At the time of writing, each repository can store up to **10 GB**. An account gets **1 TB** total by default, and Cloudflare says this can be raised on request.

The number of repositories and namespaces is unlimited. Both control-plane and per-repository Git operations allow 2,000 requests per 10 seconds.

Check the [current limits](https://developers.cloudflare.com/artifacts/platform/limits/) before designing around those numbers. Artifacts is still in beta, so they can change.

## The interesting part

Agents already know Git.

They know how to clone a repository, create a branch, commit files, inspect a diff, and push the result. Artifacts doesn't invent a new filesystem API for that workflow.

It gives agents the interface they already understand, while giving us an API to create and control repositories at scale.

That's the part I find interesting. The storage is useful, but the real idea is simpler: give every agent an isolated place to work, and make the handoff a Git remote.
