DropboxVFS in two runtimes:
@struktoai/mirage-node, usesclient_id+client_secret+ long-lived refresh token to fetch short-lived access tokens server-side.@struktoai/mirage-browser, supports the same refresh token via PKCE (no client secret in the bundle).
/2/files/list_folder for directories, /2/files/download for content, and
/2/files/upload / create_folder_v2 / delete_v2 / move_v2 / copy_v2 for writes
(single-call uploads cap at ~150 MB). Credentials are obtained the same way in both runtimes, see
Dropbox Credentials. The Python package ships the same
backend, see Dropbox (Python).
Node (server-side)
DropboxTokenManager caches the access token in memory and refreshes it ~5 minutes before
expiry, so cold-start API calls don’t pay the refresh round-trip.
Config
Fields marked secret are redacted in snapshots.
Mount a subfolder
PassrootPath to expose a single Dropbox folder as the mount root instead of the whole
account. Every command and FUSE/VFS op is scoped to that folder; paths outside it are
unreachable.
rootPath accepts Team/data, /Team/data, or /Team/data/ (all normalized the same way);
.. segments are rejected. Config dictionaries (e.g. via the VFS registry) may spell it
root_path. Omitting it (or passing /) mounts the account root as before.
VFS.md
The VFS.md an agent reads with Dropbox mounted at/<path>.
- Rendered
- Raw
Virtual Filesystem
Supported Unix Commands for VFS
Unix commands work on each path as on a local filesystem, as far as the path supports them:Limitations of Unix Commands for VFS
Where a path differs from a local filesystem:Run
man to list every command, and man <cmd> or <cmd> --help for one command’s usage.Integration
What Dropbox answers through its own API, so fewer files are read. Integration explains each command.
The Python Dropbox docs list when each search answers and what it can miss.
Names missing from a listing
A name missing from a cached listing that the running command did not fetch is looked up on Dropbox by path before mirage answers that it does not exist: oneget_metadata for a stat, or the download itself for a
read. A file another client created after the listing is therefore found,
and >>, touch and sed -i act on it instead of replacing it.
A listing the running command fetched itself is trusted as is, for the
whole command. Each command of a script is its own command, but one
long-running command, such as a program a runtime runs, does not see a
file another client creates after it listed the folder.
Some lookups run outside any shell command: FUSE, programmatic calls,
[ ] and [[ ]] tests, and a redirect on anything but a simple command
(a brace group, subshell, loop, if or case). No listing is the
caller’s own there, so each lookup of a name missing from a cached
listing costs one request.
Reads under fresh
Under read: fresh, a cached file is checked against its content_hash
before it is served: one get_metadata per warm read, never a folder
listing. A download names the hash in its Dropbox-API-Result header, full
or ranged, so a read stamps it with no extra request. server_modified is
not used: Dropbox repeats it across same-size rewrites.
Writes
A write records thecontent_hash its upload reply names, so a fresh read
right after a tee or sed -i downloads nothing.
Conditional writes
A Dropbox mount acceptswrite: conditional.
A write that holds a version looks the file up once (get_metadata),
refuses a file whose content_hash changed since it was read, and uploads
in update mode with the file’s rev, so Dropbox refuses (409
path/conflict) a change that lands in between; a delete sends the rev as
parent_rev. rm -r walks the folder file by file, and a mv within the
mount is Dropbox’s own move, which is not refused when its source changed
(a mv to another mount is a copy and a conditioned delete, so there a
changed source stays and mv reports the failed removal).
Browser (PKCE, no client secret)
http://localhost:5173/vfs/dropbox/dropbox_pkce.html). The bundled
examples/browser/vfs/dropbox/dropbox_pkce.ts
runs the full PKCE dance end-to-end and persists the refresh token to localStorage.
VFS mode (patchNodeFs)
Mirage exposes a patchNodeFs(workspace) shim that routes fs calls under a mount
through the workspace, so any library that uses Node’s fs API can read directly from Dropbox
without code changes.
fs.promises.* and the callbacks) are routed. Sync forms like fs.statSync and
fs.readFileSync refuse a mounted path because remote reads can’t block the event loop.
FUSE mode
For tools that need a real filesystem path (CLI tools, editors, system utilities), mount the workspace under FUSE:Available commands
DropboxVFS ships the same shell command set as the GDrive VFS:
- Filesystem:
ls,cat,head,tail,nl,wc,stat,find,tree,du,file,realpath,basename,dirname - Write (on a
WRITEmount):tee,touch,mkdir,rm,rmdir,mv,cp,truncate, shell redirection (>/>>) - Search/text:
grep,rg,awk,sed,sort,uniq,cut,diff,cmp,jq - Encoding:
base64
Examples
End-to-end runnable scripts are inexamples/typescript/vfs/dropbox/:
dropbox.ts,Workspace.shell('ls/stat/cat/tree …')shell demodropbox_vfs.ts,patchNodeFs+ nativefs.promises.*callsdropbox_fuse.ts, FUSE mount with shell access in another terminal
grep classifies the bytes it reads, including downloaded attachments. Use -I to skip binary inputs or -a (--binary-files=text) to search them as text. Text mode bypasses the content-search index and scans files directly.