> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beta.b3os.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Slack

The io.b3os/slack pack: 27 actions and 1 trigger with call snippets, fixture outputs, connection setup and error codes, generated from version 1.0.0.

`io.b3os/slack` 1.0.0 · `messaging`, `collaboration` · MIT

Post, reply to, edit and delete messages, react, search, manage channels, members, user groups, reminders and status in a Slack workspace through the Web API, with your own Slack app's bot or user token. Converted from the original B3OS Slack actions: same inputs and the same \{success, data: \{ret\}\} envelope, where ret is Slack's own response. Bot tokens (xoxb-) cover most actions; search, reminders and status need a user token (xoxp-). The event trigger receives Events API deliveries for your app, verified with its signing secret.

Every call's result carries `upstream_status` and `timing`: `validate_ms`, `inject_ms`, `render_ms`, `upstream_ms`, `map_ms` and `total_ms`. `upstream` is the service's time; the others are B3OS's own ([call actions](/actions/call)). The snippets below show no timing values, because a fixture records none.

## Connection

`token`, type `bearer`: Slack token.

A bot token (xoxb-) or user token (xoxp-) from your own Slack app, with the scopes the actions you use need: chat:write, channels:read, groups:read, channels:manage, reactions:write, users:read, users:read.email, files:read, files:write, usergroups:read, usergroups:write; user tokens add search:read, reminders:write, users.profile:write.

How to get one: [api.slack.com](https://api.slack.com/authentication/token-types).

The credential is sent only to `slack.com`.

Store the credential once as a [vault connection](/vault) for this pack and key, then name its id in a call's `connections`. Leave the key out and B3OS uses the project's newest connection for the pack and key without a `subject` ([connections](/actions/call#connections)).

Hosts it reaches: `slack.com`.

## Actions

| Action | Effect | MCP tool | Title |
|---|---|---|---|
| [`send-message`](/actions/catalog/slack#slack-send-message) | write | `slack__send-message` | Slack: Send Message |
| [`reply-to-message`](/actions/catalog/slack#slack-reply-to-message) | write | `slack__reply-to-message` | Slack: Reply to Message |
| [`send-block-kit-message`](/actions/catalog/slack#slack-send-block-kit-message) | write | `slack__send-block-kit-message` | Slack: Send Block Kit Message |
| [`update-message`](/actions/catalog/slack#slack-update-message) | write | `slack__update-message` | Slack: Update Message |
| [`delete-message`](/actions/catalog/slack#slack-delete-message) | irreversible | `slack__delete-message` | Slack: Delete Message |
| [`add-reaction`](/actions/catalog/slack#slack-add-reaction) | write | `slack__add-reaction` | Slack: Add Reaction |
| [`list-channels`](/actions/catalog/slack#slack-list-channels) | read | `slack__list-channels` | Slack: List Channels |
| [`get-channel-info`](/actions/catalog/slack#slack-get-channel-info) | read | `slack__get-channel-info` | Slack: Get Channel Info |
| [`create-channel`](/actions/catalog/slack#slack-create-channel) | write | `slack__create-channel` | Slack: Create Channel |
| [`archive-channel`](/actions/catalog/slack#slack-archive-channel) | write | `slack__archive-channel` | Slack: Archive Channel |
| [`set-channel-topic`](/actions/catalog/slack#slack-set-channel-topic) | write | `slack__set-channel-topic` | Slack: Set Channel Topic |
| [`set-channel-description`](/actions/catalog/slack#slack-set-channel-description) | write | `slack__set-channel-description` | Slack: Set Channel Description |
| [`invite-user-to-channel`](/actions/catalog/slack#slack-invite-user-to-channel) | write | `slack__invite-user-to-channel` | Slack: Invite User to Channel |
| [`kick-user`](/actions/catalog/slack#slack-kick-user) | write | `slack__kick-user` | Slack: Remove User from Channel |
| [`list-members-in-channel`](/actions/catalog/slack#slack-list-members-in-channel) | read | `slack__list-members-in-channel` | Slack: List Members in Channel |
| [`list-replies`](/actions/catalog/slack#slack-list-replies) | read | `slack__list-replies` | Slack: List Thread Replies |
| [`find-message`](/actions/catalog/slack#slack-find-message) | read | `slack__find-message` | Slack: Find Message |
| [`find-user-by-email`](/actions/catalog/slack#slack-find-user-by-email) | read | `slack__find-user-by-email` | Slack: Find User by Email |
| [`list-users`](/actions/catalog/slack#slack-list-users) | read | `slack__list-users` | Slack: List Users |
| [`get-current-user`](/actions/catalog/slack#slack-get-current-user) | read | `slack__get-current-user` | Slack: Get Current User |
| [`get-file`](/actions/catalog/slack#slack-get-file) | read | `slack__get-file` | Slack: Get File Info |
| [`list-files`](/actions/catalog/slack#slack-list-files) | read | `slack__list-files` | Slack: List Files |
| [`delete-file`](/actions/catalog/slack#slack-delete-file) | irreversible | `slack__delete-file` | Slack: Delete File |
| [`create-reminder`](/actions/catalog/slack#slack-create-reminder) | write | `slack__create-reminder` | Slack: Create Reminder |
| [`set-status`](/actions/catalog/slack#slack-set-status) | write | `slack__set-status` | Slack: Set Status |
| [`list-group-members`](/actions/catalog/slack#slack-list-group-members) | read | `slack__list-group-members` | Slack: List Group Members |
| [`update-group-members`](/actions/catalog/slack#slack-update-group-members) | write | `slack__update-group-members` | Slack: Update Group Members |

send-message

**Slack: Send Message.** Post a message to a channel, a DM (pass a user id as channel) or a thread (pass thread_ts). The bot must be a member of private channels. Returns the message ts, which identifies it for replies, edits, reactions and deletes. Not idempotent: two calls post twice.

Ref `io.b3os/slack/send-message@1.0.0` · effect `write` · connection `token` · MCP tool `slack__send-message`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/send-message@1",
          "input": {
            "channel": "C0123ABCDEF",
            "text": "Deploy finished: *v2.4.0* is live."
          },
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/send-message@1",
      input: {
        channel: "C0123ABCDEF",
        text: "Deploy finished: *v2.4.0* is live.",
      },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/send-message@1",
        "input": {
            "channel": "C0123ABCDEF",
            "text": "Deploy finished: *v2.4.0* is live.",
        },
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__send-message",
        "arguments": {
          "channel": "C0123ABCDEF",
          "text": "Deploy finished: *v2.4.0* is live."
        }
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__send-message` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Send Message (documented response shape, example values). From the bundle's `fixtures/send-message.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "channel": "C0123ABCDEF",
      "ts": "1730000000.000100",
      "message": {
        "type": "message",
        "user": "U0BOTUSER1",
        "bot_id": "B0BOTID123",
        "app_id": "A0APPID1234",
        "text": "Deploy finished: *v2.4.0* is live.",
        "ts": "1730000000.000100",
        "team": "T0TEAM12345"
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

reply-to-message

**Slack: Reply to Message.** Reply in the thread of an existing message (thread_ts is the parent message's ts). Returns the reply's ts. Not idempotent.

Ref `io.b3os/slack/reply-to-message@1.0.0` · effect `write` · connection `token` · MCP tool `slack__reply-to-message`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/reply-to-message@1",
          "input": {
            "channel": "C0123ABCDEF",
            "thread_ts": "1730000000.000100",
            "text": "Rolled back; looking into it."
          },
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/reply-to-message@1",
      input: {
        channel: "C0123ABCDEF",
        thread_ts: "1730000000.000100",
        text: "Rolled back; looking into it.",
      },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/reply-to-message@1",
        "input": {
            "channel": "C0123ABCDEF",
            "thread_ts": "1730000000.000100",
            "text": "Rolled back; looking into it.",
        },
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__reply-to-message",
        "arguments": {
          "channel": "C0123ABCDEF",
          "thread_ts": "1730000000.000100",
          "text": "Rolled back; looking into it."
        }
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__reply-to-message` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Reply to Message (documented response shape, example values). From the bundle's `fixtures/reply-to-message.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "channel": "C0123ABCDEF",
      "ts": "1730000060.000200",
      "message": {
        "type": "message",
        "user": "U0BOTUSER1",
        "bot_id": "B0BOTID123",
        "app_id": "A0APPID1234",
        "text": "Rolled back; looking into it.",
        "ts": "1730000060.000200",
        "team": "T0TEAM12345",
        "thread_ts": "1730000000.000100"
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

send-block-kit-message

**Slack: Send Block Kit Message.** Post a Block Kit message: blocks is the JSON array of layout blocks (sections, buttons, images, ...) as a string, and text is the plain fallback shown in notifications. Build and preview layouts in Slack's Block Kit Builder. Not idempotent.

Ref `io.b3os/slack/send-block-kit-message@1.0.0` · effect `write` · connection `token` · MCP tool `slack__send-block-kit-message`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/send-block-kit-message@1",
          "input": {
            "channel": "C0123ABCDEF",
            "blocks": "[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*Build 812* failed on `main`\"}}]",
            "text": "Build 812 failed on main"
          },
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/send-block-kit-message@1",
      input: {
        channel: "C0123ABCDEF",
        blocks: "[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*Build 812* failed on `main`\"}}]",
        text: "Build 812 failed on main",
      },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/send-block-kit-message@1",
        "input": {
            "channel": "C0123ABCDEF",
            "blocks": "[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*Build 812* failed on `main`\"}}]",
            "text": "Build 812 failed on main",
        },
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__send-block-kit-message",
        "arguments": {
          "channel": "C0123ABCDEF",
          "blocks": "[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*Build 812* failed on `main`\"}}]",
          "text": "Build 812 failed on main"
        }
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__send-block-kit-message` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Send Block Kit Message (documented response shape, example values). From the bundle's `fixtures/send-block-kit-message.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "channel": "C0123ABCDEF",
      "ts": "1730000100.000300",
      "message": {
        "type": "message",
        "user": "U0BOTUSER1",
        "bot_id": "B0BOTID123",
        "app_id": "A0APPID1234",
        "text": "Build 812 failed on main",
        "ts": "1730000100.000300",
        "team": "T0TEAM12345"
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

update-message

**Slack: Update Message.** Replace the text of a message the token's user or bot posted. Returns the updated message.

Ref `io.b3os/slack/update-message@1.0.0` · effect `write` · connection `token` · MCP tool `slack__update-message`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/update-message@1",
          "input": {
            "channel": "C0123ABCDEF",
            "ts": "1730000000.000100",
            "text": "Deploy finished: *v2.4.1* is live."
          },
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/update-message@1",
      input: {
        channel: "C0123ABCDEF",
        ts: "1730000000.000100",
        text: "Deploy finished: *v2.4.1* is live.",
      },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/update-message@1",
        "input": {
            "channel": "C0123ABCDEF",
            "ts": "1730000000.000100",
            "text": "Deploy finished: *v2.4.1* is live.",
        },
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__update-message",
        "arguments": {
          "channel": "C0123ABCDEF",
          "ts": "1730000000.000100",
          "text": "Deploy finished: *v2.4.1* is live."
        }
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__update-message` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Update Message (documented response shape, example values). From the bundle's `fixtures/update-message.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "channel": "C0123ABCDEF",
      "ts": "1730000000.000100",
      "text": "Deploy finished: *v2.4.1* is live.",
      "message": {
        "type": "message",
        "user": "U0BOTUSER1",
        "bot_id": "B0BOTID123",
        "app_id": "A0APPID1234",
        "text": "Deploy finished: *v2.4.1* is live.",
        "ts": "1730000000.000100",
        "team": "T0TEAM12345"
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

delete-message

**Slack: Delete Message.** Delete a message. Bot tokens can delete the bot's own messages; user tokens their user's messages (admins more). Cannot be undone.

Ref `io.b3os/slack/delete-message@1.0.0` · effect `irreversible` · connection `token` · MCP tool `slack__delete-message`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/delete-message@1",
          "input": {"channel": "C0123ABCDEF", "ts": "1730000000.000100"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/delete-message@1",
      input: { channel: "C0123ABCDEF", ts: "1730000000.000100" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/delete-message@1",
        "input": {"channel": "C0123ABCDEF", "ts": "1730000000.000100"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__delete-message",
        "arguments": {"channel": "C0123ABCDEF", "ts": "1730000000.000100"}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__delete-message` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Delete Message (documented response shape, example values). From the bundle's `fixtures/delete-message.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {"ok": true, "channel": "C0123ABCDEF", "ts": "1730000000.000100"}
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

add-reaction

**Slack: Add Reaction.** Add an emoji reaction to a message, by emoji name without colons (thumbsup, eyes, white_check_mark).

Ref `io.b3os/slack/add-reaction@1.0.0` · effect `write` · connection `token` · MCP tool `slack__add-reaction`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/add-reaction@1",
          "input": {
            "channel": "C0123ABCDEF",
            "timestamp": "1730000000.000100",
            "name": "white_check_mark"
          },
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/add-reaction@1",
      input: {
        channel: "C0123ABCDEF",
        timestamp: "1730000000.000100",
        name: "white_check_mark",
      },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/add-reaction@1",
        "input": {
            "channel": "C0123ABCDEF",
            "timestamp": "1730000000.000100",
            "name": "white_check_mark",
        },
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__add-reaction",
        "arguments": {
          "channel": "C0123ABCDEF",
          "timestamp": "1730000000.000100",
          "name": "white_check_mark"
        }
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__add-reaction` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Add Reaction (documented response shape, example values). From the bundle's `fixtures/add-reaction.json`, not a live call.

```json
{"success": true, "data": {"ret": {"ok": true}}}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

list-channels

**Slack: List Channels.** List channels the token can see: public by default, or any of public_channel, private_channel, mpim, im (comma-separated). Each channel has id, name, privacy, membership, topic, purpose and member count. Page with next_cursor (empty on the last page).

Ref `io.b3os/slack/list-channels@1.0.0` · effect `read` · connection `token` · MCP tool `slack__list-channels`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/list-channels@1",
          "input": {"types": "public_channel,private_channel", "limit": 2},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/list-channels@1",
      input: { types: "public_channel,private_channel", limit: 2 },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/list-channels@1",
        "input": {"types": "public_channel,private_channel", "limit": 2},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__list-channels",
        "arguments": {"types": "public_channel,private_channel", "limit": 2}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__list-channels` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: List Channels (documented response shape, example values). From the bundle's `fixtures/list-channels.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "channels": [
        {
          "id": "C0123ABCDEF",
          "name": "deploys",
          "is_channel": true,
          "is_private": false,
          "is_archived": false,
          "is_member": true,
          "num_members": 14,
          "topic": {"value": "Release train"},
          "purpose": {"value": "Deploy notifications"},
          "created": 1700000000
        },
        {
          "id": "G0PRIVATE01",
          "name": "incident-war-room",
          "is_channel": true,
          "is_private": true,
          "is_archived": false,
          "is_member": true,
          "num_members": 6,
          "topic": {"value": ""},
          "purpose": {"value": ""},
          "created": 1710000000
        }
      ],
      "next_cursor": "dGVhbTpDMDYxRkE1UEI="
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

get-channel-info

**Slack: Get Channel Info.** Details of one channel: name, privacy, archived flag, creator, creation time, topic, purpose and member count.

Ref `io.b3os/slack/get-channel-info@1.0.0` · effect `read` · connection `token` · MCP tool `slack__get-channel-info`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/get-channel-info@1",
          "input": {"channel": "C0123ABCDEF"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/get-channel-info@1",
      input: { channel: "C0123ABCDEF" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/get-channel-info@1",
        "input": {"channel": "C0123ABCDEF"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__get-channel-info",
        "arguments": {"channel": "C0123ABCDEF"}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__get-channel-info` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Get Channel Info (documented response shape, example values). From the bundle's `fixtures/get-channel-info.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "channel": {
        "id": "C0123ABCDEF",
        "name": "deploys",
        "is_channel": true,
        "is_private": false,
        "is_archived": false,
        "created": 1700000000,
        "creator": "U0ADMIN0001",
        "topic": {
          "value": "Release train",
          "creator": "U0ADMIN0001",
          "last_set": 1700000100
        },
        "purpose": {
          "value": "Deploy notifications",
          "creator": "U0ADMIN0001",
          "last_set": 1700000100
        },
        "num_members": 14
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

create-channel

**Slack: Create Channel.** Create a public or private channel. Names are lowercase, without spaces or periods, up to 80 characters. Returns the new channel with its id.

Ref `io.b3os/slack/create-channel@1.0.0` · effect `write` · connection `token` · MCP tool `slack__create-channel`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/create-channel@1",
          "input": {"name": "incident-2026-10-26"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/create-channel@1",
      input: { name: "incident-2026-10-26" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/create-channel@1",
        "input": {"name": "incident-2026-10-26"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__create-channel",
        "arguments": {"name": "incident-2026-10-26"}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__create-channel` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Create Channel (documented response shape, example values). From the bundle's `fixtures/create-channel.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "channel": {
        "id": "C0NEWCHAN01",
        "name": "incident-2026-10-26",
        "is_channel": true,
        "is_private": false,
        "created": 1730001000,
        "creator": "U0BOTUSER1"
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

archive-channel

**Slack: Archive Channel.** Archive a channel. Members keep read access to its history; nobody can post until it is unarchived.

Ref `io.b3os/slack/archive-channel@1.0.0` · effect `write` · connection `token` · MCP tool `slack__archive-channel`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/archive-channel@1",
          "input": {"channel": "C0NEWCHAN01"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/archive-channel@1",
      input: { channel: "C0NEWCHAN01" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/archive-channel@1",
        "input": {"channel": "C0NEWCHAN01"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__archive-channel",
        "arguments": {"channel": "C0NEWCHAN01"}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__archive-channel` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Archive Channel (documented response shape, example values). From the bundle's `fixtures/archive-channel.json`, not a live call.

```json
{"success": true, "data": {"ret": {"ok": true}}}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

set-channel-topic

**Slack: Set Channel Topic.** Set a channel's topic (shown in the channel header).

Ref `io.b3os/slack/set-channel-topic@1.0.0` · effect `write` · connection `token` · MCP tool `slack__set-channel-topic`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/set-channel-topic@1",
          "input": {
            "channel": "C0123ABCDEF",
            "topic": "Release train: v2.4.1 on Thursday"
          },
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/set-channel-topic@1",
      input: {
        channel: "C0123ABCDEF",
        topic: "Release train: v2.4.1 on Thursday",
      },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/set-channel-topic@1",
        "input": {
            "channel": "C0123ABCDEF",
            "topic": "Release train: v2.4.1 on Thursday",
        },
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__set-channel-topic",
        "arguments": {
          "channel": "C0123ABCDEF",
          "topic": "Release train: v2.4.1 on Thursday"
        }
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__set-channel-topic` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Set Channel Topic (documented response shape, example values). From the bundle's `fixtures/set-channel-topic.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "channel": {
        "id": "C0123ABCDEF",
        "name": "deploys",
        "topic": {"value": "Release train: v2.4.1 on Thursday"}
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

set-channel-description

**Slack: Set Channel Description.** Set a channel's description (its purpose).

Ref `io.b3os/slack/set-channel-description@1.0.0` · effect `write` · connection `token` · MCP tool `slack__set-channel-description`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/set-channel-description@1",
          "input": {
            "channel": "C0123ABCDEF",
            "purpose": "Deploy notifications and release coordination"
          },
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/set-channel-description@1",
      input: {
        channel: "C0123ABCDEF",
        purpose: "Deploy notifications and release coordination",
      },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/set-channel-description@1",
        "input": {
            "channel": "C0123ABCDEF",
            "purpose": "Deploy notifications and release coordination",
        },
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__set-channel-description",
        "arguments": {
          "channel": "C0123ABCDEF",
          "purpose": "Deploy notifications and release coordination"
        }
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__set-channel-description` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Set Channel Description (documented response shape, example values). From the bundle's `fixtures/set-channel-description.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "channel": {
        "id": "C0123ABCDEF",
        "name": "deploys",
        "purpose": {"value": "Deploy notifications and release coordination"}
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

invite-user-to-channel

**Slack: Invite User to Channel.** Invite up to 100 users (comma-separated user ids) to a channel the token's bot or user is in.

Ref `io.b3os/slack/invite-user-to-channel@1.0.0` · effect `write` · connection `token` · MCP tool `slack__invite-user-to-channel`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/invite-user-to-channel@1",
          "input": {"channel": "C0123ABCDEF", "users": "U0MONA00001,U0HUBOT0001"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/invite-user-to-channel@1",
      input: { channel: "C0123ABCDEF", users: "U0MONA00001,U0HUBOT0001" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/invite-user-to-channel@1",
        "input": {"channel": "C0123ABCDEF", "users": "U0MONA00001,U0HUBOT0001"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__invite-user-to-channel",
        "arguments": {"channel": "C0123ABCDEF", "users": "U0MONA00001,U0HUBOT0001"}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__invite-user-to-channel` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Invite User to Channel (documented response shape, example values). From the bundle's `fixtures/invite-user-to-channel.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "channel": {"id": "C0123ABCDEF", "name": "deploys", "num_members": 16}
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

kick-user

**Slack: Remove User from Channel.** Remove a user from a channel. They can rejoin a public channel unless they are invited again or the channel is private.

Ref `io.b3os/slack/kick-user@1.0.0` · effect `write` · connection `token` · MCP tool `slack__kick-user`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/kick-user@1",
          "input": {"channel": "C0123ABCDEF", "user": "U0HUBOT0001"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/kick-user@1",
      input: { channel: "C0123ABCDEF", user: "U0HUBOT0001" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/kick-user@1",
        "input": {"channel": "C0123ABCDEF", "user": "U0HUBOT0001"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__kick-user",
        "arguments": {"channel": "C0123ABCDEF", "user": "U0HUBOT0001"}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__kick-user` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Remove User from Channel (documented response shape, example values). From the bundle's `fixtures/kick-user.json`, not a live call.

```json
{"success": true, "data": {"ret": {"ok": true}}}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

list-members-in-channel

**Slack: List Members in Channel.** User ids of a channel's members, one page at a time (next_cursor in response_metadata). Resolve ids with get-user-info or list-users.

Ref `io.b3os/slack/list-members-in-channel@1.0.0` · effect `read` · connection `token` · MCP tool `slack__list-members-in-channel`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/list-members-in-channel@1",
          "input": {"channel": "C0123ABCDEF", "limit": 3},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/list-members-in-channel@1",
      input: { channel: "C0123ABCDEF", limit: 3 },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/list-members-in-channel@1",
        "input": {"channel": "C0123ABCDEF", "limit": 3},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__list-members-in-channel",
        "arguments": {"channel": "C0123ABCDEF", "limit": 3}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__list-members-in-channel` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: List Members in Channel (documented response shape, example values). From the bundle's `fixtures/list-members-in-channel.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "members": ["U0MONA00001", "U0HUBOT0001", "U0BOTUSER1"],
      "response_metadata": {"next_cursor": ""}
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

list-replies

**Slack: List Thread Replies.** The messages of a thread, parent first: user, text, ts and reactions. ts is the parent message's ts. has_more and response_metadata.next_cursor page long threads.

Ref `io.b3os/slack/list-replies@1.0.0` · effect `read` · connection `token` · MCP tool `slack__list-replies`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/list-replies@1",
          "input": {"channel": "C0123ABCDEF", "ts": "1730000000.000100"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/list-replies@1",
      input: { channel: "C0123ABCDEF", ts: "1730000000.000100" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/list-replies@1",
        "input": {"channel": "C0123ABCDEF", "ts": "1730000000.000100"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__list-replies",
        "arguments": {"channel": "C0123ABCDEF", "ts": "1730000000.000100"}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__list-replies` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: List Thread Replies (documented response shape, example values). From the bundle's `fixtures/list-replies.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "messages": [
        {
          "type": "message",
          "user": "U0BOTUSER1",
          "bot_id": "B0BOTID123",
          "app_id": "A0APPID1234",
          "text": "Deploy finished: *v2.4.0* is live.",
          "ts": "1730000000.000100",
          "team": "T0TEAM12345",
          "thread_ts": "1730000000.000100",
          "reply_count": 1
        },
        {
          "type": "message",
          "user": "U0MONA00001",
          "text": "Cart looks broken on mobile",
          "ts": "1730000030.000150",
          "thread_ts": "1730000000.000100"
        }
      ],
      "has_more": false,
      "response_metadata": {"next_cursor": ""}
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

find-message

**Slack: Find Message.** Search messages across the workspace with Slack's search syntax (in:#channel, from:@user, before:, after:, has:link). Needs a user token with search:read; bot tokens cannot search. Returns matches with channel, author, text, ts and permalink.

Ref `io.b3os/slack/find-message@1.0.0` · effect `read` · connection `token` · MCP tool `slack__find-message`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/find-message@1",
          "input": {"query": "in:#deploys rollback", "count": 1},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/find-message@1",
      input: { query: "in:#deploys rollback", count: 1 },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/find-message@1",
        "input": {"query": "in:#deploys rollback", "count": 1},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__find-message",
        "arguments": {"query": "in:#deploys rollback", "count": 1}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__find-message` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Find Message (documented response shape, example values). From the bundle's `fixtures/find-message.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "query": "in:#deploys rollback",
      "messages": {
        "total": 3,
        "paging": {"count": 1, "total": 3, "page": 1, "pages": 3},
        "matches": [
          {
            "iid": "a1b2c3",
            "type": "message",
            "channel": {"id": "C0123ABCDEF", "name": "deploys"},
            "user": "U0MONA00001",
            "username": "mona",
            "ts": "1729900000.000500",
            "text": "Rolled back v2.3.9",
            "permalink": "https://acme.slack.com/archives/C0123ABCDEF/p1729900000000500"
          }
        ]
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

find-user-by-email

**Slack: Find User by Email.** Find a workspace member by email address: id, name, real name, display name, time zone and profile. Needs users:read.email.

Ref `io.b3os/slack/find-user-by-email@1.0.0` · effect `read` · connection `token` · MCP tool `slack__find-user-by-email`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/find-user-by-email@1",
          "input": {"email": "mona@acme.example"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/find-user-by-email@1",
      input: { email: "mona@acme.example" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/find-user-by-email@1",
        "input": {"email": "mona@acme.example"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__find-user-by-email",
        "arguments": {"email": "mona@acme.example"}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__find-user-by-email` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Find User by Email (documented response shape, example values). From the bundle's `fixtures/find-user-by-email.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "user": {
        "id": "U0MONA00001",
        "team_id": "T0TEAM12345",
        "name": "mona",
        "real_name": "Mona Example",
        "tz": "America/Los_Angeles",
        "is_bot": false,
        "deleted": false,
        "profile": {
          "email": "mona@acme.example",
          "display_name": "mona",
          "real_name": "Mona Example",
          "title": "Staff Engineer"
        }
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

list-users

**Slack: List Users.** Workspace members with id, name, real name, time zone, bot and deleted flags and profile, one page at a time (next_cursor in response_metadata).

Ref `io.b3os/slack/list-users@1.0.0` · effect `read` · connection `token` · MCP tool `slack__list-users`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/list-users@1",
          "input": {"limit": 1},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/list-users@1",
      input: { limit: 1 },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/list-users@1",
        "input": {"limit": 1},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {"name": "slack__list-users", "arguments": {"limit": 1}}
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__list-users` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: List Users (documented response shape, example values). From the bundle's `fixtures/list-users.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "members": [
        {
          "id": "U0MONA00001",
          "name": "mona",
          "real_name": "Mona Example",
          "tz": "America/Los_Angeles",
          "is_bot": false,
          "deleted": false,
          "profile": {"display_name": "mona", "title": "Staff Engineer"}
        }
      ],
      "response_metadata": {"next_cursor": "dXNlcjpVMEcxNkFCQ0Q="}
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

get-current-user

**Slack: Get Current User.** Who the token belongs to: workspace URL and name, user or bot name and their ids. A cheap way to check that a connection works.

Ref `io.b3os/slack/get-current-user@1.0.0` · effect `read` · connection `token` · MCP tool `slack__get-current-user`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/get-current-user@1",
          "input": {},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/get-current-user@1",
      input: {},
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/get-current-user@1",
        "input": {},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {"name": "slack__get-current-user", "arguments": {}}
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__get-current-user` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Get Current User (documented response shape, example values). From the bundle's `fixtures/get-current-user.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "url": "https://acme.slack.com/",
      "team": "Acme",
      "user": "deploybot",
      "team_id": "T0TEAM12345",
      "user_id": "U0BOTUSER1"
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

get-file

**Slack: Get File Info.** Metadata of one uploaded file: name, title, type, size, uploader, channels it was shared in and permalink. Downloading the bytes needs the url_private link with the same token, which this action does not fetch.

Ref `io.b3os/slack/get-file@1.0.0` · effect `read` · connection `token` · MCP tool `slack__get-file`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/get-file@1",
          "input": {"file": "F0FILE00001"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/get-file@1",
      input: { file: "F0FILE00001" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/get-file@1",
        "input": {"file": "F0FILE00001"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {"name": "slack__get-file", "arguments": {"file": "F0FILE00001"}}
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__get-file` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Get File Info (documented response shape, example values). From the bundle's `fixtures/get-file.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "file": {
        "id": "F0FILE00001",
        "name": "release-notes.md",
        "title": "Release notes",
        "mimetype": "text/markdown",
        "filetype": "markdown",
        "size": 2048,
        "user": "U0MONA00001",
        "created": 1730000200,
        "channels": ["C0123ABCDEF"],
        "permalink": "https://acme.slack.com/files/U0MONA00001/F0FILE00001/release-notes.md"
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

list-files

**Slack: List Files.** Files in the workspace, newest first, optionally in one channel, by one user or of given types (spaces, snippets, images, gdocs, zips, pdfs). Paged with count and page.

Ref `io.b3os/slack/list-files@1.0.0` · effect `read` · connection `token` · MCP tool `slack__list-files`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/list-files@1",
          "input": {"channel": "C0123ABCDEF", "count": 1},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/list-files@1",
      input: { channel: "C0123ABCDEF", count: 1 },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/list-files@1",
        "input": {"channel": "C0123ABCDEF", "count": 1},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__list-files",
        "arguments": {"channel": "C0123ABCDEF", "count": 1}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__list-files` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: List Files (documented response shape, example values). From the bundle's `fixtures/list-files.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "files": [
        {
          "id": "F0FILE00001",
          "name": "release-notes.md",
          "title": "Release notes",
          "filetype": "markdown",
          "size": 2048,
          "user": "U0MONA00001",
          "created": 1730000200
        }
      ],
      "paging": {"count": 1, "total": 4, "page": 1, "pages": 4}
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

delete-file

**Slack: Delete File.** Delete an uploaded file. Cannot be undone.

Ref `io.b3os/slack/delete-file@1.0.0` · effect `irreversible` · connection `token` · MCP tool `slack__delete-file`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/delete-file@1",
          "input": {"file": "F0FILE00001"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/delete-file@1",
      input: { file: "F0FILE00001" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/delete-file@1",
        "input": {"file": "F0FILE00001"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {"name": "slack__delete-file", "arguments": {"file": "F0FILE00001"}}
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__delete-file` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Delete File (documented response shape, example values). From the bundle's `fixtures/delete-file.json`, not a live call.

```json
{"success": true, "data": {"ret": {"ok": true}}}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

create-reminder

**Slack: Create Reminder.** Create a Slackbot reminder for the token's user (or another user): time is a Unix timestamp, a number of seconds from now, or English like in 15 minutes or every Thursday. Needs a user token with reminders:write.

Ref `io.b3os/slack/create-reminder@1.0.0` · effect `write` · connection `token` · MCP tool `slack__create-reminder`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/create-reminder@1",
          "input": {"text": "Check the deploy dashboard", "time": "in 15 minutes"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/create-reminder@1",
      input: { text: "Check the deploy dashboard", time: "in 15 minutes" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/create-reminder@1",
        "input": {"text": "Check the deploy dashboard", "time": "in 15 minutes"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__create-reminder",
        "arguments": {"text": "Check the deploy dashboard", "time": "in 15 minutes"}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__create-reminder` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Create Reminder (documented response shape, example values). From the bundle's `fixtures/create-reminder.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "reminder": {
        "id": "Rm0REMINDER1",
        "creator": "U0MONA00001",
        "user": "U0MONA00001",
        "text": "Check the deploy dashboard",
        "recurring": false,
        "time": 1730001900,
        "complete_ts": 0
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

set-status

**Slack: Set Status.** Set the token user's status text, emoji (:palm_tree:) and optional expiry (Unix seconds; 0 keeps it). An empty status_text clears the status. Needs a user token with users.profile:write.

Ref `io.b3os/slack/set-status@1.0.0` · effect `write` · connection `token` · MCP tool `slack__set-status`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/set-status@1",
          "input": {
            "status_text": "On call",
            "status_emoji": ":pager:",
            "status_expiration": 1730073600
          },
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/set-status@1",
      input: {
        status_text: "On call",
        status_emoji: ":pager:",
        status_expiration: 1730073600,
      },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/set-status@1",
        "input": {
            "status_text": "On call",
            "status_emoji": ":pager:",
            "status_expiration": 1730073600,
        },
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__set-status",
        "arguments": {
          "status_text": "On call",
          "status_emoji": ":pager:",
          "status_expiration": 1730073600
        }
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__set-status` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Set Status (documented response shape, example values). From the bundle's `fixtures/set-status.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "profile": {
        "status_text": "On call",
        "status_emoji": ":pager:",
        "status_expiration": 1730073600,
        "display_name": "mona"
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

list-group-members

**Slack: List Group Members.** User ids in a user group (an @handle such as @oncall). Needs usergroups:read.

Ref `io.b3os/slack/list-group-members@1.0.0` · effect `read` · connection `token` · MCP tool `slack__list-group-members`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/list-group-members@1",
          "input": {"usergroup": "S0ONCALL001"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/list-group-members@1",
      input: { usergroup: "S0ONCALL001" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/list-group-members@1",
        "input": {"usergroup": "S0ONCALL001"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__list-group-members",
        "arguments": {"usergroup": "S0ONCALL001"}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__list-group-members` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: List Group Members (documented response shape, example values). From the bundle's `fixtures/list-group-members.json`, not a live call.

```json
{
  "success": true,
  "data": {"ret": {"ok": true, "users": ["U0MONA00001", "U0HUBOT0001"]}}
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

update-group-members

**Slack: Update Group Members.** Replace the members of a user group with the given user ids (comma-separated), for example to rotate @oncall. Needs usergroups:write.

Ref `io.b3os/slack/update-group-members@1.0.0` · effect `write` · connection `token` · MCP tool `slack__update-group-members`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/slack/update-group-members@1",
          "input": {"usergroup": "S0ONCALL001", "users": "U0HUBOT0001"},
          "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/slack/update-group-members@1",
      input: { usergroup: "S0ONCALL001", users: "U0HUBOT0001" },
      connections: { token: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/slack/update-group-members@1",
        "input": {"usergroup": "S0ONCALL001", "users": "U0HUBOT0001"},
        "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "slack__update-group-members",
        "arguments": {"usergroup": "S0ONCALL001", "users": "U0HUBOT0001"}
      }
    }
    ```

    Expose the pack as tools with `--packs slack` on the local server or `?packs=slack` on the remote URL, and the agent calls `slack__update-group-members` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Slack: Update Group Members (documented response shape, example values). From the bundle's `fixtures/update-group-members.json`, not a live call.

```json
{
  "success": true,
  "data": {
    "ret": {
      "ok": true,
      "usergroup": {
        "id": "S0ONCALL001",
        "handle": "oncall",
        "name": "On call",
        "users": ["U0HUBOT0001"],
        "user_count": 1
      }
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `connection_unauthorized` | 200 | no | built from the service's response |
| `forbidden` | 200 | no | built from the service's response |
| `not_found` | 200 | no | built from the service's response |
| `rate_limited` | 429 | yes | Slack rate limit reached; retry after the Retry-After header. |
| `invalid_request` | 200 | no | built from the service's response |

## Triggers

event (trigger)

**Slack event.** Fires on Slack Events API events from your own Slack app (messages, app mentions, reactions, channel and member changes, ...). Set the app's Event Subscriptions request URL to this subscription's URL (Slack's url_verification challenge is answered automatically) and paste the app's Signing Secret when you create the subscription. Every delivery's X-Slack-Signature is verified and must be at most 5 minutes old; Slack's retries of one event emit it once.

Ref `io.b3os/slack/event@1.0.0` · webhook, signature scheme `slack` with a signing secret you bind as `webhook_secret` · connection `webhook_secret`

| `with` key | Required | Description |
|---|---|---|
| `event_types` | no | Inner event types to emit, for example app_mention, message or reaction_added, or * for all. Default `["*"]`. |

In a routine:

```yaml
triggers:
  - type: action
    id: event
    uses: io.b3os/slack/event@1
    with:
      event_types:
        - app_mention
        - message
    connections:
      webhook_secret: conn_01m5t6cbgdjs1ketgcqwa2sne8
```

Event, labeled `fixture`: the recorded delivery in fixtures/event-app-mention.json (Slack event (delivery signed with a throwaway test secret)). A routine reads it as `trigger.data`; its fields are `event_id`, `team_id`, `event_time`, `type`, `channel`, `user`, `text`, `ts`, `event`.

```json
{
  "event_id": "Ev0123ABCDEF",
  "team_id": "T0123ABCD",
  "event_time": 1792929600,
  "type": "app_mention",
  "channel": "C0123ABCD",
  "user": "U0123ABCD",
  "text": "<@U0BOT1234> what is the deploy status?",
  "ts": "1792929600.000200",
  "event": {
    "type": "app_mention",
    "user": "U0123ABCD",
    "text": "<@U0BOT1234> what is the deploy status?",
    "ts": "1792929600.000200",
    "channel": "C0123ABCD",
    "event_ts": "1792929600.000200"
  }
}
```