Mounting Cloudflare R2 Buckets as Read-Only Knowledge Base Filesystems with Flue
Mount a Cloudflare R2 bucket as a read-only POSIX filesystem inside a Flue agent's sandbox by using getVirtualSandbox() to combine SQLite-backed Durable Objects with your R2 binding, exposing files at /workspace for tool-based search operations.
Flue's SDK enables you to mount Cloudflare R2 buckets as read-only knowledge base filesystems that persist across agent invocations without container overhead. This architecture creates a virtual sandbox where large documentation corpora or product catalogs remain instantly searchable via standard Unix tools like grep and glob. By combining Cloudflare's object storage with Durable Object SQLite persistence, agents gain durable, low-latency access to massive knowledge bases directly within their execution environment.
How the Virtual Sandbox Architecture Works
The R2 integration relies on a virtual filesystem implementation that bridges Cloudflare's object storage with a POSIX-compatible interface. When you initialize an agent with getVirtualSandbox(env.KNOWLEDGE_BASE), the SDK constructs a WorkspaceFileSystem that combines your R2 bucket binding with a local SQLite store from the Durable Object's storage.sql instance.
According to the source code in packages/sdk/src/cloudflare/virtual-sandbox.ts, the system performs three critical operations:
-
Workspace Construction – Lines 94-111 create a Cloudflare Workspace from the Worker's Durable Object SQLite database and the R2 bucket binding passed via the environment.
-
POSIX Adaptation – The
adaptToJustBashwrapper transforms the R2-backed filesystem into a POSIX-compatible interface thatjust-bashexpects, mounting the entire structure at/workspace(lines 117-121). -
Session Injection – When
init({ sandbox, ... })receives this environment, it injects the filesystem into the agent's session, allowing the LLM to invokeread,glob, andgreptools against remote R2 objects as if they were local files.
Because the sandbox runs inside a Cloudflare Worker with Durable Objects, the SQLite layer ensures that filesystem metadata and any uploaded changes survive across invocations, as documented in docs/deploy-cloudflare.md (lines 44-48).
Creating an R2-Backed Knowledge Base Agent
To mount an R2 bucket as a knowledge base, import getVirtualSandbox from the Cloudflare SDK module and pass your R2 binding to the initialization function:
// .flue/agents/support.ts
import { getVirtualSandbox } from '@flue/sdk/cloudflare';
import type { FlueContext } from '@flue/sdk/client';
export const triggers = { webhook: true };
export default async function ({ init, payload, env }: FlueContext) {
// env.KNOWLEDGE_BASE references the R2 binding defined in wrangler.jsonc
const sandbox = await getVirtualSandbox(env.KNOWLEDGE_BASE);
const harness = await init({
sandbox,
model: 'openrouter/moonshotai/kimi-k2.6'
});
const session = await harness.session();
// The agent now has native access to grep, glob, and read tools
return await session.prompt(
`You are a support agent. Search the knowledge base for articles
relevant to this request, then write a helpful response.
Customer: ${payload.message}`,
{ role: 'triager' },
);
}
Key implementation details:
getVirtualSandbox(env.KNOWLEDGE_BASE)– Instantiates the virtual sandbox backed by your R2 bucket and Durable Object storage (virtual-sandbox.ts, lines 94-111).init({ sandbox, ... })– Supplies the POSIX-compatible filesystem to the Flue harness so the LLM executes within this environment (deploy-cloudflare.md, lines 176-182).session.prompt()– Automatically injects filesystem tools enabling the agent to search/workspaceusing semantic equivalents ofgrep,glob, andread.
Configuring R2 Bindings in Wrangler
Before deploying, declare the R2 bucket binding in your project's wrangler.jsonc. Flue merges this configuration during the build process to ensure the binding is available in the Worker environment:
{
"name": "my-support-agent",
"compatibility_date": "2026-04-01",
"compatibility_flags": ["nodejs_compat"],
"r2_buckets": [
{
"binding": "KNOWLEDGE_BASE",
"bucket_name": "my-knowledge-base"
}
]
}
When you execute flue build --target cloudflare, the build system automatically merges this binding into dist/wrangler.jsonc, ensuring wrangler deploy provisions the correct permissions (deploy-cloudflare.md, lines 109-115).
Uploading Files to Your Knowledge Base
Populate the R2 bucket using the Wrangler CLI. Files uploaded to the bucket become immediately available under /workspace inside the agent's sandbox:
# Upload a single documentation file
wrangler r2 object put my-knowledge-base/articles/getting-started.md \
--file ./docs/getting-started.md
# Batch upload an entire documentation directory
for f in ./docs/**/*.md; do
key="articles/${f#./docs/}"
wrangler r2 object put "my-knowledge-base/$key" --file "$f"
done
The agent can then traverse these paths using glob patterns or search content using grep, treating the remote R2 objects as local POSIX files.
Summary
- Mount R2 buckets using
getVirtualSandbox(env.KNOWLEDGE_BASE)to create a POSIX-compatible filesystem backed by Cloudflare's object storage and Durable Object SQLite persistence. - Access files at
/workspacewhere the virtual sandbox presents R2 objects as local files, supporting standard Unix tool equivalents likegrep,glob, andread. - Configure bindings in
wrangler.jsoncand rely on Flue's build process to merge them automatically for deployment. - Persist across requests because the architecture uses Durable Objects, ensuring filesystem state survives between agent invocations without container cold starts.
Frequently Asked Questions
Can I write files back to the R2 bucket from the agent?
Yes, while the knowledge base pattern typically uses read-only access, the virtual sandbox supports read-write operations. Writes are cached in the Durable Object's SQLite layer (storage.sql) and can persist to R2 depending on your implementation. However, for pure knowledge base use cases, configure the bucket with read-only permissions in your Wrangler configuration to prevent accidental modifications.
How does this differ from mounting a local filesystem?
Unlike ephemeral local filesystems that disappear when the container exits, this approach uses Cloudflare R2 for durable storage combined with Durable Objects for session persistence. According to the implementation in packages/sdk/src/cloudflare/virtual-sandbox.ts, the filesystem survives across HTTP requests because the SQLite metadata and R2 bindings persist in the Cloudflare edge infrastructure, eliminating cold start overhead while maintaining terabyte-scale storage capacity.
What file sizes work best with this approach?
The virtual sandbox architecture handles large text corpora efficiently because it streams data from R2 on demand rather than loading entire buckets into memory. However, individual files that the agent reads via the read tool should remain under the LLM's context window limits. Binary files and assets store correctly in R2 but require text extraction (like PDF parsing) before the agent can process them with grep or similar tools.
Do I need to manage SQLite schemas manually?
No. Flue automatically manages the SQLite schema within the Durable Object's storage. The getVirtualSandbox function handles the connection to storage.sql and the R2 binding without requiring manual database configuration. The schema tracks filesystem metadata while the actual file contents remain in R2, creating a hybrid storage layer that requires zero DevOps maintenance.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →