Metadata-Version: 2.4
Name: slack-notifier-mcp
Version: 0.4.0
Summary: MCP server for Slack notifications with bidirectional communication
Project-URL: Homepage, https://github.com/strand-ai/slack-notifier-mcp
Project-URL: Repository, https://github.com/strand-ai/slack-notifier-mcp
Project-URL: Issues, https://github.com/strand-ai/slack-notifier-mcp/issues
Project-URL: Changelog, https://github.com/strand-ai/slack-notifier-mcp/blob/main/CHANGELOG.md
Author: Oded Falik
License: MIT
License-File: LICENSE
Keywords: claude,mcp,notifications,slack
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: fastmcp<3,>=2.0.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: slack-sdk>=3.27.0
Provides-Extra: dev
Requires-Dist: black>=24.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.3.0; extra == 'dev'
Description-Content-Type: text/markdown

# Slack Notifier MCP

[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![MCP](https://img.shields.io/badge/MCP-compatible-green.svg)](https://modelcontextprotocol.io/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)

MCP server for **bidirectional Slack communication** with Claude Code. Get notified when tasks complete, and respond to Claude's questions directly from Slack.

## Quick Start

```bash
# Add to Claude Code (one command)
claude mcp add slack-notifier -s user \
  -e SLACK_BOT_TOKEN=xoxb-your-token \
  -e SLACK_DEFAULT_CHANNEL=YOUR-CHANNEL-ID \
  -- uvx slack-notifier-mcp@latest
```

## Features

- **Send Messages** - Send messages with optional urgency levels and thread support
- **Ask & Wait** - Ask questions and wait for replies via Slack threads
- **Read Channels** - Read message history from any channel for analysis or triage
- **Discover Channels** - List and explore channels dynamically
- **Bidirectional** - Reply to Claude from Slack, get responses back in your terminal
- **Urgency Levels** - Normal, important, and critical notifications with appropriate formatting

## Slack App Setup

Before using this server, you need to create a Slack app:

1. Go to [api.slack.com/apps](https://api.slack.com/apps) and click **Create New App**
2. Choose **From scratch**, name it (e.g., "Claude Code"), and select your workspace
3. Go to **OAuth & Permissions** in the sidebar
4. Under **Scopes > Bot Token Scopes**, add:
   - `chat:write` - Send messages
   - `channels:read` - List public channels
   - `channels:history` - Read public channel messages
   - `groups:read` - List private channels
   - `groups:history` - Read private channel messages
   - `im:history` - Read DM messages (optional)
   - `users:read` - Get user display names
5. Click **Install to Workspace** at the top
6. Copy the **Bot User OAuth Token** (starts with `xoxb-`)

To get your default channel ID:
- Open Slack, right-click the channel, and select **View channel details**
- At the bottom, copy the **Channel ID** (starts with `C`)

## Installation

### Claude Code (Recommended)

```bash
claude mcp add slack-notifier -s user \
  -e SLACK_BOT_TOKEN=xoxb-your-token \
  -e SLACK_DEFAULT_CHANNEL=YOUR-CHANNEL-ID \
  -- uvx slack-notifier-mcp@latest
```

### VS Code

```bash
code --add-mcp '{"name":"slack-notifier","command":"uvx","args":["slack-notifier-mcp@latest"],"env":{"SLACK_BOT_TOKEN":"xoxb-your-token","SLACK_DEFAULT_CHANNEL":"YOUR-CHANNEL-ID"}}'
```

### Other MCP Clients

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

Add to your Claude Desktop config:
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux**: `~/.config/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "slack-notifier": {
      "command": "uvx",
      "args": ["slack-notifier-mcp@latest"],
      "env": {
        "SLACK_BOT_TOKEN": "xoxb-your-token",
        "SLACK_DEFAULT_CHANNEL": "YOUR-CHANNEL-ID"
      }
    }
  }
}
```

</details>

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

1. Go to **Settings → MCP → Add new MCP Server**
2. Select `command` type
3. Enter command: `uvx slack-notifier-mcp@latest`
4. Add environment variables for `SLACK_BOT_TOKEN` and `SLACK_DEFAULT_CHANNEL`

Or add to `~/.cursor/mcp.json`:
```json
{
  "mcpServers": {
    "slack-notifier": {
      "command": "uvx",
      "args": ["slack-notifier-mcp@latest"],
      "env": {
        "SLACK_BOT_TOKEN": "xoxb-your-token",
        "SLACK_DEFAULT_CHANNEL": "YOUR-CHANNEL-ID"
      }
    }
  }
}
```

</details>

<details>
<summary><strong>Windsurf / Other MCP Clients</strong></summary>

Any MCP-compatible client can use slack-notifier:

```json
{
  "mcpServers": {
    "slack-notifier": {
      "command": "uvx",
      "args": ["slack-notifier-mcp@latest"],
      "env": {
        "SLACK_BOT_TOKEN": "xoxb-your-token",
        "SLACK_DEFAULT_CHANNEL": "YOUR-CHANNEL-ID"
      }
    }
  }
}
```

</details>

### Local Development

```bash
git clone https://github.com/strand-ai/slack-notifier-mcp.git
cd slack-notifier-mcp
uv sync
uv run slack-notifier-mcp
```

## MCP Tools

### `send`

Send a message to Slack with optional urgency and thread support.

```python
# Simple message
send(message="Build completed successfully")

# With urgency (adds formatting and @here for critical)
send(
    message="Server is down!",
    urgency="critical"  # or "normal", "important"
)

# Reply in a thread
send(
    message="Done with the first step, moving on...",
    thread_ts="1234567890.123456"
)

# Mention user
send(
    message="Need your attention",
    mention_user=True
)
```

**Parameters:**
- `message` (required): Message text (supports Slack mrkdwn)
- `channel` (optional): Channel ID or name (uses default if not set)
- `thread_ts` (optional): Thread timestamp to reply in a thread
- `urgency` (optional): `normal`, `important`, or `critical`
- `mention_user` (optional): If true, @mentions the configured user

### `ask_user`

Send a question and wait for the user's reply.

```python
ask_user(
    question="Should I use PostgreSQL or SQLite for the database?",
    context="Setting up the backend for the new API",
    timeout_minutes=10
)
# Returns: {"success": True, "reply": "Use PostgreSQL", ...}
```

**Parameters:**
- `question` (required): The question to ask
- `channel` (optional): Channel ID or name
- `context` (optional): Additional context about what you're working on
- `timeout_minutes` (optional): How long to wait (default 5, max 30)

### `get_thread_replies`

Check for new replies in a thread.

```python
get_thread_replies(
    channel="YOUR-CHANNEL-ID",
    thread_ts="1234567890.123456",
    since_ts="1234567891.000000"  # Only newer messages
)
```

### `list_channels`

Discover available Slack channels.

```python
# List all channels the bot has access to
list_channels()

# Filter by type
list_channels(
    types="public_channel",  # or "private_channel", "mpim", "im"
    limit=50,
    exclude_archived=True
)
# Returns: {"success": True, "channels": [{"id": "C123...", "name": "general", ...}], ...}
```

**Parameters:**
- `types` (optional): Comma-separated channel types (default: "public_channel,private_channel")
- `limit` (optional): Max channels to return (default 100, max 1000)
- `exclude_archived` (optional): Exclude archived channels (default True)

### `read_channel_history`

Read messages from any channel. Great for triaging contacts, analyzing conversations, or reviewing submissions.

```python
# Read recent messages
read_channel_history(channel="landing-page-contacts", limit=100)

# Read with time filters
read_channel_history(
    channel="C1234567890",
    limit=500,
    oldest="1704067200.000000",  # Unix timestamp
    include_all_metadata=True    # Include reactions, attachments, files
)
# Returns: {"success": True, "messages": [{"text": "...", "user": "...", ...}], ...}
```

**Parameters:**
- `channel` (required): Channel ID or name
- `limit` (optional): Number of messages (default 100, max 1000)
- `oldest` (optional): Only messages after this Unix timestamp
- `latest` (optional): Only messages before this Unix timestamp
- `include_all_metadata` (optional): Include reactions, attachments, files

### `get_channel_info`

Get detailed information about a channel.

```python
get_channel_info(channel="landing-page-contacts")
# Returns: {"success": True, "channel": {"id": "...", "name": "...", "purpose": "...", ...}}
```

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `SLACK_BOT_TOKEN` | Yes | Bot token from Slack app (xoxb-...) |
| `SLACK_DEFAULT_CHANNEL` | No | Default channel for notifications |

## Example Usage

Tell Claude Code:

> "Notify me on Slack when the tests finish running"

> "Ask me on Slack whether to proceed with the database migration"

> "Send a Slack notification if any errors occur while I'm away"

## Debugging

Run the MCP inspector to test tools:

```bash
npx @anthropics/mcp-inspector uvx slack-notifier-mcp@latest
```

Check if your token works:

```bash
curl -H "Authorization: Bearer xoxb-your-token" \
  https://slack.com/api/auth.test
```

## Development

```bash
# Install with dev dependencies
uv sync --extra dev

# Run tests
uv run pytest

# Format code
uv run black slack_mcp
uv run ruff check slack_mcp --fix
```

## License

MIT
