UNPKG

@chinchillaenterprises/mcp-slack

Version:

MCP server for Slack. Single account loaded from env (SLACK_BOT_TOKEN); multi-workspace via separate server entries.

259 lines (188 loc) β€’ 13.1 kB
# MCP Slack Server A Model Context Protocol (MCP) server for Slack. **v4.0.3** loads a single account from environment variables β€” no encrypted credential store, no keychain, no runtime account switching. To use a second workspace, add a second MCP server entry with its own token (see below). ## Features - πŸ”‘ **Env-first auth**: One Slack account per server, loaded from `SLACK_BOT_TOKEN` at startup β€” no on-disk credentials - 🧩 **Multi-workspace via config**: Run one server entry per workspace (e.g. `slack`, `slack-work`) - πŸ” **Comprehensive Slack Tools**: 40+ tools for messages, channels, users, files, and more - πŸ“Έ **File Upload & Diagrams**: Upload files; render HTML/Mermaid diagrams as PNGs (diagram rendering needs a one-time `npm install puppeteer` β€” no browser is bundled; see `slack_send_diagram`) - 🀝 **Legate coordination**: `slack_poll` / `slack_claim_lane` / `slack_checkin` for multi-session agents - ✨ **Automatic Markdown Conversion**: Converts common markdown formatting to Slack's mrkdwn format ## Installation & Configuration The server reads its token from the `env` block of its MCP server entry. Add an entry to your Claude config (`~/.claude.json` or a project-local `.mcp.json`): ```jsonc { "mcpServers": { "slack": { "command": "npx", "args": ["-y", "@chinchillaenterprises/mcp-slack"], "env": { "SLACK_BOT_TOKEN": "xoxb-YOUR-BOT-TOKEN", "SLACK_USER_TOKEN": "xoxp-YOUR-USER-TOKEN" // optional } } } } ``` ### Multiple workspaces = multiple server entries There is no in-app account switching. To talk to a second workspace, add a second server entry with its own token. Tools are namespaced by entry, so they stay separate: ```jsonc { "mcpServers": { "slack": { "command": "npx", "args": ["-y", "@chinchillaenterprises/mcp-slack"], "env": { "SLACK_BOT_TOKEN": "xoxb-PERSONAL-WORKSPACE-TOKEN" } }, "slack-work": { "command": "npx", "args": ["-y", "@chinchillaenterprises/mcp-slack"], "env": { "SLACK_BOT_TOKEN": "xoxb-WORK-WORKSPACE-TOKEN" } } } } ``` ### Environment Variables | Variable | Required | Description | |----------|----------|-------------| | `SLACK_BOT_TOKEN` | **yes** | Slack bot token (`xoxb-…`). Falls back to `DEFAULT_BOT_TOKEN` for back-compat. | | `SLACK_USER_TOKEN` | no | Slack user token (`xoxp-…`) for user-scoped operations. Falls back to `DEFAULT_USER_TOKEN`. | | `SLACK_TEAM_ID` | no | Team/workspace ID. Auto-discovered via `auth.test` on first use if omitted. Falls back to `DEFAULT_TEAM_ID`. | | `SLACK_WORKSPACE` | no | Display name for the workspace. Falls back to `DEFAULT_ACCOUNT_NAME`. | If `SLACK_BOT_TOKEN` (or `DEFAULT_BOT_TOKEN`) is absent, the server still boots β€” but every tool call returns a clear error telling you to set `SLACK_BOT_TOKEN`. ## Usage ### Account Tools (read-only) - **get_active_account**: Show which workspace this server is wired to (name, team ID β€” no secrets) - **list_accounts**: List the single active account (kept for back-compat) ### Core Slack Tools #### Messaging - `slack_send_message`: Send messages to channels (with automatic markdown β†’ Slack formatting) - `slack_send_formatted_message`: Send rich Block Kit messages - `slack_send_card`: Post a polished Block Kit card (header, section blocks with two-column fields, context footer, optional color bar) - `slack_send_table`: Post a column-aligned ASCII table inside a code block (lightweight text alternative to `slack_send_diagram`) - `slack_edit_message`: Edit existing messages - `slack_delete_message`: Delete messages - `slack_schedule_message`: Schedule messages for later - `slack_forward_message`: Forward messages between channels #### Task Lifecycle (threaded, single-thread progress) - `slack_start_task`: Post a parent `⏳ <title>` card (adds a ⏳ status reaction); returns `{ task_ts, channel }` - `slack_update_task`: Post a threaded progress reply; with `step`/`total_steps` updates the parent's progress bar (no @-mentions) - `slack_complete_task`: Final threaded reply + edits the parent into a βœ…/❌ summary card, swaps the ⏳ reaction; the only task tool that may `@`-mention (`notify_user`) #### Channels & History - `slack_list_channels`: List accessible channels - `slack_get_channel_history`: Get recent messages - `slack_get_thread_replies`: Get thread conversations #### Search - `slack_search_messages`: Search across workspace - `slack_search_by_user`: Find messages from specific users - `slack_search_by_date_range`: Search within date ranges - `slack_search_files`: Search for shared files #### Users & Teams - `slack_list_users`: List workspace members - `slack_get_user_by_name`: Find users by name - `slack_get_user_info`: Get detailed user information - `slack_get_user_status`: Check user status - `slack_get_user_profile`: Get full profile details #### Files & Diagrams - `slack_upload_file`: Upload files (images, documents, text) to a channel - `slack_send_diagram`: Render HTML or Mermaid diagrams as PNG images and post to a channel (requires a one-time renderer install β€” `npm install puppeteer`, or playwright/wkhtmltoimage; not bundled, so the package install stays lean. Falls back to a clear "install a renderer" message if none is present. For plain tabular data use `slack_send_table` β€” no renderer needed.) #### Reactions & Pins - `slack_add_reaction`: Add emoji reactions - `slack_bulk_react_messages`: React to multiple messages - `slack_pin_message`: Pin important messages - `slack_unpin_message`: Unpin messages #### Productivity - `slack_create_reminder`: Set reminders - `slack_list_reminders`: View active reminders - `slack_get_workspace_stats`: Get workspace analytics ### Automatic Markdown Conversion The `slack_send_message` tool now automatically converts common markdown formatting to Slack's mrkdwn format: - **Bold**: `**text**` β†’ `*text*` - **Links**: `[text](url)` β†’ `<url|text>` - **Strikethrough**: `~~text~~` β†’ `~text~` - **Headers**: `# Header` β†’ `*Header*` - **Lists**: `- item` β†’ `β€’ item` This means Claude can use standard markdown formatting and it will appear correctly in Slack without manual conversion. ## Session UX These features keep agent-driven Slack usage cheap (in context tokens) and tidy. ### Lean tool outputs (`verbose` flag) The chatty read tools β€” `slack_get_channel_history`, `slack_list_users`, `slack_list_channels`, `slack_search_messages`, `slack_search_by_user`, `slack_search_by_date_range`, and `slack_get_workspace_stats` β€” return **lean output by default**. Lean output: - Drops pretty-print whitespace and metadata exhaust (profile image URLs, team/bot IDs, edited markers, reaction blobs, full Block Kit JSON). - **Preserves message body text verbatim** β€” content is never clipped or summarized. - Caps how many *items* are returned and appends a footer like `(showing 25 of 340 β€” pass verbose:true or a higher limit/cursor for the rest)` so nothing is silently dropped. Pass `verbose: true` on any of these tools to get the **full raw API payload** β€” the firehose is always one call away. Lean results are the main lever against the largest single source of session token cost (verbose results lingering in the context window). ### ASCII tables vs. PNG tables - `slack_send_table` renders a column-aligned monospace table inside a code block. Cheap (it's text), good for status grids and comparison matrices. Accepts an array of objects, a 2D array (first row = header), or a markdown pipe-table string. - `slack_send_diagram` renders an HTML `<table>` as a PNG image β€” use it when you want a polished, presentation-grade table. ### Threaded task lifecycle Use `slack_start_task` β†’ `slack_update_task` β†’ `slack_complete_task` to run a long task in **one thread** instead of spamming a channel. The parent card shows a live progress bar and a ⏳ β†’ βœ…/❌ status reaction. Only `slack_complete_task` may `@`-mention the user (via `notify_user`); routine updates stay quiet. ### Session identity (`chat:write.customize`) The message-posting tools (`slack_send_message`, `slack_send_formatted_message`, `slack_send_card`, and the task tools) accept optional `username`, `icon_emoji`, and `icon_url` params so a session can post under a consistent identity like `Claude Β· ChillMCP`. Defaults can be set once via environment variables: - `SLACK_SESSION_USERNAME`: default display name for posted messages - `SLACK_SESSION_ICON`: default icon β€” either a `:emoji:` name or an image URL > **Scope required:** username/icon overrides require the **`chat:write.customize`** bot scope. If the scope is missing, Slack ignores the override and the message still posts under the app's default identity (degrades gracefully). ## Advanced Features ### Credentials (env-only) There is **no on-disk credential store** β€” no keychain, no `accounts.json`, no encryption keys. The bot/user tokens live only in the `env` block of the MCP server entry and in process memory for the lifetime of the server. Rotating a token is just editing the config and restarting the server. The only file the server writes is **Legate poll state** (`~/.mcp-slack/legate-state/<call_sign>.json`) β€” poll cursors and check-in status for the multi-session coordination tools. That is not credentials. ### Performance Optimizations - Efficient 120s TTL caching of `users.list` / `conversations.list` - Lazy workspace-info hydration (`auth.test` on first use) - Minimal startup overhead ## Architecture Single account, loaded from env. Multi-workspace is achieved by running multiple server entries: ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Claude │────▢│ slack (server) │────▢│ Workspace A β”‚ β”‚ β”‚ β”‚ SLACK_BOT_TOKEN β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ │────▢│ slack-work │────▢│ Workspace B β”‚ β”‚ β”‚ β”‚ SLACK_BOT_TOKEN β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## Troubleshooting ### "No Slack bot token. Set SLACK_BOT_TOKEN…" The server booted without a token. Add `SLACK_BOT_TOKEN` to the `env` block of this server's entry in `~/.claude.json` (or `.mcp.json`) and restart. ### Missing channels or users Ensure your bot token has the necessary OAuth scopes: - `channels:read` - `chat:write` - `chat:write.customize` (only needed for the `username` / `icon_emoji` / `icon_url` session-identity overrides) - `users:read` - `files:read` - `reactions:write` (for the task-lifecycle status reactions) ### Performance issues - Check network connectivity to Slack - Verify token permissions - Review workspace size (very large workspaces may need pagination) ## Development ### Building from source ```bash git clone https://github.com/ChinchillaEnterprises/ChillMCP.git cd ChillMCP/mcp-slacker-v3 npm install npm run build ``` ### Contributing Issues and pull requests are welcome at the [GitHub repository](https://github.com/ChinchillaEnterprises/ChillMCP). ## Roadmap β€” Next Tools Needed ### ~~Priority 1: `slack_upload_file`~~ β€” DONE (v3.1.0) Upload files (images, documents, text) to a Slack channel. Uses Slack's `files.uploadV2` API. Supports any file type. Returns file URL and permalink. Requires `files:write` bot scope. ### ~~Priority 2: `slack_send_diagram`~~ β€” DONE (v3.1.0) Render an HTML/Mermaid diagram as a PNG image and post it to a Slack channel. Supports both raw HTML and Mermaid diagram syntax. Uses Puppeteer, Playwright, or wkhtmltoimage for rendering (auto-detects available engine). Temp files cleaned up after upload. **Rendering engine setup** (one of these must be available): ```bash # Recommended npm install puppeteer # Or alternatively npm install playwright # Or: brew install wkhtmltopdf ``` ### Priority 3: `slack_send_formatted_message` enhancement The existing `slack_send_formatted_message` tool should be enhanced to support Block Kit layouts for richer Slack messages (headers, sections, dividers, context blocks). ### Why These Matter The Echelon project (Chinchilla AI's agent platform) uses AI agent teams that dynamically restructure per project phase. Before each phase, the team posts their formation diagram to Slack. Currently limited to ASCII art in code blocks. These tools enable posting actual rendered diagrams as images β€” much more professional and readable. ## License MIT License - see LICENSE file for details. ## Credits Built by [Chinchilla Enterprises](https://github.com/ChinchillaEnterprises) for the MCP ecosystem.