Filesystem
Each VM has its own filesystem that the agent works in. Guest fs calls never touch the host disk, and it persists automatically across sleep/wake with no setup. See Persistence for the details.
Mounts
Section titled “Mounts”Back a guest path with external storage by adding it to the mounts config. Each mount takes a path and an optional readOnly flag, and the guest only ever sees the mounted subtree, never the wider host.
Project a real host directory into the filesystem, Docker-style. The guest sees only the mounted subtree, never the wider host filesystem. Path-escape attempts (symlinks, .., path aliasing) are confined to the mount root.
import { agentOS, setup } from "@rivet-dev/agentos";import pi from "@agentos-software/pi";
const vm = agentOS({ software: [pi], mounts: [ { path: "/home/user/repo", plugin: { id: "host_dir", config: { hostPath: "/path/to/repo" } }, readOnly: true, }, ],});
export const registry = setup({ use: { vm } });registry.start();Mount an S3 bucket with the built-in s3 plugin. Pass an optional prefix to scope storage to a key path within the bucket, useful for sharing one bucket across multiple agents.
The backend is a block store, not a one-object-per-file mapping: file contents are split into fixed-size chunks (4 MB by default) stored as individual S3 objects, with a separate metadata layer mapping each file to its chunks. This keeps large files, partial reads and writes, and snapshots efficient without rewriting whole objects.
import { agentOS, setup } from "@rivet-dev/agentos";import pi from "@agentos-software/pi";
const vm = agentOS({ software: [pi], mounts: [ { path: "/home/user/data", plugin: { id: "s3", config: { bucket: "my-bucket", prefix: "agent-data/", region: "us-east-1", }, }, }, ],});
export const registry = setup({ use: { vm } });registry.start();The s3 plugin config also accepts credentials ({ accessKeyId, secretAccessKey }) and a custom endpoint for S3-compatible providers.
Mount a Google Drive folder with the built-in google_drive plugin.
import { agentOS, setup } from "@rivet-dev/agentos";import pi from "@agentos-software/pi";
const vm = agentOS({ software: [pi], mounts: [ { path: "/home/user/drive", plugin: { id: "google_drive", config: { credentials: { clientEmail: process.env.GOOGLE_DRIVE_CLIENT_EMAIL!, privateKey: process.env.GOOGLE_DRIVE_PRIVATE_KEY!, }, folderId: process.env.GOOGLE_DRIVE_FOLDER_ID!, }, }, }, ],});
export const registry = setup({ use: { vm } });registry.start();import { agentOS, setup } from "@rivet-dev/agentos";import { createInMemoryFileSystem } from "@rivet-dev/agent-os-core";import pi from "@agentos-software/pi";
const vm = agentOS({ software: [pi], mounts: [ { path: "/home/user/scratch", driver: createInMemoryFileSystem() }, ],});
export const registry = setup({ use: { vm } });registry.start();File operations
Section titled “File operations”These operations are primarily what the agent uses inside the VM, and are also available from the client to seed inputs and read results. For large or read-only inputs (a repo, a dataset), a read-only host mount is faster than copying files in. Programs that need stdin or live output use exec instead (see Core).
Read and write
Section titled “Read and write”import { createClient } from "@rivet-dev/agentos/client";import type { registry } from "./server";
const client = createClient<typeof registry>({ endpoint: "http://localhost:6420" });const agent = client.vm.getOrCreate("my-agent");
// Write a file (string or Uint8Array)await agent.writeFile("/home/user/hello.txt", "Hello, world!");
// Read a file (returns Uint8Array)const content = await agent.readFile("/home/user/hello.txt");console.log(new TextDecoder().decode(content));Batch read and write
Section titled “Batch read and write”// Batch write (creates parent directories automatically)const writeResults = await agent.writeFiles([ { path: "/home/user/src/index.ts", content: "console.log('hello');" }, { path: "/home/user/src/utils.ts", content: "export function add(a: number, b: number) { return a + b; }" },]);
// Batch readconst readResults = await agent.readFiles([ "/home/user/src/index.ts", "/home/user/src/utils.ts",]);for (const result of readResults) { console.log(result.path, new TextDecoder().decode(result.content ?? new Uint8Array()));}Directories
Section titled “Directories”// Create a directoryawait agent.mkdir("/home/user/projects");
// List directory contentsconst entries = await agent.readdir("/home/user/projects");
// Recursive listing with metadataconst tree = await agent.readdirRecursive("/home/user", { maxDepth: 3, exclude: ["node_modules"],});for (const entry of tree) { console.log(entry.type, entry.path, entry.size);}File metadata
Section titled “File metadata”// Check if a path existsconst fileExists = await agent.exists("/home/user/hello.txt");
// Get file metadataconst info = await agent.stat("/home/user/hello.txt");console.log(info.size, info.isDirectory, info.mtimeMs);Move and delete
Section titled “Move and delete”// Move/renameawait agent.move("/home/user/old.txt", "/home/user/new.txt");
// Delete a fileawait agent.delete("/home/user/new.txt");
// Delete a directory recursivelyawait agent.delete("/home/user/temp", { recursive: true });Permissions
Section titled “Permissions”Filesystem access is governed by the VM permission policy. The filesystem scope is granted by default; restrict it by path, for example to deny a sensitive directory:
const vm = agentOS({ permissions: { fs: { default: "allow", rules: [{ mode: "deny", operations: ["*"], paths: ["/home/user/secrets/**"] }], }, },});See Permissions for the full configuration.
Sandboxes
Section titled “Sandboxes”For heavier or untrusted workloads, run a full Linux sandbox alongside the VM and mount its filesystem into agentOS. The agent then reads and writes the sandbox’s files through the same fs APIs while the sandbox handles execution. See Sandbox Mounting for setup.
Default layout
Section titled “Default layout”With no mounts configured, every VM boots an Alpine-based root filesystem with the standard POSIX directories:
/home/user: the agent’s home directory ($HOME) and default working directory (pwd) when spawned, where it reads and writes (mounts land under it, e.g./home/user/data)./bin,/sbin,/usr: installed commands (common POSIX utilities by default, plus any software you add)./etc,/lib,/opt,/root,/run,/srv,/tmp,/var,/mnt: standard system paths.
It is backed by the VM’s own filesystem and persisted across sleep/wake. Nothing comes from or touches the host disk.