The next evolution of SQLite is here! Read Announcement

Agents are inherently unpredictable, which means using them requires isolation and managing state effectively. AgentFS is a filesystem abstraction designed for agents to provide auditability, reproducibility, and portability. You can use it via an SDK that supports TypeScript, Python, and Rust, or mount the SQLite-backed agent filesystem on your host filesystem.
However, you don't always want to build the agent filesystem from scratch. For example, with coding agents, you often want to work on the same source code, but keep different coding agents isolated from each other. That's why we built copy-on-write overlay filesystem support into AgentFS, along with an agentfs run command to eliminate the hassle of manually mounting a filesystem.
The agentfs run command works similarly to, for example, docker run, but mounts the host filesystem to the sandbox with copy-on-write overlay support. When the agent running in the agentfs session writes to a file, it is automatically copied up to the SQLite-backed agent filesystem, leaving the host filesystem intact.
For example, let's say you are using a coding agent such as Claude Code, OpenCode, or Codex. First, you clone a git repository on the host filesystem:
> git clone git@github.com:tursodatabase/agentfs.git
Cloning into 'agentfs'...
remote: Enumerating objects: 3507, done.
remote: Counting objects: 100% (1287/1287), done.
remote: Compressing objects: 100% (505/505), done.
remote: Total 3507 (delta 911), reused 828 (delta 782), pack-reused 2220 (from 3)
Receiving objects: 100% (3507/3507), 3.28 MiB | 6.15 MiB/s, done.
Resolving deltas: 100% (2078/2078), done.
Then you start the coding agent with the agentfs run command:
> agentfs run claude
Welcome to AgentFS!
The following directories are writable:
- /home/penberg/tmp/agentfs (copy-on-write)
- /home/penberg/.claude
- /home/penberg/.claude.json
- /home/penberg/.local
- /home/penberg/.npm
🔒 Everything else is read-only.
To join this session from another terminal:
agentfs run --session 6b48d6e3-d7b4-499d-bc32-06bd5954530e <command>
Now you can let the coding agent work on the source code, and all its actions are isolated to the agentfs session it runs in. For example, if we ask the agent to delete a file:
> remove README.md
● Bash(rm README.md)
⎿ (No content)
● Done. README.md has been removed.
The file is unchanged in the host filesystem:
> git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
> git diff
>
However, we can join the agentfs session with the agentfs run command. First, we ask the agent to tell us the session ID:
> echo $AGENTFS_SESSION
● Bash(echo $AGENTFS_SESSION)
⎿ 6b48d6e3-d7b4-499d-bc32-06bd5954530e
● The AGENTFS_SESSION environment variable is set to:
6b48d6e3-d7b4-499d-bc32-06bd5954530e
Then, we use the session ID to start another shell in the same session, and we can see the changes:
> agentfs run --session 6b48d6e3-d7b4-499d-bc32-06bd5954530e bash
Joining existing session: 6b48d6e3-d7b4-499d-bc32-06bd5954530e
🤖 penberg@turing:~/tmp/agentfs$ git status
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: README.md
no changes added to commit (use "git add" and/or "git commit -a")
You can also control the session ID when you start the session for the first time with agentfs run by passing a session ID with the --session option. For example, if the agent is working on a feature or bug fix, the session ID could match the git branch name.
The agentfs run command combines two key components: a copy-on-write overlay filesystem that captures all file modifications without touching the host filesystem, and a sandbox that enforces read-only access to all paths except explicitly allowed ones.
The overlay filesystem has two layers: the host filesystem as a read-only base layer, and a SQLite-backed AgentFS database as a writable delta layer. When an agent reads a file, the overlay first checks if it exists in the delta layer. If not, it transparently reads from the base layer. When an agent writes to a file, the overlay copies the entire file from the base layer to the delta layer (if it hasn't already been copied), then writes to the delta copy. This is the copy-on-write behavior that keeps the host filesystem intact.
Deletions work through a whiteout mechanism: instead of actually deleting base layer files (which would modify the host), the overlay records them in a whiteout table. Subsequent reads check this table and pretend the file doesn't exist.
On Linux, we implement the overlay using FUSE (Filesystem in Userspace). FUSE lets us implement a filesystem as a regular userspace program—the kernel forwards filesystem operations to our process, which handles them using the overlay logic described above.
The overlay alone doesn't prevent agents from writing to paths outside the working directory, so we combine it with a sandbox using user namespaces and mount namespaces. We create new namespaces with unshare(), bind-mount allowed writable paths (like ~/.claude, ~/.local, ~/.npm) to preserve their writable status, then remount everything else as read-only with MS_RDONLY. Finally, we bind-mount the FUSE overlay onto the current working directory.
The agent process sees a filesystem where most paths are read-only, the working directory shows the copy-on-write overlay, and only explicitly allowed paths remain writable. Virtual filesystems like /proc, /sys, /dev, and /tmp stay writable for system functionality.
On macOS, FUSE would require installing macFUSE, a kernel extension that can break with OS updates and requires user intervention to install. Instead, we use NFS, which macOS has supported natively for decades. We start a localhost NFS server that exposes the same overlay filesystem, then mount it using the built-in /sbin/mount_nfs. The copy-on-write semantics are the same as with FUSE, only the transport layer differs.
For sandboxing, we use macOS's built-in sandbox-exec with a dynamically generated Sandbox profile. The profile allows all file reads but restricts writes to the NFS mountpoint and to paths explicitly allowed to be writable on the host filesystem, such as ~/.local. The approach provides kernel-enforced sandboxing without requiring any special privileges or kernel extensions.
When you run agentfs run claude, AgentFS creates a session with a SQLite database for the delta layer, sets up the overlay filesystem (FUSE on Linux, NFS on macOS), and spawns the agent inside the sandbox with the overlay mounted at the working directory. The agent can read everything, but writes to the working directory go to the delta layer, while writes elsewhere are blocked (except for allowed paths). As a result, you have complete isolation for agents with copy-on-write semantics, using only standard OS primitives.
The AgentFS 0.4 release has support for agentfs run. You can download the agentfs binary for Linux and macOS from:
https://github.com/tursodatabase/agentfs/releases
Once downloaded, all you need to do is run agentfs run and let your agents do their thing.