Slack MCP — Fallback for Slack Context
Purpose: Use Slack MCP when Supabase MCP (Slack project oqtkgsndvitzyfzwcdoz) is unavailable, errors (including permission denied/auth), or returns no useful data. This doc describes when and how to use Slack MCP as fallback for client and internal Slack context.
When to use Slack MCP (fallback)
- Supabase MCP is unavailable or not configured.
- Supabase Slack project returns an error (permission denied, auth, timeout, etc.).
- Supabase queries return empty or clearly insufficient results for the user’s ask.
Primary: Always try Supabase first for Slack context. If Supabase fails for any reason, immediately run this Slack MCP fallback flow in the same workflow.
Slack MCP tools
| Tool | Use |
|---|---|
slack_search_channels | Find channels by name or description. Always pass channel_types: "public_channel,private_channel" so both public and private channels the app is in are returned. Returns channel IDs and names. |
slack_read_channel | Read messages from a channel by channel_id (newest first). Use for each channel discovered above. Works for both public and private channels the app is in. No consent required. |
slack_search_public | Search messages in public channels only. No consent required. Use when you only need keyword search in public channels. |
slack_search_public_and_private | Search all channels (public, private, DMs). Use for keyword search across client-related private channels. Request user consent before use unless the workflow explicitly assumes consent (e.g. user asked for a client update). |
slack_read_thread | Read a thread by channel_id and message_ts. Use when a search result points to a thread you need in full. |
Scalable fallback workflow (no static mapping)
Use this flow for any client. No per-client channel list is required.
-
Discover channels related to the client
- Call slack_search_channels with:
query: client name (e.g. “LMNT”, “CTA”) and, if useful, common patterns like “client lmnt”, “lmnt internal”, “cta external”. Try the exact client name first; add variants if the first call returns few or no private channels.channel_types: "public_channel,private_channel"— required. The default is public only; omitting this is why private internal/external client channels were missed.
- Note every returned channel ID (and name). Cap at a reasonable number (e.g. 10–15 channels) to avoid token overflow; prefer channels whose names most clearly match the client.
- Call slack_search_channels with:
-
Read recent messages from each channel
- For each channel ID from step 1, call slack_read_channel with:
channel_id: the ID from step 1limit: 30–50 (or 50–100 if the channel is critical)- Optionally
oldest/latest: Unix timestamps for the last 7 days so you only pull recent context.
- This gives you recent context from all related public and private channels without needing a mapping or message search. No user consent is required for reading channels the app is already in.
- For each channel ID from step 1, call slack_read_channel with:
-
Optional: message-level search across all channels
- If you need keyword or phrase search across public and private channels (e.g. “blocker”, “timeline”, client name), call slack_search_public_and_private with:
query: client name or keywords andafter:YYYY-MM-DD(e.g. last 7 days).
- Consent: Request user consent before calling this tool unless the user has explicitly asked for a client update (e.g. “weekly kick-off for LMNT”, “end-of-week for CTA”) — in those cases, gathering Slack context for that client is part of the ask and consent can be assumed. Otherwise, ask once: “I’ll search Slack (including private channels) for messages about [client]. Proceed?”
- If you need keyword or phrase search across public and private channels (e.g. “blocker”, “timeline”, client name), call slack_search_public_and_private with:
-
Threads
- If a search result or read message references an important thread, use slack_read_thread with the parent message’s
channel_idandmessage_tsto get full replies.
- If a search result or read message references an important thread, use slack_read_thread with the parent message’s
Search modifiers (Slack search)
Use in the query parameter for slack_search_public or slack_search_public_and_private:
- Channel:
in:#channel-nameorin:<#C123456>; exclude with-in:channel - Author:
from:@usernameorfrom:<@U123456> - Date:
after:YYYY-MM-DD,before:YYYY-MM-DD,on:YYYY-MM-DD,during:month - Content:
"exact phrase",-word(exclude),*(wildcard, min 3 chars) - Filters:
is:thread,has:link,has:file, etc.
Space-separated terms are AND. No boolean OR/NOT in query string.
Client and internal channels (discovery only)
- Client channels: Usually named with the client or project (e.g.
#client-lmnt,#lmnt-internal,#cta-external). Use slack_search_channels with the client name and channel_types: “public_channel,private_channel” so private internal/external channels are included. Then slack_read_channel for each returned channel. - Internal channels: Search with terms like “internal”, “ai team”, “operations”. Same: use
channel_types: "public_channel,private_channel"and then read each channel as needed.
Local testing (Slack assistant)
When testing Slack assistant features locally (e.g. Linear ticket dry-run to Slack, Brainforge Assistant messages):
- Run the test or script (unit tests, dry-run script,
npm run slack-tests, etc.). - Use slack_read_channel with the test channel ID to read the latest message(s).
- For threads, use slack_read_thread with the parent message’s
ts. - Confirm expected content (copy, counts, Approve/Reject, links).
Channel ID comes from the feature config (e.g. LINEAR_TICKET_DRY_RUN_SLACK_CHANNEL_ID). If you only have a channel name, use slack_search_channels (with channel_types: "public_channel,private_channel" if it might be private) to get the ID.
Cursor rule: .cursor/rules/slack-assistant-testing-mcp.mdc
Consent
- slack_search_public: No consent required; public channels only.
- slack_read_channel: No consent required for channels the app is in (public or private).
- slack_search_public_and_private: Request and wait for user consent before use, unless the user has explicitly asked for a client update (e.g. weekly kick-off, end-of-week, touchpoint) for that client — then gathering Slack context is part of the request and consent can be assumed.
References
- supabase-context-agent.md — Primary Slack context via Supabase
- schema-reference.md — Client keys and table naming (Supabase)
- Slack UX guidelines — Threading, Block Kit (dry-run, Brainforge Assistant)
- Rule:
.cursor/rules/supabase-slack-context.mdc - Rule:
.cursor/rules/slack-assistant-testing-mcp.mdc - Skill:
.cursor/skills/slack-supabase-context/SKILL.md