Skip to content

Provider: Cloudflare D1 (reference sketch)

Informative adapter note. Not part of the normative spec. This is a design sketch, not an implemented provider — included to demonstrate that AFI covers use cases the existing implementations don't reach.

  • System: Cloudflare D1 — SQLite-compatible serverless database, accessible only over HTTP + Worker bindings
  • Backing store: D1 (SQLite dialect, no local file handle)
  • Native transport: Cloudflare Worker fronting D1, exposing MCP + HTTP AFI bindings
  • Conformance target: Level 3 (read/write)
  • Auth: Cloudflare API tokens or per-user JWT

Why this exists

AgentFS's runtime requires FUSE/NFS on a local SQLite file — impossible on D1. But D1 is a perfectly good backend for the AFI shape: it speaks SQL, supports the same schema patterns AgentFS uses, and lives inside Cloudflare's edge where a Worker can serve the AFI HTTP or MCP binding directly.

This sketch shows what a D1-backed AFI provider would look like.

Manifest

{
  "afi_version":      "0.1",
  "provider":         "afi-d1",
  "provider_version": "0.1.0",
  "profile":          3,
  "capabilities":     ["stat", "list", "read", "search", "write", "mkdir", "delete", "move"],
  "search": {
    "modes":       ["exact", "regex"],
    "max_results": 500
  },
  "path":             { "case_sensitive": true, "max_length": 4096 },
  "auth":             { "required": true, "methods": ["bearer"] }
}

Schema (D1 side)

Adopt a reduced subset of AgentFS's fs_* tables — just the pieces AFI's core operations need — stored in D1. AgentFS's full schema (fs_symlink, kv_store, tool_calls, fs_config) is intentionally out of scope for this sketch; add them back if your workload needs them.

CREATE TABLE fs_inode (
  ino          INTEGER PRIMARY KEY AUTOINCREMENT,
  mode         INTEGER NOT NULL,
  size         INTEGER NOT NULL DEFAULT 0,
  mtime        INTEGER NOT NULL,
  ctime        INTEGER NOT NULL,
  content_type TEXT
);

CREATE TABLE fs_dentry (
  parent_ino INTEGER NOT NULL,
  name       TEXT    NOT NULL,
  ino        INTEGER NOT NULL,
  PRIMARY KEY (parent_ino, name)
);

CREATE TABLE fs_data (
  ino         INTEGER NOT NULL,
  chunk_index INTEGER NOT NULL,
  data        BLOB    NOT NULL,
  PRIMARY KEY (ino, chunk_index)
);

CREATE VIRTUAL TABLE fs_fts USING fts5(content, ino UNINDEXED);

D1 supports FTS5, which turns search into a single query rather than a scan.

Operation mapping

AFI D1 (via Worker)
stat(path) Walk path → SELECT … FROM fs_inode WHERE ino = ?
list(path) SELECT name, ino FROM fs_dentry WHERE parent_ino = ?
read(path, off, len) SELECT data FROM fs_data WHERE ino = ? AND chunk_index BETWEEN ? AND ?
search(str) SELECT ino, snippet(fs_fts, 0, '', '', '…', 10) FROM fs_fts WHERE fs_fts MATCH ?
write(path, bytes) Transaction: upsert inode, dentry, chunked data, FTS index
delete(path) Delete dentry, GC inode + data + FTS on nlink = 0

Worker skeleton

// index.ts (Cloudflare Worker)
import { Hono } from "hono";
import { AfiD1 } from "./afi-d1";

const app = new Hono<{ Bindings: { DB: D1Database } }>();

app.get("/.afi/manifest.json", (c) => c.json(MANIFEST));

app.get("/afi/stat", async (c) => c.json(
  await new AfiD1(c.env.DB).stat(c.req.query("path")!)
));

app.get("/afi/list", async (c) => c.json(
  await new AfiD1(c.env.DB).list(c.req.query("path")!, {
    limit:  Number(c.req.query("limit") ?? 1000),
    cursor: c.req.query("cursor"),
    glob:   c.req.query("glob"),
  })
));

app.get("/afi/read", async (c) => {
  const { bytes, content_type } = await new AfiD1(c.env.DB).read(
    c.req.query("path")!,
    {
      offset: Number(c.req.query("offset") ?? 0),
      length: c.req.query("length") ? Number(c.req.query("length")) : undefined,
    }
  );
  return new Response(bytes, { headers: { "Content-Type": content_type } });
});

app.post("/afi/search", async (c) => c.json(
  await new AfiD1(c.env.DB).search(await c.req.json())
));

export default app;

Then any AFI-aware agent client can talk to https://your-worker.workers.dev and get the same operations as against ChromaFs, AgentFS, or supabase.sh.

Notes

  • This is the answer to "can AgentFS use D1?" — reframed as "can AFI use D1?", and the answer is yes, cleanly.
  • The Worker + D1 approach also generalizes to Vercel Edge + Postgres, Deno Deploy + KV, or any other edge-runtime + serverless-DB combo.
  • No affiliation with or endorsement from Cloudflare.