Slack
The Slack suite gives your agent three capabilities against the user’s Slack workspace: list channels, search the user’s accessible message history, and post a new message. Post is gated by per-call user approval. Reads run without prompting.
The suite is published from the aileron-connector-slack ↗ repo. The connector runs as a sandboxed WASM module talking only to slack.com:443. The user’s OAuth token lives in the Aileron vault and is injected host-side at the network boundary, so the connector code never sees the token bytes.
Posts are made with the authorizing user’s token, not as a bot. Messages appear in Slack authored by the user. This is the right shape for the Monday catch-up demo and for power-user automation generally; it is the wrong shape if you want a dedicated app identity for posts.
Prerequisite
The Aileron Slack app must be installed into your workspace. aileron action add (and add-suite) handles this for you: the CLI opens Slack’s consent screen in your browser, and clicking Allow installs the app and authorizes your user in one step.
If your workspace requires admin approval for third-party apps, Slack shows a “Request to install” button instead of Allow. A workspace admin approves the request, then you re-run the same aileron action add command.
The Aileron Slack app is not on the Slack Marketplace, so there’s no App Directory page to install from. The CLI is the install path.
Install
Whole suite (recommended)
aileron action add-suite github://ALRubinger/aileron-connector-slack/suite.toml@latestIndividual actions
Pick whichever actions you actually want exposed to the agent.
aileron action add github://ALRubinger/aileron-connector-slack/actions/list-channels@latestaileron action add github://ALRubinger/aileron-connector-slack/actions/search-messages@latestaileron action add github://ALRubinger/aileron-connector-slack/actions/send-message@latestActions
list-channels
Lists the Slack channels the user has access to in the workspace. Each entry carries id, name, topic, purpose, is_member, and the rest of Slack’s conversations.list ↗ envelope. By default only public channels are returned.
| Input | Required | Description |
|---|---|---|
limit | no | Page size. Default 100, max 1000. |
types | no | Comma-separated channel types: public_channel, private_channel, mpim, im. Default public_channel. |
cursor | no | Pagination cursor returned from a previous call’s response_metadata.next_cursor. |
exclude_archived | no | Skip archived channels. Default true. |
Idempotent. Read-only. No approval prompt.
search-messages
Searches the user’s Slack message history using Slack’s native search syntax. Returns Slack’s search.messages ↗ envelope; the messages.matches array carries the hits with text, user, username, channel, ts, and permalink.
| Input | Required | Description |
|---|---|---|
query | yes | Slack search query. Supports from:@user, in:#channel, before:YYYY-MM-DD, after:YYYY-MM-DD, has:link, has:reaction. Example: from:@alice deploy in:#release-notes after:2026-04-01. |
count | no | Results per page. Default 20, max 100. |
sort | no | score (relevance, default) or timestamp (newest first). |
page | no | 1-based page index. Default 1. |
Idempotent. Read-only. No approval prompt.
search.messages is one of Slack’s user-token-only APIs. The connector’s OAuth dance requests the search:read user scope so this action works; if the user denies that scope at consent, the action returns a missing_scope error.
send-message
Posts a message to a Slack channel as the authorizing user. The user is prompted to approve the channel and exact message text before Slack receives the post.
| Input | Required | Description |
|---|---|---|
channel | yes | Channel id (e.g. C0123456) or channel name (e.g. #general). DM ids (Dxxxx) and group ids (Gxxxx) are also accepted by Slack. |
text | yes | The message body to post. The user will be asked to approve this exact text before Slack receives it. |
thread_ts | no | Parent message timestamp (e.g. 1683750000.000100) to reply in thread. Omit to post a top-level message. |
Approval-gated (ADR-0009). The runtime asks the user via the launch-comms channel before Slack is contacted; on denial nothing is sent. Not idempotent: invoking twice posts two messages. Slack has a brief edit window but no retraction, and notifications and thread bumps fire on the original post, so approve-before-dispatch is the only safe model.
Scopes the consent screen asks for
Slack’s OAuth consent screen names the connector publisher (ALRubinger) and the requested user-token scope set:
| Scope | Used by |
|---|---|
chat:write | send-message. Posts appear as the authorizing user. |
channels:read | list-channels. |
users:read | search-messages. Resolves user ids to display names in hits. |
search:read | search-messages. User-token-only; this is what forces the OAuth dance to issue a user token rather than a bot token. |
Per ADR-0002’s OAuth section, the consent screen is a contract between the user and the entity identified on it. The user is granting these scopes to the connector publisher’s Slack app, not to Aileron itself.
Error classes
The connector emits structured errors per ADR-0010. Slack returns most logical failures as HTTP 200 with {"ok": false, "error": "<code>"}, so the connector translates both transport-level and in-body errors into the same class set.
| Class | When | What the user sees |
|---|---|---|
unauthorized | HTTP 401, or ok=false with error not_authed, invalid_auth, token_revoked, account_inactive, or token_expired. | The bound OAuth token is rejected. Re-run aileron binding setup github://ALRubinger/aileron-connector-slack to re-consent. |
missing_scope | ok=false with error missing_scope or not_allowed_token_type. | The OAuth grant is missing a scope the action requires. Re-run aileron binding setup to grant the missing scope. |
rate_limited | HTTP 429 or ok=false with error ratelimited. | Slack is throttling. The runtime’s retry layer will respect Slack’s Retry-After header for transient backoff. |
external_api_error | Any other Slack-reported error. | Body is included for the agent and the audit log. |
connector_runtime_error | Malformed input, unparseable response, or a missing required arg. | Generic; check the action’s required inputs. |
See also
- Installing an Action for the general install flow.
- aileron-connector-slack ↗ for connector source.
- Slack API: chat.postMessage ↗, conversations.list ↗, search.messages ↗ for the upstream API surface.
- ADR-0002: Connector Model
- ADR-0009: User Channel and Approval Surfaces