# Slack

## What it does

The Slack integration lets Speedwave read channels and direct messages you belong to, read files shared in Slack, find people, and post messages. Speedwave acts as you: anything it sends goes out under your name and avatar, and it only ever sees what your Slack account can already see.

## What it consists of

The connection has two pieces: a short-lived access token mounted read-only into the Slack worker, and a refresh token that never leaves the host. The worker is the only thing that talks to Slack's API; it holds the current access token and nothing else.

- ~/.speedwave/
  - tokens/
    - &lt;project&gt;/
      - slack/
        - access_token short-lived, mounted read-only into the worker
  - oauth/
    - &lt;project&gt;/
      - slack.json refresh token and workspace identity, never mounted

## How it works

You sign in once with a **Sign in with Slack** button in Speedwave Desktop. There is no Slack app to create and no token to paste: Speednet runs a single public Slack app that every install shares, and the whole exchange completes on your machine.

Clicking the button opens Slack's consent screen in your browser. You pick a workspace and click Allow, and Slack redirects the browser to a fixed local address, `http://localhost:41739/callback`, that Speedwave listens on. Speedwave picks up the code from that redirect and exchanges it for tokens right there on your machine, with no Speedwave server involved.

```mermaid
sequenceDiagram
    participant You
    participant Desktop as Speedwave Desktop
    participant Browser
    participant Slack
    You->>Desktop: Click Sign in with Slack
    Desktop->>Browser: Open Slack consent screen
    Browser->>Slack: Pick workspace, click Allow
    Slack->>Browser: Redirect to localhost:41739/callback with code
    Browser->>Desktop: Deliver code to local listener
    Desktop->>Slack: Exchange code for tokens (PKCE, on your machine)
    Desktop->>You: Card shows Connected to (workspace)
```

Once connected, Speedwave reads channels and DMs, finds people, and sends messages through a set of MCP tools. It resolves author IDs to display names so you see real names instead of raw IDs.

| Tool | What it does |
| --- | --- |
| `getChannelMessages` | Reads a channel's history. Needs `channel` (name, `#name`, or ID); `limit` is 1 to 100, default 50; an optional `oldest`/`latest` window narrows the range. Returns one page at a time, newest first, with `next_cursor`/`has_more` for pulling more. |
| `getThreadMessages` | Reads a thread. Needs `channel` and `thread_ts`; returns the parent message first, then replies oldest to newest. |
| `sendChannel` | Posts a message to a channel or DM as you. Irreversible and visible the moment it sends. |
| `listChannelIds` | Lists channels you are a member of (public and private by default). |
| `listDirectMessages` | Lists your open 1:1 and group DM conversations. |
| `openDirectMessage` | Opens or reuses a DM with 1 to 8 people, identified by Slack user ID or exact email, never by plain name. Opening is silent: the other side sees nothing until a message is actually sent. |
| `getFileContent` | Reads a text file shared in Slack (markdown, code, logs, JSON) inline, up to 1 MB, with a `truncated` flag if cut off. Refuses binary files and returns their metadata instead. |
| `downloadFile` | Downloads any file, including binaries like PDFs and images, into the project workspace at `/workspace/.speedwave/slack/`, capped at 50 MB, so it can be opened with the [Office documents](/docs/integrations/office-documents/) integration or the filesystem. |
| `getUsers` | Looks up a person by exact email. |
| `findUsers` | Fuzzy, diacritic-insensitive search by name across the workspace. Returns up to 25 matches and warns that names aren't unique, so confirm before DMing. |

Sending a message is the one action with a lasting effect: everything else only reads or, for `openDirectMessage`, opens a conversation with no visible trace until a message follows.

Channel and user lookups are backed by a lazy, cached directory (Slack's `users.list`/`conversations.list`, refreshed hourly) so repeated lookups don't hit Slack's API every time.

Sending a message is gated: before any channel post or DM, Speedwave restates the exact recipient and the verbatim text and waits for your explicit go-ahead in that turn.
**Caution:** A general instruction like "let them know" is not approval of the final wording. Confirmation happens every time, for every send.

Access tokens expire after 12 hours, and Speedwave refreshes them on the host side, rotating the refresh token each time so it stays single-use. The refresh token itself expires after 30 days of no activity, after which the integration card shows a re-authorise banner.

## Set it up

1. Open your project in Desktop and go to **Integrations** and **Slack**.
2. Click **Sign in with Slack** and pick your workspace in the browser window that opens.
3. Click **Allow**. If your workspace requires admin approval of apps, an admin has to approve the Speedwave app once before you can finish.
4. Wait for the card to show **Connected to** your workspace name, then click **restart now** so the worker picks up the credentials.

<DesktopFrame screen="integrations" />

See [Connect an integration](/docs/guides/connect-an-integration/) for the general pattern every integration follows.

## Security boundaries

The sign-in only requests user scopes, so Speedwave can do exactly what your account can do and nothing more: it cannot create, archive, or rename channels, invite anyone, or change workspace settings. It can only read conversations you are already a member of. There is no way to add the integration to a channel you are not in.

The worker only ever holds the short-lived access token, mounted read-only; the refresh token and your workspace identity stay in a file that no container mounts. For how that split keeps a compromised worker from reaching other services, see [how credentials are handled](/docs/security/credentials/).