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
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.