Multi-workspace Slack MCP server with draft+confirm safety, vault auto-export, and triple-mode auth (xoxc/xoxp/xoxb).
slack-mcp has well-structured tool definitions with clear naming (verb_noun pattern) and comprehensive parameter descriptions. All 7 tools have input schemas with types and descriptions. However, output schemas are not documented in the visible code, parameter constraints lack enums where appropriate (e.g., channel types, sort directions), and error handling guidance is minimal. Descriptions are solid (100-250 chars) but could be more LLM-optimized. No tool annotations (readOnlyHint/destructiveHint) despite clear risk classifications in metadata.
Delete one of your own messages. Calls chat.delete with (channel, ts). xoxc user tokens can delete their OWN messages without special scopes. Returns ok=True on success. message_not_found is treated as a soft success (already-deleted or wrong ts). Low-consequence (only your own messages, no destructive cascade) so no draft+confirm. The audit log records every call.
List channels in the workspace. types: comma-separated subset of public_channel, private_channel, mpim, im. Default omits DMs to keep responses short. limit caps results at the API page size.
Mark a channel read up to a given message ts. Affects unread state across all your linked devices. Use the ts of the most recent message you've read.
Read recent messages from a channel. channel accepts ID (C12345) or name (#general). Newest first. Auto-exports the result to the vault at 🤖 AI Chats/Slack/<workspace>/<channel>.md (best-effort).
Substring match against channel names + topics. Case-insensitive.
Output schemas not documented. LLMs cannot infer what fields are returned or plan downstream tool calls. read_channel mentions vault export but no structured response schema is visible.
Parameter values lack enum constraints. 'types' accepts comma-separated values (public_channel, private_channel, mpim, im) but is defined as free-form string. 'sort_dir' in search_messages should be enum(asc|desc). LLMs will hallucinate invalid values.
No tool annotations despite clear risk classifications. delete_own_message and update_own_message are marked DESTRUCTIVE/WRITE in metadata but lack destructiveHint/idempotentHint in schema. Agents cannot reason about safety.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 59 | <=2025-11-25 | v2 |
Search messages with Slack's full-text search. Slack search modifiers work in `query`: `in:#channel`, `from:@user`, `before:YYYY-MM-DD`, `after:YYYY-MM-DD`, `"exact phrase"`. The explicit `channel` param is sugar — when provided, prepends `in:<channel>` to the query. Requires xoxc or xoxp auth (xoxb cannot search). Errors loudly with the workspace's actual auth_type if search isn't available.
Stage an edit to one of your own messages. Does NOT update until confirm_send is called. Fetches the current message text up front so the draft preview shows BOTH the BEFORE and AFTER strings — a visual diff in plain Python. After confirm_send, the message is edited in place via chat.update. Returns a draft_id, the resolved workspace + channel + target_ts, and a preview dict with `before`, `after`, `target_ts`. Drafts expire after 1 hour and can only be confirmed once.
Error handling lacks recovery guidance. search_messages states 'Errors loudly with the workspace's actual auth_type if search isn't available' but does not tell the LLM what to do next (e.g., 'Use xoxc or xoxp token instead').
Parameter 'workspace' is optional with implicit default (primary workspace) but this behavior is not enforced or validated in visible code. If primary is misconfigured, silent failures occur.