Back to MCP Servers

Slack

Your complete Slack context for Claude—DMs, channels, threads, search. No OAuth apps, no admin approval. `--setup` and done, 11 tools, auto-refresh.

communicationslack
By jtalk22
2920Updated 5 days agoJavaScriptMIT

Installation

npx -y slack-mcp-server

Configuration

{
  "mcpServers": {
    "slack-mcp-server": {
      "command": "npx",
      "args": ["-y", "slack-mcp-server"]
    }
  }
}

How to use

  1. Run the installation command above (if needed)
  2. Open your Claude Code settings file (~/.claude/settings.json)
  3. Add the configuration to the mcpServers section
  4. Restart Claude Code to apply changes

npm version npm weekly downloads CI MCP Registry npm provenance signed

<div align="center"> <h1>Slack MCP Server</h1> <h3>Slack for your AI agent — no OAuth, no admin, no app to register.</h3> <p> <kbd>Claude Code</kbd> <kbd>Claude Desktop</kbd> <kbd>Cursor</kbd> <kbd>Copilot</kbd> <kbd>Windsurf</kbd> <kbd>Gemini CLI</kbd> <kbd>Codex CLI</kbd> </p> <p><b>If you can read it in Slack, your agent can read it too.</b> It borrows the session tokens your browser already holds — no registered app, no scope review, no admin in the loop. 21 tools. One command:</p> </div>
npx -y @jtalk22/slack-mcp --setup
<div align="center"> <a href="https://jtalk22.github.io/slack-mcp-server/public/demo-video.html"> <img src="docs/images/demo-poster.png" width="800" alt="Watch the demo: 47 unread Slack messages become one morning briefing — without opening Slack"> </a> <p><sub><b><a href="https://jtalk22.github.io/slack-mcp-server/public/demo-video.html">▶ Watch the full 3:24 demo — with chapters</a></b> · <a href="https://jtalk22.github.io/slack-mcp-server/public/demo-slack-mcp.html">interactive demo</a> · <a href="docs/SETUP.md">setup guide</a></sub></p> </div> <p align="center"> <a href="#the-trick-session-tokens-not-oauth">Why no OAuth</a> · <a href="#install">Install</a> · <a href="#the-21-tools">The 21 tools</a> · <a href="#workflows-slack-in-typed-json-out">Workflows</a> · <a href="#how-token-storage-works">Token storage</a> · <a href="#hosted-optional--the-oss-package-is-complete-without-it">Hosted</a> </p>

The trick: session tokens, not OAuth

Slack's official MCP server is OAuth-first — a registered app, admin approval, and (for several clients) compatibility workarounds that don't exist yet (see the tracked Claude Code / Copilot DCR discussion). For a lot of people the "integration" quietly degrades into screenshotting messages into a chat window. That isn't an integration.

So this server does the obvious thing instead: it reads the xoxc- + xoxd- session tokens your browser is already holding and speaks Slack's own API with them. No app install, no scopes to request, no admin in the loop — and because there's no bot user and no installed app, nothing appears in the workspace admin panel. Your agent's footprint is exactly your open browser tab's: no more, no less.

<div align="center"> <img src="docs/images/diagram-oauth-comparison.svg" alt="OAuth app registration vs. browser session tokens" width="820"> </div>
Slack Official MCPThis Server
OAuth app requiredYesNo
Admin approvalYesNo
Claude Code · Cursor · Copilot · Windsurf · Gemini CLI · Codex CLIBlocked or partial (DCR)All six, today
Setup time~30 min~2 min
ToolsLimited21
Visible to adminsYesNo — session-token transport

<sub>Same permissions either way — your agent sees exactly what you see. The difference is who has to approve it.</sub>

<details> <summary><b>Is this against Slack's terms?</b></summary> <br>

Honest answer: it's a gray area, and you should know exactly what this does before you run it. This server automates <i>your own session</i> — the same class of thing as a browser extension or a userscript. It grants your agent nothing you don't already have: it can't read a channel you can't read, join a workspace you're not in, or act as anyone but you. There is no permission escalation anywhere in this codebase — just your cookie, used from your machine.

What it does <i>not</i> do: it does not evade compliance exports, DLP, or retention. Those run server-side at Slack and see this traffic like any other client's. "Invisible to admins" means there is no <i>app install</i> to review — not that your messages stop being subject to workspace policy.

If your workspace's acceptable-use policy forbids unofficial clients, respect it — the OAuth-based <a href="https://mcp.revasserlabs.com">hosted version</a> exists for exactly that case.

</details>

Watch it run

<div align="center"> <a href="https://jtalk22.github.io/slack-mcp-server/public/demo-video.html"> <img src="docs/images/watch-it-run.gif" width="900" alt="Real session: the agent calls slack_conversations_unreads, pulls channel history, and writes the morning briefing"> </a> <p><sub>A real session at 2× — unread counts → history pull → the briefing. <a href="https://jtalk22.github.io/slack-mcp-server/public/demo-video.html">Full 3:24 with chapters →</a></sub></p> </div>

Install

Node.js 20+. One command extracts your tokens, validates them, and remembers where to keep them:

npx -y @jtalk22/slack-mcp --setup

Register the server with your client, restart it, then ask your agent to run slack_health_check — a workspace name in the reply means you're live. Pick your client:

<details> <summary><strong>Claude Code</strong></summary>

Add to ~/.claude.json:

{
  "mcpServers": {
    "slack": { "type": "stdio", "command": "npx", "args": ["-y", "@jtalk22/slack-mcp"] }
  }
}

Or in one line: claude mcp add slack -- npx -y @jtalk22/slack-mcp

</details> <details> <summary><strong>Claude Desktop</strong></summary>

macOS~/Library/Application Support/Claude/claude_desktop_config.json Windows / Linux%APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "slack": { "command": "npx", "args": ["-y", "@jtalk22/slack-mcp"] }
  }
}

On Windows and Linux, auto-refresh is unavailable — supply tokens explicitly with an "env": { "SLACK_TOKEN": "xoxc-…", "SLACK_COOKIE": "xoxd-…" } block.

</details> <details> <summary><strong>Cursor</strong></summary>

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "slack": { "command": "npx", "args": ["-y", "@jtalk22/slack-mcp"] }
  }
}
</details> <details> <summary><strong>GitHub Copilot (VS Code)</strong></summary>

Add to .vscode/mcp.json:

{
  "servers": {
    "slack": { "command": "npx", "args": ["-y", "@jtalk22/slack-mcp"] }
  }
}
</details> <details> <summary><strong>Windsurf</strong></summary>

Add to ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "slack": { "command": "npx", "args": ["-y", "@jtalk22/slack-mcp"] }
  }
}
</details> <details> <summary><strong>Gemini CLI</strong></summary>

Add to ~/.gemini/settings.json:

{
  "mcpServers": {
    "slack": { "command": "npx", "args": ["-y", "@jtalk22/slack-mcp"] }
  }
}
</details> <details> <summary><strong>Codex CLI</strong></summary>

Add to ~/.codex/config.toml:

[mcp_servers.slack]
command = "npx"
args = ["-y", "@jtalk22/slack-mcp"]

Or via CLI: codex mcp add slack -- npx -y @jtalk22/slack-mcp

</details> <details> <summary><strong>Any other stdio MCP client</strong></summary>

Anything that speaks stdio MCP works — point it at npx -y @jtalk22/slack-mcp. On macOS, tokens auto-extract from Chrome (no env block needed); elsewhere, pass SLACK_TOKEN / SLACK_COOKIE via env.

</details> <details> <summary><strong>Docker</strong></summary>
docker pull ghcr.io/jtalk22/slack-mcp-server:latest
{
  "mcpServers": {
    "slack": {
      "command": "docker",
      "args": ["run", "-i", "--rm",
               "-v", "~/.slack-mcp-tokens.json:/root/.slack-mcp-tokens.json",
               "ghcr.io/jtalk22/slack-mcp-server"]
    }
  }
}
</details>

Full walkthrough — including the optional keep-tokens-fresh LaunchAgent — in docs/SETUP.md.


The 21 tools

Every workspace write-path tool carries an MCP destructive annotation so clients can gate it.

ToolDescriptionSafety
Read the workspace — 12 read-only tools
slack_health_checkVerify token validity and workspace inforead-only
slack_token_statusToken age, health, and cache statsread-only
slack_refresh_tokensAuto-extract fresh tokens from Chromeread-only*
slack_list_conversationsList DMs and channelsread-only
slack_conversations_historyGet messages from a channel or DMread-only
slack_get_full_conversationExport full history with threadsread-only
slack_search_messagesSearch across the workspaceread-only
slack_get_threadGet thread repliesread-only
slack_users_infoGet user detailsread-only
slack_list_usersList workspace users (paginated, 500+)read-only
slack_users_searchSearch users by name, display name, or emailread-only
slack_conversations_unreadsGet channels/DMs with unread messagesread-only
Act in the workspace — 4 write-path tools, all annotated destructive
slack_send_messageSend a message to any conversationdestructive
slack_add_reactionAdd an emoji reaction to a messagedestructive
slack_remove_reactionRemove an emoji reaction from a messagedestructive
slack_conversations_markMark a conversation as readdestructive
Workflow profiles — 2 tools, local JSON
slack_workflow_saveSave a workflow profile to ~/.slack-mcp-workflows.jsonlocal-write
slack_workflowsList saved workflow profilesread-only
Hosted-brain stubs — 3 tools
slack_smart_searchSemantic search across indexed channelshosted-stub†
slack_catch_me_upAI-summarized digest of unreads + priority threadshosted-stub†
slack_triagePrioritized action queue across channelshosted-stub†

<sub>* slack_refresh_tokens writes the local token file only. † Hosted stubs return a structured upgrade payload (signup_url, free_tier_quota, pro_value_prop) — no Slack call happens from OSS. ‡ Accepts include_rich_message_fields — see Rich message fields.</sub>


Workflows: Slack in, typed JSON out

Reading messages is table stakes. The primitives turn Slack into a typed data source your automation can consume directly. Bind a workflow_kind to a set of channels, priority people, retention, and cadence with slack_workflow_save (stored locally at ~/.slack-mcp-workflows.json). The hosted brain reads those profiles and returns structured JSON per kind — no prompt-parsing, no scraping, feed it straight into Linear, Notion, or a status dashboard.

workflow_kindReturns
incident_room{incident_summary, timeline, open_risks, owner_gaps, next_actions}
exec_brief`{summary, decisions, risks, asks, action_i

View source on GitHub