Skip to main content
Glama

SlackMCP

Node.js MCP License: MIT

A self-hosted Model Context Protocol server for Slack. SlackMCP gives AI assistants such as Codex, Claude, and other MCP clients direct access to your Slack workspace. Your assistant can read, search, and send messages as you, with no signatures, footers, or attribution added.

SlackMCP runs on your own machine and talks directly to Slack's Web API. It uses no hosted proxy and sends no telemetry, and your token stays on your machine.


Why SlackMCP

  • Messages are sent exactly as written. SlackMCP never adds "sent by" text, signatures, footers, branding blocks, or attribution metadata. What you write is what your colleagues see.

  • It acts as you. With a User OAuth Token, messages come from your own Slack account, not a bot.

  • Data goes only to Slack. Requests go only to https://slack.com/api/, redirects are refused, and tokens and message bodies are never logged.

  • Results are readable. Read and search results replace raw user IDs with display names, so assistants can follow a conversation without extra lookups.

  • Writes are handled safely. Writes are never retried automatically, so a failed or uncertain send cannot produce a duplicate. Rate limits come back with Slack's suggested retry delay.

  • It follows the standard. It is built on the official MCP SDK and works with both earlier and current (2026-07-28) MCP stdio clients.

Related MCP server: Slack MCP Server

Features

Tool

Description

Required scopes

slack_auth_test

Verify the connected workspace and account

None

slack_list_conversations

List channels, private channels, DMs, and group DMs

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

slack_read_channel

Read channel or DM history

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

slack_read_thread

Read a message and its thread replies

Matching *:history scope

slack_search_messages

Search every conversation the token can see

search:read

slack_list_users

List workspace members and their IDs

users:read

slack_send_message

Send a message, optionally as a thread reply

chat:write

slack_edit_message

Replace the text of an existing message

chat:write

slack_open_dm

Open or resume a DM or group DM

im:write, mpim:write

slack_get_permalink

Get a shareable link to a message

None

slack_add_reaction

Add an emoji reaction to a message

reactions:write

Each tool carries MCP annotations (read-only, destructive, idempotent), so clients can tell safe reads from writes and ask for confirmation before writes.

Requirements

  • Node.js 22.16 or later

  • A Slack workspace where you can install apps (some workspaces need admin approval)

  • An MCP-compatible client, such as Codex, Claude Desktop, Claude Code, or Cursor

Installation

git clone https://github.com/jaggerjack61/SlackMCP.git
cd SlackMCP
npm ci --ignore-scripts

Configuration

1. Create the Slack app

  1. Go to api.slack.com/apps and choose Create New App → From a manifest.

  2. Select your workspace and paste the contents of slack-app-manifest.json. The manifest requests every user scope listed above. If you only need to send messages, you can trim it to chat:write.

  3. Under OAuth & Permissions, click Install to Workspace and approve.

  4. Copy the User OAuth Token (starts with xoxp-).

User or bot token? A User OAuth Token (xoxp-) acts as your own account and is required for search and for reading channel threads. A Bot User OAuth Token (xoxb-) acts as the app's bot user. Either way, Slack decides the sender name and any app labels it shows; SlackMCP cannot change these.

2. Store the token

cp .env.example .env
chmod 600 .env

Edit .env:

SLACK_TOKEN=xoxp-your-token-here

SlackMCP loads the .env file next to package.json, whatever directory your client starts it from. A SLACK_TOKEN already set in the process environment takes precedence. Never commit .env or paste your token into a chat.

3. Register the server with your MCP client

Codex. Add the following to ~/.codex/config.toml (template: config/codex.toml.example):

[mcp_servers.slack_local]
command = "node"
args = ["/absolute/path/to/SlackMCP/src/index.js"]

Claude Desktop, Cursor, and other JSON-configured clients. Merge the following into the client's mcpServers object (template: config/mcp.json.example):

{
  "mcpServers": {
    "slack-local": {
      "command": "node",
      "args": ["/absolute/path/to/SlackMCP/src/index.js"]
    }
  }
}

If your client can't find node, replace it with the full path printed by command -v node.

4. Verify

Restart or reload your MCP client, then ask your assistant to run slack_auth_test. It should report your workspace and Slack user. If another Slack integration is also installed, tell your assistant to use slack-local for messaging.

Usage

Once connected, ask your assistant in plain language:

  • "Summarise what I missed in #engineering today."

  • "Find the thread where we discussed the Q3 launch date."

  • "Reply in that thread: 'Confirmed for the 14th, I'll update the tracker.'"

  • "DM Priya the link to that message."

Formatting

Messages use Slack's mrkdwn syntax (*bold*, _italic_, <https://example.com|label>), not standard Markdown. Set mrkdwn: false on slack_send_message to send plain text. Link and media previews (unfurls) are off by default and can be turned on per message. Messages can be up to 40,000 characters.

Addressing conversations

Send and edit tools take a conversation ID (starting with C, G, or D), not a user ID. To message a person, call slack_open_dm first to get their DM conversation ID. Message timestamps (ts) are passed as strings.

User names

slack_read_channel, slack_read_thread, and slack_search_messages replace user IDs with names:

  • <@U…> mentions in message text become @Name

  • each message gets a user_name field

  • a top-level user_names map keeps the original IDs, so your assistant can still write <@ID> mentions when replying

Names are fetched with users.info and cached for as long as the server runs. If a name can't be fetched, the ID is left as it is and the read still succeeds.

Pagination

Read and list tools return one page at a time. To get the next page, pass response_metadata.next_cursor as cursor. Search pages through results with page and reports the total in paging.pages.

Network and proxy configuration

On Node.js 24 or later, set NODE_USE_ENV_PROXY=1 when launching to send requests through HTTP_PROXY / HTTPS_PROXY. Configure your MCP client to pass these variables on to the server (along with NO_PROXY and NODE_EXTRA_CA_CERTS if needed). Don't write proxy credentials into client config files.

Security

  • Your token is read once at startup from .env or the environment. Restart the server after changing it.

  • Requests are sent only to https://slack.com/api/, and redirects are refused.

  • Tokens and message bodies are never logged. Errors return only Slack's error code and, where relevant, the missing scopes.

  • Writes are never retried automatically. If a send fails because of a network error, check the conversation before sending again.

  • Search can return results from private channels and DMs your account can access. Grant only the scopes you need.

To report a vulnerability, please open a private security advisory on GitHub rather than a public issue.

Development

npm start   # run the stdio server (waits for an MCP client)
npm test    # run the test suite

The test suite runs a real MCP client against the server over stdio, with Slack's responses mocked. It covers protocol negotiation for earlier and current MCP clients, exact message preservation, edit behaviour, pagination, input validation, user-name resolution, missing credentials, rate limiting, and failures where delivery is unknown. No real Slack messages are sent.

Project structure

src/
  index.js    Entry point: loads .env and starts the stdio transport
  server.js   Registers the MCP tools and handles errors
  tools.js    Tool definitions, input schemas, and Slack method mapping
  slack.js    Slack Web API client
  users.js    User ID → display name resolution with caching
test/         Node test runner suites and a stdio test fixture
config/       Sample client configurations

Troubleshooting

Symptom

Resolution

Unable to start Slack MCP

SLACK_TOKEN is missing. Check .env or your client's environment settings.

Slack API error: missing_scope

The error lists the scopes needed. Add them in the Slack app settings and reinstall the app.

Slack API error: not_in_channel

The account is not a member of that channel. Join it first.

Slack API error: channel_not_found

Check the conversation ID. To message a person, call slack_open_dm to get their DM ID.

Search or thread reads fail with a bot token

These need a User OAuth Token (xoxp-).

Client reports node not found

Use the absolute path from command -v node in the client config.

References

License

Released under the MIT License.

Available Tools

11 tools
slack_add_reactionB

Add an authorized emoji reaction to a message. Use an emoji name without colons.

NameRequiredDescriptionDefault
nameYes
channelYesSlack conversation ID. Resolve the intended channel or DM before sending.
timestampYesSlack message timestamp, kept as a string.

TDQS

B3.3/5.0
Behavior3/5

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

Annotations already declare readOnly=false, destructive=false, idempotent=false and openWorld=true, so the mutation and non-idempotency profile is covered structurally. The description adds only the word 'authorized', hinting that the emoji must exist/permitted in the workspace, but it does not say what happens on duplicate reactions or on invalid emoji — the two most likely failure modes for a non-idempotent write.

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 short sentences, zero waste, with the core action front-loaded and the parameter hint trailing. Nothing to trim and nothing buried.

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 small 3-parameter mutation with no output schema, the description is minimal but workable: it names the action and the one undocumented parameter. It omits the duplicate-reaction behavior and the success response, which matter for a non-idempotent write with no output schema to fall back on.

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 67%: channel and timestamp are already documented in the schema, leaving only 'name' undocumented there. The description addresses exactly that gap by saying 'use an emoji name without colons', which is useful guidance (though the pattern already excludes ':'). It adds nothing about how to obtain the message timestamp or channel ID beyond what the schema says.

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 and resource: 'Add an authorized emoji reaction to a message.' An agent immediately knows the operation. No sibling tool touches reactions, so explicit differentiation from siblings is less critical, though it never says how it relates to the message-read/send tools.

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?

There is no statement of when to use this versus other tools, no prerequisites beyond the ambiguous word 'authorized', and no mention of what to do if the reaction already exists. The agent must infer usage entirely from the tool name and schema.

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

slack_auth_testA
Read-onlyIdempotent

Check the configured token and identify the connected Slack workspace and account.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds that it inspects the configured token and surfaces connected identity, but says nothing about what happens on an invalid or expired token (error vs. structured negative result) or what data is returned.

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 front-loaded sentence with the diagnostic action first and the yielded information second; no filler, no repetition of the tool name.

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 no-parameter, no-output-schema diagnostic, the description covers both purpose and the identity information obtained. The only gap is failure behavior, which matters for a test-style tool but is a minor omission.

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 and the schema is an empty object, so there is nothing for the description to disambiguate. Baseline 4 applies for a no-parameter definition.

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 uses two specific verbs, 'check' the configured token and 'identify' the connected workspace and account, so the resource and outcome are unambiguous. It doesn't name any sibling, but none of the listed Slack tools perform authentication, so an agent can still tell it apart from them.

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 only implied: an agent can infer this is a diagnostic to run before or when other Slack calls fail, but the description never states when to call it, when not to, or that it precedes the read/write siblings. No prerequisites or failure conditions are given.

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

slack_edit_messageA
DestructiveIdempotent

Replace an editable message with the exact supplied body. No signature or attribution is added. Only edit when authorized. Sending blocks:[] clears existing structured message blocks; Slack may retain an edited indicator.

NameRequiredDescriptionDefault
tsYesSlack message timestamp, kept as a string.
textYesExact message body. Use Slack mrkdwn (*bold*, _italic_) unless mrkdwn is false. Never append a signature or attribution.
parseNonone
channelYesSlack conversation ID. Resolve the intended channel or DM before sending.

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and openWorldHint=true, but the description adds real behavioral context beyond them: no signature/attribution is appended, existing structured blocks are wiped by blocks:[], and Slack may retain an edited indicator. The mention of a blocks:[] argument that does not exist in the input schema creates some ambiguity about what the tool actually accepts.

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?

Three short front-loaded sentences with the core behavior first and side effects after; little waste. The blocks:[] clause is the only part that is not self-explanatory in context.

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?

Annotations cover the mutation/safety profile and no output schema exists, and the description covers side effects like block clearing. It omits failure behavior (what happens when a message is not editable or ts is stale) and references a blocks parameter not present in the schema, leaving a gap for a destructive write 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 75%, so the schema already explains ts, text, and channel including the 'never append a signature' rule that the description repeats. The description adds nothing about parse or the missing blocks field, so it neither compensates for the gap nor contributes new parameter meaning.

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+resource ('Replace an editable message') and pins down the semantics with 'exact supplied body'. It implicitly separates itself from slack_send_message (edit vs. create) but never names or explicitly contrasts that sibling.

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?

'Only edit when authorized' is the sole usage constraint and it is vague about what authorization means or how to verify it. No explicit alternative is offered (e.g., use slack_send_message for new messages, slack_search_messages to locate ts), so routing must be inferred from the sibling list.

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

slack_list_conversationsB
Read-onlyIdempotent

List visible Slack channels and DMs. Follow response_metadata.next_cursor for more pages.

NameRequiredDescriptionDefault
limitNo
typesNopublic_channel,private_channel,im,mpim
cursorNonext_cursor from the previous page; omit for the first page.
exclude_archivedNo

TDQS

B3.3/5.0
Behavior3/5

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

Annotations already declare the operation as read-only, idempotent, open-world, and non-destructive. The description adds useful pagination behavior via response_metadata.next_cursor and clarifies the visibility scope, but it does not explain what 'visible' means, authentication requirements, rate limits, or the return structure.

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 two short sentences with no wasted text. The core purpose and pagination instruction are front-loaded and easy to scan.

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?

With four optional parameters, a moderate schema, and no output schema, the description is adequate but incomplete. Defaults reduce the burden, yet the description does not explain how limit, types, or exclude_archived affect results, leaving gaps for callers relying on the description.

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

Parameters2/5

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

Schema description coverage is only 25%, with just the cursor parameter documented. The description mentions channels and DMs, loosely mapping to the types parameter, but it does not explain the allowed type values, the limit parameter, or exclude_archived, so it fails to compensate for the low 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?

The description uses a specific verb and resource: 'List visible Slack channels and DMs.' It clearly identifies the object being listed and its scope, though it does not explicitly differentiate itself from siblings such as slack_read_channel or slack_search_messages.

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 for discovering visible conversations, and the pagination instruction is explicit. However, there is no guidance on when to use this instead of alternatives like slack_search_messages or slack_read_channel, nor are there any exclusions or prerequisites.

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

slack_list_usersB
Read-onlyIdempotent

List workspace users to resolve user IDs. Follow response_metadata.next_cursor for more pages.

NameRequiredDescriptionDefault
limitNo
cursorNonext_cursor from the previous page; omit for the first page.

TDQS

B3.3/5.0
Behavior3/5

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

Annotations already declare readOnly, idempotent, non-destructive and openWorld, so the safety profile is covered. The description adds a genuinely useful behavioral cue about pagination via response_metadata.next_cursor, but says nothing about Slack rate limits (users.list is heavily throttled), what user types/statuses are returned, or result size.

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 short sentences, purpose front-loaded followed by the pagination instruction. Nothing wasted and nothing buried.

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 read-only listing tool with annotations and no output schema, the description covers purpose and paging but leaves the limit parameter and the composition of the returned user list (bots, deactivated accounts) unexplained. Adequate but with clear gaps.

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

Parameters2/5

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

Schema coverage is only 50%: cursor is documented in the schema, but limit (default 15, max 100) is undocumented everywhere. The description contributes no parameter meaning at all, not even hinting at page size behavior, so it fails to compensate for the coverage gap.

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+resource ("List workspace users") and adds the reason ("to resolve user IDs"), which makes it clearly distinct from siblings like slack_list_conversations or slack_search_messages. It does not explicitly name an alternative tool, 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 Guidelines3/5

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

The phrase "to resolve user IDs" implies the use case, so an agent can infer when this beats slack_search_messages. But there are no explicit when-to-use/when-not conditions and no mention of alternatives or prerequisites.

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

slack_open_dmA
Idempotent

Open or resume a direct message with explicitly authorized users. Returns a conversation ID for sending. Does not send a message.

NameRequiredDescriptionDefault
usersYes

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare idempotency, open-world behavior, and non-destructiveness. The description adds useful context by stating that it returns a conversation ID and does not send a message, but it omits important behavioral details such as what happens when multiple users are supplied.

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 purpose and followed immediately by the return value and the non-send caveat. Every sentence adds distinct information.

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?

The description covers purpose, return value, and the crucial fact that it does not send a message. However, for a tool with a single 0%-documented array parameter, it leaves out parameter semantics and multi-user behavior that an agent needs to invoke it correctly.

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

Parameters2/5

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

Schema description coverage is 0%, and the description does not explain the 'users' parameter at all—not the Slack ID format, the 1–8 item limit, or whether multiple users create a group DM. It only vaguely refers to 'explicitly authorized users.'

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+resource ('Open or resume a direct message'), identifies the target population ('explicitly authorized users'), and explicitly distinguishes itself from slack_send_message by saying it 'Does not send a message.'

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?

The description makes the intended workflow clear: use it to obtain a conversation ID before sending. It does not name an alternative tool or state exclusions beyond 'explicitly authorized users,' so it falls 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.

slack_read_channelA
Read-onlyIdempotent

Read a page of channel or DM history, newest first. Requires access to the conversation. Follow next_cursor for more pages. User mentions in text are shown as @name; user_names maps user IDs to names (use <@ID> to mention someone when sending).

NameRequiredDescriptionDefault
limitNo
cursorNonext_cursor from the previous page; omit for the first page.
latestNoSlack message timestamp, kept as a string.
oldestNoSlack message timestamp, kept as a string.
channelYesSlack conversation ID. Resolve the intended channel or DM before sending.

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/non-destructive, so the description's value is the extra behavior it adds: results come newest-first, pages are chained through next_cursor, and mentions are rendered as @name with a user_names map for resolving IDs. These are concrete traits an agent would not get from the annotations or schema, though access-failure behavior is not described.

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?

Three tight sentences with the core action and ordering front-loaded, followed by prerequisites and pagination. The trailing parenthetical about how to mention someone is slightly tangential to a read operation but is genuinely useful cross-context and costs only a clause.

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?

With no output schema, the description carries the burden of explaining the response, and it does so for the key pieces: next_cursor, the user_names map, and mention formatting. What remains unstated is the shape of the message objects themselves and what happens when the channel is inaccessible.

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 80%, so cursor, oldest, latest and channel are already documented in the schema. The description reinforces the cursor pattern and explains the user_names/mention convention, but adds nothing about limit bounds or how oldest/latest interact with newest-first ordering. Baseline 3 is appropriate.

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 first sentence gives a specific verb and resource ('Read a page of channel or DM history') plus ordering ('newest first'), which lets an agent distinguish this from message-sending or search tools. It does not explicitly name the closest sibling, slack_read_thread, so the boundary between reading a whole channel and reading one thread is left implicit.

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 only implied: the tool is for pulling conversation history and 'Requires access to the conversation.' The pagination instruction ('Follow next_cursor for more pages') is operational guidance rather than a when-to-use rule. There is no statement about when to prefer slack_read_thread or slack_search_messages instead.

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

slack_read_threadA
Read-onlyIdempotent

Read a parent message and its thread replies. A user token is needed for public/private channel threads. Follow next_cursor for more pages. User mentions in text are shown as @name; user_names maps user IDs to names (use <@ID> to mention someone when sending).

NameRequiredDescriptionDefault
tsYesParent message timestamp.
limitNo
cursorNonext_cursor from the previous page; omit for the first page.
channelYesSlack conversation ID. Resolve the intended channel or DM before sending.

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already cover safety (readOnly, idempotent, non-destructive), so the description's added value is real: it discloses the auth requirement for private channels and the pagination contract via next_cursor. It also explains how mentions are rendered and what user_names contains, which is behavioral detail an agent cannot get from annotations or schema.

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?

Four short sentences, front-loaded with the core action and pagination immediately after. The closing note about user_names and <@ID> mentioning drifts toward slack_send_message usage, but it is brief and still informs interpretation of this tool's output.

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?

With no output schema, the description carries the burden of explaining returns, and it does so for the parts an agent must handle: pagination cursor, mention rendering, and the user_names mapping. It does not describe the overall response shape (e.g., whether the parent message is included in the list), which is the main remaining gap.

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 75%, with limit left undescribed, so the schema does most of the work. The description still adds meaning beyond it by tying cursor to the next_cursor value returned from the previous page, which is the one non-obvious parameter interaction.

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 and resource: reads a parent message plus its thread replies. That scope ('thread replies') implicitly distinguishes it from slack_read_channel and slack_search_messages, but no sibling is named explicitly, so 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?

Gives one real prerequisite (a user token is needed for public/private channel threads), which is genuinely useful selection context. However, it never says when to choose this over slack_read_channel or slack_search_messages, so the usage guidance is implied rather than explicit.

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

slack_search_messagesA
Read-onlyIdempotent

Search messages visible to the token, including private conversations it can access. Requires a user token with search:read. Use Slack search operators to limit the query. Follow paging.pages using page. User mentions in text are shown as @name; user_names maps user IDs to names (use <@ID> to mention someone when sending).

NameRequiredDescriptionDefault
pageNo
sortNotimestamp
countNo
queryYes
sort_dirNodesc
highlightNo

TDQS

A4/5.0
Behavior4/5

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

Annotations already establish readOnly, idempotent, non-destructive, and openWorld behavior. The description adds useful operational context beyond that: the user-token auth requirement, the search:read scope, and pagination via paging.pages/page.

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?

Front-loaded with purpose and auth requirement, then the query and pagination guidance. Most sentences earn their place, though the trailing user_names/mention note is tangential to search itself and slightly compresses multiple ideas into one sentence.

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?

With no output schema, the description does explain result-adjacent details like @name rendering and the user_names mapping. It also covers auth and pagination, but omits result contents and the semantics of the sort, count, and highlight parameters.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must carry the burden for six parameters. It explains query format (operators, @name and <@ID> mention syntax) and page, but leaves sort, sort_dir, count, and highlight entirely undocumented.

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 ('Search messages') plus a precise scope: messages visible to the token, including private conversations it can access. This distinguishes it from read-oriented siblings like slack_read_channel and slack_read_thread, which are scoped to a single conversation.

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?

Provides clear usage context: search operators to constrain the query and a required user token with search:read. It does not explicitly say when to prefer slack_read_channel or slack_read_thread, or when not to use search.

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

slack_send_messageA

Send the exact supplied message body to an authorized Slack channel or DM, with no added signature, footer, blocks, or attribution metadata. Only send when the user authorized the content and destination. Do not retry blindly after an uncertain result.

NameRequiredDescriptionDefault
textYesExact message body. Use Slack mrkdwn (*bold*, _italic_) unless mrkdwn is false. Never append a signature or attribution.
parseNonone
mrkdwnNo
channelYesSlack conversation ID. Resolve the intended channel or DM before sending.
thread_tsNoSlack message timestamp, kept as a string.
unfurl_linksNo
unfurl_mediaNo
reply_broadcastNo

TDQS

A3.9/5.0
Behavior5/5

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

Goes well beyond annotations by specifying that nothing is appended (no signature, footer, blocks, or attribution), that user authorization is a precondition, and that retries after uncertain outcomes are dangerous — context the idempotentHint=false flag only hints at. These are the exact failure modes for a messaging tool.

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, front-loaded with the core action, followed by authorization and retry constraints. No filler or restatement of the tool name.

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?

The auth/retry guidance is valuable, but with no output schema the description never says what is returned (e.g., the message ts needed for threading or permalinks), and it leaves six of eight parameters undocumented. Adequate for a safe send, incomplete for correct invocation of threading and formatting options.

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

Parameters2/5

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

Schema coverage is only 38%: thread_ts, mrkdwn, parse, unfurl_links, unfurl_media, and reply_broadcast have no documentation in either the schema or description. The description clarifies the 'text' semantics (exact body, no blocks) but leaves half the parameters, including threading and link unfurling, unexplained.

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 and resource ('Send the exact supplied message body to an authorized Slack channel or DM') with clear scope that separates it from read/search siblings. It never names slack_edit_message, so an agent must infer that this tool creates new messages rather than modifying existing ones.

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 explicit gating conditions — only send when the user authorized content and destination — plus a caution against blind retries after an uncertain result. It does not name alternatives (e.g., use slack_edit_message to revise an already-sent message), which would have taken this to a 5.

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. 11 tool updatesv1.0.0
    • First observedslack_add_reaction
    • First observedslack_auth_test
    • First observedslack_edit_message
    • First observedslack_get_permalink
    • First observedslack_list_conversations
    • First observedslack_list_users
    • First observedslack_open_dm
    • First observedslack_read_channel
    • First observedslack_read_thread
    • First observedslack_search_messages
    • First observedslack_send_message

TDQS

A3.7/5.0

Scored across 11 tools

Disambiguation4/5

Tools mostly target distinct resources/actions (list vs read vs send vs search vs edit). The only mild overlaps are slack_read_channel vs slack_read_thread and slack_open_dm vs slack_send_message, but descriptions clearly differentiate them (history vs thread replies, and opening vs sending).

Naming Consistency4/5

All tools use a consistent slack_ prefix and follow verb_noun ordering (list_conversations, read_channel, send_message). The only minor deviation is slack_auth_test, where the noun/verb order is inverted, but it remains readable.

Tool Count5/5

Eleven tools is well within the 3-15 sweet spot for a Slack messaging surface. Each tool covers a distinct operation (auth, list, read, search, send, edit, react, permalink, open DM) without redundancy.

Completeness4/5

Core read/write workflows (list, read, search, send, edit, react, permalink, open DM) are covered. Minor gaps remain: no delete/remove message, no documented way to send a thread reply (thread_ts not exposed), and no file upload support.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A read-only MCP server that enables AI assistants to access Slack workspace data, including channels, messages, threads, and user information.
    49,032 npm
    3
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol (MCP) server for Slack workspace integration. This server allows AI assistants to interact directly with your Slack workspace, providing tools to manage channels, send messages, list users, and upload files.
    49,032 npm
    1
    MIT