Connect your AI Agents to Slack in minutes

Merge lets you securely connect your agents to Slack and thousands of tools instantly

Available tools

list_bookmarks

List the bookmarks pinned to a channel's header. Returns each bookmark's ID, title, link and emoji. Use listchannels to find the channelid, and use this tool to get the bookmarkid that editbookmark and remove_bookmark require.

add_bookmark

Pin a link to a channel's header as a bookmark. Use listchannels to find the channelid. Slack currently only supports link bookmarks. Returns the new bookmark's ID for later editbookmark or removebookmark calls.

edit_bookmark

Change an existing channel bookmark's title, link or emoji. Only the fields you pass are changed. Use listbookmarks to find the bookmarkid and listchannels for the channelid.

remove_bookmark

Remove a bookmark from a channel's header. Use listbookmarks to find the bookmarkid and listchannels for the channelid. This cannot be undone; re-add with add_bookmark.

create_canvas

Create a new standalone Slack canvas with optional title and markdown content. Returns the canvas ID.

edit_canvas

Write to or edit an existing Slack canvas by applying one or more change operations. Use 'insertatend' to append content, 'insertatstart' to prepend, or 'replace'/'delete' with a section_id for targeted edits.

delete_canvas

Permanently delete a Slack canvas by ID. This action cannot be undone.

create_channel_canvas

Create a canvas linked to a Slack channel. The canvas appears in the channel's canvas tab. Provide an optional markdown body for the initial content.

list_channels

List channels in the workspace (public and private; direct messages are excluded by default). Returns a lean set of fields by default (id, name, isprivate, isarchived, ismember, nummembers, topic); request more via the 'fields' parameter. Paginate with cursor/pageinfo. For multi-workspace org-wide tokens, pass teamid (omitting it returns an error listing workspace IDs).

create_channel

Create a new channel

get_channel_info

Get information about a channel using Channel ID (not channel name)

join_channel

Join a channel

close_conversation

Close a direct message or group direct message, removing it from your own sidebar. Not a delete: Slack cannot delete a DM, and the other participants keep seeing it. Use opendm or getusersconversations to find the conversation ID. For a channel use leavechannel, which this does not accept.

leave_channel

Leave a public or private channel you are a member of. Use listchannels to find channel IDs. To leave a DM or group DM use closeconversation instead.

archive_channel

Archive a channel, making it read-only for everyone. Use listchannels to find channel IDs. Reversible with unarchivechannel. You cannot archive the general channel or a DM.

unarchive_channel

Restore a previously archived channel to active use. Use listchannels with excludearchived false to find archived channel IDs.

get_channel_members

Get members of a channel

invite_to_channel

Invite one or more users to a channel by ID. When inviting multiple users, set force=true to invite the valid ones even if some IDs are invalid or already in the channel; without force, one bad ID fails the whole call.

kick_from_channel

Remove a user from a channel

set_channel_topic

Set the topic for a channel

set_channel_purpose

Set the purpose for a channel

rename_channel

Rename a channel

get_file_info

Get a file's metadata: name, type, size, owner and share locations. Use listfiles to find file IDs. This does not return the file contents; use getfile_content for the bytes.

list_files

List files in the workspace, most recent first by default. sort (created|timestamp) and sortdir (asc|desc) order the returned page only - files.list has no server-side sort, so ordering is not consistent across pages. Uploader and channels resolve to username/channel_names; raw IDs stay in user/channels. Paginate with count/page.

delete_file

Permanently delete a file and remove it from every conversation it was shared in. Use list_files to find file IDs. This cannot be undone.

share_file

Share an existing file into one or more channels by posting its permalink, which Slack unfurls into a file attachment. Use listfiles to find the fileid and listchannels for channel IDs. This does NOT make the file publicly accessible; use makefile_public for that.

get_file_content

Get the content of a file. Text-like files return plain text in 'content'. Binary files (images, PDFs, etc.) return base64-encoded bytes in 'contentbase64' with 'mimetype' and 'encoding' set, so the caller can base64-decode back to the exact original file. For name, size or owner only, use getfile_info, which does not download.

make_file_public

Create a public share URL for a file, readable without a Slack account. Use listfiles to find file IDs. Reverse it with revokefilepublicurl.

revoke_file_public_url

Revoke a file's public share URL, so it is again readable only inside Slack. Use list_files to find file IDs.

upload_file

Upload a file or image to Slack. Provide the bytes as base64 in content, not a URL and not plain text, OR a filereference from the file upload API (POST /api/v1/files/) for files up to 100 MB, which streams in without entering the model's context. Set channelid to post it; use listchannels for channel IDs. Set alttxt for images.

post_message

Send a message to a Slack channel using Channel ID (not channel name). Set mrkdwn=false to post text literally with no Slack formatting applied.

update_message

Update an existing message in Slack. Slack rejects changing text/blocks and reply_broadcast in the same edit - send a broadcast edit with content unchanged, then edit content separately. Every edit requires text or blocks: metadata-only edits must resend the existing text.

delete_message

Delete a message from Slack

get_message_permalink

Get a permanent link to a message

get_conversation_history

Get message history from a channel by Channel ID. Filter by Unix timestamps (oldest='1640995200.123456', latest=...) or convenience params (daysago, hoursago, startdate, enddate). inclusive=True includes boundary messages. includeallmetadata=true adds each message's eventtype/eventpayload metadata (off by default).

schedule_message

Schedule a message to be sent later

delete_scheduled_message

Delete a scheduled message

add_reaction

Add an emoji reaction to a message

get_reactions

Read the emoji reactions on a message: which emoji, how many people used each, and the user IDs who did. Names come back canonicalised, so a reaction added as 'thumbsup' reads back as '+1'; match on the returned name, not the one you sent. Use listchannels for the channel ID and getconversationhistory for the message timestamp. addreaction and remove_reaction are the write counterparts.

remove_reaction

Remove an emoji reaction from a message

get_conversation_replies

Get all replies in a Slack thread. MUST be called whenever a message has replycount > 0 (from getconversationhistory, searchmessages, etc.) to get full context. Set includeallmetadata=true to include each message's eventtype/eventpayload metadata (off by default). When presenting results, show username/displayname instead of userid.

list_unread_direct_messages

Get all unread direct messages and group DMs with their message content. When presenting results to users, always display username/displayname instead of userid for better readability.

list_unread_channel_messages

Get all unread messages from channels with their message content. Uses smart prioritization to check most recently active channels first. When presenting results to users, always display username/displayname instead of userid for better readability.

list_scheduled_messages

List scheduled messages that haven't been sent yet

get_unread_messages_from_channel

Get all unread messages from a specific channel. Uses the channel's lastread timestamp to accurately identify unread messages. When presenting results to users, always display username/displayname instead of user_id for better readability.

get_unread_messages_from_user

Get all unread direct messages from a specific user. When presenting results to users, always display username/displayname instead of userid for better readability.

post_message_by_name

Send a message to a person or channel by name instead of ID. Resolves display name, real name, username, email, or channel name and sends the message. With org-wide tokens spanning multiple workspaces, optionally pass team_id to scope the lookup. If you already have a Slack user/channel ID, pass it as name to skip the search.

list_pinned_messages

List all pinned messages and items in a channel

pin_message

Pin a message to a channel

unpin_message

Remove a pinned message from a channel

search_context

Search Slack semantically, built for agents. Prefer over searchmessages for natural-language questions. Searches public channels ONLY unless channeltypes names privatechannel/im/mpim. Cannot be scoped to one channel: use searchmessages with in:#channel. Also searches files and channels via content_types. before/after are Unix seconds. Max 20 per page; paginate with cursor.

search_messages

Search Slack messages using Slack's exact search syntax. For time windows use date modifiers (after:YYYY-MM-DD, before:YYYY-MM-DD) or the convenience params (daysago, hoursago, startdate, enddate). With from:@username, never guess a username - call list_users first for the exact one. Paginated.

search_files

Search for files across Slack using keywords with enhanced timestamp handling and automatic pagination. Supports channel filtering, file type filtering, and efficient date-based searches. IMPORTANT: When using from:@username, NEVER guess usernames - use list_users tool first to find the exact username/display name.

get_user_info

Get complete user information including workspace role, permissions, and profile

get_current_user

Resolve the authenticated user ('me'/'myself') to their Slack user ID and profile. Call this first whenever a request refers to the current user (e.g. 'send me a DM', 'message myself') to get the user_id to open a DM or post to.

list_users

List users in the workspace. Returns a lean set of fields by default (id, name, realname, displayname, email, isbot, deleted); request more via the 'fields' parameter. Paginate with cursor/pageinfo. Use lookupuserbyemail or searchusers to find a specific person. For multi-workspace org-wide tokens, pass team_id (omitting it returns an error listing workspace IDs).

lookup_user_by_email

Resolve an email address to a Slack user, returning their ID and profile. Use this when you have an address; use list_users to browse or search by name. The address must match the one on the account exactly.

get_user_presence

Check whether a user is active or away. Use listusers or lookupuserbyemail to find user IDs. Querying yourself returns the extra connection and last-activity detail.

set_user_presence

Set your own presence status (auto or away)

set_dnd_duration

Turn on Do Not Disturb for your own account for a number of minutes from now. Calling this again replaces the current snooze rather than extending it. This is separate from setuserpresence, which only controls the away indicator and does not silence notifications.

set_user_profile

Set profile information for a user

get_users_conversations

Get conversations a user is a member of. For org-wide tokens spanning multiple workspaces, pass team_id; if omitted, the error lists the available workspace IDs to choose from.

set_user_status

Set your status text and emoji. statustext is required: pass an empty string to clear it. For statusemoji, an empty string clears it and null leaves the current emoji untouched.

clear_user_status

Clear the status for a user

list_usergroups

List the workspace's user groups (mentionable @handles, also called subteams). Returns each group's ID, name, handle, description, default channels and member count. Use this to find the usergroupid every other user group tool needs. Set includeusers=true to get member IDs inline. Slack returns all groups at once, so there is no pagination.

create_usergroup

Create a user group (a mentionable @handle). Name and handle must both be unique in the workspace; Slack returns namealreadyexists or handlealreadyexists otherwise, so call listusergroups first to check. The optional channels list sets the default channels new members are added to; use listchannels to find channel IDs. Add members afterwards with setusergroupusers.

update_usergroup

Update a user group's name, handle, description, or default channels. Use listusergroups for the usergroupid and listchannels for channel IDs. Only the fields you pass change. channels replaces the default-channel list applied to future members; it does not add current members to those channels. For that use inviteusergrouptochannel. To change membership use setusergroupusers.

enable_usergroup

Re-enable a disabled user group so it can be mentioned again. Use listusergroups with includedisabled=true to find disabled groups and their IDs.

disable_usergroup

Disable a user group so it can no longer be mentioned. Slack has no delete for user groups, so this is how a group is retired; its membership is preserved and enableusergroup restores it. Use listusergroups to find the usergroup_id.

list_usergroup_users

List the member user IDs of one user group. Use listusergroups to find the usergroupid, and getuserinfo or listusers to turn the returned IDs into names. Read the current members with this before calling setusergroup_users, which replaces the whole list. Slack returns all members at once, so there is no pagination.

set_usergroup_users

Replace a user group's entire membership with the given user IDs. This is an absolute set, not an add: anyone not in userids is removed. To add or remove a few people, call listusergroupusers first and pass the modified full list. Slack rejects an empty list, so use disableusergroup to retire a group. Use listusergroups for the usergroupid and lookupuserby_email for user IDs.

invite_usergroup_to_channel

Invite every current member of a user group to a channel. Slack has no single API for this, so the tool expands the group's membership, skips anyone already in the channel, and invites the rest. Use listusergroups for the usergroupid and listchannels for the channelid. This adds people now; to set the channels future members join automatically, use update_usergroup instead.

validate_credential

Validate Slack credentials. Verifies credentials during setup.

mark_channel_read

Mark a channel as read up to a given message, clearing its unread badge for the authenticated user. Pass the timestamp of the newest message you have processed; get it from getconversationhistory or the unread tools. Use listchannels to find the channelid.

open_dm

Open a direct message conversation with one user, or a group DM with several, and return the conversation ID to pass to postmessage. Safe to call repeatedly; Slack returns the existing conversation if one is already open. Use lookupuserbyemail or list_users to find user IDs.

post_ephemeral_message

Post a message only one user can see in a channel, leaving no trace for anyone else. Useful for a private nudge or confirmation without adding channel noise. Delivery is not guaranteed: the user must be active in Slack and a member of the channel. Use listchannels for the channelid and lookupuserbyemail for the userid.

get_team_info

Get the authenticated user's Slack workspace: its ID, name, slug and email domain. Use this when you need the workspace ID (teamid) that listchannels, list_users and the user group tools accept for org-wide tokens.

get_user_profile

Get a user's full Slack profile including title, phone, timezone, status and any workspace custom fields. Richer than getuserinfo, which returns only core account fields. Omit userid for the authenticated user. Use lookupuserbyemail or list_users to find IDs.

View all tools by creating a free accountSee more tools

How to set up Merge Agent Handler

In an mcp.json file, add the configuration below, and restart Cursor.

Learn more in the official documentation ↗

1{
2  "mcpServers": {
3    "agent-handler": {
4      "url": "https://ah-api-develop.merge.dev/api/v1/tool-packs/{TOOL_PACK_ID}/registered-users/{REGISTERED_USER_ID}/mcp",
5      "headers": {
6        "Authorization": "Bearer yMt*****"
7      }
8    }
9  }
10}
11
Copy Code

Open your Claude Desktop configuration file and add the server configuration below. You'll also need to restart the application for the changes to take effect.

Make sure Claude is using the Node v20+.

Learn more in the official documentation ↗

1{
2  "mcpServers": {
3    "agent-handler": {
4      "command": "npx",
5      "args": [
6        "-y",
7        "mcp-remote@latest",
8        "https://ah-api-develop.merge.dev/api/v1/tool-packs/{TOOL_PACK_ID}/registered-users/{REGISTERED_USER_ID}/mcp",
9        "--header",
10        "Authorization: Bearer ${AUTH_TOKEN}"
11      ],
12      "env": {
13        "AUTH_TOKEN": "yMt*****"
14      }
15    }
16  }
17}
Copy Code
Copied!

Open your Windsurf MCP configuration file and add the server configuration below.
Click on the refresh button in the top right of the Manage MCP server page or in the top right of the chat box in the box icon.

Learn more in the official documentation ↗

1{
2    "mcpServers": {
3      "agent-handler": {
4        "command": "npx",
5        "args": [
6          "-y",
7          "mcp-remote@latest",
8          "https://ah-api.merge.dev/api/v1/tool-packs/<tool-pack-id>/registered-users/<registered-user-id>/mcp",
9          "--header",
10          "Authorization: Bearer ${AUTH_TOKEN}"
11        ],
12        "env": {
13          "AUTH_TOKEN": "<ah-production-access-key>"
14        }
15      }
16    }
17  }
Copy Code

In Command Palette (Cmd+Shift+P on macOS, Ctrl+Shift+P on Windows), run "MCP: Open User Configuration".

You can then add the configuration below and press "start" right under servers. Enter the auth token when prompted.

Learn more in the official documentation ↗

1{
2  "inputs": [
3    {
4      "type": "promptString",
5      "id": "agent-handler-auth",
6      "description": "Agent Handler AUTH_TOKEN", // "yMt*****" when prompt
7      "password": true
8    }
9  ],
10  "servers": {
11    "agent-handler": {
12      "type": "stdio",
13      "command": "npx",
14      "args": [
15        "-y",
16        "mcp-remote@latest",
17        "https://ah-api-develop.merge.dev/api/v1/tool-packs/{TOOL_PACK_ID}/registered-users/{REGISTERED_USER_ID}/mcp",
18        "--header",
19        "Authorization: Bearer ${input:agent-handler-auth}"
20      ]
21    }
22  }
23}
Copy Code

FAQs on using Merge's Slack  MCP server

FAQs on using Merge's Slack  MCP server

How can I use the Slack MCP server?

The Slack MCP server allows AI agents to search channels and files, send and read messages, fetch user profiles, and much more.

To use Slack with Merge Agent Handler, you'd use Agent Handler’s standard flow:

  • Add Slack to a Tool Pack: Create or configure a Tool Pack and add the Slack connector with the specific tools you want to enable (e.g., list_channels, post_message)
  • Set up authentication: Choose between individual authentication (user-specific Slack credentials) and shared authentication (organization-level access)
  • Register users: Create registered users in Agent Handler who’ll interact with Slack through your agent
  • Authenticate via Merge Link: When a user first attempts a Slack tool call, Agent Handler automatically prompts them through a guided authentication flow using Merge Link
  • Make tool calls: Once you've authenticated your agent, it can execute Slack tool calls with built-in security, observability, and DLP safeguards

What are popular tools for Slack’s MCP server?

Search tools

  • Search messages and files: Filter by date, user, and type; retrieve metadata and content
  • Search users: Filter by name, partial name, email, or ID; retrieve user details and status
  • Search private and public channels: Filter by name/description; retrieve channel metadata

Messaging tools

  • Send messages: Send to any Slack conversation
  • Read channels: Retrieve full message history
  • Read threads: Retrieve entire threaded conversations

User management

  • Fetch user profiles: Retrieve full profile metadata, including custom fields

What makes Merge Agent Handler’s Slack MCP server better than alternative Slack MCP servers?

Secure authentication & credential handling

Merge Agent Handler provides built-in authentication flows, user onboarding, and dynamic authorization handling so Slack credentials are managed securely and consistently.

Granular security with data loss prevention (DLP)

The Security Gateway actively scans Slack tool inputs and outputs for sensitive information and can block, redact, or mask data. This protects against data misuse across Slack interactions.

Real-time observability with fully-searchable logs

Agent Handler logs every tool call and underlying Slack API request. These server Logs are fully searchable, allowing you to easily debug, audit, and optimize your agentic workflows with Slack.

Connector Studio for customization

Merge Agent Handler’s Slack MCP server already includes 50+ tools. But you can modify existing ones and add any with ease.

How does Merge Agent Handler manage authentication?

Merge handles all Slack credential workflows—including onboarding prompts, dynamic authorization flows, and individual vs. shared authentication configuration—through Merge Agent Handler and built-in auth logic.

For each connector in a Tool Pack, you can determine whether Slack requires individual authentication or can use shared authentication.

Can I set custom security rules for Slack tool calls?

Yes. Agent Handler supports:

  • Default DLP rules
  • Custom rules that scan Slack tool inputs and responses for sensitive data
  • Actions, including block, redact, or mask

For example, you can set rules that block post_message calls that contain credit card numbers before they're sent to Slack channels; redact social security numbers from search_messages responses; and log any get_user_profile calls that access employee phone numbers.

What are common use cases for the Slack MCP server?

  • Knowledge retrieval: An AI agent can search Slack message history, threads, and channels to answer questions, surface past decisions, and provide context
  • Automated notifications and updates: Agents can post status updates, such as daily summaries, to specific channels based on data from connected systems (e.g., issues in Jira)
  • Workflow orchestration: Agents can coordinate cross-platform actions, like creating an Asana ticket from a Slack conversation and then posting the ticket link back to the thread
  • Meeting and event coordination: Agents can parse Slack discussions to identify scheduling needs, check availability across calendar systems, and send meeting confirmations to relevant channels or users
  • Customer support triage: Agents can monitor support channels, categorize requests, and route issues to the appropriate team members

Can employees use Merge Agent Handler to connect their AI tools to Slack?

Yes, Agent Handler for Employees lets your employees connect Claude, ChatGPT, Microsoft Copilot, Cursor, and other MCP-compatible AI tools to Slack without bypassing IT governance.

Instead of setting up direct connections with personal credentials that IT can't monitor or revoke, each employee authenticates through Agent Handler and gets individual credentials tied to their identity.

IT also provisions access by role or group via SCIM. A sales rep, for example, gets Slack access to coordinate deals, Salesforce to track pipeline, and Gong to review call recordings; while an engineer gets Slack access to collaborate with the team, GitLab to manage code and issues, and Datadog to monitor service health.

Every tool call an employee's AI makes to Slack is also inspected against your DLP rules and logged to a searchable audit trail, giving security teams full visibility into what data was accessed and by whom.

Explore other MCP servers built and managed by Merge

onedrive
OneDrive
onedrive_gcc
OneDrive GCC High
onenote
OneNote
oracle_hcm
Oracle HCM
oracle_sales_cloud
Oracle Sales Cloud
oracle_scm
Oracle SCM
ordinal
Ordinal
oura
Oura
outlook
Outlook
outlook_gcc_high
Outlook GCC High
pagerduty
PagerDuty
paypal
PayPal
peec
Peec AI
pendo
Pendo
pipedrive
Pipedrive
plaud
Plaud
podium
Podium
posthog
PostHog
pubmed
PubMed
pylon
Pylon
quartr
Quartr
quickbooks_online
QuickBooks Online
ramp
Ramp
readme
ReadMe

Ready to try it out?

Whether you're an engineer experimenting with agents or a product manager looking to add tools, you can get started for free now