/discord/.
For token setup, see Discord Setup.
Config
Fields marked secret are redacted in snapshots.
VFS.md
The VFS.md an agent reads with Discord mounted at/<path>.
- Rendered
- Raw
Virtual Filesystem
VFS Layout
/<path>
- A guild, channel, member or attachment name is
<display-name>__<id>. The display name keeps Discord’s spelling (spaces, apostrophes, emoji); only/becomes∕(U+2215).lsthe parent first to find exact names, and quote a name that has spaces. - Messages are JSONL; use
jqfor fields such as.content,.author.usernameand.attachments. A day’sfiles/may be empty. - Without
start_time/end_time, a channel lists the latest 30 days up to its newest message; a date glob finds earlier days. - With
start_time/end_time, listings cover that scope; messages and attachments outside it are absent, direct paths included. Users and channel metadata stay available as context. grepandrgread the files they reach, sogrepneeds-rfor a directory. Under a channel that reads every listed day, attachments included: they download from the CDN, and binary ones such as JPG or PDF produce noise.
start_time=unbounded (inclusive), end_time=unbounded (exclusive). Explicit paths and globs cannot escape this scope.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 <cmd> or <cmd> --help for one command’s usage./ is replaced with ∕
(U+2215) so it cannot collide with a directory boundary. The Discord
snowflake ID is appended after __ (double underscore) on guild,
channel, member, and attachment names so VFS specific commands can
extract it without an extra lookup, and so two same named entities never
collide. Quote names containing spaces in shell commands. stat also
exposes the ID in the extra dict (see Finding IDs).
Guilds
The root lists one directory per guild the bot has access to.Channels
/discord/<guild>/channels/ lists text channels (types 0, 5, 15).
Each channel directory contains day-partitioned directories for the
30 days leading up to the channel’s last message. Each day directory
holds:
chat.jsonl, the day’s messages (one JSON object per line).files/, attachments posted on that day. Each blob is named<stem>__<attachment-id>.<ext>, where the stem keeps the original filename’s spelling (only/is replaced). The ID suffix keeps the filename collision-free.cat’ing a blob downloads it from the Discord CDN.
last_message_id on the channel object,
so inactive channels show dates around their last activity, not today.
Soft errors (403 missing permissions, 404 unknown channel, 429 rate
limit) on a single day are swallowed so listings, find, and grep
keep working across the rest of the tree.
Members
/discord/<guild>/members/ lists one .json file per member.
Reading a member file returns the full member payload from the
Discord API.
Smart Commands
grep / rg
grep -r and rg read every day’s chat.jsonl under the directory they walk,
so a channel or guild costs one history fetch per day. Name a day directory or a
date glob to search a large channel. Discord’s own search is not used: a reply
carries the message it answers (referenced_message), which that search does
not tie to the reply’s day, so it cannot say which days hold a word.
head / tail
head and tail on file-level paths use the Discord messages API directly
(GET /channels/{id}/messages) instead of downloading the full day’s history.
Cache
The Discord VFS usesIndexCacheStore (same as S3, disk and GitHub).
Index entries store guild IDs, channel IDs, and last_message_id for
date range computation. File bytes go through the workspace
file cache.
Integration
What Discord answers through its own API, so fewer files are read. Integration explains each command.Example
examples/python/vfs/discord/discord.py for the full working example.
Finding IDs
VFS-specific commands require Discord snowflake IDs (channel_id, guild_id, message_id). These can be extracted
from the filesystem:
Working with Large Channels
Tips for efficient access on busy channels:Shell Commands
Standard commands available on the mounted Discord tree:
Acting on Discord (sending, editing, reactions, threads, polls,
member and guild info, search) goes through the
discord CLI when installed; the mounted tree
stays read-oriented. The
<name>__<id> path segments supply the
snowflake IDs the CLI flags take.
Time scope
Setstart_time and/or end_time in the mount’s YAML config (or pass
start_time/end_time to Python; startTime/endTime to the TypeScript
constructor). Bounds are RFC3339 timestamps with an explicit timezone and
at most millisecond precision. Start is inclusive; end is exclusive.
An omitted or null bound is open. Start must precede end.
stat, date globs, and grep/rg cannot escape the scope. Scoped searches scan
the filtered files. User/member
and channel/server metadata remain visible as context.
These settings apply to the VFS, not to separately installed account CLIs.
mode: read prevents mount writes; it does not freeze upstream edits or deletions.
Rebuild/remount the VFS to change its scope so cached listings and bytes are cleared.