Skip to main content
Glama

slack-bot-mcp

An MCP server that lets an AI agent work in Slack as a bot. The agent can send DMs and channel messages, find members by email or name, read history and threads, react to messages, and wait for replies.

It is built on Chat SDK (chat + @chat-adapter/slack). By default it receives events over Socket Mode, so it needs no public URL. Set SLACK_MODE=webhook to receive events through a Request URL instead.

Quick start

SLACK_BOT_TOKEN=xoxb-... SLACK_APP_TOKEN=xapp-... npx -y @liusdev/slack-bot-mcp@latest
# or
SLACK_BOT_TOKEN=xoxb-... SLACK_APP_TOKEN=xapp-... pnpm dlx @liusdev/slack-bot-mcp@latest

Check the installed version with npx -y @liusdev/slack-bot-mcp@latest -v (or --version); --help lists usage. The whoami tool also reports server_version.

Claude Code

claude mcp add slack-bot \
  -e SLACK_BOT_TOKEN=xoxb-... \
  -e SLACK_APP_TOKEN=xapp-... \
  -- npx -y @liusdev/slack-bot-mcp@latest

Claude Desktop, Cursor and other MCP clients

{
  "mcpServers": {
    "slack-bot": {
      "command": "npx",
      "args": ["-y", "@liusdev/slack-bot-mcp@latest"],
      "env": {
        "SLACK_BOT_TOKEN": "xoxb-...",
        "SLACK_APP_TOKEN": "xapp-..."
      }
    }
  }
}

Related MCP server: Slack MCP Server

Create the Slack app

A Slack app manifest is a YAML file that describes an app's configuration. The manifest below sets up everything this server needs in one step:

  • a bot user that people can DM (the App Home Messages tab)

  • the bot token scopes the tools use

  • the app_mention and message.im events, which feed get_inbox

  • Socket Mode, so no public URL is needed

  1. Go to api.slack.com/apps, click Create New App, choose From an app manifest, pick your workspace, and paste the manifest below.

  2. Under Basic Information → App-Level Tokens, generate a token with the connections:write scope. This is SLACK_APP_TOKEN (xapp-…).

  3. Under OAuth & Permissions, install the app to the workspace and copy the Bot User OAuth Token. This is SLACK_BOT_TOKEN (xoxb-…).

  4. Invite the bot to any private channel it should read or post in: /invite @AI Assistant.

display_information:
  name: AI Assistant
features:
  app_home:
    messages_tab_enabled: true
    messages_tab_read_only_enabled: false
  bot_user:
    display_name: AI Assistant
    always_online: true
oauth_config:
  scopes:
    bot:
      - app_mentions:read
      - channels:history
      - channels:read
      - chat:write
      - chat:write.public
      - groups:history
      - groups:read
      - im:history
      - im:read
      - im:write
      - mpim:history
      - mpim:read
      - reactions:read
      - reactions:write
      - users:read
      - users:read.email
settings:
  event_subscriptions:
    bot_events:
      - app_mention
      - message.im
  interactivity:
    is_enabled: true
  org_deploy_enabled: false
  socket_mode_enabled: true
  token_rotation_enabled: false

Use an existing app

To reuse an app you already created, open it at api.slack.com/apps and select App Manifest in the sidebar. Merge in the scopes, events, socket_mode_enabled and app_home settings above. Do not paste over the whole manifest: that replaces the app's current configuration and can drop scopes, events or Request URLs it already uses. Save, then click Reinstall to Workspace under OAuth & Permissions so new scopes take effect. If the app has no app-level token yet, create one as in step 2.

You can drop scopes you do not need. Tools that lack a scope return an error that names the missing scope. chat:write.public lets the bot post in public channels without being invited first.

Tools

Tool

What it does

Bot scopes

whoami

Bot identity, connection status, granted scopes, and the scopes each tool is missing

none

users_search

Find members by email, name, display name, @handle or job title

users:read, users:read.email

user_info

Profile of one user (ID, email or @handle)

users:read

channels_list

List channels, filtered by type, name or membership

channels:read, groups:read, im:read, mpim:read

send_message

Post to a channel, a thread, or a user's DM: Markdown or plain text, an optional context line, or custom Block Kit. expect_reply: true saves the message as a pending question

chat:write, im:write

edit_message

Replace the content of a message the bot posted (same formatting options as send_message)

chat:write

delete_message

Delete a message the bot posted (bots cannot delete other people's messages)

chat:write

conversations_history

Read recent messages in a channel or DM

channels:history, groups:history, im:history, mpim:history

conversations_replies

Read a thread

same as above

reactions_add, reactions_remove

Add or remove an emoji reaction

reactions:write

wait_for_reply

Wait briefly (default 45 s) for a reply; saves the question as pending on timeout

history scopes

check_replies

Check all pending questions, or one conversation, once and return any answers

history scopes

get_inbox

DMs and @mentions the bot received while the server was running

app_mention and message.im events

Wherever a tool takes a channel or user, you can pass:

  • a channel ID (C…), #channel-name, or Slack markup (<#C…>)

  • a user ID (U…), @handle, email, or display name

For a user, the tool opens a DM with them. If a name matches several users, the tool returns the candidates so the agent can ask which one you mean.

Bot tokens cannot call Slack's search.messages API, so this server has no message search.

Message formatting

send_message has three levels of formatting:

  • text alone: standard Markdown (bold, lists, code, links, quotes), or plain text with format: "plain".

  • context: small grey details under a divider at the bottom of the message, such as the Jira ticket or comment a question refers to. Each item is { label, value, url? } or a pre-formatted mrkdwn string:

    {
      "target": "quy@example.com",
      "text": "Does `VECURA_CONTENT_BACKEND_URL` have a public staging address?",
      "context": [
        { "label": "Jira", "value": "VEC-123", "url": "https://example.atlassian.net/browse/VEC-123" },
        { "label": "Comment", "value": "#4521", "url": "https://example.atlassian.net/browse/VEC-123?focusedCommentId=4521" }
      ]
    }

    This renders as: the question, a divider, then Jira: VEC-123 · Comment: #4521 in small text.

  • blocks: any Block Kit layout (header, section fields, images and so on). text then becomes the notification fallback, and context is still appended. Try layouts in the Block Kit Builder. Interactive elements such as buttons are not supported, because the server does not handle clicks. If Slack rejects the blocks, the error lists the invalid fields.

Errors

Every tool returns failures as an MCP tool error (isError: true). The text says what failed, why, and what to do. For example:

Permission denied: the Slack bot is missing the OAuth scope `reactions:write` needed to add the :eyes: reaction.
Scopes the bot currently has: chat:write,users:read.
A Slack workspace admin must add it under api.slack.com/apps → your app → OAuth & Permissions → Bot Token Scopes, then reinstall the app to the workspace.

The server also explains common Slack errors: not_in_channel, channel_not_found, users_not_found, is_archived, invalid_auth, and rate limits with the retry delay. Without users:read.email, Slack silently leaves emails out of user lists. In that case, email lookups report the missing scope instead of "user not found".

Configuration

Variable

Required

Default

Description

SLACK_BOT_TOKEN

yes

Bot token, xoxb-…

SLACK_APP_TOKEN

socket mode

App-level token with connections:write, xapp-…

SLACK_MODE

no

socket

socket or webhook

SLACK_SIGNING_SECRET

webhook mode

Signing secret from Basic Information

SLACK_MCP_HTTP_PORT

no

3000

Port for incoming Slack events in webhook mode

SLACK_MCP_HTTP_PATH

no

/slack/events

Path for incoming Slack events in webhook mode

SLACK_MCP_ALLOWED_CHANNELS

no

any

Comma-separated targets send_message may post to: channel IDs, #names, user IDs or emails

SLACK_MCP_LOG_LEVEL

no

info

debug, info, warn, error or silent. Logs go to stderr

SLACK_MCP_STATE_DIR

no

~/.slack-bot-mcp

Where pending questions are stored, one JSON file per workspace

SLACK_MCP_PENDING_TTL_DAYS

no

7

Pending questions older than this are dropped

Webhook mode

Set SLACK_MODE=webhook and SLACK_SIGNING_SECRET. The server then listens on SLACK_MCP_HTTP_PORT. In the app settings, turn off Socket Mode and set the Request URL under Event Subscriptions and Interactivity to https://<your-host>/slack/events.

Waiting for replies

People may answer in a minute or the next morning. Polling inside one agent turn is cheap for the server but not for the agent: every wait_for_reply call is a model turn that re-reads the whole conversation. So the server keeps waits short and remembers what it is waiting for:

  1. The agent sends the question with send_message and expect_reply: true. The server saves it as a pending question in SLACK_MCP_STATE_DIR, which outlives the MCP process and the agent session.

  2. If a quick answer is likely, the agent calls wait_for_reply once or twice. After two timeouts the tool tells the agent to stop and report back to the user.

  3. Later, check_replies with no arguments checks every pending question in one call, returns the answers, and removes answered questions from the list.

Something has to run the agent again for step 3; the server cannot wake an agent. Slack's official MCP server has no wait tool either, so agents using it re-read threads the same way. Options:

  • The user asks: "check Slack replies".

  • A loop in an open session, for example /loop 30m check Slack replies and continue in Claude Code.

  • A scheduled run, for example a cron job at 8:00 running claude -p "check Slack replies and continue".

Each check is one short turn, instead of one turn every minute.

To let a single wait_for_reply call block longer, raise your client's tool timeout and pass a larger timeout_seconds (up to 300). In Claude Code, set MCP_TOOL_TIMEOUT in milliseconds, for example MCP_TOOL_TIMEOUT=320000.

Running several instances

Every tool except get_inbox calls the Slack Web API directly with the bot token. Those tools give the same results no matter how many agents run this server at once. Keep in mind:

  • Events are split. Slack delivers each event to only one of an app's open Socket Mode connections. Each instance's get_inbox therefore sees only part of the incoming messages. wait_for_reply and check_replies read the Web API, so they are not affected.

  • Connection limit. Slack allows at most 10 Socket Mode connections per app. Instances beyond that cannot open a socket, so their get_inbox reports the connection error. Their other tools still work.

  • Rate limits are shared. All instances spend the same token's Slack rate limits. A tool that hits a limit fails at once and says how long to wait.

Development

pnpm install
pnpm dev          # rebuild on change
pnpm test
pnpm typecheck
pnpm build
npx @modelcontextprotocol/inspector node dist/index.js   # try the tools interactively

Releasing

Pushing a v* tag publishes to npm through GitHub Actions (.github/workflows/publish.yml). The workflow authenticates with npm Trusted Publishing, so the repository stores no npm token.

npm version patch        # or minor / major: bumps package.json, commits, and tags
git push --follow-tags   # the tag triggers the publish workflow

The workflow fails if the tag does not match the package.json version.

Available Tools

14 tools
channels_listList Slack channelsA
Read-only

List channels the bot can see, optionally filtered by name. Private channels and DMs appear only if the bot is a member. is_member: false means the bot must be invited before it can post there (unless it has chat:write.public).

NameRequiredDescriptionDefault
limitNoMaximum number of channels to return
queryNoCase-insensitive filter on channel name, topic or purpose
typesNoConversation types to include
member_onlyNoOnly channels the bot is a member of

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds genuinely useful behavioral context beyond that: membership-gated visibility and the chat:write.public exception for posting. It doesn't describe pagination or return shape, but with annotations present a 4 fits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, no waste, with the core scope front-loaded before the visibility caveats.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, but the description covers the key semantic an agent needs: which channels appear and what membership means. It could say more about returned fields or pagination, but it is adequate for a filtered list tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema documents limit, query, types, and member_only. The description adds meaning around membership gating but references 'is_member', which is not a parameter name (the parameter is member_only) – this could confuse an agent mapping it to input. Baseline 3 for full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Uses a specific verb (List) and resource (channels) with an explicit scope: 'channels the bot can see'. The optional name filter is stated. It doesn't explicitly differentiate itself from siblings like conversations_history, but the resource is distinct enough to route correctly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context on visibility: private channels and DMs appear only if the bot is a member, and explains the is_member=false implication. It stops short of naming alternatives or stating exclusions ('use X instead'), which keeps it from a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_repliesCheck for Slack repliesA

Check once, without waiting, whether people answered the bot. With no arguments, checks every pending question (saved by send_message with expect_reply, or by wait_for_reply on timeout), including ones from earlier sessions; answered questions are removed from the pending list. With channel and since_ts, checks one conversation instead. Cheap to call, so use it for long waits: end your turn, then call it later from a scheduled or looped run.

NameRequiredDescriptionDefault
channelNoCheck only this conversation (ID, #name, or user). Requires since_ts. Omit to check all pending questions.
dismissNoPending question IDs to drop without an answer (e.g. no longer needed)
since_tsNoWith channel: only messages after this ts
thread_tsNoWith channel: thread to check; new top-level messages in the channel are checked too

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, it discloses that answered questions are removed from the pending list and that earlier-session pending questions are included. It does not describe authorization needs or rate limits, but the key mutation of pending state is explained.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core behavior, then covers mode selection and usage advice without filler. The parenthetical about pending-question sources earns its place by explaining the tool's state model.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

It covers behavior, modes, side effects, and long-wait workflow, which is strong for a tool with four optional parameters and full schema coverage. Because there is no output schema and the description does not explain the return shape, a minor completeness gap remains.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents channel, since_ts, thread_ts, and dismiss. The description adds mode-level context for no-argument versus channel/since_ts usage, but it does not add parameter details beyond the schema, making 3 the appropriate baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: checking once, without waiting, whether people answered the bot. It also distinguishes the all-pending mode from the single-conversation mode, so an agent can identify the tool's role immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear usage context: no arguments checks all pending questions, channel plus since_ts checks one conversation, and it is cheap to call for long waits via scheduled or looped runs. It does not explicitly route the agent to wait_for_reply as the blocking alternative, so it falls short of full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

conversations_historyRead Slack channel historyA
Read-only

Read recent messages from a channel or DM, newest first. channel accepts a channel ID, #channel-name, or a user (ID, @handle, email) for the bot's DM with them. Use cursor from the previous response to page further back. Thread replies are not included; use conversations_replies for those.

NameRequiredDescriptionDefault
limitNoNumber of messages to return
cursorNoPagination cursor from a previous call
latestNoOnly messages before this time (same formats as oldest)
oldestNoOnly messages after this time: Slack ts, ISO date, or relative (30m, 6h, 2d, 1w)
channelYesChannel ID, #channel-name, or user (ID, @handle, email) for a DM
include_activityNoInclude join/leave/topic change messages

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, so safety is covered; the description adds real behavioral context – result ordering (newest first), pagination direction, and the fact that thread replies are omitted. It stops short of mentioning rate limits or any auth scope quirks, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with what it returns and the ordering, then paging, then the exclusion. Every clause carries information an agent would otherwise have to guess.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering the read-only/open-world profile and the schema covering all six parameters, this description covers what remains: result scope, ordering, pagination mechanics, and thread exclusion. No output schema exists, so no return-shape explanation is owed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so every parameter including limit, latest, oldest, and include_activity is already documented. The description only reinforces `channel` (repeating the schema's own wording) and adds a bit on `cursor`; it does not explain the relative/ISO time formats that make oldest/latest non-obvious.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read recent messages from a channel or DM'), plus ordering ('newest first') and the DM/channel scope. It explicitly sets itself apart from conversations_replies, so an agent can distinguish it 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives both the paging procedure ('use `cursor` from the previous response to page further back') and the exclusion rule with a named alternative ('Thread replies are not included; use conversations_replies for those'). The condition that selects the sibling is explicit, not inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

conversations_repliesRead a Slack threadA
Read-only

Read the replies in a thread, oldest first, including the parent message. thread_ts is the ts of the parent message (or of any message in the thread).

NameRequiredDescriptionDefault
limitNoNumber of messages to return
cursorNoPagination cursor from a previous call
channelYesChannel ID, #channel-name, or user (ID, @handle, email) for a DM
thread_tsYesTimestamp of the thread's parent message

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered; the description then adds real behavioral detail the annotations don't: results are ordered oldest first and the parent message is included in the result set. It stays silent on pagination behavior (limit default 50, max 200) and on whether you must page through large threads, which is the remaining gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero waste, with the ordering-and-parent guarantee front-loaded before the parameter note. Nothing is repeated from the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter read tool with full schema coverage and covered safety annotations, this is close to complete: result ordering and parent inclusion are stated. The remaining omission is pagination guidance — with limit capped at 200 and a cursor parameter, an agent would benefit from knowing when to expect truncation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaning the schema does not: thread_ts accepts the ts of the parent message *or of any message in the thread*, which actually extends the schema's narrower 'parent message' wording. That resolves a real ambiguity in how to call it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Read') and resource ('replies in a thread') plus the ordering and the inclusion of the parent message, which is genuinely distinguishing information. It does not, however, contrast itself with the sibling check_replies or conversations_history, so an agent must infer which of the three thread-reading tools applies.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the resource name — you call it when you want a thread's contents — but there is no explicit 'use this instead of X when Y' guidance despite check_replies and conversations_history being obvious overlaps. The thread_ts clarification hints at the calling context but doesn't set boundaries.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_messageDelete a Slack messageA
DestructiveIdempotent

Delete a message the bot posted, identified by channel and ts (as returned by send_message). Slack only lets a bot delete its own messages. Deleting the parent of a thread leaves its replies in place. This cannot be undone, so confirm with the user unless they asked for it.

NameRequiredDescriptionDefault
tsYesTimestamp of the bot's message to delete
channelYesChannel ID, #channel-name, or user (ID, @handle, email) for a DM

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the destructive/idempotent annotations by disclosing the permission constraint (bot can only delete its own messages), the thread consequence (deleting a parent leaves replies), and irreversibility. These are exactly the behaviors an agent needs before invoking a destructive call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, each carrying a distinct and necessary fact: identity, permission scope, thread side effect, irreversibility/confirmation. The destructive warning is placed at the end where it lands before invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter destructive tool with no output schema, the definition covers identity, preconditions, side effects, and safety. The only minor gap is what the agent should expect on success or failure (e.g., error when the message isn't the bot's own).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are already documented; the description adds provenance for ts ('as returned by send_message'), which helps the agent source the value correctly. No additional format or validation detail beyond that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (delete) and resource (a message the bot posted), plus the identifying keys (channel, ts). It also implicitly distinguishes itself from siblings like send_message and edit_message by scoping the operation to the bot's own messages.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Establishes clear preconditions: the message must be one the bot posted, and Slack enforces that constraint. It also gives a confirmation directive ('confirm with the user unless they asked for it'), though it never names an alternative sibling (e.g., edit_message to blank content) for cases where deletion isn't possible.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

edit_messageEdit a Slack messageA
DestructiveIdempotent

Replace the content of a message the bot posted, identified by channel and ts (as returned by send_message). Slack only lets a bot edit its own messages. The new text, context and blocks fully replace the old content, so resend any context you want to keep.

NameRequiredDescriptionDefault
tsYesTimestamp of the bot's message to edit
textYesNew message content. When `blocks` is set, this is only the notification/fallback text
blocksNoCustom Slack Block Kit blocks (https://docs.slack.dev/reference/block-kit/blocks), e.g. header, section with fields, image, markdown, context, divider. Replaces the rendered `text`; `context` is still appended. Do not use interactive elements (buttons, menus): this server does not handle clicks.
formatNomarkdown: standard Markdown rendered by Slack. plain: sent as-ismarkdown
channelYesChannel ID, #channel-name, or user (ID, @handle, email) for a DM
contextNoSmall grey details shown under a divider at the bottom of the message, joined with ·. Example: [{label:"Jira", value:"VEC-123", url:"https://…"}, {label:"Comment", value:"#4521", url:"https://…"}]

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes beyond the annotations' destructiveHint=true by explaining exactly what is destroyed: text, context and blocks fully replace the old content, so callers must resend anything they want kept. It also discloses the Slack-side permission restriction that the bot can only edit its own messages — an auth constraint neither the schema nor annotations carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the action and identity, then the permission caveat, then the replacement warning. No filler and nothing repeated from the schema verbatim.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no output schema, it covers the essentials: what it mutates, what is lost, and who is allowed to call it. Failure modes (invalid ts, editing another user's message) and the resulting edit timestamp are not addressed, though those are secondary.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is already 100%, so baseline is 3; the description adds cross-parameter semantics the schema only partly implies — that text, context and blocks jointly overwrite rather than merge, and that ts must originate from send_message. It does not touch the format parameter, which the schema already covers.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Replace the content of a message') and pins down the identifier ('channel and ts, as returned by send_message'). That naming distinguishes it cleanly from send_message, delete_message and reactions_* siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear precondition — the bot may only edit messages it posted — and tells the agent where the ts comes from ('as returned by send_message'). It does not explicitly contrast with delete_message or with sending a fresh message, but the context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_inboxGet messages sent to the botA

Return direct messages and @mentions the bot received while this MCP server was running. Only covers events delivered to this process: messages sent before it started, or delivered to another running instance of the same Slack app, are not here. To reliably fetch replies in a known channel or thread, use wait_for_reply or conversations_history.

NameRequiredDescriptionDefault
limitNoMaximum number of messages (most recent kept)
sinceNoOnly messages after this time: Slack ts, ISO date, or relative (30m, 2h)
channelNoOnly messages from this channel or DM (ID, #name, or user)
mark_readNoMark returned messages as read
unread_onlyNoOnly messages not returned by a previous get_inbox call

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavior the annotations don't convey: the inbox is process-local and volatile, so history is incomplete by design. It does not explain why readOnlyHint=false, namely that mark_read defaults to true and mutates read state — that justification lives only in the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: capability first, caveat second, alternative routing third. Every sentence carries distinct information and the most decision-relevant constraint is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the critical risk for this tool — that results are an incomplete, process-scoped window — which is what an agent most needs to avoid misinterpreting an empty inbox. With no output schema, the return shape is only loosely implied, but message lists are conventional enough that this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters (limit, since, channel, mark_read, unread_only) are already documented with formats and defaults. The description adds no parameter-level detail, which meets the baseline for fully covered schemas but no more.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Return direct messages and @mentions the bot received') plus the precise scope ('while this MCP server was running'). It also names the sibling tools that serve related needs, so an agent can distinguish it from conversations_history and wait_for_reply without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states the exclusion case (messages before startup or delivered to another instance are absent) and routes the agent to wait_for_reply or conversations_history for reliable replies. It does not mention check_replies, a sibling that sounds closely related, leaving a small gap in the alternative-selection guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reactions_addAdd a Slack reactionB
Idempotent

Add an emoji reaction to a message as the bot.

NameRequiredDescriptionDefault
tsYesTimestamp of the message
emojiYesEmoji name without colons, e.g. thumbsup, eyes, white_check_mark
channelYesChannel ID, #channel-name, or user (ID, @handle, email) for a DM

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare idempotentHint=true, destructiveHint=false and openWorldHint=true, so safety and repeat-call behavior are covered. The description adds one genuinely useful behavioral fact beyond the annotations: the reaction is attributed to the bot, not the calling user. It says nothing about failure modes 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence with the effect front-loaded and no filler. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-param, fully documented, annotation-backed tool, the description is nearly sufficient; the actor disclosure closes the main ambiguity. The remaining gap is prerequisites and error behavior, which matters less for an idempotent non-destructive call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, including a concrete emoji naming example ('thumbsup, eyes') and channel formats, so the schema carries the parameter semantics. The description adds nothing on top, which is the expected baseline here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb + resource ('Add an emoji reaction to a message') and it adds the actor identity ('as the bot'). It is clearly distinct from reactions_remove by name and verb direction, though it never names the sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no prerequisites (bot must be a member of the channel, reactions:write scope), and no pointer to reactions_remove for the inverse operation. Usage is only inferable from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reactions_removeRemove a Slack reactionA
DestructiveIdempotent

Remove an emoji reaction the bot previously added to a message.

NameRequiredDescriptionDefault
tsYesTimestamp of the message
emojiYesEmoji name without colons, e.g. thumbsup, eyes, white_check_mark
channelYesChannel ID, #channel-name, or user (ID, @handle, email) for a DM

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true and openWorldHint=true, so the safety profile is covered structurally. The description adds one genuinely useful behavioral constraint beyond them — that only the bot's own reactions qualify — but says nothing about what happens on failure (e.g., reaction absent) or whether removal triggers notifications.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the verb and resource, with zero filler. Nothing could be cut without losing the scope constraint.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple three-parameter mutation with complete schema docs, full annotation coverage and no output schema, the description covers what is needed to call it correctly. The only gap is failure-mode behavior when the reaction is not present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and all three parameters carry their own docs, including the emoji-without-colons format. The description adds no parameter-level detail, so this sits at the baseline for a fully documented schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Remove) and resource (an emoji reaction) with a meaningful scope constraint: only reactions the bot previously added. That scope distinguishes it from a general reaction-removal or from reactions_add, though it never names the sibling tool directly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: the 'previously added by the bot' clause tells the agent this is the undo path for reactions_add, but there is no explicit when-to-use, when-not-to-use, or named alternative. An agent must infer that it cannot be used to remove other users' reactions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_messageSend a Slack messageA

Post a message as the bot to a channel, a thread, or a user's DM. target accepts a channel ID (C…), #channel-name, user ID (U…), @handle, email, or a person's name; users get a direct message. Use context to add small reference details under a divider at the bottom (Jira ticket, comment link, source, IDs). Use blocks only when you need a custom Block Kit layout (header, fields, images, etc.). Returns the message ts, which you can pass to wait_for_reply or use as thread_ts to reply in a thread.

NameRequiredDescriptionDefault
textYesMessage content. When `blocks` is set, this is only the notification/fallback text, so keep it a short summary
blocksNoCustom Slack Block Kit blocks (https://docs.slack.dev/reference/block-kit/blocks), e.g. header, section with fields, image, markdown, context, divider. Replaces the rendered `text`; `context` is still appended. Do not use interactive elements (buttons, menus): this server does not handle clicks.
formatNomarkdown: standard Markdown rendered by Slack. plain: sent as-ismarkdown
targetYesChannel ID, #channel-name, user ID, @handle, email, or name
contextNoSmall grey details shown under a divider at the bottom of the message, joined with ·. Example: [{label:"Jira", value:"VEC-123", url:"https://…"}, {label:"Comment", value:"#4521", url:"https://…"}]
thread_tsNoTimestamp of the parent message, to reply inside that thread
expect_replyNoSet true when the message asks something you need an answer to. The question is saved as pending, so check_replies can find the answer later, even from a new session.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag this as a non-read-only, open-world write, so the description's added behavior carries the credit: it posts as the bot, resolves users to DMs, appends `context` under a divider, treats `text` as fallback when `blocks` is set, and explicitly warns that interactive elements are unsupported. Remaining gaps are permission requirements and failure modes (e.g., bot not in channel, ambiguous name resolution).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, front-loaded with the core action, then parameter guidance ordered by importance (target, context, blocks), then the return value. Every sentence carries distinct operational content with no restatement of the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter write tool with no output schema, the description covers the send target, layout mode, and return value (`ts` usable as `thread_ts` or with wait_for_reply). It omits what failure looks like and any constraints on DMing users the bot has never interacted with, which an agent may need when a send silently fails.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description earns above that by clarifying target resolution semantics (email/name → DM) and giving a usage rule for `blocks` vs `text` that the schema doesn't state. It does not, however, explain precedence among identifier types or ambiguity handling for names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource+scope: 'Post a message as the bot to a channel, a thread, or a user's DM.' That single sentence distinguishes it from edit_message, delete_message, and the read-oriented siblings, and the DM-vs-channel outcome is stated explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives real selection guidance: users get a DM (not a channel post), `context` is for small reference details, and `blocks` should be used 'only when you need a custom Block Kit layout.' It also points forward to wait_for_reply/thread_ts. It stops short of naming siblings it should not be used instead of (edit_message, delete_message), so no explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

user_infoGet Slack user detailsB
Read-only

Get profile details for one Slack user, identified by user ID (U…), email, or @handle.

NameRequiredDescriptionDefault
userYesUser ID (U…), email address, or @handle

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, and the description adds nothing beyond that — no mention of permission requirements for reading profiles, rate limits, or what happens when the identifier fails to resolve.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One front-loaded sentence with the action, scope, and identifier forms in the first clause; nothing is padded. It is close to minimal but could carry one more clause of routing or behavior without bloat.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter read with no output schema, the description still does not indicate what 'profile details' includes (display name, email, title, timezone) or the shape of the result, leaving the agent guessing at return contents.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single parameter already documents 'User ID (U…), email address, or @handle'. The description restates the same accepted formats without adding new meaning such as precedence between them, so it sits at the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource ('Get profile details for one Slack user') and scopes it to a single user, which implicitly separates it from the list-oriented users_search. It never names that sibling, so the differentiation is inferred rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by 'one Slack user' versus the sibling users_search and whoami, but the description never says explicitly when to pick this tool over those alternatives, nor any prerequisite such as needing a user ID from a search first.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wait_for_replyWait for a Slack replyA

Block for a short time until someone other than the bot replies in a channel, DM or thread, then return the new messages. Use it only when an answer is likely within a minute or two; every call costs a model turn. Pass since_ts = the ts of your question (from send_message). Replies both as new messages and inside the question's thread are found. On replied: false, follow the returned next_step: after a couple of timeouts, stop waiting, tell the user, and collect the answer later with check_replies. Keep timeout_seconds below your MCP client's tool-call timeout (often 60 seconds; Claude Code users can raise it with MCP_TOOL_TIMEOUT).

NameRequiredDescriptionDefault
channelYesChannel ID, #channel-name, or user (ID, @handle, email) for their DM
since_tsNots of your question; only later messages count (default: now)
from_userNoOnly count messages from this user (ID, @handle, or email)
thread_tsNoThread to check; new top-level messages in the channel are checked too
timeout_secondsNoHow long to wait; keep it below the MCP client's tool-call timeout
poll_interval_secondsNoHow often to check Slack

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (readOnlyHint=false, destructiveHint=false, openWorldHint=true) by disclosing the blocking cost per call, the `replied: false` contract with `next_step`, the recommendation to cap retries, and the hard interaction with the MCP client's tool-call timeout. Nothing here contradicts the annotations — the tool does read Slack but consumes a model turn, so readOnlyHint=false is not inconsistent with the text.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first clause, and each subsequent sentence carries a distinct operational rule with no filler. It is dense but slightly long, with the Claude Code MCP_TOOL_TIMEOUT parenthetical being the only marginal content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-parameter blocking poll tool with no output schema, it covers the blocking semantics, the failure return fields, the retry policy, and the client-side timeout ceiling. An agent can call this correctly and know what to do on a timeout without further information.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: `since_ts` should be the ts of the question from send_message, and `timeout_seconds` must stay under the client's tool-call timeout. It also explains that replies both as top-level messages and inside the question's thread are matched, which is not evident from the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with precise scope: blocks until a human (not the bot) replies in a channel, DM, or thread, then returns the new messages. It also implicitly distinguishes itself from the non-blocking sibling check_replies, which it names later.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly bounds when to use it ('only when an answer is likely within a minute or two; every call costs a model turn') and gives a decision path for the failure case: follow `next_step`, and after a couple of timeouts stop and use check_replies instead. That is when/when-not/alternative guidance in full.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

whoamiSlack bot statusA
Read-only

Show the server version, which Slack bot and workspace this server is connected to, the connection mode, the OAuth scopes the bot has, and which tools are missing scopes. Call this first when a Slack action fails with a permission error.

NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds meaningful context beyond that: the tool surfaces scopes and specifically which tools are missing scopes, making it a diagnostic rather than an identity call. It does not describe output format or failure modes, but with annotations carrying the safety signal this is solid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence listing the returned fields, followed by one actionable routing sentence. Every clause earns its place; the field list is long but each item is a distinct diagnostic output. Front-loading the verb 'Show' keeps it readable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description carries the burden of explaining return values, and it does so explicitly by enumerating the six categories of information returned. Combined with the troubleshooting trigger, an agent has enough to call it correctly and interpret the result. It could be slightly more complete by noting that it is workspace/bot-scoped rather than user-scoped.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, which is the baseline-4 case: there is nothing for the description to disambiguate. The description correctly implies no arguments are needed and focuses on what the call reveals.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a concrete verb ("Show") and enumerates the exact resources returned: server version, connected bot, workspace, connection mode, granted scopes, and missing-scope tools. This clearly reframes the ambiguous name 'whoami' into a Slack diagnostic tool. It does not explicitly contrast with the sibling user_info, which sounds superficially similar, so it falls just short of 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a crisp trigger condition: "Call this first when a Slack action fails with a permission error." That is a genuine when-to-use rule tied to the sibling family of Slack actions. It stops short of naming a true alternative or stating when not to call it, so it is strong but not complete.

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.

  1. 14 tool updatesv0.6.1
    • First observedchannels_list
    • First observedcheck_replies
    • First observedconversations_history
    • First observedconversations_replies
    • First observeddelete_message
    • First observededit_message
    • First observedget_inbox
    • First observedreactions_add
    • First observedreactions_remove
    • First observedsend_message
    • First observeduser_info
    • First observedusers_search
    • First observedwait_for_reply
    • First observedwhoami

TDQS

A3.8/5.0

Scored across 14 tools

Disambiguation4/5

Most tools map to distinct resource+action pairs (send/edit/delete_message, reactions_add/remove, conversations_history/replies), and the descriptions explicitly explain boundaries. The one fuzzy cluster is read/wait behavior: check_replies, wait_for_reply, get_inbox and conversations_history all retrieve incoming messages and differ only in polling semantics and scope, which an agent must read carefully to pick correctly. user_info vs users_search is also mildly overlap-prone but clarified by the descriptions.

Naming Consistency3/5

Conventions are mixed: verb_noun (send_message, edit_message, check_replies, get_inbox, wait_for_reply), noun_verb mirroring Slack's API (channels_list, reactions_add, reactions_remove, conversations_history, conversations_replies), a bare noun (user_info) and a bare verb-ish name (whoami). All names remain readable and most are guessable to anyone familiar with Slack's API, but there is no single predictable pattern to extrapolate from.

Tool Count5/5

14 tools sit comfortably in the well-scoped 3-15 range, and each tool earns its place: identity/context, user & channel discovery, message lifecycle, reading, reactions, and reply-waiting. No obvious filler or redundant duplicate tools.

Completeness4/5

The core bot messaging lifecycle is fully covered: send, edit, delete, read history and thread replies, react/unreact, receive mentions/DMs, and wait/check for replies, plus discovery tools for users and channels. Gaps are minor-to-moderate: no file upload/download, no message search, no channel creation/invite or member listing, and edit/delete are limited to the bot's own messages, but agents can work around these for typical bot workflows.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Enables AI agents to interact with Slack workspaces through OAuth authentication, supporting message reading, posting to channels and threads, and channel discovery with popularity sorting.
    4
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to interact with Slack workspaces through comprehensive channel management, messaging, direct messages, search functionality, and user management capabilities.
    30
    3 npm
    2
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to interact with Slack workspaces through natural language, supporting channel management, message operations, user profiles, reactions, and threaded conversations.
    -
  • A
    license
    A
    quality
    C
    maintenance
    Enables AI assistants to interact with Slack workspaces, including listing channels, posting messages, replying to threads, adding reactions, and retrieving user information.
    10
    12 npm
    MIT