/mongodb/.
For connection setup, see MongoDB Setup.
Config
Filesystem Layout
The mount mirrors MongoDB’scluster → database → collection / view
model. The database directory always appears in the path, even when
databases filters to a single entry.
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 all stream from this file; nothing
materializes the full collection in memory.
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; stat still exposes document_count for the number of documents.
schema.json
Generated from a 100-document$sample. Includes:
- field path → observed BSON type frequencies (nested paths unioned across the sample)
- indexes from
listIndexesplus access counts from$indexStats - the
$jsonSchemavalidator if one is registered
database.json
Lists every collection and view under the database with their document counts. Useful forcat /mongodb/<db>/database.json to get an overview
without recursing into each entity.
Elided fields
Fields listed underelide_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:
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:
- Text index exists → uses
$text(ranked by relevance) - Atlas Search index exists → uses
$search(fuzzy, Lucene-based) - Neither → falls back to
$regexon sampled string fields
mirage/core/mongodb/scope.py.
head / tail / tail -f
head and tail use server-side sort + limit; the requested count
is capped at max_doc_limit. 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 resource usesIndexCacheStore (same as RAM/S3/disk/GitHub)
for listings: database names, collection names, and document counts.
Document content is not cached. The resource 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 underexamples/python/mongodb/:
mongodb.py— agent-shell workflow:ls,tree,cat,head,tail,wc,stat,grep/rgat every scope,jq,find,cd+ relative paths.mongodb_vfs.py— in-process VFS:os.listdirandopen()walk every readdir level (root, database,collections/,views/, entity) and readdatabase.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 cancat/ls/headthe mountpoint directly.
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: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.