| name | permission-slip-openclaw-skill-slack |
| description | Check unread Slack, read channels and threads, search, and post messages through a Slack workspace connected to Permission Slip. Use when the user says things like "check my Slack", "any unread messages?", "what's in |
Slack (via Permission Slip)
This skill lets you act on the user's Slack workspace by driving the
permission-slip CLI. You never talk to the Slack API directly — every action
goes through Permission Slip, which enforces the user's approval policy.
This skill contains no code of its own: it is a thin shim over the
permission-slip CLI. All authentication, approval enforcement, and
default-workspace selection live in Permission Slip and its built-in slack
connector.
Defaults
- "Check my Slack" → list unread conversations.
Run
slack.list_unread (no parameters). It returns conversations with unread
messages, each with an unread count and a latest-message preview.
Coverage caveat: Slack only exposes unread counts for DMs and group
DMs — public/private channels are not included (Slack's API doesn't
surface channel unread counts). The response's notes field spells this out.
To check a specific channel, call slack.read_channel_messages with oldest
set to that channel's last_read_ts. Relay this DM/channel limitation to the
user rather than implying "nothing unread" means fully caught up.
- Workspace selection: omit
--instance. Permission Slip auto-selects the
user's default Slack instance. Only pass --instance if the user explicitly
names a second workspace.
Preflight (run once per session, before the first action)
permission-slip whoami — confirm this agent is registered. If not, tell
the user to register (permission-slip register ...) and stop.
permission-slip connectors — confirm slack is available. If it's missing,
the user hasn't connected a Slack workspace yet; point them at the connector
setup docs and stop.
Intent -> action mapping
| User says | Action | Params |
|---|
| "check my Slack", "any unread?" | slack.list_unread | none |
| "list my channels" | slack.list_channels | — |
| "what's in #channel?" | slack.read_channel_messages | {"channel":<id>,"limit":<n>} |
| "read that thread" | slack.read_thread | {"channel":<id>,"thread_ts":<ts>} |
| "search Slack for X" | slack.search_messages | {"query":"<text>"} |
| "who is @user?" | slack.get_user_profile | {...} |
| "message #channel" | slack.send_message | message params |
| "DM so-and-so" | slack.send_dm | DM params |
| "react with :emoji:" | slack.add_reaction | reaction params |
| "delete that message" | slack.delete_message | HIGH risk |
| "archive #channel" | slack.archive_channel | HIGH risk |
Risk tiers (governs the approval gate)
- Low (often auto-approve via standing approvals):
list_unread,
list_channels, read_channel_messages, read_thread, search_messages,
list_users, get_user_profile, send_message, send_dm, add_reaction,
remove_reaction, pin_message, mark_read, upload_file, schedule_message.
- Medium:
create_channel, set_topic, rename_channel, invite_to_channel,
remove_from_channel, update_message, unpin_message.
- High (destructive — always confirm with the user first):
delete_message,
archive_channel.
Note: posting (send_message / send_dm) is rated low by the connector,
so it may auto-approve. Even so, always confirm the exact target and wording
with the user before sending — a posted message can't be quietly taken back.
How to run an action
permission-slip request \
--action slack.list_unread \
--params '{}'
The CLI prints JSON. Two outcomes — rely on what the CLI returns, don't assume
from the action name:
- Auto-approved: the result includes the action output. Unread/listing
results include
channel_id (and ts / thread_ts for messages) — use those
for follow-up reads or replies.
- Pending approval: the CLI returns a request id in a
pending state. Tell
the user plainly: "That needs your approval — I've sent the request to
Permission Slip; I'll know once you approve it." Then poll with
permission-slip request-status <id> and report the outcome. Never claim a
message was sent, edited, or deleted until the status is approved and
executed.
Presenting results
- Summarize unread briefly (channel/DM, count, latest preview). Don't dump raw
JSON unless asked.
- Use emojis to make the list easier to scan — e.g. 💬 channel, 👤 DM,
🧵 thread, 🔵 unread count, 📎 attachment. Keep it tasteful: one or two icons
per line, not a wall of emoji.
- If there's nothing unread, say the workspace is all caught up — don't retry.
- Deletes and channel archives are destructive. Always confirm the exact
target with the user before submitting, and make clear it requires approval.
- On error, surface the connector's message verbatim and suggest the fix rather
than guessing.
Constraints
- One concern per request. For several messages, make one request each.
- Treat medium/high-risk actions as approval-gated and communicate the wait;
for low-risk posts, still confirm content and target before sending.