
Slack
io.github.mindstone由 GitHub 帳號 mindstone 發布v0.3.7更新於 Nov 7, 2026
Slack MCP server: channels, messages, threads, reactions, users, files, and scheduled messages
概覽
Slack MCP 伺服器,讓助理在已連線的工作區中搜尋、讀取、傳送與管理 Slack 訊息、頻道、討論串、使用者、檔案與釘選內容。
- 可以做什麼
- 搜尋與讀取訊息、稍後再看內容、訊息連結、頻道歷史、未讀訊息與討論串回覆
- 傳送、撰寫、回覆、排程、編輯與刪除訊息,並可傳送提醒筆記給自己
- 管理頻道:列出、建立、標示已讀、邀請成員,以及處理釘選與書籤
- 依名稱或電子郵件查詢使用者、開啟私訊,並新增或移除表情回應
- 下載與上傳檔案附件,並管理提醒(實驗性)
- 檢查工作區連線狀態與權杖健康狀況
- 適用情境
- 適合希望助理直接在 Slack 工作區中作業的情境,例如查找過往討論、草擬或張貼回覆、處理未讀頻道,或把附件取用到任務中。較適合已有宿主應用負責 Slack OAuth 並將權杖保存在自己電腦上的使用者。
- 執行需求
- 透過 npx 在本機執行,需要 Node.js 20+ 與 npm。需要由宿主應用完成 Slack OAuth 流程並寫入各工作區的權杖檔案,本伺服器只負責讀取。必要環境變數:SLACK_CONFIG_PATH 與 SLACK_TEAM_ID。選用:SLACK_CLIENT_ID 與 SLACK_CLIENT_SECRET(用於更新輪換權杖)、SLACK_DISABLE_REFRESH、SLACK_REQUEST_TIMEOUT_MS、SLACK_MAX_RETRIES、MCP_WORKSPACE_PATH。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Slack,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
@mindstone/mcp-server-slack
[npm version] [License: FSL-1.1-MIT]
Slack workspace MCP server — channels, messages, threads, reactions, users, files, bookmarks, and scheduled messages via the Slack Web API.
Multi-workspace Slack MCP. Host-driven OAuth, per-workspace credentials files on disk, and a security review on every release.
Status
- Version: 0.3.5 · npm
- Auth: OAuth (host-orchestrated) (
SLACK_CLIENT_SECRET) - Tools: 39 (messages, channels, threads, users, files, pins)
- Surface: cloud-api
- Machine-readable:
STATUS.json
Why this exists
When we started building this connector, Slack had not yet released an official MCP server — that came later (announced February 2026, generally available April 2026). The community Slack MCPs available at the time each got parts of the job right, but none of them combined fast user-name lookups for small and medium workspaces, the correct mention format for modern Slack (most still used the deprecated link_names=true), support for more than one Slack workspace from the same user account, and tokens that stay on the user's own machine. Slack's official server now exists and is a fine choice for many use cases. We continue to maintain this one because the host application handles the login flow, each workspace has its own credentials file on disk under the user's control, and the connector goes through our own security review before each release.
Example interaction
"Find the most recent message from Alice in #q3-planning and react with :eyes:."
Tools the host calls:
lookup_user_by_email— resolves Alice's email to her Slack user ID.search_slack_messages— searches#q3-planningfor her most recent message, returning the channel + timestamp.add_slack_reaction— adds theeyesreaction to that message.
Response (trimmed):
Requirements
- Node.js 20+
- npm
- A host application that performs the Slack OAuth flow and writes per-workspace token files to
${SLACK_CONFIG_PATH}/workspaces/{teamId}.json. This server reads those files; it does not initiate OAuth itself.
One-click install
[Add to Cursor] [Add to VS Code] [Add to VS Code Insiders]
After clicking the button, your host will prompt you to fill: SLACK_CONFIG_PATH, SLACK_TEAM_ID, SLACK_CLIENT_SECRET, SLACK_REQUEST_TIMEOUT_MS, SLACK_MAX_RETRIES.
Manual config for Claude Desktop / Claude Code / Goose / Continue.dev (Slack)
Quick Start
Install & build
npx (once published)
Local
Configuration
This server is designed to run alongside a host application that performs the Slack OAuth flow on its own. The host writes credentials to disk; this server reads them.
Required environment variables
SLACK_CONFIG_PATH— Path to the Slack config directory (host-managed). Containsconfig.json(workspace metadata) andworkspaces/{teamId}.json(per-workspace tokens, mode 0600).SLACK_TEAM_ID— Workspace team ID (per-workspace instance).
Optional environment variables
SLACK_CLIENT_ID— OAuth Connected App client ID. Only needed to refresh a rotating token. Saved non-rotating tokens authorize the Slack API directly without it. When a refresh is required but this is absent, the server fails loud withREFRESH_NO_CLIENT_CREDENTIALSand directs the host to re-authenticate.SLACK_CLIENT_SECRET— OAuth Connected App client secret. Same conditions asSLACK_CLIENT_ID.SLACK_DISABLE_REFRESH— Set to1to disable token refresh on this surface. The server will fail-closed with a structuredauth_requiredresponse on token expiry instead of attempting anoauth.v2.accessrefresh. Use this on the cloud surface so desktop remains the sole refresh authority and avoids racing for single-use refresh tokens.SLACK_REQUEST_TIMEOUT_MS— Override the default 60s upstream timeout. Must be a positive integer ≤ 300000 (5 minutes).MCP_WORKSPACE_PATH— Directory thatupload_slack_filereads are constrained to. Paths outside it (including symlinks pointing outside) are refused. Defaults to the system temp dir when unset.
Authentication flow
The host calls the authenticate_slack_workspace tool. The OSS server returns a structured auth_required response of the form:
The host's MCP service recognises this shape and dispatches to its registered Slack OAuth orchestrator (the desktop browser flow). Once the user signs in, the host writes tokens to ${SLACK_CONFIG_PATH}/workspaces/{teamId}.json and the server picks them up on the next call.
The OSS server never initiates OAuth itself.
Host configuration examples
This server is designed for host-orchestrated OAuth: the host writes per-workspace token files to disk and the server reads them. The examples below show the env shape — your host application is responsible for populating ${SLACK_CONFIG_PATH}/workspaces/{teamId}.json before tool calls succeed.
Claude Desktop / Cursor
Until the host has written ${SLACK_CONFIG_PATH}/workspaces/T0123ABCD.json for that team, every tool call returns a structured auth_required response (see the Authentication flow above).
Local development (no npm publish needed)
People reads and authorization
list_slack_users, get_slack_user_profile, lookup_user_by_email, message name enrichment and the profile shown by open_slack_dm use user authorization first. If it is absent or refused for authorization, scope or token-type reasons, the read may try bot authorization once. A retry starts the read again, including pagination and username resolution. Neither authorization can supply permissions it was not granted; email lookup still needs users:read.email.
Other errors returned to the read runner do not trigger this retry. Writes keep their identity: opening a DM uses user authorization once, and send_myself_a_note uses only bot authorization. If Slack refuses the app's authorization, a notified note cannot be sent even while other Slack actions still work. Reconnecting may restore it.
list_slack_workspaces tests bot and user authorization independently with auth.test. connected means at least one passed; tokenHealth.botToken and tokenHealth.userToken report each result separately (valid, refused, unavailable, or missing / not_configured). Having a saved token does not establish that Slack accepts it.
invalid_auth, token_expired, token_revoked and account_inactive stay unchanged in the result's code field, alongside recovery guidance and next_step. When these people reads, DM opening or notified-note sending surface a credential refusal, the result also includes a fixed token_role (user or bot) when the attempt is known. Structured errors acquiring credentials keep their existing recovery shape.
Tools (39)
Authentication
authenticate_slack_workspace— Returns structured auth_required response; the host drives OAuth.list_slack_workspaces— Check Slack connection status (connected, token health, near-expiry).
Messages
search_slack_messages— Search across all channels (Slack search modifiers supported).querymay be left out whento_me,afterorbeforeis given; a call with none of them is refused. Uses Slack's Real-Time Search API (assistant.search.context) when the connected app holds the granularsearch:read.*scopes; otherwise falls back to legacysearch.messages, whose results are equally complete. The response records which backend ran insearch_backend; that field is diagnostic only and the fallback is not narrated to the user, because enabling the Real-Time Search path is an app-configuration change rather than anything the person asking can do. The fallback is cached per workspace only for installation-scoped refusals (missing_scope,not_allowed_token_type,feature_not_enabled, endpoint-deprecation codes) — a resource-specificaccess_deniedsurfaces as an ordinary error and RTS is retried on the next call.get_slack_saved_messages— Get messages saved for later (usesis:saved). Same search-backend reporting assearch_slack_messages.get_slack_message_by_link— Retrieve a message from its permalink URL.compose_slack_message— Open an inline editable compose form before sending; the form posts viapost_slack_messagewhen the user clicks Send.post_slack_message— Post a message; DM recipient verification baked in. Self-DMs are blocked and redirected tosend_myself_a_note(a user-token self-DM never notifies).reply_to_slack_thread— Reply to an existing thread.schedule_slack_message— Schedule a message for the future. Self-DMs are blocked (scheduled self-notes are not supported yet).list_scheduled_slack_messages— List pending scheduled messages (optionally per channel), with the IDs needed to cancel them.delete_scheduled_slack_message— Cancel a scheduled message before it posts.update_slack_message— Edit a message you posted.delete_slack_message— Permanently delete a message you posted.send_myself_a_note— Send yourself a note that actually notifies you (posts a DM from the bot to the authenticated user). Use this for "jot something down" / reminders instead of a user-token self-DM.
Text sent as you (post_slack_message, reply_to_slack_thread, schedule_slack_message, update_slack_message, and the upload_slack_file comment) writes a mention of the connector's own bot user as plain @name text when the workspace record has a bot user ID, so a host that listens for your mentions of its bot is not retriggered by its own replies. Other users' mentions are sent unchanged.
A workspace record can describe a personal app: appKind: "own" with its own appId, clientId, clientSecret and appName. Then thread replies post as that app's bot, and token refresh uses the record's clientId/clientSecret pair instead of SLACK_CLIENT_ID/SLACK_CLIENT_SECRET. If the bot is not in the channel, the reply is posted as you and the tool result says so, with a hint to invite the app. Records without appKind behave as before: replies are sent as you.
Compose send status
In hosts that remember send status, sending a message closes its other compose copies. Reloaded cards show "Message sent" with the send time and hide Reopen because they do not have the sent contents. The copy used to send keeps its posted contents in a read-only sent view, including when confirmation follows a lost reply. After an error or block reply, a later sent status from another copy shows only the sent bar, without this copy's contents. While a send is in progress, other copies show “Sending…” with Send, Retry, Cancel and Save draft (where available) disabled. Replies to this copy’s own requests keep those controls locked until the other send ends. If the send ends without a confirmed outcome, those copies return to editing and keep any earlier uncertainty. A copy waiting for its own Send reply keeps its sending view. Sent views stay read-only, and uncertainty remains until a send is confirmed. After an error or missing confirmation, check whether the message was sent before using Retry; the notice stays visible while editing and returns on Reopen. Collapsing the card does not resolve that uncertainty. Policy-block explanations stay visible while editing with Send disabled. Cancel says "Nothing sent" only when no send may have gone through, including a not-dispatched failure before the request left the device.
When sending is blocked by your settings, your organization or security policy, the card hides Retry and keeps Cancel. If the server is stopped, Retry remains available.
Send requests declare _meta: { 'mcp-app/cardOutcome': 'sent' } to supporting hosts.
Channels
list_slack_channels— List channels (filterable, paginated).get_slack_channel_history— Get recent messages from a channel.create_slack_channel— Create a new channel (public or private).mark_slack_channel_as_read— Mark messages read up to a timestamp.get_slack_unread_messages— Get unread messages based on your read position.invite_user_to_channel— Add users to a channel (bulk).
Threads
get_slack_thread_replies— Get all replies in a thread.
Reactions
add_slack_reaction— Add an emoji reaction to a message.remove_slack_reaction— Remove your own reaction from a message.list_slack_emoji— List the workspace's custom emoji (name → URL/alias, both wrapped in<untrusted-content>envelopes). Entries that violate Slack's emoji name/value constraints are dropped and reported (omitted_invalid_entries), never forwarded.
Pins
list_slack_pins— List messages pinned in a channel.pin_slack_message— Pin a message to a channel.unpin_slack_message— Remove a message from a channel's pinned items (the message itself is not deleted).
Users
list_slack_users— List active users (auto-paginates name filter).get_slack_user_profile— Get detailed profile for a user.lookup_user_by_email— Find a user by exact email (preferred resolution method).open_slack_dm— Open a DM with a user (returns DM channel + verified recipient identity).
Files
download_slack_file— Download a file attachment by ID or URL.upload_slack_file— Upload a local file (workspace-constrained, race-free reads; max 50MB) and optionally share it to a channel or thread. Uses the 3-step external upload flow.
Workspace
add_slack_bookmark— Add a bookmark to a channel.list_slack_bookmarks— List a channel's bookmarks.add_slack_reminder— [EXPERIMENTAL] Create a reminder (Slack API partially deprecated; preferschedule_slack_message).list_slack_reminders— [EXPERIMENTAL] List your reminders.complete_slack_reminder— [EXPERIMENTAL] Mark a reminder complete.delete_slack_reminder— [EXPERIMENTAL] Permanently delete a reminder.
Security notes
- Slack-owned download URL guard —
download_slack_filevalidates that the Slack-suppliedurl_private_downloadis HTTPS and onslack.com/*.slack.combefore attaching the workspace bearer token. The download helper also setsredirect: 'manual'and re-validates every redirect hop, so a 302 from a compromised Slack edge to an attacker-controlled host can never replay the bearer token (added in 0.1.3 to close findingslack-010). - Untrusted-content envelopes — every tool that returns external text wraps it in
<untrusted-content source="…">…</untrusted-content>envelopes per AGENTS.md invariant #6, with close-tag breakout escaping. This applies to message text, channel topics/purposes, search results, thread replies, unread messages, and downloaded file content/names. Hosts must keep the envelopes intact when surfacing tool output to the model (added in 0.1.3 to close findingsslack-001..007). - Atomic, durable token persistence — token files are written via temp-file +
fsync+rename, thenchmod 0600, so a crash mid-write cannot lose Slack's single-use refresh token. - Refresh-failure differentiation — transient network errors, HTTP 429 rate-limits, Slack auth rejections (
invalid_grant), and malformed responses produce distinct error codes so hosts can react correctly without retrying unrecoverable failures. - No host-internal vocabulary — host-side bridge identifiers and bundled HTTP paths are explicitly absent from the published artefact (enforced by
scripts/check-no-bridge-strings.shduringprepublishOnly, and byscripts/check-internal-refs.mjs— also run asnpm run security:internal-refs— which additionally rejects internal issue-tracker references insrc/anddist/). - Race-free upload source reads —
upload_slack_filevalidates the source path inside the workspace, then opens it once (no-follow, non-blocking), enforces regular-file-only and the 50MB cap viafstaton the opened descriptor, re-verifies the descriptor's dev+inode against a fresh confined path resolution (defeats post-validation replacement, including swapped ancestor directories), and reads the bytes through the descriptor with the cap enforced on what is actually read. - Envelope parity on add-paths —
add_slack_bookmarkandadd_slack_reminderenvelope the Slack-returned title/text exactly like the list paths, with close-tag breakout escaping.
Full implementation-level notes (request-timeout composition, MSW request manifest, token-file error states, server-version drift checks, etc.) live in docs/connectors/slack-cohort-hygiene.md.
Live probe
A live probe gate is committed at test/live-probe.ts. It is not auto-run; trigger it manually:
The probe runs against the packed tarball (not the workspace source), exercising initialize + tools/list + 5 read-only + 2 write tool calls, and logs search.messages P95 latency to validate the 60s timeout default.
By default the probe is read-only: write probes (post_slack_message, add_slack_reaction) only run when LIVE_PROBE_TEST_CHANNEL_ID is set, otherwise they are skipped and the probe still exits OK.
Publish-gate mode
For pre-publish certification, run:
probe:live:gate sets LIVE_PROBE_REQUIRE_WRITES=1, which causes the probe to fail rather than skip if LIVE_PROBE_TEST_CHANNEL_ID is missing or any write probe doesn't complete cleanly. Use this before cutting a release.
Licence
FSL-1.1-MIT — Functional Source License, Version 1.1, with MIT future licence. The software converts to MIT licence on 2030-04-08.
來源:connectors/slack/README.md,提交 5510a4b
工具
0版本歷史
6- v0.3.5Nov 4, 2026
- v0.3.4Nov 3, 2026
- v0.3.3Oct 31, 2026
- v0.3.2Oct 31, 2026
- v0.3.1Oct 29, 2026
- v0.3.0Sep 16, 2026
評分
已滿足適用檢查項的 80%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具必需15 分
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分
請在儲存庫或註冊中心條目中宣告授權條款。