# Slack MCP Server
An MCP (Model Context Protocol) server that exposes the Slack API, enabling AI agents (Claude, Cursor, etc.) to interact with Slack directly.
Provides **20 tools** and **2 resources** with focused Slack API coverage.
## Features
- **20 MCP Tools** — channels, messages, users, files, and reactions
- **2 MCP Resources** — `slack://channels` and `slack://users` for workspace discovery
- **Rate Limit Handling** — automatic retry with `Retry-After` backoff via slack_sdk built-in handlers
- **Safety Controls** — channel whitelist for message-sending restrictions, write tools disabled by default
- **Conditional Tool Registration** — search tools auto-disabled when User Token is not provided
- **Block Kit Support** — all message tools accept Block Kit JSON
- **Multiple Transports** — stdio (default), SSE, and streamable-http
- **Docker Support** — production-ready Dockerfile included
## Requirements
- Python >= 3.10
- [uv](https://docs.astral.sh/uv/) (recommended) or pip
- Slack Bot Token (`xoxb-...`) — required
- Slack User Token (`xoxp-...`) — optional, enables search features
## Installation
```bash
git clone https://github.com/software-engineer-mj/slack-mcp.git
cd slack-mcp
uv sync
```
## Configuration
```bash
cp .env.example .env
```
Edit the `.env` file and fill in your tokens:
| Variable | Required | Description |
|----------|----------|-------------|
| `SLACK_BOT_TOKEN` | Yes | Bot token (`xoxb-...`) |
| `SLACK_USER_TOKEN` | No | User token (`xoxp-...`) for search features |
| `SLACK_MCP_LOG_LEVEL` | No | Log level: `DEBUG`, `INFO` (default), `WARNING`, `ERROR` |
| `SLACK_MCP_ALLOWED_CHANNELS` | No | Comma-separated channel IDs to restrict message sending (e.g., `C123,C456`). Default: all channels allowed |
### Safety Controls
**Channel Whitelist:** When `SLACK_MCP_ALLOWED_CHANNELS` is set, message-sending tools (`send_message`, `reply_to_thread`, `update_message`) are restricted to the listed channels only.
### Slack App Permissions (Bot Token Scopes)
The Bot Token requires the following OAuth scopes:
| Scope | Purpose |
|-------|---------|
| `channels:read` | List and view channel info |
| `channels:history` | Read channel message history |
| `groups:read` | View private channels |
| `groups:history` | Read private channel history |
| `chat:write` | Send and update messages |
| `im:read` | View direct messages |
| `im:history` | Read DM history |
| `im:write` | Open DMs |
| `mpim:read` | View group DMs |
| `mpim:history` | Read group DM history |
| `users:read` | View user info |
| `users:read.email` | Look up users by email |
| `users.profile:read` | View user profiles |
| `reactions:read` | View reactions |
| `reactions:write` | Add reactions |
| `files:read` | View files |
| `files:write` | Upload files |
Additional scope required for User Token:
| Scope | Purpose |
|-------|---------|
| `search:read` | Search messages and files |
## Usage
### stdio (default)
```bash
uv run python -m slack_mcp
```
### SSE transport
```bash
uv run python -m slack_mcp --transport=sse
```
### Streamable HTTP transport
```bash
uv run python -m slack_mcp --transport=streamable-http
```
### Docker
```bash
docker build -t slack-mcp .
docker run -e SLACK_BOT_TOKEN=xoxb-your-token \
-e SLACK_USER_TOKEN=xoxp-your-token \
slack-mcp
```
To restrict channels:
```bash
docker run -e SLACK_BOT_TOKEN=xoxb-your-token \
-e SLACK_MCP_ALLOWED_CHANNELS=C123,C456 \
slack-mcp
```
## MCP Client Configuration
### Claude Desktop
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"slack": {
"command": "uv",
"args": ["run", "--directory", "/path/to/slack-mcp", "python", "-m", "slack_mcp"],
"env": {
"SLACK_BOT_TOKEN": "xoxb-your-token",
"SLACK_USER_TOKEN": "xoxp-your-token"
}
}
}
}
```
### Claude Code
Add to `.mcp.json`:
```json
{
"mcpServers": {
"slack": {
"command": "uv",
"args": ["run", "--directory", "/path/to/slack-mcp", "python", "-m", "slack_mcp"],
"env": {
"SLACK_BOT_TOKEN": "xoxb-your-token",
"SLACK_USER_TOKEN": "xoxp-your-token"
}
}
}
}
```
## Development
```bash
# Install with dev dependencies
uv sync --dev
# Run tests
uv run pytest tests/ -v
# Lint
uv run ruff check src/ tests/
# Format
uv run ruff format src/ tests/
```
## Available Tools (20)
### Channels (6)
| Tool | Description |
|------|-------------|
| `list_channels` | List channels (with cursor pagination support) |
| `get_channel_info` | Get channel details |
| `get_channel_history` | Read channel message history |
| `get_channel_members` | List channel members (with cursor pagination support) |
| `get_channel_summary` | Summarize recent activity (resolved names + threads) |
| `open_conversation` | Open a DM conversation |
### Messages (5)
| Tool | Description |
|------|-------------|
| `send_message` | Send a message (supports Block Kit) |
| `reply_to_thread` | Reply to a thread (supports Block Kit) |
| `get_thread_replies` | Get thread replies |
| `update_message` | Update a message (supports Block Kit) |
| `search_messages` | Search messages (requires User Token) |
### Users (4)
| Tool | Description |
|------|-------------|
| `list_users` | List users (with cursor pagination support) |
| `get_user_info` | Get user details (cached) |
| `get_user_profile` | Get user profile |
| `lookup_user_by_email` | Look up a user by email |
### Files (3)
| Tool | Description |
|------|-------------|
| `list_files` | List files (with page-based pagination) |
| `upload_file` | Upload a file |
| `search_files` | Search files (requires User Token) |
### Reactions (2)
| Tool | Description |
|------|-------------|
| `add_reaction` | Add an emoji reaction |
| `list_reactions` | Get all reactions on a message |
## MCP Resources
| URI | Description |
|-----|-------------|
| `slack://channels` | CSV list of all channels (id, name, is_private, num_members) |
| `slack://users` | CSV list of all users (id, name, real_name, is_bot, deleted) |
## Project Structure
```
src/slack_mcp/
├── __init__.py # FastMCP server instance
├── __main__.py # Entry point with auto-discovery
├── client.py # SlackClient singleton (API calls, error handling, pagination)
├── exceptions.py # Custom exception hierarchy
├── lifespan.py # Server lifecycle (conditional tool registration, safety controls)
├── resources.py # MCP resources (channels, users)
└── tools/
├── __init__.py
├── channels.py # Channels
├── files.py # Files
├── messages.py # Messages (Block Kit support)
├── reactions.py # Reactions
└── users.py # Users
tests/
├── conftest.py # Shared fixtures (mock Slack clients)
├── test_client.py # SlackClient tests (error handling, pagination, safety)
├── test_exceptions.py # Exception hierarchy tests
├── test_pagination.py # Pagination utility tests
├── test_resources.py # MCP resource tests
└── tools/
├── test_channels.py
├── test_files.py
├── test_messages.py
├── test_reactions.py
└── test_users.py
```
## License
MIT - see [LICENSE](LICENSE) for details.