Skip to main content
Glama
Slack MCP Server

Slack MCP Server

by bcharleson

Slack Agent CLI

A CLI and Model Context Protocol (MCP) server for Slack API integration. Use slack from the terminal for scripting and agent workflows, or slack mcp for AI assistant integration via stdio MCP.

AI agents: See AGENTS.md for install, auth, all commands, MCP tool names, and workflow examples.

Features

Channel Management

  • List all accessible channels (public/private)

  • Get channel information and details

  • Create new channels

  • Archive channels

  • Join/leave channels

  • Set channel topics

  • Fetch channel message history

Messaging

  • Post messages to channels

  • Reply to message threads

  • Update and delete messages

  • Add and remove emoji reactions

  • Get message reactions

Direct Messages (DMs)

  • Send direct messages to users

  • List DM and group DM conversations

  • Fetch DM conversation history

  • Open new DM conversations

Search (requires User Token)

  • Search messages across the workspace

  • Search files

  • Combined search for messages and files

User Management

  • List workspace users

  • Get user profile information

  • Check user presence/online status

  • Look up users by email

  • Get bot and team information

Related MCP server: Slack MCP Server

Prerequisites

  • Python 3.10 or higher

  • A Slack workspace with admin access to create apps

  • Slack Bot Token (xoxb-...) for most operations

  • Slack User Token (xoxp-...) for search functionality

Installation

Requires Node.js 18+ and Python 3.10+.

npm install -g slack-agent-cli
slack --version

MCP via global install:

slack mcp

From source (Python)

1. Clone the Repository

git clone https://github.com/bcharleson/slack-agent-cli.git
cd slack-agent-cli

2. Create Virtual Environment

python3.12 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

3. Install Dependencies

pip install -e .

Or install from requirements:

pip install -r requirements.txt

Slack App Setup

1. Create a Slack App

  1. Go to Slack API Apps

  2. Click "Create New App" → "From scratch"

  3. Name your app and select your workspace

2. Configure Bot Token Scopes

Navigate to OAuth & Permissions and add these Bot Token Scopes:

Channels

  • channels:read - View basic channel info

  • channels:write - Manage public channels

  • channels:history - View messages in public channels

  • groups:read - View private channels

  • groups:write - Manage private channels

  • groups:history - View messages in private channels

Messaging

  • chat:write - Send messages

  • reactions:read - View reactions

  • reactions:write - Add reactions

Direct Messages

  • im:read - View DM info

  • im:write - Start DMs

  • im:history - View DM history

  • mpim:read - View group DM info

  • mpim:write - Start group DMs

  • mpim:history - View group DM history

Users

  • users:read - View users

  • users:read.email - View user emails

If you need search functionality, add these User Token Scopes:

  • search:read - Search messages and files

4. Install the App

  1. Click "Install to Workspace"

  2. Authorize the app

  3. Copy the Bot User OAuth Token (starts with xoxb-)

  4. If using search, also copy the User OAuth Token (starts with xoxp-)

Configuration

Environment Variables

Create a .env file in the project root:

# Required: Bot Token for most operations
SLACK_BOT_TOKEN=xoxb-your-bot-token-here

# Optional: User Token for search functionality
SLACK_USER_TOKEN=xoxp-your-user-token-here

You can copy the example file:

cp .env.example .env
# Then edit .env with your tokens

Usage

CLI

After installation, the slack command exposes grouped subcommands that mirror the MCP tools:

# Channels
slack channels list
slack channels info C01234567
slack channels history C01234567 --limit 10

# Messages
slack messages post C01234567 "Hello from the CLI"
slack messages reply C01234567 1710000000.000100 "Thread reply"

# DMs
slack dms send U01234567 "Quick note from CLI"
slack dms list

# Search (requires SLACK_USER_TOKEN)
slack search messages "project update in:#general"

# Users / workspace
slack users list
slack users lookup brandon@example.com
slack workspace team

# Output formatting
slack --pretty channels list
slack --output json --quiet channels list

Global options:

  • --bot-token / SLACK_BOT_TOKEN

  • --user-token / SLACK_USER_TOKEN

  • --output json|pretty (default: json)

  • --pretty shorthand

  • --quiet for exit-code-only automation

MCP server

Start the stdio MCP server:

slack mcp
# or
slack-agent-cli mcp

Running the Server (development)

source venv/bin/activate
python -m slack_agent_cli.cli mcp

Claude Desktop Configuration

Add to your Claude Desktop configuration file:

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

{
  "mcpServers": {
    "slack": {
      "command": "/path/to/slack-agent-cli/venv/bin/python",
      "args": ["-m", "slack_agent_cli"],
      "cwd": "/path/to/slack-agent-cli",
      "env": {
        "SLACK_BOT_TOKEN": "xoxb-your-bot-token",
        "SLACK_USER_TOKEN": "xoxp-your-user-token"
      }
    }
  }
}

Replace /path/to/slack-agent-cli with the actual path to your installation.

Cursor IDE Configuration

Add to your Cursor MCP settings (~/.cursor/mcp.json):

{
  "mcpServers": {
    "slack-agent-cli": {
      "command": "slack",
      "args": ["mcp"],
      "env": {
        "SLACK_BOT_TOKEN": "xoxb-your-bot-token",
        "SLACK_USER_TOKEN": "xoxp-your-user-token"
      }
    }
  }
}

Or with a global install:

{
  "mcpServers": {
    "slack-agent-cli": {
      "command": "slack",
      "args": ["mcp"],
      "env": {
        "SLACK_BOT_TOKEN": "xoxb-your-bot-token",
        "SLACK_USER_TOKEN": "xoxp-your-user-token"
      }
    }
  }
}

Available Tools

Channel Tools

Tool

Description

list_channels

List all accessible channels

get_channel_info

Get details about a specific channel

create_channel

Create a new channel

archive_channel

Archive a channel

get_channel_history

Fetch message history

join_channel

Join a channel

leave_channel

Leave a channel

set_channel_topic

Set channel topic

Message Tools

Tool

Description

post_message

Post a message to a channel

reply_to_thread

Reply in a thread

get_thread_replies

Get all replies in a thread

add_reaction

Add emoji reaction

remove_reaction

Remove emoji reaction

get_message_reactions

Get reactions on a message

update_message

Update an existing message

delete_message

Delete a message

DM Tools

Tool

Description

send_dm

Send a direct message

list_conversations

List DM conversations

get_dm_history

Fetch DM history

open_dm

Open a DM conversation

Search Tools (requires User Token)

Tool

Description

search_messages

Search messages

search_files

Search files

search_all

Search both messages and files

User Tools

Tool

Description

list_users

List workspace users

get_user_info

Get user details

get_user_presence

Check if user is online

lookup_user_by_email

Find user by email

get_user_profile

Get detailed profile

get_bot_info

Get bot identity

get_team_info

Get workspace info

Testing

Using MCP Inspector

npx @modelcontextprotocol/inspector python -m slack_agent_cli

This opens a web interface to test all available tools interactively.

Manual Testing

  1. Start the server

  2. Use Claude Desktop or another MCP client

  3. Try basic commands:

    • "List all channels in the workspace"

    • "Get the history of #general channel"

    • "Send a message to #test-channel saying Hello!"

Troubleshooting

"SLACK_BOT_TOKEN is not set"

Ensure your .env file exists and contains the token, or set it in your MCP client configuration.

"Search requires a User Token"

Search operations require a User Token (SLACK_USER_TOKEN). Add User Token scopes to your Slack app and include the token.

"channel_not_found"

The bot may not have access to the channel. Ensure:

  1. The channel exists

  2. The bot is a member of private channels

  3. The channel ID is correct (use list_channels to find IDs)

"missing_scope"

Your Slack app is missing required permissions. Check the OAuth scopes section above and add the missing scopes in your Slack app settings.

Development

Project Structure

slack-agent-cli/
├── src/
│   └── slack_agent_cli/
│       ├── cli/
│       │   └── main.py            # Click CLI + `slack mcp`
│       ├── core/
│       │   └── output.py          # JSON/pretty output helpers
│       ├── operations/            # Shared handlers for CLI + MCP
│       │   ├── channels.py
│       │   ├── messages.py
│       │   ├── search.py
│       │   └── users.py
│       ├── tools/                   # MCP tool registration
│       ├── utils/
│       │   └── slack_client.py
│       └── server.py              # FastMCP stdio server
├── pyproject.toml
├── package.json
├── AGENTS.md                      # AI agent guide (commands, MCP, workflows)
├── requirements.txt
├── .env.example
└── README.md

Adding New Tools

  1. Create or edit a file in src/slack_agent_cli/tools/

  2. Define tools using the @mcp.tool() decorator

  3. Register the tools in the server by calling the registration function

License

MIT License

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Available Tools

30 tools
add_reactionA
    Add an emoji reaction to a message.

    Args:
        channel_id: The ID of the channel containing the message (e.g., "C01234567")
        timestamp: The timestamp of the message to react to
        emoji: The emoji name without colons (e.g., "thumbsup", "heart", "rocket")

    Returns:
        Dictionary indicating success or error
    

Inputs: channel_id (required), timestamp (required), emoji (required). Returns: object

archive_channelA
    Archive a Slack channel.

    Args:
        channel_id: The ID of the channel to archive (e.g., "C01234567")

    Returns:
        Dictionary indicating success or error
    

Inputs: channel_id (required). Returns: object

create_channelA
    Create a new Slack channel.

    Args:
        name: Name for the new channel (max 80 chars, lowercase,
              no spaces, use hyphens instead)
        is_private: Whether to create a private channel. Default: False

    Returns:
        Dictionary containing the created channel's details
    

Inputs: name (required), is_private. Returns: object

delete_messageB
    Delete a message from a channel.

    Args:
        channel_id: The ID of the channel containing the message (e.g., "C01234567")
        timestamp: The timestamp of the message to delete

    Returns:
        Dictionary indicating success or error
    

Inputs: channel_id (required), timestamp (required). Returns: object

get_bot_infoB
    Get information about the authenticated bot user.

    Returns:
        Dictionary containing bot identity information
    

Inputs: no named parameters. Returns: object

get_channel_historyA
    Fetch message history from a Slack channel.

    Args:
        channel_id: The ID of the channel (e.g., "C01234567")
        limit: Maximum number of messages to return (1-1000). Default: 20
        oldest: Unix timestamp of oldest message to include (optional)
        latest: Unix timestamp of latest message to include (optional)

    Returns:
        Dictionary containing list of messages with sender, text,
        timestamp, and thread info
    

Inputs: channel_id (required), limit, oldest, latest. Returns: object

get_channel_infoA
    Get detailed information about a specific Slack channel.

    Args:
        channel_id: The ID of the channel (e.g., "C01234567")

    Returns:
        Dictionary containing channel details including name, topic,
        purpose, member count, and creation date
    

Inputs: channel_id (required). Returns: object

get_dm_historyA
    Fetch message history from a DM or group DM conversation.

    Args:
        channel_id: The ID of the DM conversation (e.g., "D01234567")
        limit: Maximum number of messages to return (1-1000). Default: 20
        oldest: Unix timestamp of oldest message to include (optional)
        latest: Unix timestamp of latest message to include (optional)

    Returns:
        Dictionary containing list of messages
    

Inputs: channel_id (required), limit, oldest, latest. Returns: object

get_message_reactionsA
    Get all reactions on a specific message.

    Args:
        channel_id: The ID of the channel containing the message (e.g., "C01234567")
        timestamp: The timestamp of the message

    Returns:
        Dictionary containing the message and its reactions
    

Inputs: channel_id (required), timestamp (required). Returns: object

get_team_infoB
    Get information about the Slack workspace/team.

    Returns:
        Dictionary containing workspace information
    

Inputs: no named parameters. Returns: object

get_thread_repliesB
    Get all replies in a message thread.

    Args:
        channel_id: The ID of the channel containing the thread (e.g., "C01234567")
        thread_ts: The timestamp of the parent message
        limit: Maximum number of replies to return (1-1000). Default: 20

    Returns:
        Dictionary containing the thread messages
    

Inputs: channel_id (required), thread_ts (required), limit. Returns: object

get_user_infoC
    Get detailed information about a specific user.

    Args:
        user_id: The ID of the user (e.g., "U01234567")

    Returns:
        Dictionary containing detailed user profile information
    

Inputs: user_id (required). Returns: object

get_user_presenceC
    Get the presence/online status of a user.

    Args:
        user_id: The ID of the user (e.g., "U01234567")

    Returns:
        Dictionary containing user presence information
    

Inputs: user_id (required). Returns: object

get_user_profileB
    Get the profile information for a user.

    Args:
        user_id: The ID of the user (e.g., "U01234567")

    Returns:
        Dictionary containing detailed profile fields
    

Inputs: user_id (required). Returns: object

join_channelB
    Join a Slack channel.

    Args:
        channel_id: The ID of the channel to join (e.g., "C01234567")

    Returns:
        Dictionary indicating success or error with channel info
    

Inputs: channel_id (required). Returns: object

leave_channelA
    Leave a Slack channel.

    Args:
        channel_id: The ID of the channel to leave (e.g., "C01234567")

    Returns:
        Dictionary indicating success or error
    

Inputs: channel_id (required). Returns: object

list_channelsB
    List all accessible Slack channels in the workspace.

    Args:
        types: Comma-separated channel types to include.
               Options: public_channel, private_channel, mpim, im
               Default: "public_channel,private_channel"
        exclude_archived: Whether to exclude archived channels. Default: True
        limit: Maximum number of channels to return (1-1000). Default: 100

    Returns:
        Dictionary containing list of channels with their details
    

Inputs: types, exclude_archived, limit. Returns: object

list_conversationsA
    List direct message and group DM conversations.

    Args:
        types: Comma-separated conversation types. Default: "im,mpim"
               Options: im (1:1 DMs), mpim (group DMs)
        limit: Maximum number of conversations to return. Default: 50

    Returns:
        Dictionary containing list of DM conversations
    

Inputs: types, limit. Returns: object

list_usersB
    List all users in the Slack workspace.

    Args:
        limit: Maximum number of users to return (1-1000). Default: 100
        include_locale: Include locale information for users. Default: False

    Returns:
        Dictionary containing list of users with their profiles
    

Inputs: limit, include_locale. Returns: object

lookup_user_by_emailB
    Find a user by their email address.

    Args:
        email: The email address to look up

    Returns:
        Dictionary containing the user's profile if found
    

Inputs: email (required). Returns: object

open_dmB
    Open a direct message or group DM conversation.

    Args:
        user_ids: Comma-separated user IDs to open a conversation with
                  (e.g., "U01234567" for DM, "U01234567,U07654321" for group DM)

    Returns:
        Dictionary containing the conversation channel details
    

Inputs: user_ids (required). Returns: object

post_messageA
    Post a message to a Slack channel.

    Args:
        channel_id: The ID of the channel to post to (e.g., "C01234567")
        text: The message text to post (supports Slack markdown)
        thread_ts: Optional thread timestamp to reply in a thread
        unfurl_links: Whether to unfurl text-based URLs. Default: True
        unfurl_media: Whether to unfurl media URLs. Default: True

    Returns:
        Dictionary containing the posted message details including timestamp
    

Inputs: channel_id (required), text (required), thread_ts, unfurl_links, +1 more. Returns: object

remove_reactionA
    Remove an emoji reaction from a message.

    Args:
        channel_id: The ID of the channel containing the message (e.g., "C01234567")
        timestamp: The timestamp of the message
        emoji: The emoji name without colons (e.g., "thumbsup", "heart", "rocket")

    Returns:
        Dictionary indicating success or error
    

Inputs: channel_id (required), timestamp (required), emoji (required). Returns: object

reply_to_threadA
    Reply to a message thread in Slack.

    Args:
        channel_id: The ID of the channel containing the thread (e.g., "C01234567")
        thread_ts: The timestamp of the parent message to reply to
        text: The reply message text (supports Slack markdown)
        broadcast: Whether to also post the reply to the channel. Default: False

    Returns:
        Dictionary containing the posted reply details
    

Inputs: channel_id (required), thread_ts (required), text (required), broadcast. Returns: object

search_allA
    Search both messages and files across the Slack workspace.

    Note: Requires a User Token (SLACK_USER_TOKEN) as search is not
    available with bot tokens.

    Args:
        query: Search query string. Supports Slack search modifiers.
        sort: Sort order - "timestamp" or "score". Default: "timestamp"
        sort_dir: Sort direction - "asc" or "desc". Default: "desc"
        count: Number of results per type (1-100). Default: 10

    Returns:
        Dictionary containing both message and file search results
    

Inputs: query (required), sort, sort_dir, count. Returns: object

search_filesA
    Search files across the Slack workspace.

    Note: Requires a User Token (SLACK_USER_TOKEN) as search is not
    available with bot tokens.

    Args:
        query: Search query string. Supports Slack search modifiers:
               - "in:#channel" to search in specific channel
               - "from:@user" to search files from a user
               - "type:pdf" to filter by file type
               Example: "quarterly report type:pdf in:#finance"
        sort: Sort order - "timestamp" or "score". Default: "timestamp"
        sort_dir: Sort direction - "asc" or "desc". Default: "desc"
        count: Number of results to return (1-100). Default: 20
        types: Comma-separated file types to filter (optional)
               Options: images, videos, pdfs, docs, snippets, etc.

    Returns:
        Dictionary containing search results with files and metadata
    

Inputs: query (required), sort, sort_dir, count, +1 more. Returns: object

search_messagesA
    Search messages across the Slack workspace.

    Note: Requires a User Token (SLACK_USER_TOKEN) as search is not
    available with bot tokens.

    Args:
        query: Search query string. Supports Slack search modifiers:
               - "in:#channel" to search in specific channel
               - "from:@user" to search messages from a user
               - "has:reaction" to find messages with reactions
               - "before:YYYY-MM-DD" or "after:YYYY-MM-DD" for date filters
               Example: "project update in:#general from:@john"
        sort: Sort order - "timestamp" or "score". Default: "timestamp"
        sort_dir: Sort direction - "asc" or "desc". Default: "desc"
        count: Number of results to return (1-100). Default: 20

    Returns:
        Dictionary containing search results with messages and metadata
    

Inputs: query (required), sort, sort_dir, count. Returns: object

send_dmB
    Send a direct message to a user.

    Args:
        user_id: The ID of the user to message (e.g., "U01234567")
        text: The message text to send (supports Slack markdown)

    Returns:
        Dictionary containing the sent message details
    

Inputs: user_id (required), text (required). Returns: object

set_channel_topicC
    Set the topic for a Slack channel.

    Args:
        channel_id: The ID of the channel (e.g., "C01234567")
        topic: The new topic text for the channel

    Returns:
        Dictionary indicating success with the new topic
    

Inputs: channel_id (required), topic (required). Returns: object

update_messageB
    Update an existing message.

    Args:
        channel_id: The ID of the channel containing the message (e.g., "C01234567")
        timestamp: The timestamp of the message to update
        text: The new message text

    Returns:
        Dictionary indicating success with updated message details
    

Inputs: channel_id (required), timestamp (required), text (required). Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 30 tools

    Disambiguation5/5

    Each tool has a distinct purpose with clear boundaries, such as add_reaction vs. remove_reaction, or get_channel_history vs. get_thread_replies. The descriptions specify unique actions and resources, preventing confusion or overlap in functionality.

    Naming Consistency5/5

    All tools follow a consistent verb_noun naming pattern (e.g., add_reaction, archive_channel, create_channel). The naming is uniform throughout, using snake_case and clear action words, making the tool set predictable and easy to navigate.

    Tool Count3/5

    With 30 tools, the count is on the higher side for a Slack server, potentially feeling heavy. While it covers many aspects of Slack's API, it might be borderline for typical agent use, as some tools could be consolidated or omitted without losing core functionality.

    Completeness5/5

    The tool set provides comprehensive coverage for Slack interactions, including channel management, messaging, user info, reactions, threads, and search. It supports full CRUD operations for messages and channels, with no obvious gaps that would hinder agent workflows in this domain.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables interaction with Slack workspaces through comprehensive integration capabilities. Supports channel management, messaging, thread replies, reactions, and message history retrieval through natural language commands.
      156 npm
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Enables comprehensive Slack workspace integration through AI assistants, allowing users to manage channels, send messages, upload files, search conversations, and interact with users through natural language commands.
      17
      ISC
    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants to interact with Slack workspaces through natural language, supporting channel management, message operations, user profiles, reactions, and threaded conversations.
      -
    • A
      license
      A
      quality
      D
      maintenance
      Integrates AI assistants with Slack workspaces using OAuth 2.0 authenticated user tokens for secure, multi-functional interaction. It enables comprehensive operations including channel management, message searching, file handling, and reaction management through natural language.
      20
      169 npm
      MIT