Skip to main content
The MongoDB VFS exposes MongoDB databases, collections, and documents as a virtual filesystem mounted at some prefix such as /mongodb/. For connection setup, see MongoDB Setup.

Config

Filesystem Layout

The mount mirrors MongoDB’s cluster → database → collection / view model. The database directory always appears in the path, even when databases filters to a single entry.
Example:
Discovery lists databases, collections, views, and their fixed file names. It does not enumerate one filesystem entry per document. Schema inspection is separate from bulk document reads, so discovering a collection does not require exporting it. These paths and read contracts are shared by Python and TypeScript.

documents.jsonl

One JSON object per line, encoded with BSON Relaxed Extended JSON. BSON-specific types round-trip through their canonical $ wrappers:
cat / head / tail / grep / jq can read this file through the same streaming interface. The cursor fetches documents in batches; head can stop after a prefix. Commands that need the whole input, such as sort or jq -s, can still buffer it. Use bounded reads when exploring a large collection. Because the file is rendered on demand, stat / ls -l report no size and du returns 0 for it (computing the real size would require rendering the whole collection). Use wc -c documents.jsonl for the actual rendered byte count, or wc -l documents.jsonl for an exact document count (which can scan the collection). stat -c %s prints - for an unknown size and 0 only for a known empty file. Missing dates also display as -. Long directory listings include a total row. GNU ls reports allocated disk blocks there; the VFS does not expose allocation metadata, so Mirage prints total ? for nonempty listings and total 0 for empty listings. This is an intentional divergence from GNU output, not a sum of rendered file sizes. stat checks existence and type without counting documents, sampling fields, or fetching indexes. This keeps ls, find, and opening a stream independent of the collection size. The same unknown-size convention applies to Postgres row exports and other rendered VFS files.

schema.json

Generated from the first 100 documents in _id order. Includes:
  • field path → observed BSON type frequencies (nested paths unioned across the sample)
  • index definitions from listIndexes, without volatile access counters
  • the $jsonSchema validator if one is registered
Repeated reads of unchanged data produce identical bytes. Schema reads do not include document counts or $indexStats, so reading a schema cannot change its own content. Views skip indexes.

database.json

Lists collection and view names using two catalog listings, without a per-collection count. Useful for cat /mongodb/<db>/database.json to get an overview without recursing into each entity.

Elided fields

Fields listed under elide_fields are dropped entirely from documents.jsonl output. The type stays documented in schema.json, so heavy fields (embeddings, large binary, raw text blobs) can be hidden from agent reads without losing the schema signal:
Nested paths use dot notation. Elision applies to both cat (one-shot streaming reads) and tail -f (live change-stream follows).

Streaming and Limits

cat, grep, head, and tail -f consume documents lazily through a batched PyMongo async cursor (or change stream); the consumer cancels to stop fetching. There is no truncation notice because nothing is forced into memory ahead of the consumer.

Smart Commands

grep at different scopes

grep uses MongoDB’s query engine at directory scopes instead of streaming all documents through the regex pipeline:
At collection or higher scope the VFS picks the best server-side strategy from the indexes available:
  1. Text index exists → uses $text (ranked by relevance)
  2. Atlas Search index exists → uses $search (fuzzy, Lucene-based)
  3. Neither → falls back to $regex on sampled string fields
Scope detection is handled by mirage/core/mongodb/scope.py.

head / tail / tail -f

tail uses server-side sort + limit. A count past max_doc_limit prints the last max_doc_limit documents, then says on stderr that the output is incomplete and exits 1, rather than printing fewer lines than asked in silence. head streams in _id order and stops after the count. tail -f opens a Mongo change stream filtered to insert events and yields each new document as a JSONL line in the same format as cat:
tail -f requires the cluster to be a replica set; Atlas already satisfies this. Views fall through to the non-streaming path because change streams aren’t defined on views.

Cache

The MongoDB VFS uses IndexCacheStore (same as RAM/S3/disk/GitHub) for listings: database names, collection names, and document counts. Document content is not cached. The VFS leaves caches_reads at its default of False, so cat, grep, head, and tail always query the live collection instead of serving a stored snapshot. This keeps reads consistent with a mutable database and ensures tail -f follows the live change stream rather than replaying cached bytes.

Example

Runnable examples

Three working examples live under examples/python/mongodb/:
  • mongodb.py — agent-shell workflow: ls, tree, cat, head, tail, wc, stat, grep/rg at every scope, jq, find, cd + relative paths.
  • mongodb_vfs.py — in-process VFS: os.listdir and open() walk every readdir level (root, database, collections/, views/, entity) and read database.json, schema.json, documents.jsonl (collection + view).
  • mongodb_fuse.py — same coverage as the VFS example, but the tree is mounted as a real filesystem so other processes can cat/ls/head the mountpoint directly.
All three default to the mirage_test database seeded by python/scripts/seed_mongodb_test.py.

Finding IDs

_id is serialized as {"$oid": "..."} under Extended JSON:

Working with Large Collections

Streaming is the default; reach for these patterns when you want to keep the round trip small:
Hide embeddings or large blobs from agent reads with elide_fields; schema.json still documents the original type so the agent can decide when to ask for the raw bytes through a different path.

Shell Commands

Standard commands available on the mounted MongoDB tree: