Turn the forked slack-mcp-server into a CLI so running many agents no
longer means one resident MCP process each. Every command is a
short-lived process that reads the shared on-disk cache.
- rename module to github.com/paymog/slack-cli (go install/homebrew/ldflags)
- internal/toolcall: invoke the upstream tool handlers in-process; the only
mcp-go coupling lives here, so pkg/handler and pkg/provider are reused
byte-for-byte (clean upstream merges, fork-and-extend)
- internal/{cli,cmds,config,credstore,runtime,output}: cobra command tree,
keyring-backed credential profiles, provider bootstrap, result printing
- 21 tools as subcommands (channels, conversations, users, usergroups,
saved, reactions, attachments, cache); write tools keep their env gating
- goreleaser + homebrew release workflow; ships a skills/slack-cli skill
- unit tests for config/credstore/toolcall; MCP server still builds
The MCP server (cmd/slack-mcp-server) is kept intact.
The sort=popularity option forced fetching every channel the user belongs
to before sorting client-side — hundreds of API calls on large workspaces.
The Slack API doesn't support server-side sorting, so this was inherently
expensive. Remove it and always stop fetching once we have enough results,
using the Slack API's native cursor for pagination.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When sort is not "popularity", stop paginating the Slack API as soon as
we have enough results for the requested limit, and pass through the
API's native cursor. On large workspaces this avoids hundreds of API
calls when only a small number of channels are requested.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a new MCP tool to list channels the calling user is a member of,
using the users.conversations API. Follows the same pattern as
usergroups_me vs usergroups_list.
Unlike channels_list which returns all workspace channels, channels_me
returns only channels the user has joined — useful on large workspaces
where channels_list returns thousands of results.
Supports channel_types, sort (by popularity), limit, and cursor
parameters.
Closes#251. Adds keyword filtering to channels_list so users can find
channels without paginating through the entire list. Matches are
case-insensitive substrings; query_targets controls which fields to
search (name by default, optionally topic and purpose).