From marketing
Handles Slack channel and thread messaging with context-aware session management. Reads messages, sends replies, searches channels/users, drafts, and schedules via Slack MCP tools.
npx claudepluginhub anton-abyzov/vskill --plugin marketingThis skill uses the workspace's default tool permissions.
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.
evals/activation-prompts.jsonevals/benchmark.jsonevals/evals.jsonevals/history/2026-03-08T20-34-47.861Z.jsonevals/history/2026-03-08T20-35-35.493Z.jsonevals/history/2026-03-08T20-35-42.665Z.jsonevals/history/2026-03-08T20-51-47.638Z.jsonevals/history/2026-03-08T20-53-30.068Z.jsonevals/history/2026-03-09T01-01-13.821Z.jsonevals/history/2026-03-09T01-02-08.368Z.jsonevals/history/2026-03-09T01-02-12.745Z.jsonevals/history/2026-03-09T01-02-14.372Z.jsonevals/history/2026-03-09T01-02-17.684Z.jsonevals/history/2026-03-09T01-09-40.352Z.jsonevals/history/2026-03-10T02-59-31.661Z.jsonevals/history/2026-03-10T02-59-33.349Z.jsonevals/history/2026-03-10T03-23-08.999Z.jsonevals/history/2026-03-10T03-24-05.753Z.jsonevals/history/2026-03-10T05-21-54.029Z.jsonevals/history/2026-03-10T05-22-53.449Z.jsonAutomates Slack messaging to channels/DMs, conversation search, channel/user management, reactions, and threads using Composio toolkit via Rube MCP.
Automates Slack workspace tasks like sending messages to channels/DMs, searching conversations, finding channels/users, and managing reactions via Composio toolkit and Rube MCP tools.
Automates Slack via CLI for AI agents: read messages/threads/history, search/download attachments, send/edit/delete/reply, manage channels/users/workflows/unreads/mark read.
Share bugs, ideas, or general feedback.
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 |