Slack MCP Server
Enables AI assistants to interact with Slack workspaces through secure OAuth 2.0 authentication. Supports posting messages, reading channel history, and listing channels across multiple workspaces with production-ready security features.
README
Slack MCP Server
A production-ready Model Context Protocol (MCP) server for Slack integration. This server enables AI assistants to interact with Slack workspaces through a secure, multi-tenant OAuth flow.
Features
- 🔐 Secure OAuth 2.0 Flow - Full Slack OAuth v2 implementation with state validation
- 🏢 Multi-Tenant Support - Handle multiple Slack workspaces simultaneously
- 🔄 Token Rotation - Automatic token refresh for long-lived installations
- 🛡️ Production Security - CORS, API key protection, Helmet.js, request timeouts
- 📊 Structured Logging - Pino logger with configurable log levels
- 🐳 Docker Ready - Multi-stage Dockerfile with non-root user
- ⚡ MCP Tools - Post messages, read channel history, list channels
Architecture
This server uses the Streamable HTTP transport for MCP, making it suitable for web-based AI assistants. It manages:
- OAuth Flow:
/slack/installand/slack/oauth/callbackendpoints - MCP Endpoint:
/mcpfor all MCP protocol communication - Session Management: Automatic session pruning with configurable TTL
- Installation Storage: Pluggable storage interface (in-memory by default)
Prerequisites
- Slack App - Create a Slack app at api.slack.com/apps
- Node.js - Version 18+ required
- pnpm - Package manager (or npm/yarn)
Quick Start
1. Install Dependencies
pnpm install
2. Configure Environment
Copy the example environment file and fill in your values:
cp .env.example .env
Required variables:
SLACK_CLIENT_ID- From your Slack app's OAuth settingsSLACK_CLIENT_SECRET- From your Slack app's OAuth settingsSLACK_REDIRECT_URI- Your callback URL (e.g.,https://yourdomain.com/slack/oauth/callback)SLACK_SCOPES- Comma-separated bot scopes (e.g.,chat:write,channels:history,channels:read)AFFINITYBOTS_MCP_API_KEY- Secret key to protect your MCP endpoint
3. Run Development Server
pnpm dev
The server will start on http://localhost:8080 by default.
4. Install Slack App
- Navigate to
http://localhost:8080/slack/install - Authorize the app for your workspace
- You'll be redirected back with a success message
5. Use MCP Tools
Connect your MCP client to http://localhost:8080/mcp with:
- Authorization header:
Bearer YOUR_AFFINITYBOTS_MCP_API_KEY - Origin header: Must match
ALLOWED_ORIGINSif configured
Available MCP Tools
slack_post_message
Post a message to a Slack channel.
Parameters:
team_id(string) - Slack workspace/team ID (T...)channel_id(string) - Channel/DM ID (C... or D...)text(string) - Message text (1-4000 characters)thread_ts(string, optional) - Thread timestamp to reply to
slack_get_channel_history
Read messages from a Slack channel.
Parameters:
team_id(string) - Slack workspace/team IDchannel_id(string) - Channel/DM IDlimit(number, optional) - Number of messages (1-200, default: 50)
slack_list_channels
List all channels in the workspace.
Parameters:
team_id(string) - Slack workspace/team IDtypes(string, optional) - Channel types:public_channel,private_channel,mpim,im(default:public_channel)limit(number, optional) - Number of channels (1-1000, default: 200)
Configuration
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
PORT |
No | 8080 |
Server port |
HOST |
No | 0.0.0.0 |
Server host |
PUBLIC_BASE_URL |
No | http://localhost:8080 |
Public URL for OAuth redirects |
SLACK_CLIENT_ID |
Yes | - | Slack app client ID |
SLACK_CLIENT_SECRET |
Yes | - | Slack app client secret |
SLACK_REDIRECT_URI |
Yes | - | OAuth callback URL |
SLACK_SCOPES |
Yes | - | Comma-separated bot scopes |
AFFINITYBOTS_MCP_API_KEY |
Recommended | - | API key for MCP endpoint |
ALLOWED_ORIGINS |
No | - | Comma-separated allowed origins for CORS |
SESSION_TTL_MS |
No | 900000 |
MCP session timeout (15 min) |
LOG_LEVEL |
No | info |
Log level: trace, debug, info, warn, error, fatal |
Required Slack Scopes
At minimum, your Slack app needs these bot token scopes:
chat:write- Post messageschannels:history- Read public channel messageschannels:read- List public channels
Additional recommended scopes:
groups:history- Read private channel messagesgroups:read- List private channelsim:history- Read direct messagesim:read- List direct messagesmpim:history- Read group DM messagesmpim:read- List group DMs
Production Deployment
Using Docker
Build the image:
docker build -t slack-mcp-server .
Run the container:
docker run -d \
-p 8080:8080 \
-e SLACK_CLIENT_ID=your_client_id \
-e SLACK_CLIENT_SECRET=your_client_secret \
-e SLACK_REDIRECT_URI=https://yourdomain.com/slack/oauth/callback \
-e SLACK_SCOPES=chat:write,channels:history,channels:read \
-e AFFINITYBOTS_MCP_API_KEY=your_secret_key \
-e ALLOWED_ORIGINS=https://yourdomain.com \
slack-mcp-server
Production Checklist
- [ ] Set
AFFINITYBOTS_MCP_API_KEYto a strong random value - [ ] Configure
ALLOWED_ORIGINSwith your frontend domains - [ ] Use HTTPS for all endpoints (required by Slack)
- [ ] Set
PUBLIC_BASE_URLto your public HTTPS URL - [ ] Replace
InMemoryInstallStorewith persistent storage (Redis/PostgreSQL) - [ ] Set up monitoring and alerting
- [ ] Configure log aggregation
- [ ] Set appropriate
SESSION_TTL_MSfor your use case - [ ] Enable Slack token rotation in your app settings (recommended)
- [ ] Set up rate limiting at the reverse proxy level
- [ ] Configure health check monitoring on
/health
Storage
The default InMemoryInstallStore is suitable for development but not for production. For production, implement the InstallStore interface with a persistent backend:
export interface InstallStore {
upsert(install: SlackInstallation): Promise<void>;
getByTeamId(teamId: string): Promise<SlackInstallation | null>;
}
Recommended storage options:
- PostgreSQL - Best for relational data and complex queries
- Redis - Fast, simple key-value storage
- MongoDB - Document-based storage
- DynamoDB - Serverless AWS option
Security Features
Implemented
- ✅ CSRF protection via OAuth state parameter
- ✅ API key authentication for MCP endpoint
- ✅ CORS with origin allowlist
- ✅ Helmet.js security headers
- ✅ Request timeouts (30s)
- ✅ Session expiration and pruning
- ✅ Automatic token refresh
- ✅ Secure error messages (no info leakage)
- ✅ Non-root Docker user
Recommended Additional Security
- Add rate limiting (e.g., express-rate-limit)
- Use a reverse proxy (nginx, Caddy) with TLS
- Implement request size limits
- Add request ID tracking
- Set up WAF rules
- Enable Slack signing secret verification for webhooks (if added)
Monitoring
Health Check
curl http://localhost:8080/health
Returns ok if the server is running.
Logs
The server uses structured JSON logging via Pino. Key log events:
- OAuth flow initiation and completion
- MCP session creation and expiration
- Token refresh operations
- API errors and warnings
- Security events (unauthorized access, invalid origins)
Set LOG_LEVEL=debug for detailed debugging.
Troubleshooting
OAuth Errors
"Invalid or expired state"
- The OAuth state token expired (10 min TTL)
- Try the installation flow again
"Slack OAuth failed: invalid_code"
- The authorization code was already used or expired
- Restart the installation flow
"Origin not allowed"
- Your frontend origin is not in
ALLOWED_ORIGINS - Add your origin to the environment variable
MCP Errors
"Unauthorized"
- Missing or invalid
Authorizationheader - Ensure you're sending
Bearer YOUR_API_KEY
"Unknown or expired session"
- MCP session expired (default 15 min)
- Reinitialize the MCP connection
"No Slack installation found"
- The workspace hasn't installed the app
- Complete the OAuth flow first
Token Errors
"Token refresh failed"
- The refresh token is invalid or revoked
- User needs to reinstall the app
- Check if token rotation is enabled in Slack app settings
Development
Project Structure
slack-mcp-server/
├── src/
│ ├── index.ts # Main server and routing
│ ├── mcp.ts # MCP tool definitions
│ ├── slackOauth.ts # OAuth flow handlers
│ ├── slackClient.ts # Slack API client with token refresh
│ ├── installStore.ts # Installation storage interface
│ └── security.ts # Security utilities
├── Dockerfile
├── package.json
├── tsconfig.json
└── README.md
Adding New Tools
Register new tools in src/mcp.ts:
server.tool(
"tool_name",
"Tool description",
{
team_id: z.string(),
// ... other parameters
},
async ({ team_id, ...params }) => {
const slack = await getSlackClientForTeam(store, team_id);
// ... implement tool logic
return { content: [{ type: "text", text: "result" }] };
}
);
Testing
# Run development server with debug logging
LOG_LEVEL=debug pnpm dev
# Build for production
pnpm build
# Run production build
pnpm start
License
MIT
Support
For issues and questions:
- Check the IMPLEMENTATION.md guide
- Review Slack API documentation at api.slack.com
- Check MCP documentation at modelcontextprotocol.io
Contributing
Contributions welcome! Please:
- Follow the existing code style
- Add tests for new features
- Update documentation
- Ensure all lints pass
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。