KosmoKrator

productivity

Slack Lua API for KosmoKrator Agents

Agent-facing Lua documentation and function reference for the Slack KosmoKrator integration.

25 functions 13 read 12 write API token auth

Lua Namespace

Agents call this integration through app.integrations.slack.*. Use lua_read_doc("integrations.slack") inside KosmoKrator to discover the same reference at runtime.

Agent-Facing Lua Docs

This is the rendered version of the full Lua documentation exposed to agents when they inspect the integration namespace.

Slack — Lua API Reference

Overview

The Slack integration provides 25 tools for interacting with Slack workspaces: sending and managing messages, managing channels, uploading and listing files, looking up users, adding emoji reactions, and managing usergroups.

All tools are called via app.integrations.slack.<tool_name>({ ... }) and return a Lua table with the API response.

Authentication

The Slack integration uses a Bot Token (xoxb-...) obtained from your Slack app configuration.

Create a token: Slack → Your App → OAuth & Permissions → Bot User OAuth Token

The bot token determines which channels and actions are available based on the OAuth scopes assigned to the app (e.g. chat:write, channels:read, files:write).


Messages

Send a message to a Slack channel or DM. Supports text formatting, Block Kit blocks, thread replies, and link unfurling.

NameTypeRequiredDescription
channelstringyesChannel ID or name (e.g. "#general" or "C12345678").
textstringyesMessage text.
blocksstringnoJSON array of Slack Block Kit blocks for rich formatting.
thread_tsstringnoTimestamp of the parent message to reply in a thread.
reply_broadcastbooleannoIf true, also post the reply to the channel (requires thread_ts).
unfurl_linksbooleannoIf true, enable unfurling of links.
markdownbooleannoIf true, enable mrkdwn formatting in text.
local result = app.integrations.slack.send_message({
  channel = "C12345678",
  text = "Hello from the integration!"
})
-- result.ts is the timestamp of the sent message
-- result.channel is the channel ID
-- Reply in a thread
local result = app.integrations.slack.send_message({
  channel = "C12345678",
  text = "Replying to the thread",
  thread_ts = "1234567890.123456"
})
-- Rich formatting with Block Kit
local result = app.integrations.slack.send_message({
  channel = "C12345678",
  text = "Deploy notification",
  blocks = '[{"type":"section","text":{"type":"mrkdwn","text":"*Deploy complete*\nVersion `2.1.0` is live."}}]'
})

app.integrations.slack.update_message({ channel, ts, text, blocks })

Update an existing Slack message’s text or blocks.

NameTypeRequiredDescription
channelstringyesChannel ID where the message was posted.
tsstringyesTimestamp of the message to update.
textstringnoNew message text.
blocksstringnoJSON array of Slack Block Kit blocks.
local result = app.integrations.slack.update_message({
  channel = "C12345678",
  ts = "1234567890.123456",
  text = "Updated message content"
})
-- result.ok == true on success
-- Update with Block Kit
local result = app.integrations.slack.update_message({
  channel = "C12345678",
  ts = "1234567890.123456",
  text = "Status update",
  blocks = '[{"type":"section","text":{"type":"mrkdwn","text":"*Status:* ✅ Complete"}}]'
})

app.integrations.slack.delete_message({ channel, ts })

Delete a Slack message by channel and timestamp.

NameTypeRequiredDescription
channelstringyesChannel ID where the message was posted.
tsstringyesTimestamp of the message to delete.
local result = app.integrations.slack.delete_message({
  channel = "C12345678",
  ts = "1234567890.123456"
})
-- result.ok == true on success

app.integrations.slack.get_message({ channel, ts, thread_ts })

Get a specific message by its timestamp. Optionally retrieve a message within a thread.

NameTypeRequiredDescription
channelstringyesChannel ID.
tsstringyesTimestamp of the message to retrieve.
thread_tsstringnoIf provided, fetches a reply within this thread instead.
local result = app.integrations.slack.get_message({
  channel = "C12345678",
  ts = "1234567890.123456"
})
-- result.message contains the full message object
-- Get a specific thread reply
local result = app.integrations.slack.get_message({
  channel = "C12345678",
  ts = "1234567891.654321",
  thread_ts = "1234567890.123456"
})

app.integrations.slack.search_messages({ query, count, page, sort, sort_dir })

Search for messages across all Slack channels and DMs. Supports Slack search modifiers.

NameTypeRequiredDescription
querystringyesSearch query. Supports modifiers like from:, in:, has:, after:, before:.
countintegernoNumber of results per page (default 20, max 100).
pageintegernoPage number of results (default 1).
sortstringnoSort order: "score" (default) or "timestamp".
sort_dirstringnoSort direction: "desc" (default) or "asc".
local result = app.integrations.slack.search_messages({
  query = "deploy after:2024-01-01"
})
-- result.messages.matches contains the matching messages
-- Search with modifiers
local result = app.integrations.slack.search_messages({
  query = "from:@alice in:#engineering has:link",
  count = 50,
  sort = "timestamp",
  sort_dir = "desc"
})

Get a permalink URL for a specific Slack message.

NameTypeRequiredDescription
channelstringyesChannel ID where the message is posted.
message_tsstringyesTimestamp of the message.
local result = app.integrations.slack.get_permalink({
  channel = "C12345678",
  message_ts = "1234567890.123456"
})
-- result.permalink is the full URL to the message

app.integrations.slack.get_channel_history({ channel, limit, oldest, latest, cursor })

Get message history for a Slack channel. Supports cursor-based pagination and time range filtering.

NameTypeRequiredDescription
channelstringyesChannel ID.
limitintegernoNumber of messages to return (default 100, max 1000).
oldeststringnoStart of time range, as a Unix timestamp.
lateststringnoEnd of time range, as a Unix timestamp.
cursorstringnoPagination cursor from a previous response.
local result = app.integrations.slack.get_channel_history({
  channel = "C12345678",
  limit = 50
})
-- result.messages contains the message list
-- result.response_metadata.next_cursor for pagination
-- Filter by time range
local result = app.integrations.slack.get_channel_history({
  channel = "C12345678",
  oldest = "1704067200",
  latest = "1704153600",
  limit = 100
})
-- Paginate through history
local result = app.integrations.slack.get_channel_history({
  channel = "C12345678",
  limit = 100,
  cursor = "dXNlcjpVMDYxTkZUVDI="
})

app.integrations.slack.get_thread_replies({ channel, ts, limit, cursor })

Get all replies in a Slack message thread.

NameTypeRequiredDescription
channelstringyesChannel ID.
tsstringyesTimestamp of the parent message (thread root).
limitintegernoNumber of replies to return per page (default 1000).
cursorstringnoPagination cursor from a previous response.
local result = app.integrations.slack.get_thread_replies({
  channel = "C12345678",
  ts = "1234567890.123456"
})
-- result.messages contains the parent message and all replies

Channels

app.integrations.slack.list_channels({ types, exclude_archived, limit, cursor })

List all Slack channels visible to the bot. Supports filtering by channel type and cursor-based pagination.

NameTypeRequiredDescription
typesstringnoComma-separated channel types: "public_channel", "private_channel", "mpim", "im". Default: "public_channel".
exclude_archivedbooleannoExclude archived channels (default: true).
limitintegernoNumber of channels to return per page (default 100, max 1000).
cursorstringnoPagination cursor from a previous response.
local result = app.integrations.slack.list_channels({
  types = "public_channel,private_channel",
  exclude_archived = true
})
-- result.channels contains the channel list
-- result.response_metadata.next_cursor for pagination
-- Include DMs and group messages
local result = app.integrations.slack.list_channels({
  types = "public_channel,private_channel,mpim,im",
  limit = 200
})

app.integrations.slack.get_channel({ channel })

Get detailed information about a Slack channel.

NameTypeRequiredDescription
channelstringyesChannel ID.
local result = app.integrations.slack.get_channel({
  channel = "C12345678"
})
-- result.channel contains the channel object (name, topic, purpose, members, etc.)

app.integrations.slack.create_channel({ name, is_private })

Create a new Slack channel (public or private).

NameTypeRequiredDescription
namestringyesChannel name (lowercase, no spaces, max 80 chars).
is_privatebooleannoCreate a private channel instead of public (default: false).
local result = app.integrations.slack.create_channel({
  name = "project-alpha",
  is_private = false
})
-- result.channel contains the newly created channel object
-- result.channel.id is the channel ID
-- Create a private channel
local result = app.integrations.slack.create_channel({
  name = "secret-project",
  is_private = true
})

app.integrations.slack.set_topic({ channel, topic })

Set the topic text on a Slack channel.

NameTypeRequiredDescription
channelstringyesChannel ID.
topicstringyesThe new topic text.
local result = app.integrations.slack.set_topic({
  channel = "C12345678",
  topic = "Sprint 42 — Apr 1–15"
})
-- result.topic contains the updated topic object

app.integrations.slack.set_purpose({ channel, purpose })

Set the purpose text on a Slack channel.

NameTypeRequiredDescription
channelstringyesChannel ID.
purposestringyesThe new purpose text.
local result = app.integrations.slack.set_purpose({
  channel = "C12345678",
  purpose = "Coordination for the Q2 product launch"
})
-- result.purpose contains the updated purpose object

app.integrations.slack.archive_channel({ channel })

Archive a Slack channel by its ID.

NameTypeRequiredDescription
channelstringyesChannel ID to archive.
local result = app.integrations.slack.archive_channel({
  channel = "C12345678"
})
-- result.ok == true on success

app.integrations.slack.invite_to_channel({ channel, users })

Invite one or more users to a Slack channel.

NameTypeRequiredDescription
channelstringyesChannel ID.
usersstringyesComma-separated list of user IDs to invite.
local result = app.integrations.slack.invite_to_channel({
  channel = "C12345678",
  users = "U11111111,U22222222"
})
-- result.ok == true on success
-- result.channel contains the updated channel object

Files

app.integrations.slack.upload_file({ channel, content, filename, title, initial_comment, thread_ts })

Upload a file to Slack using the modern external upload flow. The file content is posted to a channel, optionally as a thread reply.

NameTypeRequiredDescription
channelstringyesChannel ID to post the file to.
contentstringyesFile content (text).
filenamestringyesFilename with extension (e.g. "report.txt").
titlestringnoTitle of the file.
initial_commentstringnoComment to include with the file post.
thread_tsstringnoTimestamp of the parent message to reply in a thread.
local result = app.integrations.slack.upload_file({
  channel = "C12345678",
  content = "Name,Email\nAlice,[email protected]\nBob,[email protected]",
  filename = "contacts.csv",
  title = "Contact List",
  initial_comment = "Here is the latest contact list."
})
-- result.files contains the uploaded file objects
-- Upload as a thread reply
local result = app.integrations.slack.upload_file({
  channel = "C12345678",
  content = "Line 1\nLine 2\nLine 3",
  filename = "log-output.txt",
  thread_ts = "1234567890.123456",
  initial_comment = "Here are the logs you asked for."
})

app.integrations.slack.list_files({ channel, user, types, count, page })

List files in the Slack workspace, with optional filtering by channel, user, or file type. Supports page-based pagination.

NameTypeRequiredDescription
channelstringnoChannel ID to filter files by.
userstringnoUser ID to filter files by.
typesstringnoComma-separated file types: "spaces", "snippets", "images", "gdocs", "zips", "pdfs".
countintegernoNumber of files per page (default 100).
pageintegernoPage number (default 1).
local result = app.integrations.slack.list_files({
  channel = "C12345678",
  count = 20,
  page = 1
})
-- result.files contains the file list
-- result.paging contains pagination info
-- Filter by file type
local result = app.integrations.slack.list_files({
  user = "U11111111",
  types = "images,pdfs",
  count = 50
})

app.integrations.slack.get_file({ file })

Get detailed information about a Slack file by its ID.

NameTypeRequiredDescription
filestringyesFile ID.
local result = app.integrations.slack.get_file({
  file = "F12345678"
})
-- result.file contains the file object (name, title, mimetype, size, url_private, etc.)

Users

app.integrations.slack.list_users({ limit, cursor, include_locale })

List all users in the Slack workspace. Supports cursor-based pagination.

NameTypeRequiredDescription
limitintegernoNumber of users per page (default 100, max 1000).
cursorstringnoPagination cursor from a previous response.
include_localebooleannoInclude user locale information (default: false).
local result = app.integrations.slack.list_users({
  limit = 200
})
-- result.members contains the user list
-- result.response_metadata.next_cursor for pagination
-- Paginate through all users
local all_users = {}
local cursor = ""

repeat
  local result = app.integrations.slack.list_users({
    limit = 200,
    cursor = cursor
  })
  for _, user in ipairs(result.members or {}) do
    table.insert(all_users, user)
  end
  cursor = (result.response_metadata or {}).next_cursor or ""
until cursor == ""

app.integrations.slack.get_user({ user })

Get detailed information about a Slack user by their ID.

NameTypeRequiredDescription
userstringyesUser ID.
local result = app.integrations.slack.get_user({
  user = "U12345678"
})
-- result.user contains the user object (name, real_name, profile, etc.)

app.integrations.slack.find_user_by_email({ email })

Look up a Slack user by their email address.

NameTypeRequiredDescription
emailstringyesEmail address to look up.
local result = app.integrations.slack.find_user_by_email({
  email = "[email protected]"
})
-- result.user contains the user object
-- result.user.id is the user ID

Reactions & Usergroups

app.integrations.slack.add_reaction({ channel, name, timestamp })

Add an emoji reaction to a Slack message.

NameTypeRequiredDescription
channelstringyesChannel ID where the message is posted.
namestringyesEmoji name without colons (e.g. "thumbsup", "heart").
timestampstringyesTimestamp of the message to react to.
local result = app.integrations.slack.add_reaction({
  channel = "C12345678",
  name = "thumbsup",
  timestamp = "1234567890.123456"
})
-- result.ok == true on success
-- React to a newly sent message
local msg = app.integrations.slack.send_message({
  channel = "C12345678",
  text = "Great work everyone!"
})
app.integrations.slack.add_reaction({
  channel = msg.channel,
  name = "rocket",
  timestamp = msg.ts
})

app.integrations.slack.remove_reaction({ channel, name, timestamp })

Remove an emoji reaction from a Slack message.

NameTypeRequiredDescription
channelstringyesChannel ID where the message is posted.
namestringyesEmoji name without colons (e.g. "thumbsup", "heart").
timestampstringyesTimestamp of the message.
local result = app.integrations.slack.remove_reaction({
  channel = "C12345678",
  name = "thumbsup",
  timestamp = "1234567890.123456"
})
-- result.ok == true on success

app.integrations.slack.list_usergroups({ include_count, include_disabled, include_users })

List all Slack usergroups in the workspace.

NameTypeRequiredDescription
include_countbooleannoInclude the number of users in each usergroup (default: false).
include_disabledbooleannoInclude disabled usergroups (default: false).
include_usersbooleannoInclude the list of users in each usergroup (default: false).
local result = app.integrations.slack.list_usergroups({
  include_count = true,
  include_users = true
})
-- result.usergroups contains the usergroup list

app.integrations.slack.update_usergroup_members({ usergroup, users })

Set the member list for a Slack usergroup. Note: This replaces the entire member list, not appends to it.

NameTypeRequiredDescription
usergroupstringyesUsergroup ID.
usersstringyesComma-separated list of user IDs to set as members.
local result = app.integrations.slack.update_usergroup_members({
  usergroup = "S12345678",
  users = "U11111111,U22222222,U33333333"
})
-- result.usergroup contains the updated usergroup object

Pagination

Several list endpoints support cursor-based pagination. When a response includes response_metadata.next_cursor, pass that value as cursor in the next call to retrieve the next page. An empty cursor string means no more results.

ToolPagination styleKey params
list_channelsCursorlimit, cursor
list_usersCursorlimit, cursor
get_channel_historyCursorlimit, cursor
get_thread_repliesCursorlimit, cursor
search_messagesPage numbercount, page
list_filesPage numbercount, page

Notes

  • Channel identifiers: Channels can be referenced by ID (e.g. "C12345678") or name (e.g. "#general"). IDs are preferred for reliability.
  • Message timestamps: Slack uses floating-point Unix timestamps (e.g. "1234567890.123456") as unique message identifiers. Always store and pass these as strings.
  • Block Kit: The blocks parameter accepts a JSON string, not a Lua table. Use vim.json.encode() or construct the JSON manually.
  • Bot scope requirements: Ensure your Slack app has the necessary OAuth scopes for each operation (e.g. chat:write for sending messages, channels:read for listing channels, files:write for uploads).
  • Rate limits: Slack API rate limits apply. Use pagination parameters rather than requesting large result sets in a single call.
  • Usergroups: The update_usergroup_members tool replaces the entire member list. Fetch the current list first if you need to add or remove individual members.
  • Thread replies: When replying in a thread, pass the parent message’s ts value as thread_ts in send_message, not the ts of another reply.

Multi-Account Usage

If you have multiple slack accounts configured, use account-specific namespaces:

-- Default account (always works)
app.integrations.slack.function_name({...})

-- Explicit default (portable across setups)
app.integrations.slack.default.function_name({...})

-- Named accounts
app.integrations.slack.work.function_name({...})
app.integrations.slack.personal.function_name({...})

All functions are identical across accounts — only the credentials differ.

Raw agent markdown
# Slack — Lua API Reference

## Overview

The Slack integration provides 25 tools for interacting with Slack workspaces: sending and managing messages, managing channels, uploading and listing files, looking up users, adding emoji reactions, and managing usergroups.

All tools are called via `app.integrations.slack.<tool_name>({ ... })` and return a Lua table with the API response.

## Authentication

The Slack integration uses a **Bot Token** (`xoxb-...`) obtained from your Slack app configuration.

Create a token: **Slack → Your App → OAuth & Permissions → Bot User OAuth Token**

The bot token determines which channels and actions are available based on the OAuth scopes assigned to the app (e.g. `chat:write`, `channels:read`, `files:write`).

---

## Messages

### `app.integrations.slack.send_message({ channel, text, thread_ts, blocks, reply_broadcast, unfurl_links, markdown })`

Send a message to a Slack channel or DM. Supports text formatting, Block Kit blocks, thread replies, and link unfurling.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID or name (e.g. `"#general"` or `"C12345678"`). |
| `text` | string | yes | Message text. |
| `blocks` | string | no | JSON array of Slack Block Kit blocks for rich formatting. |
| `thread_ts` | string | no | Timestamp of the parent message to reply in a thread. |
| `reply_broadcast` | boolean | no | If true, also post the reply to the channel (requires `thread_ts`). |
| `unfurl_links` | boolean | no | If true, enable unfurling of links. |
| `markdown` | boolean | no | If true, enable mrkdwn formatting in text. |

```lua
local result = app.integrations.slack.send_message({
  channel = "C12345678",
  text = "Hello from the integration!"
})
-- result.ts is the timestamp of the sent message
-- result.channel is the channel ID
```

```lua
-- Reply in a thread
local result = app.integrations.slack.send_message({
  channel = "C12345678",
  text = "Replying to the thread",
  thread_ts = "1234567890.123456"
})
```

```lua
-- Rich formatting with Block Kit
local result = app.integrations.slack.send_message({
  channel = "C12345678",
  text = "Deploy notification",
  blocks = '[{"type":"section","text":{"type":"mrkdwn","text":"*Deploy complete*\nVersion `2.1.0` is live."}}]'
})
```

---

### `app.integrations.slack.update_message({ channel, ts, text, blocks })`

Update an existing Slack message's text or blocks.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID where the message was posted. |
| `ts` | string | yes | Timestamp of the message to update. |
| `text` | string | no | New message text. |
| `blocks` | string | no | JSON array of Slack Block Kit blocks. |

```lua
local result = app.integrations.slack.update_message({
  channel = "C12345678",
  ts = "1234567890.123456",
  text = "Updated message content"
})
-- result.ok == true on success
```

```lua
-- Update with Block Kit
local result = app.integrations.slack.update_message({
  channel = "C12345678",
  ts = "1234567890.123456",
  text = "Status update",
  blocks = '[{"type":"section","text":{"type":"mrkdwn","text":"*Status:* ✅ Complete"}}]'
})
```

---

### `app.integrations.slack.delete_message({ channel, ts })`

Delete a Slack message by channel and timestamp.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID where the message was posted. |
| `ts` | string | yes | Timestamp of the message to delete. |

```lua
local result = app.integrations.slack.delete_message({
  channel = "C12345678",
  ts = "1234567890.123456"
})
-- result.ok == true on success
```

---

### `app.integrations.slack.get_message({ channel, ts, thread_ts })`

Get a specific message by its timestamp. Optionally retrieve a message within a thread.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID. |
| `ts` | string | yes | Timestamp of the message to retrieve. |
| `thread_ts` | string | no | If provided, fetches a reply within this thread instead. |

```lua
local result = app.integrations.slack.get_message({
  channel = "C12345678",
  ts = "1234567890.123456"
})
-- result.message contains the full message object
```

```lua
-- Get a specific thread reply
local result = app.integrations.slack.get_message({
  channel = "C12345678",
  ts = "1234567891.654321",
  thread_ts = "1234567890.123456"
})
```

---

### `app.integrations.slack.search_messages({ query, count, page, sort, sort_dir })`

Search for messages across all Slack channels and DMs. Supports Slack search modifiers.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `query` | string | yes | Search query. Supports modifiers like `from:`, `in:`, `has:`, `after:`, `before:`. |
| `count` | integer | no | Number of results per page (default 20, max 100). |
| `page` | integer | no | Page number of results (default 1). |
| `sort` | string | no | Sort order: `"score"` (default) or `"timestamp"`. |
| `sort_dir` | string | no | Sort direction: `"desc"` (default) or `"asc"`. |

```lua
local result = app.integrations.slack.search_messages({
  query = "deploy after:2024-01-01"
})
-- result.messages.matches contains the matching messages
```

```lua
-- Search with modifiers
local result = app.integrations.slack.search_messages({
  query = "from:@alice in:#engineering has:link",
  count = 50,
  sort = "timestamp",
  sort_dir = "desc"
})
```

---

### `app.integrations.slack.get_permalink({ channel, message_ts })`

Get a permalink URL for a specific Slack message.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID where the message is posted. |
| `message_ts` | string | yes | Timestamp of the message. |

```lua
local result = app.integrations.slack.get_permalink({
  channel = "C12345678",
  message_ts = "1234567890.123456"
})
-- result.permalink is the full URL to the message
```

---

### `app.integrations.slack.get_channel_history({ channel, limit, oldest, latest, cursor })`

Get message history for a Slack channel. Supports cursor-based pagination and time range filtering.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID. |
| `limit` | integer | no | Number of messages to return (default 100, max 1000). |
| `oldest` | string | no | Start of time range, as a Unix timestamp. |
| `latest` | string | no | End of time range, as a Unix timestamp. |
| `cursor` | string | no | Pagination cursor from a previous response. |

```lua
local result = app.integrations.slack.get_channel_history({
  channel = "C12345678",
  limit = 50
})
-- result.messages contains the message list
-- result.response_metadata.next_cursor for pagination
```

```lua
-- Filter by time range
local result = app.integrations.slack.get_channel_history({
  channel = "C12345678",
  oldest = "1704067200",
  latest = "1704153600",
  limit = 100
})
```

```lua
-- Paginate through history
local result = app.integrations.slack.get_channel_history({
  channel = "C12345678",
  limit = 100,
  cursor = "dXNlcjpVMDYxTkZUVDI="
})
```

---

### `app.integrations.slack.get_thread_replies({ channel, ts, limit, cursor })`

Get all replies in a Slack message thread.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID. |
| `ts` | string | yes | Timestamp of the parent message (thread root). |
| `limit` | integer | no | Number of replies to return per page (default 1000). |
| `cursor` | string | no | Pagination cursor from a previous response. |

```lua
local result = app.integrations.slack.get_thread_replies({
  channel = "C12345678",
  ts = "1234567890.123456"
})
-- result.messages contains the parent message and all replies
```

---

## Channels

### `app.integrations.slack.list_channels({ types, exclude_archived, limit, cursor })`

List all Slack channels visible to the bot. Supports filtering by channel type and cursor-based pagination.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `types` | string | no | Comma-separated channel types: `"public_channel"`, `"private_channel"`, `"mpim"`, `"im"`. Default: `"public_channel"`. |
| `exclude_archived` | boolean | no | Exclude archived channels (default: true). |
| `limit` | integer | no | Number of channels to return per page (default 100, max 1000). |
| `cursor` | string | no | Pagination cursor from a previous response. |

```lua
local result = app.integrations.slack.list_channels({
  types = "public_channel,private_channel",
  exclude_archived = true
})
-- result.channels contains the channel list
-- result.response_metadata.next_cursor for pagination
```

```lua
-- Include DMs and group messages
local result = app.integrations.slack.list_channels({
  types = "public_channel,private_channel,mpim,im",
  limit = 200
})
```

---

### `app.integrations.slack.get_channel({ channel })`

Get detailed information about a Slack channel.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID. |

```lua
local result = app.integrations.slack.get_channel({
  channel = "C12345678"
})
-- result.channel contains the channel object (name, topic, purpose, members, etc.)
```

---

### `app.integrations.slack.create_channel({ name, is_private })`

Create a new Slack channel (public or private).

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `name` | string | yes | Channel name (lowercase, no spaces, max 80 chars). |
| `is_private` | boolean | no | Create a private channel instead of public (default: false). |

```lua
local result = app.integrations.slack.create_channel({
  name = "project-alpha",
  is_private = false
})
-- result.channel contains the newly created channel object
-- result.channel.id is the channel ID
```

```lua
-- Create a private channel
local result = app.integrations.slack.create_channel({
  name = "secret-project",
  is_private = true
})
```

---

### `app.integrations.slack.set_topic({ channel, topic })`

Set the topic text on a Slack channel.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID. |
| `topic` | string | yes | The new topic text. |

```lua
local result = app.integrations.slack.set_topic({
  channel = "C12345678",
  topic = "Sprint 42 — Apr 1–15"
})
-- result.topic contains the updated topic object
```

---

### `app.integrations.slack.set_purpose({ channel, purpose })`

Set the purpose text on a Slack channel.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID. |
| `purpose` | string | yes | The new purpose text. |

```lua
local result = app.integrations.slack.set_purpose({
  channel = "C12345678",
  purpose = "Coordination for the Q2 product launch"
})
-- result.purpose contains the updated purpose object
```

---

### `app.integrations.slack.archive_channel({ channel })`

Archive a Slack channel by its ID.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID to archive. |

```lua
local result = app.integrations.slack.archive_channel({
  channel = "C12345678"
})
-- result.ok == true on success
```

---

### `app.integrations.slack.invite_to_channel({ channel, users })`

Invite one or more users to a Slack channel.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID. |
| `users` | string | yes | Comma-separated list of user IDs to invite. |

```lua
local result = app.integrations.slack.invite_to_channel({
  channel = "C12345678",
  users = "U11111111,U22222222"
})
-- result.ok == true on success
-- result.channel contains the updated channel object
```

---

## Files

### `app.integrations.slack.upload_file({ channel, content, filename, title, initial_comment, thread_ts })`

Upload a file to Slack using the modern external upload flow. The file content is posted to a channel, optionally as a thread reply.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID to post the file to. |
| `content` | string | yes | File content (text). |
| `filename` | string | yes | Filename with extension (e.g. `"report.txt"`). |
| `title` | string | no | Title of the file. |
| `initial_comment` | string | no | Comment to include with the file post. |
| `thread_ts` | string | no | Timestamp of the parent message to reply in a thread. |

```lua
local result = app.integrations.slack.upload_file({
  channel = "C12345678",
  content = "Name,Email\nAlice,[email protected]\nBob,[email protected]",
  filename = "contacts.csv",
  title = "Contact List",
  initial_comment = "Here is the latest contact list."
})
-- result.files contains the uploaded file objects
```

```lua
-- Upload as a thread reply
local result = app.integrations.slack.upload_file({
  channel = "C12345678",
  content = "Line 1\nLine 2\nLine 3",
  filename = "log-output.txt",
  thread_ts = "1234567890.123456",
  initial_comment = "Here are the logs you asked for."
})
```

---

### `app.integrations.slack.list_files({ channel, user, types, count, page })`

List files in the Slack workspace, with optional filtering by channel, user, or file type. Supports page-based pagination.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | no | Channel ID to filter files by. |
| `user` | string | no | User ID to filter files by. |
| `types` | string | no | Comma-separated file types: `"spaces"`, `"snippets"`, `"images"`, `"gdocs"`, `"zips"`, `"pdfs"`. |
| `count` | integer | no | Number of files per page (default 100). |
| `page` | integer | no | Page number (default 1). |

```lua
local result = app.integrations.slack.list_files({
  channel = "C12345678",
  count = 20,
  page = 1
})
-- result.files contains the file list
-- result.paging contains pagination info
```

```lua
-- Filter by file type
local result = app.integrations.slack.list_files({
  user = "U11111111",
  types = "images,pdfs",
  count = 50
})
```

---

### `app.integrations.slack.get_file({ file })`

Get detailed information about a Slack file by its ID.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `file` | string | yes | File ID. |

```lua
local result = app.integrations.slack.get_file({
  file = "F12345678"
})
-- result.file contains the file object (name, title, mimetype, size, url_private, etc.)
```

---

## Users

### `app.integrations.slack.list_users({ limit, cursor, include_locale })`

List all users in the Slack workspace. Supports cursor-based pagination.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `limit` | integer | no | Number of users per page (default 100, max 1000). |
| `cursor` | string | no | Pagination cursor from a previous response. |
| `include_locale` | boolean | no | Include user locale information (default: false). |

```lua
local result = app.integrations.slack.list_users({
  limit = 200
})
-- result.members contains the user list
-- result.response_metadata.next_cursor for pagination
```

```lua
-- Paginate through all users
local all_users = {}
local cursor = ""

repeat
  local result = app.integrations.slack.list_users({
    limit = 200,
    cursor = cursor
  })
  for _, user in ipairs(result.members or {}) do
    table.insert(all_users, user)
  end
  cursor = (result.response_metadata or {}).next_cursor or ""
until cursor == ""
```

---

### `app.integrations.slack.get_user({ user })`

Get detailed information about a Slack user by their ID.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `user` | string | yes | User ID. |

```lua
local result = app.integrations.slack.get_user({
  user = "U12345678"
})
-- result.user contains the user object (name, real_name, profile, etc.)
```

---

### `app.integrations.slack.find_user_by_email({ email })`

Look up a Slack user by their email address.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `email` | string | yes | Email address to look up. |

```lua
local result = app.integrations.slack.find_user_by_email({
  email = "[email protected]"
})
-- result.user contains the user object
-- result.user.id is the user ID
```

---

## Reactions & Usergroups

### `app.integrations.slack.add_reaction({ channel, name, timestamp })`

Add an emoji reaction to a Slack message.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID where the message is posted. |
| `name` | string | yes | Emoji name without colons (e.g. `"thumbsup"`, `"heart"`). |
| `timestamp` | string | yes | Timestamp of the message to react to. |

```lua
local result = app.integrations.slack.add_reaction({
  channel = "C12345678",
  name = "thumbsup",
  timestamp = "1234567890.123456"
})
-- result.ok == true on success
```

```lua
-- React to a newly sent message
local msg = app.integrations.slack.send_message({
  channel = "C12345678",
  text = "Great work everyone!"
})
app.integrations.slack.add_reaction({
  channel = msg.channel,
  name = "rocket",
  timestamp = msg.ts
})
```

---

### `app.integrations.slack.remove_reaction({ channel, name, timestamp })`

Remove an emoji reaction from a Slack message.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel` | string | yes | Channel ID where the message is posted. |
| `name` | string | yes | Emoji name without colons (e.g. `"thumbsup"`, `"heart"`). |
| `timestamp` | string | yes | Timestamp of the message. |

```lua
local result = app.integrations.slack.remove_reaction({
  channel = "C12345678",
  name = "thumbsup",
  timestamp = "1234567890.123456"
})
-- result.ok == true on success
```

---

### `app.integrations.slack.list_usergroups({ include_count, include_disabled, include_users })`

List all Slack usergroups in the workspace.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `include_count` | boolean | no | Include the number of users in each usergroup (default: false). |
| `include_disabled` | boolean | no | Include disabled usergroups (default: false). |
| `include_users` | boolean | no | Include the list of users in each usergroup (default: false). |

```lua
local result = app.integrations.slack.list_usergroups({
  include_count = true,
  include_users = true
})
-- result.usergroups contains the usergroup list
```

---

### `app.integrations.slack.update_usergroup_members({ usergroup, users })`

Set the member list for a Slack usergroup. **Note:** This replaces the entire member list, not appends to it.

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `usergroup` | string | yes | Usergroup ID. |
| `users` | string | yes | Comma-separated list of user IDs to set as members. |

```lua
local result = app.integrations.slack.update_usergroup_members({
  usergroup = "S12345678",
  users = "U11111111,U22222222,U33333333"
})
-- result.usergroup contains the updated usergroup object
```

---

## Pagination

Several list endpoints support cursor-based pagination. When a response includes `response_metadata.next_cursor`, pass that value as `cursor` in the next call to retrieve the next page. An empty cursor string means no more results.

| Tool | Pagination style | Key params |
|------|-----------------|------------|
| `list_channels` | Cursor | `limit`, `cursor` |
| `list_users` | Cursor | `limit`, `cursor` |
| `get_channel_history` | Cursor | `limit`, `cursor` |
| `get_thread_replies` | Cursor | `limit`, `cursor` |
| `search_messages` | Page number | `count`, `page` |
| `list_files` | Page number | `count`, `page` |

---

## Notes

- **Channel identifiers:** Channels can be referenced by ID (e.g. `"C12345678"`) or name (e.g. `"#general"`). IDs are preferred for reliability.
- **Message timestamps:** Slack uses floating-point Unix timestamps (e.g. `"1234567890.123456"`) as unique message identifiers. Always store and pass these as strings.
- **Block Kit:** The `blocks` parameter accepts a JSON string, not a Lua table. Use `vim.json.encode()` or construct the JSON manually.
- **Bot scope requirements:** Ensure your Slack app has the necessary OAuth scopes for each operation (e.g. `chat:write` for sending messages, `channels:read` for listing channels, `files:write` for uploads).
- **Rate limits:** Slack API rate limits apply. Use pagination parameters rather than requesting large result sets in a single call.
- **Usergroups:** The `update_usergroup_members` tool **replaces** the entire member list. Fetch the current list first if you need to add or remove individual members.
- **Thread replies:** When replying in a thread, pass the parent message's `ts` value as `thread_ts` in `send_message`, not the `ts` of another reply.

---

## Multi-Account Usage

If you have multiple slack accounts configured, use account-specific namespaces:

```lua
-- Default account (always works)
app.integrations.slack.function_name({...})

-- Explicit default (portable across setups)
app.integrations.slack.default.function_name({...})

-- Named accounts
app.integrations.slack.work.function_name({...})
app.integrations.slack.personal.function_name({...})
```

All functions are identical across accounts — only the credentials differ.

Metadata-Derived Lua Example

local result = app.integrations.slack.slack_send_message({
  channel = "example_channel",
  text = "example_text",
  blocks = "example_blocks",
  thread_ts = "example_thread_ts",
  reply_broadcast = true,
  unfurl_links = true,
  markdown = true
})
print(result)

Functions

slack_send_message

Send a message to a Slack channel or DM. Supports text, blocks, and thread replies.

Operation
Write write
Full name
slack.slack_send_message
ParameterTypeRequiredDescription
channel string yes Channel ID or name (e.g., "#general" or "C12345678").
text string yes Message text.
blocks string no JSON array of Slack Block Kit blocks for rich formatting.
thread_ts string no Timestamp of the parent message to reply in a thread.
reply_broadcast boolean no If true, also post the reply to the channel (thread_ts required).
unfurl_links boolean no If true, enable unfurling of links.
markdown boolean no If true, enable mrkdwn formatting in text.

slack_update_message

Update an existing Slack message.

Operation
Write write
Full name
slack.slack_update_message
ParameterTypeRequiredDescription
channel string yes Channel ID where the message was posted.
ts string yes Timestamp of the message to update.
text string no New message text.
blocks string no JSON array of Slack Block Kit blocks.

slack_delete_message

Delete a message from a Slack channel.

Operation
Write write
Full name
slack.slack_delete_message
ParameterTypeRequiredDescription
channel string yes Channel ID where the message was posted.
ts string yes Timestamp of the message to delete.

slack_get_message

Get a specific message by its timestamp. Optionally fetch a message within a thread.

Operation
Read read
Full name
slack.slack_get_message
ParameterTypeRequiredDescription
channel string yes Channel ID.
ts string yes Timestamp of the message to retrieve.
thread_ts string no If provided, fetches a reply within this thread instead.

slack_search_messages

Search for messages across all Slack channels and DMs.

Operation
Read read
Full name
slack.slack_search_messages
ParameterTypeRequiredDescription
query string yes Search query. Supports Slack search modifiers like "from:", "in:", "has:", etc.
count integer no Number of results per page (default 20, max 100).
page integer no Page number of results (default 1).
sort string no Sort order: "score" (default) or "timestamp".
sort_dir string no Sort direction: "desc" (default) or "asc".

slack_get_channel_history

Get message history for a Slack channel. Supports pagination with cursors.

Operation
Read read
Full name
slack.slack_get_channel_history
ParameterTypeRequiredDescription
channel string yes Channel ID.
limit integer no Number of messages to return (default 100, max 1000).
oldest string no Start of time range, as a Unix timestamp.
latest string no End of time range, as a Unix timestamp.
cursor string no Pagination cursor from a previous response.

slack_get_thread_replies

Get all replies in a Slack message thread.

Operation
Read read
Full name
slack.slack_get_thread_replies
ParameterTypeRequiredDescription
channel string yes Channel ID.
ts string yes Timestamp of the parent message (thread root).
limit integer no Number of replies to return per page (default 1000).
cursor string no Pagination cursor from a previous response.

slack_list_channels

List all Slack channels the bot has access to.

Operation
Read read
Full name
slack.slack_list_channels
ParameterTypeRequiredDescription
types string no Comma-separated channel types: "public_channel", "private_channel", "mpim", "im". Default: "public_channel".
exclude_archived boolean no Exclude archived channels (default: true).
limit integer no Number of channels to return per page (default 100, max 1000).
cursor string no Pagination cursor from a previous response.

slack_get_channel

Get detailed information about a Slack channel.

Operation
Read read
Full name
slack.slack_get_channel
ParameterTypeRequiredDescription
channel string yes Channel ID.

slack_create_channel

Create a new Slack channel.

Operation
Write write
Full name
slack.slack_create_channel
ParameterTypeRequiredDescription
name string yes Channel name (lowercase, no spaces, max 80 chars).
is_private boolean no Create a private channel instead of a public one (default: false).

slack_set_topic

Set the topic for a Slack channel.

Operation
Write write
Full name
slack.slack_set_topic
ParameterTypeRequiredDescription
channel string yes Channel ID.
topic string yes The new topic text.

slack_set_purpose

Set the purpose for a Slack channel.

Operation
Write write
Full name
slack.slack_set_purpose
ParameterTypeRequiredDescription
channel string yes Channel ID.
purpose string yes The new purpose text.

slack_archive_channel

Archive a Slack channel.

Operation
Write write
Full name
slack.slack_archive_channel
ParameterTypeRequiredDescription
channel string yes Channel ID to archive.

slack_invite_to_channel

Invite one or more users to a Slack channel.

Operation
Write write
Full name
slack.slack_invite_to_channel
ParameterTypeRequiredDescription
channel string yes Channel ID.
users string yes Comma-separated list of user IDs to invite.

slack_upload_file

Upload a file to Slack using the modern external upload flow. The file content is posted to a channel or as a thread reply.

Operation
Write write
Full name
slack.slack_upload_file
ParameterTypeRequiredDescription
channel string yes Channel ID to post the file to.
content string yes File content (text).
filename string yes Filename with extension (e.g., "report.txt").
title string no Title of the file.
initial_comment string no Comment to include with the file post.
thread_ts string no Timestamp of the parent message to reply in a thread.

slack_list_files

List files in Slack, optionally filtered by channel, user, or file type.

Operation
Read read
Full name
slack.slack_list_files
ParameterTypeRequiredDescription
channel string no Channel ID to filter files by.
user string no User ID to filter files by.
types string no Comma-separated file types: "spaces", "snippets", "images", "gdocs", "zips", "pdfs".
count integer no Number of files per page (default 100).
page integer no Page number (default 1).

slack_get_file

Get detailed information about a Slack file.

Operation
Read read
Full name
slack.slack_get_file
ParameterTypeRequiredDescription
file string yes File ID.

slack_list_users

List all users in the Slack workspace.

Operation
Read read
Full name
slack.slack_list_users
ParameterTypeRequiredDescription
limit integer no Number of users per page (default 100, max 1000).
cursor string no Pagination cursor from a previous response.
include_locale boolean no Include user locale information (default: false).

slack_get_user

Get detailed information about a Slack user by their user ID.

Operation
Read read
Full name
slack.slack_get_user
ParameterTypeRequiredDescription
user string yes User ID.

slack_find_user_by_email

Look up a Slack user by their email address.

Operation
Read read
Full name
slack.slack_find_user_by_email
ParameterTypeRequiredDescription
email string yes Email address to look up.

slack_add_reaction

Add an emoji reaction to a Slack message.

Operation
Write write
Full name
slack.slack_add_reaction
ParameterTypeRequiredDescription
channel string yes Channel ID where the message is posted.
name string yes Emoji name without colons (e.g., "thumbsup", "heart").
timestamp string yes Timestamp of the message to react to.

slack_remove_reaction

Remove an emoji reaction from a Slack message.

Operation
Write write
Full name
slack.slack_remove_reaction
ParameterTypeRequiredDescription
channel string yes Channel ID where the message is posted.
name string yes Emoji name without colons (e.g., "thumbsup", "heart").
timestamp string yes Timestamp of the message.

slack_list_usergroups

List all usergroups in the Slack workspace.

Operation
Read read
Full name
slack.slack_list_usergroups
ParameterTypeRequiredDescription
include_count boolean no Include the number of users in each usergroup (default: false).
include_disabled boolean no Include disabled usergroups (default: false).
include_users boolean no Include the list of users in each usergroup (default: false).

slack_update_usergroup_members

Update the members of a Slack usergroup.

Operation
Write write
Full name
slack.slack_update_usergroup_members
ParameterTypeRequiredDescription
usergroup string yes Usergroup ID.
users string yes Comma-separated list of user IDs to set as members.