SlackResource in two runtimes:
@struktoai/mirage-node, talks tohttps://slack.com/api/*directly using a bot token (and optionally a user token forsearch.messages).@struktoai/mirage-browser, stays secret-free: a small proxy server on your backend holds the token and forwards/api/slack/*tohttps://slack.com/api/*. The browser only ever sees the proxy URL.
/slack/channels/, /slack/dms/, /slack/users/) and the same shell commands, and both pair with the slack CLI for acting on the workspace.
Get a bot token
- Visit the Slack API basics page and create an app for your workspace.
- Under OAuth & Permissions, add the bot scopes you need. The minimum for read access is:
channels:history,channels:readgroups:history,groups:readim:history,im:readusers:read
- For posting messages, also add
chat:write. - For
search.messages, Slack requires a user token (xoxp-…) withsearch:read. Bot tokens (xoxb-…) getnot_allowed_token_type. Provide it via the optionalsearchTokenfield. - Install the app to your workspace and copy the Bot User OAuth Token (
xoxb-…).
Node (server-side)
Browser
https://slack.com/api/*, attaching the Authorization: Bearer … header server-side.
1. Server: minimal proxy
2. Browser: wire it up
Filesystem layout
chat.jsonl plus a files/ directory for attachments shared that day. Each user file is the full profile JSON returned by users.profile.get. The Slack ID is embedded after __ in directory and file names so you can extract it for the resource-specific commands without an extra lookup.
Shell commands
Every standard MIRAGE shell command works 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.
Troubleshooting
`not_allowed_token_type` on slack search / rg /slack/
`not_allowed_token_type` on slack search / rg /slack/
search.messages requires a user token (xoxp-…) with search:read scope. Set searchToken on the SlackConfig:rg and slack search fail; channel-scope rg (e.g. rg foo /slack/channels/general__C…/) still works since it streams the JSONL files directly.CORS error in browser
CORS error in browser
The browser cannot call
https://slack.com/api/* directly, Slack does not set permissive CORS headers. You must run the proxy server shown above (or your own equivalent) and point proxyUrl at it.`rate_limited` from Slack
`rate_limited` from Slack
SlackResource uses an IndexCacheStore (default TTL 600s) to deduplicate channel / user / date listings, but high-volume reads of .jsonl files can still hit Slack’s per-method rate limits. Cache hits avoid the API entirely; tune indexTtl if your workspace changes slowly. Per Slack docs, Tier 3 methods like conversations.history allow ~50 requests / minute / workspace.Examples
examples/typescript/slack/slack.ts, shell commands against/slack/(ls,cat,grep,jq,tree,find,cd, glob).examples/typescript/slack/slack_vfs.ts,patchNodeFs(ws)so nativenode:fscalls route through the workspace.examples/typescript/slack/slack_fuse.ts, FUSE-mount the workspace so external processes can browse/slack/as a real filesystem.examples/typescript/slack/slack_browser/, proxy server +@struktoai/mirage-browserSlackResource demo.