slack-mcp
Allows reading, searching, and downloading files across multiple Slack workspaces via user tokens, including searching messages, reading channel history and threads, resolving channels and users, downloading images and files, drafting messages, and sending messages or file attachments only with explicit confirmation.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@slack-mcpsearch my workspaces for messages about the Q3 budget"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
slack-mcp
A local, stdio MCP server that lets Claude Desktop and Claude Code read, search, and download files across multiple Slack workspaces at once — without disconnecting and reconnecting Slack's built-in connector.
Each workspace uses a user token (xoxp-) you install yourself. No
"stealth"/xoxc browser tokens — safe for institutional or SSO-managed workspaces.
Every tool takes a required workspace argument naming an entry in your config.
Tools
Tool | What it does |
| List configured workspaces (names + descriptions). Start here. |
| Report which OAuth scopes a token has and which tools work. |
| Search messages (Slack operators, e.g. |
| Channel history by ID or |
| All replies in a thread. |
| List/resolve channels. |
| Look up a user by ID or email. |
| Download a file (see below). |
| Preview a message; never sends. |
| Sends only with |
Messages include file metadata: id, name, mimetype, size, filetype.
download_file resolves the file via files.info, then fetches
url_private_download with a Bearer token:
Images → returned inline (downscaled to ≤1568px long edge to stay under size limits) and a full-resolution copy saved to
~/slack-downloads/<workspace>/<channel>/.Other files → saved to that same folder; the path is returned.
Channels, DMs, and users. The channel argument accepts a channel ID
(C…/G…), a DM/IM ID (D…), a #name, or a user ID (U…/W…). Passing a
user ID to send_message opens a direct message to that person — pass your own
user ID to DM yourself (get it from get_user(workspace, "you@example.com")).
Attachments. Give send_message a file_path to upload a local file. If text
is also present it becomes the file's comment, so one call posts the message and the
attachment together; confirm=True is still required. Uploading needs the
files:write scope (and im:write to attach to a DM addressed by a user ID) — see
the reinstall note below.
Scope awareness. The server reads each token's granted scopes from Slack's
x-oauth-scopes header (cached per workspace) and checks them before each call. If a
scope is missing it returns a clear, actionable message naming the scope and workspace
instead of a cryptic Slack missing_scope error — and only that workspace/tool is
affected; the others keep working. check_access(workspace) reports the full picture.
Related MCP server: Slack MCP Server
Prerequisites
macOS or Linux
uv(brew install uv)Python ≥ 3.11 (uv will fetch one if needed)
A member account on each Slack workspace you want to access
1. Get the code + install dependencies
git clone https://github.com/TYTYBU/slack-mcp.git ~/Projects/slack-mcp
cd ~/Projects/slack-mcp
uv sync2. Create a Slack app — once per workspace
A Slack app is tied to the workspace it's created in, so repeat this for each workspace (selecting the right one in the picker each time).
Go to https://api.slack.com/apps → Create New App → From an app manifest.
Select the target workspace in the dropdown. ← the only thing that differs between workspaces.
Paste the contents of
manifest.yamland continue.On the review screen click Create and Install, then authorize.
If the workspace requires admin approval, you'll be prompted to request it.
Left sidebar → OAuth & Permissions → copy the User OAuth Token (starts with
xoxp-).
The scopes requested (all user scopes, no bot token):
search:read, channels:history, groups:history, im:history, mpim:history,
channels:read, groups:read, im:read, mpim:read, users:read,
users:read.email, files:read, chat:write, files:write, im:write.
The last two (files:write, im:write) are only needed to upload attachments
with send_message(file_path=…). Everything else works without them.
Which token? You want the User OAuth Token (
xoxp-) only.
❌ Don't generate an app-level token (
xapp-) — that's for Socket Mode, which this server doesn't use (the manifest setssocket_mode_enabled: false).❌ Not a bot token (
xoxb-), not a browser token (xoxc-/xoxd-).On the review screen, "What it can do in Slack (15)" = the 15 scopes above; "What it can respond to in Slack (0)" = event subscriptions, which this server doesn't use —
0is correct.
search:readand reading history only cover channels your account can already see — private channels/DMs require you to be a member.
Adding scopes to an app you already installed (e.g. turning on attachments later): open the app at https://api.slack.com/apps → App Manifest, paste the updated
manifest.yaml, save, then OAuth & Permissions → Reinstall to Workspace. The new scopes attach to your existing token — with token rotation off (this manifest), thexoxp-token doesn't change, so there's usually nothing to edit inworkspaces.toml. Just runcheck_access(workspace)to confirm the scope is now present; only update the token if it actually changed. Do this per workspace. Until you reinstall,check_accessshows the scope as missing and upload calls fail with a clear message — read-only tools keep working.
3. Configure tokens
Tokens stay out of the repo in ~/.config/slack-mcp/workspaces.toml (the repo
only ships workspaces.example.toml as a template):
mkdir -p ~/.config/slack-mcp
cp workspaces.example.toml ~/.config/slack-mcp/workspaces.toml
# edit in your xoxp- tokens, then lock the file down:
chmod 600 ~/.config/slack-mcp/workspaces.toml[workspaces.myworkspace]
token = "xoxp-..."
description = "My Workspace" # optional, for your reference
[workspaces.another-lab]
token = "xoxp-..."
description = "Another Lab"The table name (
myworkspace,another-lab) is theworkspacevalue you pass to the tools — keep it short; letters, digits,_and-are allowed.One block per workspace; names must be unique.
The server warns on stderr if the file isn't
600or a token isn'txoxp-.
Config path can be overridden with the
SLACK_MCP_CONFIGenvironment variable.
4. Register with Claude
Claude Code (available in every project)
claude mcp add --scope user slack-mcp -- uv --directory ~/Projects/slack-mcp run slack-mcpVerify:
claude mcp list # should show: slack-mcp ... ✔ Connected--scope user makes it available in all your projects/sessions. A session that
was already open won't see it until you start a fresh session.
Claude Desktop (claude_desktop_config.json)
~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"slack-mcp": {
"command": "/opt/homebrew/bin/uv",
"args": ["--directory", "/Users/you/Projects/slack-mcp", "run", "slack-mcp"]
}
}
}Claude Desktop launches with a minimal
PATHand usually can't finduvby name, so use its absolute path — runwhich uv(Apple Silicon Homebrew:/opt/homebrew/bin/uv; Intel:/usr/local/bin/uv). Use an absolute--directorytoo. After editing, fully quit Claude Desktop (⌘Q) and reopen it — closing the window isn't enough.
5. Smoke test
Direct (fastest): exercises the tools against your real tokens, no Claude needed.
# list workspaces only (no network)
uv run python scripts/smoke_test.py
# list workspaces, resolve + read a channel, (optionally) download a file
uv run python scripts/smoke_test.py myworkspace '#general'
uv run python scripts/smoke_test.py myworkspace '#general' F0123ABCDExpected: your workspaces print, the channel resolves to an ID, the last few
messages print (with any file metadata), and a provided image file_id downloads
to ~/slack-downloads/myworkspace/<channel>/ and returns an inline Image.
(An empty/unused channel prints no messages — that's not an error.)
In Claude (after step 4), ask:
Using slack-mcp, list my Slack workspaces. Then read the last 10 messages in
#generalonmyworkspace, and download the most recent image there.
Troubleshooting
Symptom | Likely cause / fix |
| Wrong/expired token, or you pasted an |
| App installed before a scope was added. Re-paste the manifest / reinstall the app; the token usually stays the same (token rotation is off), so just re-run |
| Not a member, wrong name, or private. Use |
| The channel is genuinely empty (common for unused |
Tool doesn't appear in Claude | Start a new Claude Code session; for Desktop, ⌘Q and reopen. |
Desktop server fails to start | Use the absolute |
| Create |
Using alongside the official Slack connector
Both can be enabled at once — tool names don't collide, so nothing breaks. The only ambiguity is which Claude picks for a generic "check Slack" request. Name the server explicitly ("using slack-mcp, …") when you want multi-workspace access or file downloads, or disable the official connector if this one covers your needs.
Security notes
Tokens live only in
~/.config/slack-mcp/workspaces.toml(chmod 600), never in git.The server reads/writes Slack as you; it can only see what your account can.
send_messagerequires an explicitconfirm=True; by default it just echoes the resolved workspace + channel + text so you can verify before anything is posted.Downloads are written under
~/slack-downloads/(git-ignored).
Available Tools
10 toolscheck_accessA
Report the OAuth scopes a workspace's token has, and which tools it can use.
Call this to confirm the Slack app was installed with the scopes a feature
needs — e.g. files:write (and im:write for DM attachments) before using
send_message with a file_path. Scope data comes from Slack's x-oauth-scopes
header; nothing is sent to the workspace.
Args: workspace: configured workspace name.
| Name | Required | Description | Default |
|---|---|---|---|
| workspace | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. It usefully discloses that scope data comes from Slack's x-oauth-scopes header and that nothing is sent to the workspace, making clear this is a safe read-style check; it does not cover error behavior or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: purpose first, then usage example, then behavioral note, then parameter clarification. Every sentence contributes useful information without repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. The description covers purpose, usage, data source, non-mutation, and the workspace parameter, but leaves minor gaps around how to obtain a valid workspace name and what happens if scopes are missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one required workspace parameter with 0% schema description coverage. The description clarifies it as a 'configured workspace name,' which adds some meaning beyond the bare schema field, but it does not explain the expected format or point to list_workspaces for discovery.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: report the OAuth scopes a workspace token has and which tools it can use. This is a distinct diagnostic purpose, clearly separable from sibling tools like send_message, read_channel, and list_workspaces.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to call it: to confirm the Slack app was installed with scopes a feature needs, with a concrete example of checking files:write and im:write before using send_message with a file_path. It does not state when-not to use it or name alternative diagnostic tools, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
download_fileA
Download a Slack file by its file ID.
Resolves the file via files.info, then fetches url_private_download with the workspace's Bearer token. Images are returned inline (downscaled to fit size limits) AND a full-resolution copy is saved to disk. Other files are saved to ~/slack-downloads/// and the path is returned.
Args: workspace: configured workspace name. file_id: the Slack file ID (e.g. 'F0123ABCD'), as found in message file metadata.
| Name | Required | Description | Default |
|---|---|---|---|
| file_id | Yes | ||
| workspace | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the files.info resolution step, Bearer-token authentication, inline image downscaling, full-resolution disk saving, and the return path for non-image files. It stops short of covering overwrite behavior, error cases, or permission requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first sentence, followed by useful behavioral detail and then compact parameter documentation. Every section earns its place given the low schema coverage.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a side-effectful download tool with no annotations, the description covers the important behavior: authentication, image handling, disk writes, and returned paths. An output schema exists, so return values need not be fully specified, but overwrite and error behavior remain unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the Args section adds needed meaning. It clarifies file_id with an example format and source, and explains workspace as a configured workspace name, though workspace could be more precise.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: downloading a Slack file by its file ID. It is immediately distinguishable from sibling tools such as search_messages or read_channel, none of which download files.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains that file_id is the Slack file ID found in message file metadata and that workspace is a configured workspace name. This gives clear usage context, though it does not explicitly discuss when not to use the tool or name alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draft_messageA
Preview a message WITHOUT sending it. Resolves the channel and echoes the target.
Use this to review exactly where a message would go before calling send_message.
Args: workspace: configured workspace name. channel: channel ID (C…/G…/D…) or a name like '#general'. text: the message body (Slack mrkdwn).
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| channel | Yes | ||
| workspace | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the safety profile well by emphasizing 'WITHOUT sending it' and explaining that it resolves and echoes the target. It does not mention auth requirements or rate limits, but for a preview-only tool the core behavioral distinction is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the preview/no-send behavior, then gives the when-to-use guidance, then compactly documents the three arguments. There is no wasted text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple three-parameter preview tool with an output schema, the description covers purpose, safety behavior, usage, and parameter formats. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: workspace is a configured workspace name, channel accepts an ID or '#general'-style name, and text is Slack mrkdwn. This adds useful format semantics beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action and scope: preview a message without sending it, resolve the channel, and echo the target. It is clearly distinguishable from send_message and other siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to use this tool to review where a message would go before calling send_message. This names both the triggering context and the alternative tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_userA
Look up a user by Slack ID (U…) or email address.
Args: workspace: configured workspace name. user: a user ID (U…/W…) or an email address.
| Name | Required | Description | Default |
|---|---|---|---|
| user | Yes | ||
| workspace | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. 'Look up' implies a read-only retrieval, but the description does not state permissions, error behavior for unknown users or emails, ambiguity handling, or rate limits, so it gives only minimum viable context for a simple read.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is front-loaded with the lookup purpose and followed by a short Args block. It is compact, has no filler, and the identifier-format hints earn their place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple two-parameter lookup and an output schema exists, so return values do not need explanation. The description covers both inputs and their formats, but it leaves a small gap by not explaining how to obtain valid workspace names or when this tool should be chosen over related alternatives.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate; it explains both required parameters, including that workspace is a configured workspace name and user is a U…/W… ID or email address. It could be slightly more precise about where workspace names come from, but it substantially covers the accepted input formats.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Look up a user' by Slack ID or email. It is clearly a single-user lookup, but it does not explicitly differentiate itself from siblings such as check_access or list_workspaces.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use or when-not guidance and names no alternatives. An agent can infer that it retrieves a user, but it must guess when this is preferable to other user-related or access-checking tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_channelsA
List channels in a workspace, optionally filtered by a name substring.
Args: workspace: configured workspace name. name_filter: case-insensitive substring to match channel names (empty = all). types: comma-separated: public_channel, private_channel, mpim, im. limit: max channels to return after filtering (1-1000).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| types | No | public_channel,private_channel | |
| workspace | Yes | ||
| name_filter | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. 'List' strongly implies a read-only operation and the filtering/limit semantics are disclosed, but permission requirements, rate limits, and pagination behavior are not addressed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and then gives compact parameter notes. Every sentence and argument line adds useful information without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described. The description covers the purpose and all four parameters, but leaves some operational context unstated, such as permissions or what happens when more channels match than the limit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It usefully defines all four parameters: workspace, name_filter case-insensitive substring semantics, allowed types values, and the 1-1000 limit range, though it omits the schema defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: list channels in a workspace, with optional name filtering. Clear enough to distinguish from list_workspaces and read_channel, though it does not explicitly route agents away from those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool by explaining optional filtering and type selection, but it gives no explicit when-not guidance or comparison to alternatives like read_channel or search_messages.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_workspacesA
List the Slack workspaces configured in workspaces.toml (names + descriptions).
Call this first to discover the workspace values accepted by every other tool.
Tokens are never returned.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, but the description discloses the backing store (workspaces.toml), the payload shape (names + descriptions), and an important security trait ("Tokens are never returned"). It stops short of explicitly stating that the call is read-only or has no side effects, but 'list' plus the omission of tokens makes the safety profile clear enough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, with purpose and the return fields front-loaded and the routing guidance immediately after. No filler, and every sentence carries information the schema does not.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and a zero-param tool has no parameter gaps to fill. The description covers purpose, discovery role, and a security caveat, which is everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The description correctly adds that the output contains names and descriptions rather than any parameter detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("List the Slack workspaces") plus the source and the returned fields (names + descriptions). This is clearly distinguishable from every sibling, all of which operate inside a single workspace.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"Call this first to discover the `workspace` values accepted by every other tool" gives an explicit when-to-use and explains the ordering relationship to all sibling tools. It also implicitly excludes other uses, so the agent does not have to infer routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_channelA
Read recent message history from a channel (by ID or #name).
Args: workspace: configured workspace name. channel: channel ID (C…/G…/D…) or a name like '#general'. limit: max messages, newest first (1-200). oldest: optional lower-bound Slack ts (inclusive). latest: optional upper-bound Slack ts.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| latest | No | ||
| oldest | No | ||
| channel | Yes | ||
| workspace | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the disclosure burden. It usefully states newest-first ordering, the 1-200 limit range, and that oldest is inclusive — real behavioral data — but says nothing about pagination/cursors, required permissions, or whether the bot must be a channel member, which are critical for a channel-reading tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One-line purpose statement followed by a compact Args list — front-loaded and free of filler. The structure costs little and every line carries parameter information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Return values needn't be explained since an output schema exists, and all params are covered. Missing pieces are routing guidance against the three related sibling tools and any note on pagination, which matter for a 5-parameter history-read tool in this toolset.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description fully documents all five parameters: channel ID formats (C…/G…/D…) vs '#name', limit as max messages newest-first, and Slack ts bounds with inclusivity. The only minor gap is not restating the limit default, which the schema already supplies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb+resource ('Read recent message history from a channel') with an added acceptance format for the channel identifier. However, it never distinguishes itself from sibling search_messages (which one would use for keyword queries) or read_thread (for reply threads), so an agent must infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'recent message history' plus the newest-first ordering, which suggests recency browsing rather than search. But there is no explicit when-to-use or when-not guidance and no mention of search_messages or read_thread as alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_threadB
Read all replies in a thread.
Args: workspace: configured workspace name. channel: channel ID (C…/G…/D…) or a name like '#general'. thread_ts: the ts of the thread's parent message. limit: max messages (1-1000).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| channel | Yes | ||
| thread_ts | Yes | ||
| workspace | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It says it reads replies and gives a limit range, but does not disclose ordering, pagination behavior, permission requirements, or error behavior for invalid thread_ts.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loads the core purpose before the argument list. The Args format is efficient, though it reads more like a docstring than agent-facing guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. However, for a read tool with no annotations, the description lacks usage criteria and behavioral details such as reply ordering or pagination beyond the limit parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: it explains workspace as a configured name, channel formats (C/G/D IDs or '#general'), thread_ts as the parent message timestamp, and limit bounds (1-1000). Only the limit default of 200 is omitted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb and resource: read all replies in a thread. It distinguishes itself implicitly from read_channel, but does not explicitly differentiate from search_messages or explain when a thread read is preferable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use read_thread versus siblings like read_channel or search_messages. The description only lists arguments, leaving usage conditions entirely implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_messagesA
Search messages across a workspace (Slack search operators supported).
Args: workspace: configured workspace name. query: Slack search query, e.g. 'in:#general from:@alice variant calling'. count: max matches to return (1-100). sort: 'score' (relevance) or 'timestamp' (newest first).
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | score | |
| count | No | ||
| query | Yes | ||
| workspace | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It does disclose useful behavior: Slack search operator support, the 1-100 count bound, and what the two sort modes mean. It omits the search's coverage (DM/private channel scope), permission requirements, and pagination/result-cap behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the one-line purpose, then a compact args list that earns its place because the schema has zero descriptions. No filler sentences or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value explanation is not required, and parameters are fully covered. What's missing for a search tool with no annotations is scope and access context — whether results span DMs/private channels and whether the workspace must be pre-authorized via check_access.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so all meaning must come from the description — and it documents all four parameters: workspace as a configured name, query with a concrete operator example, count as a 1-100 match cap, and sort's two values explained semantically ('score' = relevance, 'timestamp' = newest first). That is meaningfully more than the bare schema titles.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Search messages") plus the scope ("across a workspace"), and notes Slack search operators are supported. That distinguishes it from the targeted-read siblings like read_channel and read_thread, though it never names them explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the query example ('in:#general from:@alice variant calling') signals this is the tool for filtered/keyword retrieval across a workspace. There is no explicit guidance on when to prefer this over read_channel, read_thread, or list_channels, and no prerequisites are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_messageA
Send a message to a channel — ONLY when confirm=True.
With confirm=False (the default) nothing is sent: the tool echoes back the workspace, resolved channel, text, and any attachment so they can be verified first. Call again with confirm=True to actually post.
Pass file_path to upload a local file as an attachment. When both text and
file_path are given, the text becomes the file's comment so one call posts
both together. Uploading requires the files:write scope (and im:write to
attach to a DM via a user ID); check_access reports whether the token has them.
Args: workspace: configured workspace name. channel: channel ID (C…/G…/D…) or a name like '#general', or a user ID (U…/W…) to DM that person. text: the message body (Slack mrkdwn). May be empty when file_path is set. confirm: must be True to actually send; False returns a preview only. thread_ts: optional parent ts to reply in a thread. file_path: optional path to a local file to upload as an attachment. file_title: optional display title for the attachment (defaults to the filename).
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | ||
| channel | Yes | ||
| confirm | No | ||
| file_path | No | ||
| thread_ts | No | ||
| workspace | Yes | ||
| file_title | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so: it discloses that confirm=False sends nothing and instead echoes back workspace, channel, text and attachments, explains the combined text+file comment behavior, and names the required OAuth scopes (files:write, im:write) with a pointer to check_access. That is unusually rich behavioral context for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The safety-critical constraint is front-loaded in the first line and the prose above the Args block adds real information. The Args list is long but earns its place given zero schema coverage; only minor redundancy remains between the prose and the parameter list.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be spelled out, and the description still explains what the preview payload contains. Combined with scope requirements, attachment semantics and threading, an agent has everything needed to call it correctly on the first try.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 7 parameters, so the description must compensate and does — it documents accepted channel formats (C…/G…/D…, '#general', U…/W… for DMs), notes text is Slack mrkdwn and may be empty when file_path is set, and clarifies thread_ts, file_path and file_title defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Send a message to a channel') plus an immediate hard gate ('ONLY when confirm=True'). The confirm/preview mechanism makes it distinguishable from sibling draft_message without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit two-step protocol: call with confirm=False to preview, then repeat with confirm=True to post, and it states the preconditions for attachments. It does not, however, contrast itself with the sibling draft_message, which is the nearest alternative for composing without sending.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
10 tool updates
v0.1.0- First observed
check_access - First observed
download_file - First observed
draft_message - First observed
get_user - First observed
list_channels - First observed
list_workspaces - First observed
read_channel - First observed
read_thread - First observed
search_messages - First observed
send_message
TDQS
Scored across 10 tools
Most tools target clearly distinct operations (search vs read vs list vs get vs download), and the workspace/channel argument patterns make intent clear. The one real ambiguity is draft_message versus send_message with confirm=False, which both produce a non-sending preview of the same message — an agent could reasonably pick either. read_channel and read_thread are close but adequately differentiated by thread_ts.
Every tool follows a clean verb_noun snake_case pattern: list_workspaces, search_messages, read_channel, read_thread, list_channels, get_user, download_file, draft_message, send_message. The single-word-ish check_access still fits the verb_noun shape. No camelCase or stylistic mixing.
Ten tools is well within the sweet spot and each maps to a concrete Slack workflow: discovery, access check, search, read, user lookup, file download, drafting, and sending. Nothing feels redundant or padded.
Read/search/send workflows are solid, but the surface is read-plus-post only: there is no update/edit message, delete message, or reaction tool, so an agent cannot correct or acknowledge messages. User discovery is also a gap — get_user requires an ID or email but there is no list_users, forcing agents to infer users from message metadata.
Maintenance
Related MCP Connectors
Enable interaction with Slack workspaces. Supports subscribing to Slack events through Resources.
Catch up on Slack without reading it. Unreads, threads, search. Browser-session or hosted OAuth.
Workspace messaging: conversations, contacts, agents, and connected lines through scoped OAuth.
Appreciate teammates, celebrate milestones, and run workspace ops from MCP clients via OAuth.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables interaction with Slack workspaces as a user, supporting channel listing, message posting, threading, reactions, and user management via the Slack API.811MIT
- AlicenseBqualityDmaintenanceEnables interaction with Slack workspaces through comprehensive channel management, messaging, user management, file uploads, and Block Kit formatting. Features secure credential storage via macOS Keychain and supports all major Slack operations including reactions and workspace information.263MIT
- AlicenseAqualityDmaintenanceIntegrates AI assistants with Slack workspaces using OAuth 2.0 authenticated user tokens for secure, multi-functional interaction. It enables comprehensive operations including channel management, message searching, file handling, and reaction management through natural language.20169 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants like Cursor and Claude Desktop to interact with Slack workspaces, allowing message sending, channel reading, user management, and file operations through natural language.MIT