Skip to main content
The Slack VFS exposes a Slack workspace as a virtual filesystem mounted at some prefix such as /slack/. For token setup, see Slack Setup.

Config

Fields marked secret are redacted in snapshots.

VFS.md

The VFS.md an agent reads with Slack mounted at /<path>.

Virtual Filesystem

/<path> layout

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.
Example:
Directory names embed the Slack ID so that write commands (slack send-message --channel, etc.) can reference the correct VFS without extra lookups.

Channels

/slack/channels/ lists public and private channels the bot has access to. The channel ID is appended after __. Each channel directory contains day-partitioned directories for the last 90 days (or since channel creation, whichever is shorter). Each date directory contains chat.jsonl plus a files/ directory for attachments shared that day. The date range is derived from the channel’s created timestamp.

DMs

/slack/dms/ lists direct message conversations. The DM ID is appended after __. Like channels, DM directories contain daily directories with chat.jsonl and files/.

Users

/slack/users/ lists one .json file per non-deleted, non-bot user. Reading a user file calls get_user_profile() and returns the full profile JSON from the Slack API.

Cache

The Slack VFS uses IndexCacheStore (same as Discord and other mounts). Index entries store channel IDs, DM IDs, user IDs, and channel creation timestamps for date range computation. File bytes go through the workspace file cache.

Example

See examples/python/vfs/slack/slack.py for the full working example.

Finding IDs

VFS-specific commands require Slack IDs (channel_id, user_id, ts). These can be extracted from the filesystem:

Working with Large Channels

Channels with many messages produce large chat.jsonl files per day. Tips for efficient access:

Shell Commands

Standard commands available on the mounted Slack tree: Acting on Slack (sending, reacting, pins, member info, search) goes through the slack CLI when installed; the mounted tree stays read-oriented. The <name>__<id> path segments supply the channel and user IDs the CLI flags take.

Integration

What Slack answers through its own API, so fewer files are read. Integration explains each command. With a user token, grep -rw and rg -w read only the channel and DM days Slack search names, and print what reading every day would. Search covers message text, file names and titles (search.files) and reactions (has::name:); listing a day already fetches its history, so this saves the second fetch of each day it rules out. A file hit names each day the file was shared. Users, file blobs and a day searched on its own are always read. Every day is read when the word is a key or fixed value of the message JSON, a file-type or URL word, a join or leave message word, or part of a user’s name or of the workspace’s domain, and when a search fails, returns more than 1,000 messages or finds nothing. With a separate search_token, every day is also read when the scope holds a private channel or a DM that token’s user is not in (a bot’s own DMs), since their search never sees it; that token needs channels:read, groups:read, im:read and mpim:read to list the conversations it sees. walk_limit: -1 in the mount’s "@all" command limit reads every file instead, since Slack indexes a message some time after it is posted, and a word held only in another field of a message (a bot’s username, an unfurled link) is not searched.

Time scope

Set start_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.
With a bound configured, channel listings cover the selected period rather than the default recent window. Day directories use UTC. Messages are selected by creation time, and attachments follow their parent messages. Direct paths, stat, date globs, and grep/rg cannot escape the scope: a search only rules out files, so 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.