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

# Slack

> Connect a Herm agent to Slack DMs and channel mentions.

Slack gives an agent a workspace identity so teammates can message it directly
or mention it in channels. Herm creates normal sessions behind the scenes, so
Slack conversations still use the agent's configured prompt, tools, skills,
roles, vault access, memory, and approval policies.

To send operational failures for multiple agents to one Slack channel instead,
see [Slack notifications](/guides/notifications).

## What Slack uses

* **Agents** provide the versioned configuration, tools, skills, MCP servers,
  roles, and vault access. See [Agents](/api-reference/agents).
* **Sessions** hold the Slack conversation transcript and subject scope. See
  [Sessions](/api-reference/sessions).
* **Streaming events** remain available for products that also render their own
  UI or logs. See [Stream session events](/api-reference/stream-events).

## Connect Slack

Open the agent in Herm, then go to **Connect > Slack**:

```
https://herm.run/app/agents/{agentId}/connect/slack
```

From there:

1. Review the Slack app display name, description, session role, and vault
   access.
2. Generate the Slack app manifest.
3. Create the Slack app from that manifest at Slack's app dashboard and install
   it to the target workspace.
4. Paste the bot token and app-level token back into Herm to verify and connect.

Herm checks that the tokens belong to the same Slack app and workspace before
storing the connection. Tokens are cleared after submission and are never shown
again.

## Message the agent

After the connection is active, Slack members can:

* DM the agent.
* Mention the agent in channels where the app is present.
* Continue the same Slack thread while Herm manages the underlying session.
* Upload supported files with a DM or thread message in direct session mode.
* Receive files the agent creates, such as a CSV, as native Slack attachments
  in the same thread.

Slack file uploads support PDF, CSV, XLSX, plain text, Markdown, DOCX, PNG,
JPEG, WebP, GIF, and BMP. A message can include up to 10 files and 40 MiB of
file content in total. Unsupported or unavailable files produce an attachment
notice instead of being silently discarded.

When the agent writes a supported file under `/opt/data` during the turn
(for example with `write_file`), Herm uploads it into the thread. The reply
does not need to include the sandbox path. Hermes `MEDIA:<path>` tags are
also attached.

Inbound file reads require `files:read`. Outbound file attachments require
`files:write`. Reconnect an existing Slack app using a newly generated
manifest so Slack grants both scopes.

Each Slack thread maps to one Herm session. Slack sessions start with approvals
enabled and YOLO mode off. Sensitive tools still follow the agent's configured
permission policy, and messages become part of the Herm transcript and memory.

Anyone who can message the agent in Slack can talk to it, including Slack
Connect members and guests. Messages from bots and deactivated accounts are
ignored and are not processed as agent turns.

## How replies appear

While Herm is working, Slack shows a live thread status such as **Thinking…**,
**Using {Tool}…** (or **Calling tool…** when the tool name is unknown), or
**Finishing…**. Named tool activity is also streamed into the reply as Slack
`task_update` cards, so the in-thread widget shows the same tool names instead
of a generic “Calling tools” label. Slack expires the thread status after two
minutes unless it is refreshed; Herm re-sends the current status while the
turn is still running. When the turn finishes, that status clears.

Connect Slack can hide specific tools from that status. The picker lists every
built-in tool and the agent's custom tools; nothing is hidden until those
checkboxes are saved. Hidden tools still run; Slack shows **Thinking…** instead
of announcing them.

What you see in the message itself depends on session mode:

| Mode            | Reply behavior                                                                                                    |
| --------------- | ----------------------------------------------------------------------------------------------------------------- |
| Direct          | Herm streams assistant text into Slack as it arrives, updating the same reply.                                    |
| Customer-backed | Herm buffers the assistant text and posts (or updates) one Slack reply after the turn reaches a durable boundary. |

In both modes:

* Slack shows the agent's user-facing assistant text, not private chain-of-thought
  or other internal reasoning.
* Tool use still happens according to the agent's tools and permission policy.
* If the turn fails, Herm posts a safe failure message such as asking the user
  to try again.
* If the turn needs a human decision, Herm posts an approval or clarification
  prompt instead of finishing the reply.

Customer-backed replies use a deterministic Slack client message ID and
reconcile the thread before posting again, so a crash mid-delivery does not
normally create duplicate assistant messages.

## Thread queueing

Inbound Slack messages are stored as durable jobs.

Within a single Slack thread:

1. Herm processes at most one agent turn at a time.
2. If the user sends another message while a turn is still running, that message
   is queued.
3. After the current turn finishes, Herm claims the next queued message for
   that thread in arrival order.

Other threads are not blocked. Work in one thread can continue while another
thread is busy.

If a follow-up arrives before the original root mention is durable, Slack may
redeliver it. Herm does not start a second root turn from that race.

## Approvals

When a tool requires approval, Herm parks the turn and posts an approval prompt
in the thread with **Allow once** and **Deny** actions.

While approval is pending:

* The turn stays waiting on that human decision.
* Ordinary thread chatter is ignored and does not become a new agent prompt.
* Mentioning the bot again may get a short reminder that the turn is still
  waiting on Allow once or Deny.

After someone resolves the approval, Herm resumes the same turn. Slack sessions
default to approvals enabled; change tool permission policy on the agent if you
want different behavior.

## Clarifications

When the agent needs a clarification, Herm parks the turn and posts the
question in the thread.

If the clarification includes choices:

* **1–5 options** render as Slack buttons.
* **6 or more options** render as a Slack select menu.
* The prompt also says you can reply in the thread, so freeform answers still
  work.

If there are no choices, Herm posts a plain-text prompt and expects a thread
reply.

While clarification is pending:

* Only the user who started the turn can answer. That person can use a choice
  control or reply in the thread.
* Clicks or replies from other users are rejected for that waiting turn.
* Ordinary chatter does not start a parallel agent turn until the clarification
  is resolved.

After the answer is accepted, Herm resumes the same turn. If the user sends
another message after that, it is queued like any other follow-up.

## Session modes

Slack can run in two modes:

| Mode            | Use when                                                                                |
| --------------- | --------------------------------------------------------------------------------------- |
| Direct          | Herm should manage Slack sessions and runtime routing for the agent.                    |
| Customer-backed | Your backend should receive Slack work and map it into your own customer/session model. |

Use direct mode for the default Herm-hosted setup. Use customer-backed mode when
your product needs to own the customer mapping or route Slack work through your
own service before it reaches Herm.

Inbound Slack file content is forwarded in both modes. Customer-backed runtimes
must accept inline message attachments and forward them unchanged to the Prism
session events API.

Deploy the customer runtime attachment contract before enabling the matching
gateway release; older runtimes reject inline attachment payloads.

In customer-backed mode, Herm does not invent synthetic failures for your custom
tools. Your backend owns custom-tool results and the stream resumes from its
durable cursor.
