Your AI agent can read your repo, run your tests, and open a pull request. Then it hits a wall. The context it needs is in Slack: the incident thread, the decision nobody wrote down, the "we changed the deploy order last week" message.
Getting an agent into Slack normally means building a Slack app, picking OAuth scopes, and waiting for an admin to approve it. That is a lot of work before the first useful message.
SlackCLI is a different path. It is a single open source binary that talks to Slack from your terminal, and every read command speaks JSON. If your agent can run a shell command, it can use Slack.
SlackCLI is an unofficial project. It is not affiliated with or supported by Slack Technologies.
Up and running in about a minute
brew tap shaharia-lab/tap
brew install slackcli
slackcli auth login-auto
login-auto opens a browser, you sign in to Slack the way you always do, and SlackCLI captures the session tokens for every workspace on that account. Nothing leaves your machine. Credentials land in ~/.config/slackcli/workspaces.json with file mode 0600.
Prefer a real bot token for a server or a CI job? That works too:
slackcli auth login --token=xoxb-your-token --workspace-name="My Team"
Now try something:
slackcli conversations unread
See it in action
Demo: https://github.com/shaharia-lab/slackcli#-see-it-in-action
Sign in, browse conversations, search the workspace, read a thread from a permalink, reply, react, read a Canvas as Markdown, and pipe --json into jq. All from the terminal.
Why a CLI is a good tool for an AI agent
Most agent frameworks are happiest when a tool is a plain command with plain output. SlackCLI is built exactly that way.
-
JSON everywhere. Every read command takes
--json, so the agent gets structured data instead of screen scraping. - Clean streams. JSON goes to stdout. Spinners, warnings, and update notices go to stderr. A pipe carries only data.
-
Simple exit codes.
0on success,1on failure. An empty search result is still a success, so check the data, not the exit code. - Links work as input. Anywhere the CLI wants a channel ID or a timestamp, you can paste a Slack permalink instead. A human drops a link in the prompt and the agent runs with it.
- One static binary. No Python environment, no Node runtime, no server to keep alive.
-
Many workspaces at once. Add
--workspace=automation-botto any command to pick an identity on purpose.
Seven things an agent can do today
1. Catch up on what you missed
slackcli conversations unread --json | jq '[.unread_channels[] | {name, unread_count}]'
Feed that to a model and you have a morning digest.
2. Read a thread from a link
slackcli conversations read --permalink="$LINK" --json | jq -r '.messages[].text'
The JSON also carries a resolved users array, so user IDs are not opaque.
3. Search the workspace history
slackcli search messages "deploy failed" --in=engineering --limit=50 --json
All of Slack's own search operators work: in:, from:, before:, after:, has:, is:.
4. Find a channel or a person
slackcli search channels incident --json
slackcli search people "ada@example.com" --json
5. Reply where the conversation is happening
slackcli messages send --permalink="$LINK" --message="Root cause found, fix is in #4821"
Passing a permalink replies in that thread, so no ID juggling is needed.
6. Post a report humans actually want to read
slackcli messages send \
--recipient-id=C1234567890 \
--message="Nightly build report" \
--blocks='[{"type":"markdown","text":"# Nightly build\n\n- [x] Build\n- [x] Tests\n- [ ] Deploy"}]'
Native Block Kit markdown and table blocks mean headings, task lists, code fences, and real tables instead of a wall of text.
7. Read a Canvas as Markdown
slackcli canvas read F1234567890 --json | jq -r '.markdown'
Team runbooks and specs often live in a Canvas. Now they are just Markdown your agent can read.
Wiring it into an agent
You do not need an SDK or an MCP server. Give the agent shell access and one short instruction block:
You can use the `slackcli` command to work with Slack.
Read commands (always add --json):
slackcli conversations unread --json
slackcli conversations read <channel-id|--permalink=URL> --json
slackcli search messages "<query>" --in=<channel> --json
slackcli canvas read <file-id> --json
Write commands (ask me first):
slackcli messages send --permalink=<url> --message="<text>"
slackcli messages react --permalink=<url> --emoji=<name>
Run `slackcli <group> --help` if you need the exact options.
That is the whole integration. A useful first prompt:
Read the last 50 messages in #incidents, find any unresolved issue from today, and draft a summary for me. Do not post it yet.
Because slackcli <group> --help prints the authoritative options for the installed version, an agent can discover the rest on its own.
Keep it safe
Slack access is real access, so a few rules are worth setting up front.
- Separate the identity. Give automation its own bot token workspace profile instead of copying your personal browser session onto a server.
- Keep a human on writes. Reads are cheap and reversible. Posting is not. A simple "ask before sending" rule in the agent prompt goes a long way.
-
Treat the config as a secret.
~/.config/slackcli/workspaces.jsonand the browser profile hold live credentials. Do not commit them, sync them, or copy them around.slackcli auth logoutclears both. -
Refresh tokens without a window. Browser tokens expire with the session.
slackcli auth login-auto --headlessrenews them in an unattended job once the profile has signed in once. - Watch the rate limits. Commands that resolve many users or channels make one API call per entity, which adds up on a large workspace.
Try it
brew tap shaharia-lab/tap
brew install slackcli
slackcli auth login-auto
slackcli conversations unread
SlackCLI is MIT licensed, built with Bun, and ships prebuilt binaries for macOS, Linux, and Windows. It has over 400 tests and a full user guide.
⭐ Star it on GitHub if it saves you a trip to the Slack tab, and tell me in the comments what you would want your agent to do in Slack. Feature requests start as an issue.
Top comments (0)