Skip to content

zenyr/slack-cli

 
 

Repository files navigation

slack

Bun-only monorepo CLI for Slack workflows. MCP-style resources + tools.

  • Runtime: Bun (>=1.3.9)
  • Version: 0.1.0
  • Package: @zenyr/slack-cli

Install

bun install

Link globally

bun run link   # installs `slack` binary via bun link
slack --help

Run without linking

bun start -- <command> [options]
# or
bun run --cwd=apps/cli src/main.ts <command> [options]

Auth

Token priority (highest → lowest): env vars → persisted store.

Environment variables

Variable Type Description
SLACK_MCP_XOXP_TOKEN xoxp-... User token (preferred)
SLACK_MCP_XOXB_TOKEN xoxb-... Bot token

Note: xoxc/xoxd (edge) tokens are not supported. Unset them and use xoxp/xoxb.

Persistent store (auth commands)

slack auth login --type <xoxp|xoxb> --token <token>
# or pipe via stdin:
printf '<token>' | slack auth login --type <xoxp|xoxb>

slack auth logout                  # clear active session
slack auth use <xoxp|xoxb>        # switch active token type
slack auth check [--json]          # verify session
slack auth whoami [--json]         # show identity (user, team, token type)

Global Flags

Flag Alias Description
--help -h Show help
--version -v Show version
--json Structured JSON output (all commands)
-- Stop flag parsing; remaining args treated as positionals

Commands

slack help

Show top-level help.


slack schema [<command> [subcommand ...]] [--json]

Show machine-readable command capability metadata for agents.

slack schema --json
slack schema messages post --json

slack version

Print CLI version.


slack resources [--json]

List MCP-style resources.

Resources:

URI Format Description
slack://<workspace>/channels text/csv Channels, DMs, group DMs with basic metadata
slack://<workspace>/users text/csv Workspace users for lookups and context enrichment

slack tools [--json]

List referenced MCP tools from spec.

Tools: conversations_history, conversations_replies, conversations_add_message, conversations_search_messages, channels_list, reactions_add, reactions_remove, attachment_get_data, users_search, usergroups_list, usergroups_create, usergroups_update, usergroups_users_update, usergroups_me


slack batch

slack batch "<command arg...>" "<command arg...>" [--stop-on-error[=<bool>]] [--fail-on-error[=<bool>]] [--json]

Run multiple commands in one process.


slack channels list

slack channels list [--type <public|private|im|mpim>] [--sort <name|popularity>] [--limit <n>] [--cursor <cursor>] [--json]

List channels.

Flag Values Description
--type public|private|im|mpim Filter by channel type
--sort name|popularity Sort order
--limit n Max results
--cursor cursor string Pagination cursor

slack users list

slack users list [<query>] [--cursor=<cursor>] [--limit=<n>] [--json]

List users. Optional positional <query> for filtering.


slack users get

slack users get <user-id> [user-id ...] [--json]

Get users by user ID. Supports batch lookup in one call.


slack users search

slack users search [<query>] [--cursor=<cursor>] [--limit=<n>] [--json]

Search users by query string.


slack attachment get

slack attachment get <file-id> [--json]

Get attachment metadata by file ID.


slack messages search

slack messages search <query> [--channel <value>] [--user <value>] [--after <date>] [--before <date>] [--threads] [--json]

Search messages.

Flag Values Description
--channel channel ID Filter by channel
--user user ID Filter by user
--after YYYY-MM-DD|1d|1w|30d|90d Messages after date/duration
--before YYYY-MM-DD|1d|1w|30d|90d Messages before date/duration
--threads flag Include thread replies

slack messages fetch

slack messages fetch <message-url> [--thread[=<bool>]] [--resolve-users[=<bool>]] [--json]

Fetch one message by permalink URL. Use --thread to expand to the full thread.

Flag Description
--thread Include full thread (default: false)
--resolve-users Resolve user IDs to usernames/display names

Use this command when input is a Slack message URL.


slack messages history

slack messages history <channel-id> [--oldest=<ts>] [--latest=<ts>] [--limit=<n>] [--cursor=<cursor>] [--include-activity] [--json]

Fetch channel message history.

Flag Description
--oldest Slack timestamp lower bound (seconds.fraction)
--latest Slack timestamp upper bound
--limit Max messages
--cursor Pagination cursor
--include-activity Include channel activity events

slack messages post

slack messages post <channel-id> <text> [--thread-ts=<ts>] [--blocks[=<bool>]] [--payload=<json|->] [--dry-run[=<bool>]] [--unfurl-links[=<bool>]] [--unfurl-media[=<bool>]] [--reply-broadcast[=<bool>]] [--json]

Post plain text message to channel. Markdown is auto-converted to Slack mrkdwn.

Flag Description
--thread-ts Reply in thread (seconds.fraction)
--blocks Build Block Kit blocks from Markdown
--payload Read complete request object from JSON or stdin (-)
--dry-run Validate and print normalized request without posting
--unfurl-links Unfurl links (bool: true|false|1|0|yes|no|on|off)
--unfurl-media Unfurl media
--reply-broadcast Also send reply to channel

Channel post policy (env-based guard):

Variable Format Behavior
SLACK_MCP_POST_CHANNEL_ALLOWLIST C123,C456 Only allow listed channel IDs
SLACK_MCP_POST_CHANNEL_DENYLIST C123,C456 Block listed channel IDs

Channel IDs must match pattern ^[CGD][A-Z0-9]+$. Invalid IDs in policy vars block all posts.


slack messages post-ephemeral

slack messages post-ephemeral <channel-id> <user-id> <text> [--thread-ts=<ts>] [--blocks[=<json|bool|->]] [--payload=<json|->] [--dry-run[=<bool>]] [--json]

Post ephemeral message visible only to <user-id> in <channel-id>.


slack messages delete

slack messages delete <message-url> [--json]
slack messages delete <channel-id> <timestamp> [--json]

Delete message by permalink URL or by channel ID + Slack timestamp.


slack messages update

slack messages update <message-url> <text> [--blocks[=<json|bool|->]] [--payload=<json|->] [--dry-run[=<bool>]] [--json]
slack messages update <channel-id> <timestamp> <text> [--blocks[=<json|bool|->]] [--payload=<json|->] [--dry-run[=<bool>]] [--json]

Update message text by permalink URL or by channel ID + Slack timestamp.


slack messages replies

slack messages replies <channel-id> <thread-ts> [--oldest=<ts>] [--latest=<ts>] [--limit=<n>] [--cursor=<cursor>] [--json]

Fetch thread message replies.

Use this command when you already know both <channel-id> and <thread-ts> and want thread messages directly.

Quick decision:

Situation Command
You have a Slack message URL slack messages fetch <message-url>
You already have channel-id + thread-ts slack messages replies <channel-id> <thread-ts>

slack reactions add

slack reactions add <channel-id> <timestamp> <emoji-name> [--json]

Add reaction emoji to message. <emoji-name> without colons (e.g. thumbsup).


slack reactions remove

slack reactions remove <channel-id> <timestamp> <emoji-name> [--json]

Remove reaction emoji from message.


slack usergroups list

slack usergroups list [--include-users[=<bool>]] [--include-disabled[=<bool>]] [--include-count[=<bool>]] [--json]

List user groups.


slack usergroups get

slack usergroups get <usergroup-id> [usergroup-id ...] [--include-users[=<bool>]] [--include-disabled[=<bool>]] [--include-count[=<bool>]] [--json]

Get user groups by ID (batch supported).


slack usergroups create

slack usergroups create <name> <handle> [--description=<text>] [--channels=<comma-separated-channel-ids>] [--json]

Create user group.


slack usergroups update

slack usergroups update <usergroup-id> <name> <handle> [--description=<text>] [--channels=<comma-separated-channel-ids>] [--json]

Update user group metadata.


slack usergroups users update

slack usergroups users update <usergroup-id> <user-id> [user-id ...] --yes [--json]

Replace user group members. --yes required (destructive, confirms overwrite).


slack usergroups me list

slack usergroups me list [--json]

List current user's user group memberships.


slack usergroups me join

slack usergroups me join <usergroup-id> [--json]

Join current user to a user group.


slack usergroups me leave

slack usergroups me leave <usergroup-id> [--json]

Remove current user from a user group.


JSON Output

All commands accept --json, but prefer plain text by default to reduce output/token size.

  • Use default text mode for quick human checks.
  • Use --json only for automation/parsing (e.g. jq), integrations, or deep debugging.

Output shape:

{
  "ok": true,
  "command": "messages.post",
  "message": "human-readable summary",
  "data": { ... },
  "textLines": ["line1", "line2"]
}

Error shape:

{
  "ok": false,
  "command": "messages.post",
  "error": "INVALID_ARGUMENT",
  "message": "error detail",
  "hint": "remediation hint"
}

Error codes: INVALID_ARGUMENT, INTERNAL_ERROR

Project Layout

apps/
  cli/                    # CLI entrypoint (bin: slack → src/main.ts)
packages/
  commands/               # command registry, handlers, router, parse
  config/                 # shared COMMANDS/RESOURCES/TOOLS spec
  auth/                   # auth service, token store, types

Dev Scripts

bun start              # run CLI (loads .env)
bun test               # run all tests (turbo)
bun run lint           # biome check + fix
bun run typecheck      # tsc across all packages
bun run link           # install global `slack` binary
bun run unlink         # remove global binary

About

The most powerful MCP Slack Server with no permission requirements, Apps support, GovSlack, DMs, Group DMs and smart history fetch logic.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 100.0%