Back to the MCP Gateway catalog

MCP Gateway · Catalog

Slack icon

Slack MCP server

Official

Slack MCP is the official Model Context Protocol server for Slack, with OAuth and tools that let agents search messages, read channels and threads, send and schedule messages, and manage canvases. Connect it through the Speakeasy MCP Gateway and agents such as Claude, Cursor, and ChatGPT get one governed URL for it, with SSO, RBAC, and a full audit trail.

Communication13 toolsAuth: oauth

Behind the MCP Gateway

Run Slack MCP behind the MCP Gateway

One URL for every agent, sign-in through your IdP, RBAC down to the tool, and every Slack call inspected and logged.

Deploy on MCP Gateway

Tools · 13

Each tool below can be allowed or denied per team and role at the MCP Gateway, and every call is inspected and logged.

slack_send_message

Sends a message to a Slack channel or user. To DM a user, use their user_id as channel_id. If the user wants to send a message to themselves, the current logged in user's user_id is U08AX7WMX1S. Return the message link to the user. Message uses standard markdown (**bold**, _italic_, `code`, ~strikethrough~, lists, links, code blocks). Limited to 5000 chars per text element. Do not include sensitive info in link query params. Cannot post to externally shared (Slack Connect) channels. Thread replies: set thread_ts to parent message timestamp, reply_broadcast=true to also post to channel. Use slack_search_channels to find channel IDs, slack_search_users to find user IDs. If user has not reviewed the message, use slack_send_message_draft instead.

slack_schedule_message

Schedules a message for future delivery to a Slack channel. Does NOT send immediately — use slack_send_message for that. post_at must be a Unix timestamp at least 2 minutes in the future, max 120 days out. Message is markdown formatted. Once scheduled, cannot be edited via API — user should use "Drafts and sent" in Slack UI. Thread replies: provide thread_ts and optionally reply_broadcast=true. Cannot schedule in externally shared (Slack Connect) channels. Use slack_search_channels to find channel IDs, slack_search_users to find user IDs (usable as channel_id for DMs).

slack_create_canvas

Creates a Slack Canvas document from Canvas-flavored Markdown content. Return the canvas link to the user. Not available on free teams. Use slack_read_canvas to read existing canvases. Use slack_update_canvas to edit an existing canvas. ## Canvas Formatting Guidelines: REQUIRED: Must be a non-empty string when updating canvas content. Only omit this field if you are updating ONLY the title. The canvas content, formatted as Canvas-flavored Markdown. Canvas-flavored Markdown is different from Slack message formatting. When creating content for Canvases, adhere to the following Canvas-only rules: - The content should be formatted as standard Markdown, including headers, lists, links, checklists, and other Markdown formatting. - When writing user IDs, you should format them as: `![](@U15CTCJ83)` where `U15CTCJ83` is the user\'s Slack ID. - When user references are used in their own line, they will render as larger cards, if referenced inline they will render as special text. - When writing channel IDs, you should format them as: `![](#C15CTCJ83)` where `C15CTCJ83` is the channel\'s Slack ID. Always use the channel\'s ID, NEVER use the channel name. - NEVER output a channel as <#C1234567890> or a user as <@U1234567890>, even when part of a text quote, instead use the format above. - Links should be formatted as: `[link text](https://example.com)`. Do not surround the link in angle brackets. - IMPORTANT: Only use these URL schemes in links: `http://`, `https://`, `mailto:`, `tel:`, `ftp://`, `slack://`, or relative paths starting with `/`. Other schemes like `javascript:`, `data:`, `file:` will be automatically removed from the canvas. - Images should be formatted as: `![alt text](https://example.com/image.png)` - Image syntax must appear only in a top-level, stand-alone line. Images are not supported in other elements - Salesforce records should be formatted as: `![](ssr:<org_id>/<record_id>)` where `<org_id>` is the Salesforce org ID and `<record_id>` is the Salesforce record ID, the org ID and record ID should be the full IDs which would be 18 characters long. Example: `![](ssr:70Dj038B0WJ0ACNCSD/X01j50VP066SCCIPDJ)` - Salesforce records syntax must appear only in a top-level, stand-alone line. Salesforce records are not supported in other elements - Quoted text should be formatted as: `> This is quoted text`, but you should only use quotes on their own line. - Slack-style emojis are supported, e.g. :tada: or :wave: - Use only ATX headings `#`, `##`, `###`. NEVER use deeper headings `####`-`######`. - Do not place headings inside list items. - In list items, allow only paragraphs with inline formatting. - Thematic breaks (---, ***, ___) are only allowed at the top level. - When nesting lists, do not mix list types: - Numbered lists can only contain nested numbered lists, and cannot contain nested bulleted lists - Bulleted lists can only contain nested bulleted lists, and cannot contain nested numbered lists - Code blocks are not allowed inside list items. - Tables should be formatted as, where <br> can be used for multi-line content: |Header|Header2| |---|---| |content1|content2<br>line two| - The title provided through the `title` field will be used as the title of the canvas. Do not include the title in the content section. <example1> # Headers # Status :large_green_circle: On Track # Goal The channel to coordinate the build, testing, and launch of Platypus # :people_hugging:Stakeholders ![](@U071CCRCVFH) ![](@UQSSGHV0Q) # :books:Resources * Project Plan * Google Drive # :slack:Related channels * ![](#C073UAJRW4R) - Project Channel * ![](#C084UBTRX4J) - [GTM Channel](https://gtm.wiki.com) </example1> <example2> |Message|User Author| |---|---| |[Here is the python guide](https://team.slack.com/archives/C016VCYCL74/p1727122965001469)|![](@U071CCRCVFH)| |[The Java guide isn\'t ready](https://team.slack.com/archives/C016VCYCL74/p1727122965001469)|![](@UQSSGHV0Q)|\n\n # Python Guide\n ## Step 1\n ```python print("Hello, world!") ```\n\n </example2> - When a layout is requested use the ::: {.layout} as the starting delimiter and ::: as the ending delimiter of the full layout. Then each column should be wrapped in ::: {.column} as the starting delimiter and ::: as the ending delimiter. There can only be up to 3 columns in a layout and tables and callouts are not supported in layouts or columns. - Callouts should be formatted with ::: {.callout} as the starting delimiter and ::: as the ending delimiter in markdown. Use them to highlight important information, such as warnings, important prerequisites, and notices. - Do not use tables within callouts and callouts cannot be nested within other elements. <example_markdown_with_callout> ::: {.callout} This is a callout ::: </example_markdown_with_callout> - In block quotes, ONLY use: plain text paragraphs with inline formatting. No headings, lists, code blocks, or nested quotes. - Code blocks are allowed only at the top level (not inside block quotes or list items). CRITICAL RESTRICTIONS - Canvas Nesting Rules (MUST FOLLOW): - In list items, ONLY use: plain text paragraphs with inline formatting (bold, italic, inline `code`, links). - Code blocks, block quotes, and headings must always be separated from lists by blank lines. - In layouts no tables or callouts are supported.- Layouts are not supported in tables or callouts. <example_correct_usage> - Item with inline `code` formatting - Item with **bold** text and [links](https://example.com) </example_correct_usage> <example_blocks_and_quotes_outside_lists> ``` code block at top level ``` - List item one - List item two > Block quote at top level ### Heading at top level </example_blocks_and_quotes_outside_lists> WHEN CITING SOURCES: - When your content references information from web search results or other sources, you MUST include inline citation links using the [[N]](url) format throughout the content, exactly as you would in a chat response. - Place citations inline next to the claims they support, e.g. "Shaidorov won gold [[7]](https://en.wikipedia.org/wiki/...)" - Do NOT collapse all sources into a single "Source:" line at the bottom. Each fact should be cited where it appears. - The citation links will be automatically enriched with page titles for readability. - Format date headings and key dates (including due dates, deadlines, milestones) as ![](slack_date:YYYY-MM-DD) ONLY. Never append day names or date text. ## Examples of appropriate usage of date formatting in your output: Correct usage: <example_date_heading_correct> ## ![](slack_date:2025-12-16) </example_date_heading_correct> Incorrect usage (has day name and date text): <example_date_heading_incorrect> ## ![](slack_date:2025-12-16) December 16th - Monday </example_date_heading_incorrect>- User Profile Cards: To display a user's profile card as a standalone section (not inline), use the format ![](@user_id) where user_id is the Slack user ID. CRITICAL: Use parentheses () around @user_id, NOT angle brackets <>. Example: ![](@U0TDAU873). Profile cards should be on their own line and will render as larger cards with user information. ## Examples of appropriate usage of user profile cards in your output: Correct usage (standalone profile card on its own line): <example_user_profile_card_correct> # Team Members ![](@U0TDAU873) ![](@U12345678) </example_user_profile_card_correct>- Slack Files: ONLY for files with URLs matching *.slack.com/files/*, ALWAYS embed using ![](file_reference). For standalone display (card): place on its own line. For inline reference (clickable text): embed directly in paragraph like "The ![](https://example.slack.com/files/U123/F456/doc.pdf) contains...". Do not use this syntax for non-Slack files.

slack_update_canvas

Updates an existing Slack Canvas document with markdown content. Supports appending, prepending, or replacing content. ## CRITICAL WARNING Using `action=replace` WITHOUT providing a `section_id` will **OVERWRITE THE ENTIRE CANVAS** content. This is destructive and irreversible. You MUST call `slack_read_canvas` first to retrieve section IDs, then pass the appropriate `section_id` to replace only the target section. ## Action Behavior ### With `section_id`: - `append`: Adds new content to the END of the specified section's block (inserted after the last content under that section, just before the next header section) - `prepend`: Inserts new content immediately AFTER the targeted element. If the section_id is a header, content appears after the header line but before the section's existing body content. If the section_id is a non-header element (paragraph, list, table, etc.), content is inserted directly after that element. - `replace`: Replaces ONLY the specified section's content block (safe) **Important:** The `section_id_mapping` contains IDs for ALL content elements — headers (`#`, `##`, `###`), paragraphs, lists, tables, and callouts — not just header sections. For best results with append/prepend, target a header section_id to insert within that section's block. ### Without `section_id`: - `append`: Adds content to the END of the canvas (after the last section) - `prepend`: Inserts content after the canvas title but before existing body content (the title is preserved) - `replace`: ⚠️ **REPLACES THE ENTIRE CANVAS** — avoid unless user explicitly wants full replacement ## Args: canvas_id (str, required): ID of the canvas to update (e.g., "F1234567890") action (str, required): One of "append", "prepend", or "replace". Defaults to "append" content (str, required): Markdown-formatted content to insert or replace section_id (Optional[str]): Section ID from slack_read_canvas. Can reference any content element (header, paragraph, list, table, callout). For append/prepend, targeting a header section_id is recommended as it operates on the header's content block. append inserts after the last content in that section's block (before the next header); prepend inserts immediately after the targeted element; replace overwrites the section's block. STRONGLY RECOMMENDED for replace action to avoid overwriting the entire canvas. ## Returns: canvas_id (str): ID of the updated canvas canvas_url (str): URL link to the updated canvas — always share this with the user section_id_mapping (dict): Updated mapping of section IDs to their markdown content after the edit. Each key is a section ID string (e.g., "temp:C:abc123") and each value is the markdown content of that element. Contains IDs for ALL content elements (headers, paragraphs, lists, tables, callouts), not just headers. Use these section IDs in subsequent `slack_update_canvas` calls to target specific sections, enabling multi-step editing workflows without needing to call `slack_read_canvas` again between edits. ## When to Use - User wants to add content to an existing canvas (append/prepend) - User wants to update a specific section of a canvas (replace with section_id) - User wants to rewrite an entire canvas (replace without section_id — only if explicitly requested) ## When NOT to Use - User wants to create a new canvas (use `slack_create_canvas` instead) - User wants to read a canvas (use `slack_read_canvas` instead) - User only wants to send a simple message (use `slack_send_message` instead) ## Recommended Workflow for Editing a Section 1. Call `slack_read_canvas` with the canvas_id to get content and section IDs 2. Identify the target section_id from the section_id_mapping 3. Call `slack_update_canvas` with action=replace and the section_id ## Examples Append to the end of a canvas (no section_id): slack_update_canvas(canvas_id="F0123ABC456", action="append", content="## New Section Here is the appended content.") Append to the end of a specific section: slack_update_canvas(canvas_id="F0123ABC456", action="append", section_id="temp:C:abc123", content="## New Section This content is added at the end of the specified section.") Replace a specific section (safe — only that section is changed): slack_update_canvas(canvas_id="F0123ABC456", action="replace", section_id="temp:C:abc123", content="## Updated Section This replaces only the targeted section.") Prepend within a specific section (inserts right after the section header, before existing body content): slack_update_canvas(canvas_id="F0123ABC456", action="prepend", section_id="temp:C:abc123", content="This paragraph appears right after the section header, before the section's existing body content.") ## Error Codes: - `not_supported_free_team`: Canvas operations not supported on free teams - `canvas_not_found`: Invalid canvas_id or user lacks access - `invalid_content`: Content format is invalid - `permission_denied`: User lacks permission to edit this canvas - `section_not_found`: The provided section_id does not exist in the canvas ## Canvas Formatting Guidelines: REQUIRED: Must be a non-empty string when updating canvas content. Only omit this field if you are updating ONLY the title. The canvas content, formatted as Canvas-flavored Markdown. Canvas-flavored Markdown is different from Slack message formatting. When creating content for Canvases, adhere to the following Canvas-only rules: - The content should be formatted as standard Markdown, including headers, lists, links, checklists, and other Markdown formatting. - When writing user IDs, you should format them as: `![](@U15CTCJ83)` where `U15CTCJ83` is the user\'s Slack ID. - When user references are used in their own line, they will render as larger cards, if referenced inline they will render as special text. - When writing channel IDs, you should format them as: `![](#C15CTCJ83)` where `C15CTCJ83` is the channel\'s Slack ID. Always use the channel\'s ID, NEVER use the channel name. - NEVER output a channel as <#C1234567890> or a user as <@U1234567890>, even when part of a text quote, instead use the format above. - Links should be formatted as: `[link text](https://example.com)`. Do not surround the link in angle brackets. - IMPORTANT: Only use these URL schemes in links: `http://`, `https://`, `mailto:`, `tel:`, `ftp://`, `slack://`, or relative paths starting with `/`. Other schemes like `javascript:`, `data:`, `file:` will be automatically removed from the canvas. - Images should be formatted as: `![alt text](https://example.com/image.png)` - Image syntax must appear only in a top-level, stand-alone line. Images are not supported in other elements - Salesforce records should be formatted as: `![](ssr:<org_id>/<record_id>)` where `<org_id>` is the Salesforce org ID and `<record_id>` is the Salesforce record ID, the org ID and record ID should be the full IDs which would be 18 characters long. Example: `![](ssr:70Dj038B0WJ0ACNCSD/X01j50VP066SCCIPDJ)` - Salesforce records syntax must appear only in a top-level, stand-alone line. Salesforce records are not supported in other elements - Quoted text should be formatted as: `> This is quoted text`, but you should only use quotes on their own line. - Slack-style emojis are supported, e.g. :tada: or :wave: - Use only ATX headings `#`, `##`, `###`. NEVER use deeper headings `####`-`######`. - Do not place headings inside list items. - In list items, allow only paragraphs with inline formatting. - Thematic breaks (---, ***, ___) are only allowed at the top level. - When nesting lists, do not mix list types: - Numbered lists can only contain nested numbered lists, and cannot contain nested bulleted lists - Bulleted lists can only contain nested bulleted lists, and cannot contain nested numbered lists - Code blocks are not allowed inside list items. - Tables should be formatted as, where <br> can be used for multi-line content: |Header|Header2| |---|---| |content1|content2<br>line two| - The title provided through the `title` field will be used as the title of the canvas. Do not include the title in the content section. <example1> # Headers # Status :large_green_circle: On Track # Goal The channel to coordinate the build, testing, and launch of Platypus # :people_hugging:Stakeholders ![](@U071CCRCVFH) ![](@UQSSGHV0Q) # :books:Resources * Project Plan * Google Drive # :slack:Related channels * ![](#C073UAJRW4R) - Project Channel * ![](#C084UBTRX4J) - [GTM Channel](https://gtm.wiki.com) </example1> <example2> |Message|User Author| |---|---| |[Here is the python guide](https://team.slack.com/archives/C016VCYCL74/p1727122965001469)|![](@U071CCRCVFH)| |[The Java guide isn\'t ready](https://team.slack.com/archives/C016VCYCL74/p1727122965001469)|![](@UQSSGHV0Q)|\n\n # Python Guide\n ## Step 1\n ```python print("Hello, world!") ```\n\n </example2> - When a layout is requested use the ::: {.layout} as the starting delimiter and ::: as the ending delimiter of the full layout. Then each column should be wrapped in ::: {.column} as the starting delimiter and ::: as the ending delimiter. There can only be up to 3 columns in a layout and tables and callouts are not supported in layouts or columns. - Callouts should be formatted with ::: {.callout} as the starting delimiter and ::: as the ending delimiter in markdown. Use them to highlight important information, such as warnings, important prerequisites, and notices. - Do not use tables within callouts and callouts cannot be nested within other elements. <example_markdown_with_callout> ::: {.callout} This is a callout ::: </example_markdown_with_callout> - In block quotes, ONLY use: plain text paragraphs with inline formatting. No headings, lists, code blocks, or nested quotes. - Code blocks are allowed only at the top level (not inside block quotes or list items). CRITICAL RESTRICTIONS - Canvas Nesting Rules (MUST FOLLOW): - In list items, ONLY use: plain text paragraphs with inline formatting (bold, italic, inline `code`, links). - Code blocks, block quotes, and headings must always be separated from lists by blank lines. - In layouts no tables or callouts are supported.- Layouts are not supported in tables or callouts. <example_correct_usage> - Item with inline `code` formatting - Item with **bold** text and [links](https://example.com) </example_correct_usage> <example_blocks_and_quotes_outside_lists> ``` code block at top level ``` - List item one - List item two > Block quote at top level ### Heading at top level </example_blocks_and_quotes_outside_lists> WHEN CITING SOURCES: - When your content references information from web search results or other sources, you MUST include inline citation links using the [[N]](url) format throughout the content, exactly as you would in a chat response. - Place citations inline next to the claims they support, e.g. "Shaidorov won gold [[7]](https://en.wikipedia.org/wiki/...)" - Do NOT collapse all sources into a single "Source:" line at the bottom. Each fact should be cited where it appears. - The citation links will be automatically enriched with page titles for readability. - Format date headings and key dates (including due dates, deadlines, milestones) as ![](slack_date:YYYY-MM-DD) ONLY. Never append day names or date text. ## Examples of appropriate usage of date formatting in your output: Correct usage: <example_date_heading_correct> ## ![](slack_date:2025-12-16) </example_date_heading_correct> Incorrect usage (has day name and date text): <example_date_heading_incorrect> ## ![](slack_date:2025-12-16) December 16th - Monday </example_date_heading_incorrect>- User Profile Cards: To display a user's profile card as a standalone section (not inline), use the format ![](@user_id) where user_id is the Slack user ID. CRITICAL: Use parentheses () around @user_id, NOT angle brackets <>. Example: ![](@U0TDAU873). Profile cards should be on their own line and will render as larger cards with user information. ## Examples of appropriate usage of user profile cards in your output: Correct usage (standalone profile card on its own line): <example_user_profile_card_correct> # Team Members ![](@U0TDAU873) ![](@U12345678) </example_user_profile_card_correct>- Slack Files: ONLY for files with URLs matching *.slack.com/files/*, ALWAYS embed using ![](file_reference). For standalone display (card): place on its own line. For inline reference (clickable text): embed directly in paragraph like "The ![](https://example.slack.com/files/U123/F456/doc.pdf) contains...". Do not use this syntax for non-Slack files. ## What NOT to Expect: ❌ Does NOT create new canvases (use `slack_create_canvas`) ❌ Does NOT support setting canvas permissions or sharing ❌ Does NOT support deleting a canvas

slack_search_public

Searches for messages, files in public Slack channels ONLY. Current logged in user's user_id is U08AX7WMX1S. `slack_search_public` does NOT generally require user consent for use, whereas you should request and wait for user consent to use `slack_search_public_and_private`. --- `query` should include keywords or natural language question with search modifiers. Search modifiers: in:channel-name / in:<#C123456> / -in:channel Channel filter in:<@U123456> / in:@username DM filter from:<@U123456> / from:username Author filter (angle brackets are literal for IDs) to:<@U123456> / to:me Recipient filter creator:@user Canvas creator filter is:thread / is:saved / has:pin / has:link / has:file Content filters has::emoji: / hasmy::emoji: Reaction filters before:YYYY-MM-DD / after:YYYY-MM-DD / on:YYYY-MM-DD / during:month Date filters "exact phrase" / -word / * (wildcard, min 3 chars) Text matching File search: use `content_types="files"` with `type:` filter (images, documents, pdfs, spreadsheets, presentations, canvases, lists, emails, audio, videos). All standard modifiers work with file searches. Search types: 1. Natural language — Triggered by natural language questions. Finds topically related content even without exact keywords. May return broadly related results — combine with filters for precision. ✅ Semantic search is available for this user. 2. Keyword — exact matches, space-separated = AND, no boolean operators (AND/OR/NOT). Use slack_read_thread for thread details, slack_read_canvas for canvas content, slack_read_channel for surrounding messages. Strategy: break into multiple small searches, use modifiers to narrow, try keyword then semantic (or vice versa), broaden if 0 results. --- Examples: ✅ Use query="What's our holiday schedule? in:#general" query="bug report after:2024-01-08" sort="timestamp" query="from:<@Jane Doe> in:dev bug report" Additional parameters: include_context (Optional[bool]) Include surrounding context messages for each result (default: true). Set to false to reduce response size. max_context_length (Optional[int]) Max character length for each context message. Longer messages are truncated.

slack_search_public_and_private

Searches for messages, files in ALL Slack channels, including public channels, private channels, DMs, and group DMs. Current logged in user's user_id is U08AX7WMX1S. --- `query` should include keywords or natural language question with search modifiers. Search modifiers: in:channel-name / in:<#C123456> / -in:channel Channel filter in:<@U123456> / in:@username DM filter from:<@U123456> / from:username Author filter (angle brackets are literal for IDs) to:<@U123456> / to:me Recipient filter creator:@user Canvas creator filter is:thread / is:saved / has:pin / has:link / has:file Content filters has::emoji: / hasmy::emoji: Reaction filters before:YYYY-MM-DD / after:YYYY-MM-DD / on:YYYY-MM-DD / during:month Date filters "exact phrase" / -word / * (wildcard, min 3 chars) Text matching File search: use `content_types="files"` with `type:` filter (images, documents, pdfs, spreadsheets, presentations, canvases, lists, emails, audio, videos). All standard modifiers work with file searches. Search types: 1. Natural language — Triggered by natural language questions. Finds topically related content even without exact keywords. May return broadly related results — combine with filters for precision. ✅ Semantic search is available for this user. 2. Keyword — exact matches, space-separated = AND, no boolean operators (AND/OR/NOT). Use slack_read_thread for thread details, slack_read_canvas for canvas content, slack_read_channel for surrounding messages. Strategy: break into multiple small searches, use modifiers to narrow, try keyword then semantic (or vice versa), broaden if 0 results. --- Examples: ✅ Use (with user consent) query="What's our holiday schedule? in:#general" query="bug report after:2024-01-08" sort="timestamp" query="from:<@Jane Doe> in:dev bug report" Additional parameters: include_context (Optional[bool]) Include surrounding context messages for each result (default: true). Set to false to reduce response size. max_context_length (Optional[int]) Max character length for each context message. Longer messages are truncated.

slack_search_channels

Search for Slack channels by name or description. Returns channel names, IDs, topics, purposes, and archive status. Query tips: use terms matching channel names/descriptions (e.g., "engineering", "project alpha"). Names are typically lowercase with hyphens. Use slack_read_channel to read messages from a known channel. Use slack_search_public to search message content across channels.

slack_search_users

Search for Slack users by name, email, or profile attributes (department, role, title). Current logged in user's Slack user_id is U08AX7WMX1S. Query syntax: full names ("John Smith"), partial names ("John"), emails ("john@company.com"), departments/roles ("engineering"), combinations ("John engineering"), exclusions ("engineering -intern"). Space-separated terms = AND. Use slack_read_user_profile for detailed info on a known user ID. Use slack_search_public with from: filter to find messages by a user.

slack_read_channel

Reads messages from a Slack channel in reverse chronological order (newest first). To read DM history, use a user_id as channel_id. Read-only. Use slack_read_thread with message_ts to read thread replies. Use slack_search_channels to find a channel ID by name. Use slack_search_public to search across channels. If 'channel_not_found', try slack_search_channels first.

slack_read_thread

Reads messages from a specific Slack thread (parent message + all replies). Read-only. Requires channel_id and message_ts of the parent message. Use slack_search_public or slack_read_channel to find these values. Use slack_search_public with "is:thread" to find threads by content. Use slack_send_message with thread_ts to reply to a thread.

slack_read_canvas

Retrieves the markdown content and section ID mapping of a Slack Canvas document. Read-only. Use slack_create_canvas to create new canvases. Use slack_search_public to find canvases by name or content. Use slack_update_canvas to edit canvas content.

slack_read_user_profile

Retrieves detailed profile information for a Slack user: contact info, status, timezone, organization, and role. Read-only. Defaults to current user if user_id not provided. Use slack_search_users to find a user ID by name or email.

slack_send_message_draft

Creates a draft message in a Slack channel. The draft is saved to the user's "Drafts & Sent" in Slack without sending it. ## When to Use - User wants to prepare a message without sending it immediately - User needs to compose a message for later review or sending - User wants to draft a message to a specific channel ## When NOT to Use - User wants to send a message immediately (use `slack_send_message` instead) - User wants to schedule a message (use `slack_send_message` with scheduling) - User wants to create drafts in multiple channels (call this tool multiple times) - Channel is externally shared (Slack Connect channel) - drafts in externally shared channels are not supported ## Input Parameters: - `channel_id`: Single channel ID where the draft should be created - `message`: The draft message content using standard markdown. Supports **bold**, _italic_, `code`, ~strikethrough~, >blockquotes, lists, links, and code blocks. - `thread_ts` (optional): Timestamp of the parent message to create a draft reply in a thread (e.g., "1234567890.123456") ## Output: Returns `channel_link` - a Slack web client URL (e.g., https://app.slack.com/client/T123/C456) that opens the channel in the web app where the draft was created. ## Finding value for `channel_id` input: - Use `slack_search_users` tool to find user ID for DMs, then use their user_id as the channel_id ## Error Codes: - `channel_not_found`: Invalid channel ID or user does not have access to the channel - `draft_already_exists`: A draft already exists for this channel (user should edit or delete the existing draft first) - `failed_to_create_draft`: Draft creation failed for an unknown reason - `mcp_externally_shared_channel_restricted`: Cannot create drafts in externally shared channels (Slack Connect channels) ## Notes: - Drafts are created as attached drafts (linked to the specific channel) - User must have write access to the channel - Only one attached draft is allowed per channel - if a draft already exists, you'll get an error

Questions

What is a Slack MCP server?
A Slack MCP server exposes Slack to AI agents as Model Context Protocol tools. Instead of a custom integration per agent, any MCP client can connect to the server and call tools such as slack_send_message or slack_schedule_message to work with Slack. The server in this catalog is the official Slack MCP server, which authenticates with OAuth.
What can you do with Slack MCP?
Agents can search messages, read channels and threads, send and schedule messages, and manage canvases. The catalog lists 13 tools for this server, including slack_send_message, slack_schedule_message, and slack_create_canvas. The full list with descriptions is on this page.
Why put Slack MCP behind an MCP gateway?
Connecting the Slack MCP server directly to each client means a separate credential per developer, no inventory of who can reach Slack through an agent, and no record of what agents did with it. An MCP gateway sits between every agent and the Slack server, so sign-in runs through your identity provider, role-based access decides which teams can call which Slack tools, and every call is inspected and logged in one place. The Speakeasy MCP Gateway applies those controls to Slack and to every other server in your catalog.
How do you connect Slack MCP through a gateway?
Add the Slack server from the Speakeasy MCP catalog and every agent reaches it through one gateway URL, next to the rest of your approved servers. Authentication uses OAuth 2.1 with PKCE and dynamic client registration, sign-in runs through your identity provider, and role-based access controls decide which teams can use which Slack tools. Every prompt, response, and tool call is inspected and logged at the gateway.
How is this different from an unofficial Slack MCP?
Community-built Slack MCP servers wrap the same Slack surface but are not vendor-maintained, and most authenticate with a static credential that gives an agent everything the credential owner can touch. This catalog lists the official Slack MCP server, which uses OAuth. Running it behind the Speakeasy MCP Gateway adds SSO, role-based access, and an audit trail of every call.

AI everywhere.

Control here.