.claude/skills/marketing/slack-messaging/SKILL.md
Slack channel and thread messaging skill with context-aware session management. Reads messages, sends replies, searches channels and users, drafts and schedules messages -- all via Slack MCP tools. Use this skill whenever the user wants to read Slack messages, reply in Slack, send a Slack message, check a Slack channel, respond to a Slack thread, monitor Slack conversations, draft a Slack message, schedule a Slack message, find a Slack channel or user, or do anything involving Slack communication. Also activate when the user mentions 'check Slack', 'reply on Slack', 'send to #channel', 'DM someone on Slack', 'what did they say in Slack', 'catch up on Slack', 'Slack thread', 'post in Slack', or references any Slack channel by name (e.g., '#general', '#engineering'). This skill manages session boundaries: thread replies stay in the same session to preserve conversational context, while new top-level channel messages start a fresh session to keep conversations isolated.
npx skillsauth add anton-abyzov/vskill slack-messagingInstall 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.
Read, send, search, draft, and schedule Slack messages across channels and threads. This skill wraps the Slack MCP tools with clear workflows and -- critically -- enforces context boundaries: thread conversations keep their context within a single session, while each new channel-level conversation gets a fresh session.
Slack conversations have natural scoping. A thread is one continuous discussion -- if you lose context mid-thread, your replies become disjointed and unhelpful. But two unrelated messages in a channel are separate conversations -- mixing their context causes confusion and information leakage between topics.
This skill enforces these boundaries so your Slack interactions stay coherent:
Stay in the same Claude Code session when:
In practice: if you have a thread_ts and you're sending another message with the same thread_ts, you are in the same conversation. Keep your context.
Start a new Claude Code session (fresh context) when:
How to start a new session: Tell the user explicitly: "This is a separate conversation. To keep context clean, please start a new Claude Code session (claude in terminal) for this response." If running autonomously, use subagents -- each top-level channel message gets its own subagent to maintain isolation.
All tools are accessed via the Slack MCP integration. Here is what each one does and when to use it:
| Tool | Purpose | Key Parameters |
|------|---------|----------------|
| slack_read_channel | Read messages from a channel (newest first) | channel_id, limit, oldest, latest |
| slack_read_thread | Read all replies in a thread | channel_id, message_ts |
| slack_send_message | Send a message to a channel or thread | channel_id, message, thread_ts (for replies) |
| slack_send_message_draft | Save a draft without sending | channel_id, message, thread_ts |
| slack_schedule_message | Schedule a message for later | channel_id, message, post_at (Unix timestamp) |
| slack_search_channels | Find channels by name or description | query |
| slack_search_users | Find users by name, email, or role | query |
| slack_search_public | Search messages in public channels | query with search modifiers |
| slack_search_public_and_private | Search all channels (needs user consent) | query with search modifiers |
Most tools require channel_id rather than channel names. Always resolve names to IDs first:
slack_search_channels with the channel name (e.g., query "engineering") to get the channel_idslack_search_users with the person's name or email to get their user_id (usable as channel_id for DMs)Cache resolved IDs within your session to avoid redundant lookups.
1. Resolve channel name -> channel_id (slack_search_channels)
2. Read messages (slack_read_channel with channel_id)
3. Present a summary: who said what, timestamps, thread indicators
4. If a message has thread replies, note the reply count
Tip: Use limit to control how many messages to fetch (default 100, max 100). Use oldest/latest timestamps to narrow a time range.
1. Get the channel_id and parent message's timestamp (message_ts)
2. Read thread (slack_read_thread with channel_id + message_ts)
3. Present the full conversation in order
The message_ts is the timestamp of the parent message that started the thread. You get it from slack_read_channel results or from a link the user shares.
1. Resolve channel_id
2. Draft the message content
3. Show the draft to the user for approval
4. Send (slack_send_message with channel_id + message)
5. Report the message link back to the user
1. Get channel_id and the parent message's thread_ts
2. Read the existing thread for context (slack_read_thread)
3. Draft your reply informed by thread context
4. Show draft to user for approval
5. Send (slack_send_message with channel_id + message + thread_ts)
6. Report the message link
Set reply_broadcast: true if the reply should also appear in the main channel (the user must request this -- don't default to it, as it notifies everyone in the channel).
1. Resolve channel_id
2. Compose the message
3. Save draft (slack_send_message_draft)
4. Tell the user where to find it: Slack's "Drafts & Sent" section
Only one draft per channel is allowed. If a draft already exists, tell the user to edit or delete it in Slack first.
1. Resolve channel_id
2. Compose the message
3. Convert the desired time to a Unix timestamp (must be at least 2 minutes in the future, max 120 days)
4. Schedule (slack_schedule_message with channel_id + message + post_at)
5. Confirm the scheduled time to the user
1. Choose search scope:
- Public only: slack_search_public (no consent needed)
- All channels: slack_search_public_and_private (ask user consent first)
2. Build query with modifiers:
- in:#channel-name — filter by channel
- from:@username — filter by author
- before:/after:/on:YYYY-MM-DD — date filters
- "exact phrase" — exact match
- is:thread — only threaded messages
3. Present results with context
This is where session management matters most. When the user asks you to "check Slack and respond to messages":
1. Read the channel (slack_read_channel)
2. Identify messages that need responses
3. For each message that needs a response:
a. If it's a thread reply -> read the full thread first (same session if it's one thread)
b. If it's a new top-level message -> TELL THE USER to handle it in a new session
OR spawn a subagent for isolation
4. Draft each response with appropriate context
5. Get approval before sending anything
The critical rule: never mix context between unrelated channel conversations. If you're handling message A about a deployment issue and message B about a team lunch, those are separate sessions.
Slack uses its own markdown variant (mrkdwn). Follow these rules:
| Format | Syntax | Note |
|--------|--------|------|
| Bold | *bold* | Single asterisks, NOT double |
| Italic | _italic_ | Underscores |
| Code | `code` | Backticks |
| Code block | ```code``` | Triple backticks |
| Quote | > quoted text | Angle bracket |
| Link | <https://example.com\|display text> | Pipe separator |
| User mention | <@USER_ID> | Use resolved user ID |
| Channel mention | <#CHANNEL_ID> | Use resolved channel ID |
Do NOT use **double asterisks** or ## headers -- they don't render in Slack.
Never send a message without the user's explicit approval. The workflow is always:
This exists because Slack messages are visible to your team immediately. A poorly worded message, a reply in the wrong thread, or an accidental channel ping can't be unseen. The 10-second approval step prevents real embarrassment.
To send a DM, use the recipient's user_id as the channel_id in slack_send_message. Find their user_id with slack_search_users.
To read DMs, use slack_read_channel with the DM channel ID. You can find DM channels by searching with slack_search_public_and_private using in:@username.
| Error | What It Means | What to Do |
|-------|---------------|------------|
| channel_not_found | Bad channel ID or no access | Re-resolve with slack_search_channels |
| not_in_channel | Bot/user not a member | Ask user to invite you or join the channel |
| msg_too_long | Over 5000 chars | Split the message into parts |
| draft_already_exists | One draft per channel limit | Tell user to clear existing draft in Slack |
| invalid_scheduled_time | post_at not 2+ min in future | Recalculate the timestamp |
| "I want to..." | Tool |
|----------------|------|
| Read recent messages in #channel | slack_read_channel |
| Read a full thread | slack_read_thread |
| Send a message to #channel | slack_send_message |
| Reply in a thread | slack_send_message + thread_ts |
| Send a DM | slack_send_message + user_id as channel_id |
| Save a draft | slack_send_message_draft |
| Schedule for later | slack_schedule_message |
| Find a channel ID | slack_search_channels |
| Find a user ID | slack_search_users |
| Search message history | slack_search_public or slack_search_public_and_private |
tools
Hand off your in-flight work to ANY other AI coding tool so you can continue exactly where you left off — works in 8+ tools (Claude Code, Codex, OpenCode, Gemini, Antigravity, Cursor, Aider, Cline/Roo, Windsurf). Writes one portable, secret-scrubbed handoff document plus a full diff of your uncommitted edits, then prints the absolute path, a clickable link, and a copy-paste resume prompt. Use this skill whenever the user is running out of subscription tokens, wants to switch tools mid-task, says 'handoff', 'continue elsewhere', 'continue on another machine', 'switch to Codex/OpenCode/Gemini/Cursor', or 'I'm out of tokens'. Self-contained: needs only git and a shell; uses 'specweave handoff' as an optional accelerator if it is on PATH.
tools
Bootstrap or update project AI-agent instruction files (AGENTS.md for Codex, CLAUDE.md for Claude Code, or both) from the current project's structure. Triggers on: write AGENTS.md, write CLAUDE.md, generate AGENTS.md, agent instructions, project conventions for AI, bootstrap agent docs, set up project memory for Codex/Claude, document dev/test/build commands for AI coding tools, single-source project instructions for any AI agent.
development
This skill should be used whenever the user asks Claude to perform any action, task, or operation — including "create X", "fix Y", "run Z", "build", "edit", "search", "deploy", or any other request involving Claude taking an action. Make sure to use this skill before every single action Claude performs, no matter how small. Activate on every action request without exception.
development
Meta-skill for creating new skills from natural language. Trigger phrases: "new skill", "create a skill", "build a skill", "make a skill", "generate a skill", "author a skill", "skill builder".