Standalone Model Context Protocol server for Slack messaging with accountability and papertrail tracking. Built with Python, FastMCP, and slack_sdk.
- Send Tool:
slack_send- Send messages to users and channels - Receive Tools (optional):
slack_get_messages- Fetch recent channel messagesslack_get_thread- Get thread repliesslack_list_channels- List available channelsslack_search_messages- Search message history
- Accountability: Automatic sender attribution on all messages
- User Resolution: Resolves usernames to Slack IDs via email lookup
- Multi-Recipient: Send to up to 10 recipients per call
- Slack Markdown: Full support for formatting, links, emoji
Copy .env.example to .env and set your bot token:
cp .env.example .envSLACK_BOT_TOKEN=xoxb-your-bot-token-here
SLACK_EMAIL_DOMAIN=yourdomain.com
MAX_RECIPIENTS=10
ENABLE_RECEIVE=false
MCP_PORT=5000Required bot scopes for sending: chat:write, chat:write.public, users:read, users:read.email
Additional scopes for receiving: channels:history, channels:read, search:read
docker compose up -ddocker build -t slack-mcp .
docker run -p 5000:5000 --env-file .env slack-mcppip install -r requirements.txt
python server.pyThe server exposes an SSE endpoint at http://localhost:5000/sse.
Send a Slack message with accountability tracking.
Parameters:
recipients(array): Usernames, email addresses, Slack user IDs, or#channelnames (max 10)message(string): Message content (supports Slack markdown)sender(string): Attribution string appended as "— Sent by {sender}"
Example:
{
"recipients": ["jsmith", "#alerts"],
"message": "Build completed! :tada:",
"sender": "CI Bot"
}Returns:
{
"success": true,
"sent": 2,
"failed": 0,
"errors": []
}Fetch recent messages from a channel.
channel(string): Channel name or IDlimit(number): Messages to retrieve (default: 10, max: 100)
Get all replies in a thread.
channel(string): Channel name or IDthread_ts(string): Thread timestamp from parent message
List all available channels with ID, name, privacy, and member count.
Search messages across channels. Supports Slack search operators:
from:username,in:#channel,has:link,after:YYYY-MM-DD
Parameters:
query(string): Search querycount(number): Results to return (default: 20, max: 100)
*bold*,_italic_,~strikethrough~`code`,```code block```<https://example.com|Link Text>:tada::rocket::white_check_mark:
| Variable | Required | Default | Description |
|---|---|---|---|
SLACK_BOT_TOKEN |
Yes | — | Slack Bot OAuth token |
SLACK_EMAIL_DOMAIN |
No | blizzard.com |
Domain for username-to-email resolution |
MAX_RECIPIENTS |
No | 10 |
Max recipients per message |
ENABLE_RECEIVE |
No | false |
Enable read tools |
MCP_PORT |
No | 5000 |
SSE server port |
Connect to the SSE endpoint from any MCP client:
http://localhost:5000/sse