plugins/sjawhar/skills/slack-bot/SKILL.md
Use when reading Slack messages, searching conversations, sending messages, listing channels, or interacting with Slack workspaces
npx skillsauth add sjawhar/dotfiles slack-botInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Interact with Slack workspaces via the slack-mcp-server. Use skill_mcp(mcp_name="slack", ...) to invoke tools.
| Tool | Purpose |
| ------------------------------- | -------------------------------------------------- |
| channels_list | List channels (public, private, DMs, group DMs) |
| conversations_history | Read messages from a channel or DM |
| conversations_replies | Read thread replies |
| conversations_search_messages | Search messages with filters (date, user, channel) |
| conversations_add_message | Send a message to a channel or thread |
| reactions_add | Add emoji reaction to a message |
| reactions_remove | Remove emoji reaction from a message |
| users_search | Search users by name, email, or display name |
| usergroups_list | List user groups in workspace |
Channels can be referenced by ID (C1234567890) or name (#general, @username_dm).
skill_mcp(mcp_name="slack", tool_name="channels_list", arguments='{"channel_types": "public_channel,private_channel"}')
skill_mcp(mcp_name="slack", tool_name="conversations_history", arguments='{"channel_id": "#general", "limit": "1d"}')
skill_mcp(mcp_name="slack", tool_name="conversations_search_messages", arguments='{"search_query": "deploy", "filter_in_channel": "#engineering"}')
skill_mcp(mcp_name="slack", tool_name="conversations_add_message", arguments='{"channel_id": "#general", "text": "Hello from the bot!", "content_type": "text/plain"}')
The limit param on history/replies accepts time ranges (1d, 1w, 30d, 90d) or message counts (50). Leave empty when using cursor for pagination.
conversations_add_message accepts three rendering paths. Default to blocks for anything with structure (lists, sections, mixed bold/links). Plain text is fine for one-liners; content_type: "text/markdown" is a trap for non-trivial messages — see below.
Slack mrkdwn syntax (used inside text and inside rich_text element text fields): *bold* (not **bold**), _italic_, ~strike~, `code`, <url|text> for links. No heading syntax.
blocks parameter (preferred for structured messages)Requires slack-mcp-server v1.3.0+ (release notes, PR #294). The MCP tool accepts a blocks parameter (JSON-stringified Block Kit array). When supplied, the server bypasses the markdown converter entirely and posts the blocks as-is; text becomes the notification fallback only.
Use one rich_text block containing a mix of rich_text_section (for headers and paragraphs) and rich_text_list (for bulleted lists). Each indent level is its OWN rich_text_list block placed directly after its parent — Slack does not support nested-list-inside-list.
skill_mcp(mcp_name="slack", tool_name="conversations_add_message", arguments='{
"channel_id": "C...",
"text": "Standup - Fri May 22",
"blocks": "[{\"type\":\"rich_text\",\"elements\":[ ... ]}]"
}')
Element reference inside rich_text:
| Element | Purpose | Key fields |
|---------|---------|-----------|
| rich_text_section | Header line, section label, or free-form paragraph | elements array of text / link / emoji |
| rich_text_list | Bulleted (or ordered) list at a single indent level | style: bullet or ordered, indent: 0/1/2, elements: array of rich_text_section (one per bullet) |
| text | Plain text run | text string, optional style: {bold, italic, code, strike} |
| link | Hyperlink | url, text (display label) |
| emoji | Emoji shortcode | name (e.g. "musical_note") |
Section transitions (*Yesterday* → *Today*) are a rich_text_section with \n, bold label, \n. No literal • / ◦ characters — Slack renders the bullets from the list structure.
skill_mcp(mcp_name="slack", tool_name="conversations_add_message", arguments='{"channel_id": "#general", "text": "Quick note: *deploy* ready in <https://example.com|staging>", "content_type": "text/plain"}')
Fine for short messages with light formatting. For lists, literal • / ◦ characters render visually but produce no semantic list structure (breaks copy/paste, accessibility, search) — use blocks instead.
content_type: "text/markdown" (AVOID for structured messages)The server converts markdown via takara2314/slack-go-util (uses goldmark). Each top-level markdown element becomes its own Slack block:
| Markdown | Resulting block | Issue |
|----------|----------------|-------|
| # Heading | HeaderBlock (plain_text) | Loses inline formatting |
| **bold paragraph** | SectionBlock (mrkdwn) | Causes 80-character word wrapping |
| - bullet | RichTextBlock containing RichTextList | OK in isolation |
| - nested (2-space indent) | Same RichTextBlock, indent: 1 | Must be 2 spaces, not 4 (4 spaces = code block per CommonMark) |
Result: a message with section + heading + paragraph + list becomes 4+ separate blocks. Bold section labels render as standalone section blocks (80-char wrap). There is no merge path to a single rich_text block. Use Path 1 instead.
The MCP conversations_history response strips Block Kit structure to a flat text representation. To see the actual block JSON (for replicating a hand-edited message), use Slack's API directly — this is debug-only, not the send path:
secrets SLACK_MCP_XOXP_TOKEN -- sh -c 'curl -s "https://slack.com/api/conversations.history?channel=$CH&latest=$TS&oldest=$TS&inclusive=true&limit=1" -H "Authorization: Bearer $SLACK_MCP_XOXP_TOKEN"' \
| jq '.messages[0].blocks'
To delete a message:
secrets SLACK_MCP_XOXP_TOKEN -- sh -c 'curl -s -X POST "https://slack.com/api/chat.delete" \
-H "Authorization: Bearer $SLACK_MCP_XOXP_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"channel\": \"C1234567890\", \"ts\": \"1234567890.123456\"}"'
development
Use when searching flights, hotels, or rental cars; comparing fares across flexible dates; discovering cheap destinations from a fixed origin; or hunting hidden-city ticketing deals. Trigger on multi-city itineraries, fare calendars, "where can I fly cheaply", price-sensitive trip planning, or any time the user wants a sanity-check against Google Flights pricing — Skiplagged surfaces hidden-city deals other engines deliberately hide.
development
Search the web via Ceramic Search (lexical/keyword-based). Use when looking up current events, recent news, time-sensitive facts, specific people/products/companies, technical docs, or any topic requiring fresh web results. Triggers on "search the web", "look up", "find recent", "latest news", "current", or when built-in knowledge is likely stale.
tools
Use when reading WhatsApp messages, searching conversations, sending messages, listing chats, or interacting with WhatsApp workspaces
tools
Watch CI status, fix failures, and merge when green