Skip to main content
Glama
README.md
# slack-mcp

A Model Context Protocol (MCP) server that enables AI assistants to interact with Slack workspaces. This server provides a bridge between AI tools and Slack, allowing you to read messages, post content, and manage Slack channels programmatically through MCP-compatible clients.

Disclaimer: This is not an official Red Hat tool.

## What is this and why should I use it?

This MCP server transforms your Slack workspace into an AI-accessible environment. It provides 21+ tools for comprehensive Slack interaction:

**Message & Thread Operations**

- Read channel history with date filtering and thread support
- Post messages and replies to threads
- Search messages across workspace or within specific channels
- Execute Slack commands

**Channel Management**

- List, join, create, and rename channels
- Look up channel IDs by name
- Invite users to channels

**Reactions & Users**

- Add and view emoji reactions
- Send direct messages and group DMs
- Manage usergroups (clear members)

**Utility**

- Check authentication status
- Cache management for performance

### Key Benefits

- **Seamless Integration**: Connect your AI assistant directly to Slack without manual copy-pasting
- **Automated Workflows**: Build AI-powered Slack bots that can read, analyze, and respond to messages
- **Enhanced Productivity**: Let AI help manage notifications, summarize conversations, or automate routine Slack tasks
- **Real-time Collaboration**: Enable AI assistants to participate in team discussions and provide instant insights

### Use Cases

- **Team Assistant**: Have an AI that can read team updates and provide summaries
- **Notification Manager**: Automatically categorize and respond to incoming messages
- **Knowledge Base**: AI that can search through channel history and provide context
- **Meeting Scheduler**: AI that can read meeting requests and help coordinate schedules

## Setting Up with Claude Code

This repo ships as a Claude Code plugin with a guided setup skill. Claude will walk you through the entire process — no manual config editing required.

Run the setup script. It handles everything — venv, Playwright, token extraction, wrapper script, and Claude Code registration. The only interaction required is logging in to Slack when the browser opens, and entering an optional channel ID for server logs, if desired.

```bash
python3 <(curl -fsSL https://raw.githubusercontent.com/redhat-community-ai-tools/slack-mcp/main/scripts/setup-slack-mcp.py)
```

Or clone the repo first and run it locally:

```bash
git clone https://github.com/redhat-community-ai-tools/slack-mcp
python3 slack-mcp/scripts/setup-slack-mcp.py
```

**Options:**


| Flag                                 | Description                                                               |
| ------------------------------------ | ------------------------------------------------------------------------- |
| `--logs-channel DXXXXXXXXX`          | Slack channel ID for server logs (optional; logs go to stderr if omitted) |
| `--workspace https://myco.slack.com` | Specific Slack workspace to open                                          |
| `--refresh-tokens`                   | Re-extract tokens when they expire (skips all other steps)                |
| `--skip-verify`                      | Skip the post-setup smoke test                                            |


When tokens expire, just run:

```bash
python3 slack-mcp/scripts/setup-slack-mcp.py --refresh-tokens
```

### Desktop App Token Refresh (Linux)

If you have the [Slack desktop app](https://slack.com/downloads/linux) installed, you can refresh tokens without opening a browser:

```bash
slack-mcp/scripts/slack-refresh-tokens --validate
```

This reads tokens directly from the desktop app's local storage on disk — no DevTools, no Playwright, no manual steps. Requires the Slack app to be signed in.


| Flag            | Description                                                                    |
| --------------- | ------------------------------------------------------------------------------ |
| `--validate`    | Verify tokens against Slack's API after extraction                             |
| `--env`         | Print tokens as env vars to stdout (for piping into other tools)               |
| `--output FILE` | Write tokens to a custom path (default: `~/.local/share/slack-mcp/tokens.env`) |


**Requirements:** `python3`, `python3-cryptography`, `secret-tool` (libsecret/gnome-keyring), `curl`, `jq`

This is useful for CI hooks or session startup scripts that need to silently refresh tokens before launching the MCP server.

---

## Bot token authentication (recommended)

For better security, use a Slack App bot token (`xoxb-`) instead of browser session tokens. Bot tokens provide:

- **Scoped access** — only the OAuth permissions you grant, not full user access
- **Distinct identity** — actions appear as the bot, not as your user account
- **Central management** — IT can audit and revoke via the Slack admin panel
- **No browser DevTools** — tokens are generated once in the Slack App settings

### Setup

1. Create a Slack App at [api.slack.com/apps](https://api.slack.com/apps)
2. Add OAuth scopes: `channels:read`, `channels:history`, `channels:manage`, `groups:read`, `groups:history`, `groups:write`, `chat:write`, `reactions:read`, `reactions:write`, `search:read`, `users:read`, `commands`, `mpim:write`
3. Install to your workspace and copy the Bot User OAuth Token (`xoxb-...`)
4. Invite the bot to channels it needs access to

### Running with a bot token

Set `SLACK_BOT_TOKEN` instead of `SLACK_XOXC_TOKEN`/`SLACK_XOXD_TOKEN`:

```json
{
  "mcpServers": {
    "slack": {
      "command": "podman",
      "args": [
        "run", "-i", "--rm",
        "-e", "SLACK_BOT_TOKEN",
        "-e", "LOGS_CHANNEL_ID",
        "quay.io/redhat-ai-tools/slack-mcp"
      ],
      "env": {
        "SLACK_BOT_TOKEN": "xoxb-...",
        "LOGS_CHANNEL_ID": "C7000000"
      }
    }
  }
}
```

`LOGS_CHANNEL_ID` is optional. When omitted, tool activity is written to **stderr** instead of posted to Slack.

If both `SLACK_BOT_TOKEN` and `SLACK_XOXC_TOKEN`/`SLACK_XOXD_TOKEN` are set, the bot token takes precedence.

## Read-only mode

For agents or automation that should **browse and search** Slack without posting, reacting, running commands, or joining channels, enable read-only mode.

- **Environment variable:** set `SLACK_MCP_READ_ONLY` to a truthy value (`1`, `true`, `yes`, or `on`, case-insensitive).
- **CLI:** pass `--read-only` when starting the server (e.g. `slack-mcp --read-only`, equivalent to setting the variable).

In read-only mode, tools that mutate Slack state (`post_message`, `send_dm`, `post_command`, `add_reaction`, `join_channel`) raise a clear error. Read tools (history, search, threads, `whoami`, channel listing, cache refresh helpers, and so on) behave as usual. Tool activity that would normally be mirrored to `LOGS_CHANNEL_ID` is written to **stderr** instead.

On startup, the server logs a line to stderr when read-only mode is active.

For Podman or Docker, add `-e SLACK_MCP_READ_ONLY=true` (and the matching key in `env`) when you want the container to run read-only.

## Running as a uv tool (local, no container)

Prefer not to run a container? Install slack-mcp as a [uv](https://docs.astral.sh/uv/) tool. This puts a `slack-mcp` command on your PATH that runs the server directly.

Requires uv and Python ≥ 3.10.

```bash
# from a clone of this repo
uv tool install .

# or straight from git
uv tool install git+https://github.com/redhat-community-ai-tools/slack-mcp
```

Run `slack-mcp --help` for a summary of flags and environment variables.

### Tokens from `tokens.env` (recommended)

`slack-mcp` reads Slack session tokens from `~/.local/share/slack-mcp/tokens.env` when they are not already set in the environment — the same file the token tooling writes:

```bash
scripts/slack-refresh-tokens          # or: python3 scripts/setup-slack-mcp.py
```

Then the MCP client config needs **no `env` block** — just the command:

```json
{
  "mcpServers": {
    "slack": {
      "command": "slack-mcp"
    }
  }
}
```

The file uses `SLACK_MCP_XOXC_TOKEN` / `SLACK_MCP_XOXD_TOKEN`; the server maps those onto the `SLACK_XOXC_TOKEN` / `SLACK_XOXD_TOKEN` it uses. Override the path with `SLACK_MCP_TOKENS_FILE`. **Real environment variables always take precedence over the file**, so you can still override per-client.

### Tokens from the client config (alternative)

To keep tokens in the MCP config instead of a file, pass them in `env`:

```json
{
  "mcpServers": {
    "slack": {
      "command": "slack-mcp",
      "env": {
        "SLACK_XOXC_TOKEN": "xoxc-...",
        "SLACK_XOXD_TOKEN": "xoxd-...",
        "LOGS_CHANNEL_ID": "C7000000"
      }
    }
  }
}
```

A bot token works the same way — set `SLACK_BOT_TOKEN` in `env` instead of the `xoxc`/`xoxd` pair. If the client does not inherit your PATH, use the absolute path (`~/.local/bin/slack-mcp` after `uv tool install`), or launch via `uv run --directory /path/to/slack-mcp slack-mcp`.

The user cache and the default `tokens.env` live under `~/.local/share/slack-mcp/` (override with `SLACK_MCP_DATA`).

Claude Code (bot token):

```bash
claude mcp add slack -e SLACK_BOT_TOKEN=xoxb-... -- slack-mcp
```

Or, with `tokens.env` already in place, no env needed:

```bash
claude mcp add slack -- slack-mcp
```

## Running with Podman or Docker

You can run the slack-mcp server in a container using Podman or Docker:

Example configuration for running with Podman:

```json
{
  "mcpServers": {
    "slack": {
      "command": "podman",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e", "SLACK_XOXC_TOKEN",
        "-e", "SLACK_XOXD_TOKEN",
        "-e", "MCP_TRANSPORT",
        "-e", "LOGS_CHANNEL_ID",
        "quay.io/redhat-ai-tools/slack-mcp"
      ],
      "env": {
        "SLACK_XOXC_TOKEN": "xoxc-...",
        "SLACK_XOXD_TOKEN": "xoxd-...",
        "MCP_TRANSPORT": "stdio",
        "LOGS_CHANNEL_ID": "C7000000"
      }
    }
  }
}
```

`LOGS_CHANNEL_ID` is optional. When omitted, tool activity is written to **stderr** instead of posted to Slack.

## Activity logging

By default, tool activity is written to **stderr** (visible in your terminal or process logs). To mirror activity to a Slack channel instead, set `LOGS_CHANNEL_ID` to any channel the bot or session user has access to — a self-DM or a DM with Slackbot works well for personal use.

```bash
LOGS_CHANNEL_ID=C7000000
```

In read-only mode, `LOGS_CHANNEL_ID` is ignored and all activity is always written to stderr.

## Running with non-stdio transport

To run the server with a non-stdio transport (such as SSE), set the `MCP_TRANSPORT` environment variable to a value other than `stdio` (e.g., `sse`).

Example configuration to connect to a non-stdio MCP server:

```json
{
  "mcpServers": {
    "slack": {
      "url": "https://slack-mcp.example.com/sse",
      "headers": {
        "X-Slack-Web-Token": "xoxc-...",
        "X-Slack-Cookie-Token": "xoxd-..."
      }
    }
  }
}
```

Extract your Slack XOXC and XOXD tokens easily using browser extensions or Selenium automation: [https://github.com/maorfr/slack-token-extractor](https://github.com/maorfr/slack-token-extractor).

TDQS

B3.4/5.0

Scored across 22 tools

Disambiguation4/5

Most tools target distinct resources and actions, but get_thread overlaps with get_channel_history's include_threads option, and clear_usergroup is essentially a special case of update_usergroup_members. Otherwise, the boundaries are clear.

Naming Consistency4/5

Tool names mostly follow a consistent verb_noun snake_case pattern (post_message, create_channel, search_messages). Minor deviations like whoami and the somewhat vague post_command keep it from being perfectly uniform.

Tool Count3/5

With 22 tools, the set is at the heavy end for an MCP server, though Slack's broad domain justifies many of them. The inclusion of cache-refresh utilities and several overlapping search/message tools makes the surface feel slightly larger than necessary.

Completeness3/5

The server covers core messaging, channel management, reactions, search, and some usergroup operations. However, there are notable gaps such as message edit/delete, channel archive/delete/leave, and usergroup create/list/get, leaving some lifecycle workflows incomplete.

Maintenance

ActivityMaintained
ResponsivenessWithin a week