mcpField
S
slackctl

slackctl

github.com/cluasProductivity1190 installsUpdated 4w ago
Repository

About slackctl

slackctl is a command-line tool for automating Slack tasks, with JSON output and commands for messages, channels, files, search, canvases, and users. It supports credential import from local apps and multi-workspace selection.

Key features

  1. 01Read, send, edit, and react to messages
  2. 02Manage channels and membership
  3. 03Upload, download, and inspect files
  4. 04Search messages and files
  5. 05Import credentials from local apps
  6. 06JSON output and workspace selection

Use cases

  1. 01Fetching a message and its thread
  2. 02Reviewing unread or saved messages
  3. 03Sending channel updates or direct messages
  4. 04Searching Slack files and exporting canvas content

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/cluas/slackctl --skill slackctl

After installing, type/slackctlin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
commands.md
output.md
targets.md

Details

From the project README

Slack automation with slackctl

slackctl is a single-binary CLI on $PATH. Invoke directly (e.g. slackctl user get @alice).

Installation

slackctl is a single static binary with no runtime dependencies, available for macOS, Linux, and Windows (amd64 + arm64).

If slackctl is not found on $PATH, install it for the current OS:

  • macOS / Linux (recommended) — Homebrew:
brew tap cluas/tap
brew install slackctl
  • Windows (recommended) — Scoop:
scoop bucket add cluas https://github.com/cluas/scoop-bucket
scoop install slackctl
  • Any OS with Go installed:
go install github.com/cluas/slackctl/cmd/slackctl@latest
  • Manual (any OS): download the archive for your OS/arch from the releases page, extract it, and put slackctl (or slackctl.exe on Windows) on your PATH.

CRITICAL: Bash command formatting rules

Claude Code's permission checker has security heuristics that force manual approval prompts. Avoid these patterns to keep commands auto-allowed.

  1. No # anywhere in the command string. Use bare channel names (general not #general).
  2. No '' (consecutive single quotes) or "" (consecutive double quotes). Triggers "potential obfuscation" check.
  3. Only | jq for filtering — no python3, no other commands. jq with single-quote-only expressions (no " inside) is safe:
    • RIGHT: slackctl search messages "query" | jq '.messages[] | .ts'
  4. No || or && chains. Run multiple slackctl commands as separate Bash tool calls.
  5. No file redirects (>, >>). Process JSON output directly, don't write to files.

Quick start (auth)

Auth auto-detection works on macOS, Linux, and Windows. It reads credentials straight from local apps (no browser automation), trying Slack Desktop first, then Chrome, then Firefox. Cookie decryption is handled per-platform: macOS Keychain, Linux Secret Service (secret-tool), and Windows DPAPI.

Per-source platform support:

Source (auth import-*)macOSLinuxWindows
import-desktop (Slack Desktop)✅✅✅
import-chrome✅✅✅
import-brave✅✅✅
import-firefox✅✅✅

Notes: On Linux, Chrome/Brave/Slack cookie decryption reads the key from the desktop keyring via secret-tool (install libsecret-tools / libsecret), falling back to the default peanuts password when no keyring is configured. Firefox cookies.sqlite is plaintext on every platform.

If credentials aren't available, run one of:

  • Slack Desktop import (macOS/Linux/Windows):
slackctl auth import-desktop
slackctl auth test
  • Firefox fallback (macOS/Linux/Windows):
slackctl auth import-firefox
slackctl auth test
  • Chrome fallback (macOS/Linux/Windows):
slackctl auth import-chrome
slackctl auth test
  • Or set env vars:
export SLACK_TOKEN="xoxc-..."
export SLACK_COOKIE_D="xoxd-..."
export SLACK_WORKSPACE_URL="https://myteam.slack.com"
slackctl auth test
  • Or add manually:
slackctl auth add --workspace-url https://myteam.slack.com --xoxc xoxc-... --xoxd xoxd-...
slackctl auth test

Check configured workspaces:

slackctl auth whoami

Canonical workflow (given a Slack message URL)

  1. Fetch a single message:
slackctl message get "https://workspace.slack.com/archives/C123/p1700000000000000"
  1. If you need the full thread:
slackctl message list "https://workspace.slack.com/archives/C123/p1700000000000000" --thread-ts 1700000000.000000

Browse recent channel messages

slackctl message list "general" --limit 20
slackctl message list "C0123ABC" --limit 10
slackctl --attachments message list "general" --limit 20

--attachments is off by default. Pass it when the message body lives in attachments rather than text.

Get unread messages

List all channels with unread messages:

slackctl message unread --limit 20

Also fetch the actual unread message content:

slackctl message unread --fetch --max-per-channel 5

Note: For Enterprise Grid, use --workspace with the enterprise URL for unread counts:

slackctl message unread --workspace longbridge-group --fetch

Get saved-for-later messages (Later)

List the user's saved messages (Slack's "Later" list):

slackctl message saved --limit 20

Also fetch the actual saved message content:

slackctl message saved --fetch

Filter by state (saved = in progress, completed, archived; default is all):

slackctl message saved --filter saved --fetch

For Enterprise Grid, the enterprise workspace is used automatically when needed.

Send, edit, delete, or react

slackctl message send "general" "here is the report"
slackctl message send U01AAAA "hello via DM"
slackctl message send "general" "threaded reply" --thread-ts 1700000000.000000
slackctl message edit "general" 1700000000.000000 "updated text"
slackctl message delete "general" 1700000000.000000
slackctl message react add "general" 1700000000.000000 "eyes"
slackctl message react remove "general" 1700000000.000000 "eyes"

Send to a user ID opens a DM automatically.

List channels + create/invite

slackctl channel list
slackctl channel list --limit 50
slackctl channel new "incident-war-room"
slackctl channel new "incident-leads" --private
slackctl channel invite "incident-war-room" "U01AAAA,U02BBBB"

Files (upload, download, list, info, delete)

Upload a file to a channel or thread:

slackctl file upload ./report.pdf "general" --title "Weekly Report" --message "Here is this week's report"
slackctl file upload ./screenshot.png "general" --thread-ts 1700000000.000000
slackctl file upload ./photo.jpg U01AAAA --message "Check this out"

Upload from stdin (pipe):

cat output.log | slackctl file upload - "general" --filename "build.log" --title "Build Log"

Download a file:

slackctl file download F0123ABCDEF --output ./downloaded.png
slackctl file download F0123ABCDEF --url-only

List, inspect, delete files:

slackctl file list --channel "general" --limit 10
slackctl file list --types images --limit 20
slackctl file info F0123ABCDEF
slackctl file delete F0123ABCDEF

Search (messages + files)

slackctl search messages "deploy failed" --limit 10
slackctl search files "report" --limit 5

Mark as read

slackctl channel mark "general" 1700000000.000000

Canvas

Fetch a Slack canvas and convert to Markdown:

slackctl canvas get "https://workspace.slack.com/docs/T123/F456"
slackctl canvas get F0123ABCDEF

Users

slackctl user list --limit 100
slackctl user get "@alice"
slackctl user get U01AAAA

Multi-workspace

If you have multiple workspaces, pass --workspace to disambiguate:

slackctl message list "general" --workspace "myteam" --limit 10
slackctl auth set-default https://myteam.slack.com

All output is JSON

All commands output JSON to stdout. Use | jq for filtering:

slackctl user get U01AAAA | jq '.email'
slackctl message list "general" --limit 5 | jq '.[].text'

References

Comments

Markdown supported