Channels: Slack and iMessage
An agent nobody can reach does nothing. Channels put it where people already talk, and they decide where it reaches back when it needs an answer.
One home, many mentions, and DMs
Slack is installed once per workspace, then configured per agent. There are exactly three modes, and an agent can use all three at once.
Home channel
at most oneThe agent answers every message there, and all of it rides one shared rolling conversation rather than a new session per message. The home channel is also the agent's alert target: alerts arrive as new threads in it. One home channel per agent, per Slack team, enforced in the database rather than only in the UI.
Mention channels
any numberThe agent answers only when it is @-mentioned, or when a message continues a thread it is already in. No alerts land here. This is how an agent sits in a busy channel without talking over everyone.
Direct messages
on or offAuthorized members can DM the agent, and each person gets their own rolling conversation with it. DMs always answer, with no mention needed.
saves are atomic
Ask the Agnt Wizard to route a channel and it writes the route directly, not as a proposal for you to approve. It can also bind one person's DMs to a specific agent, found by their Slack user id or email. That binding answers even with the agent's DMs toggle off, and each person's DMs go to one agent at a time. Once Slack is connected and the workspace's main agent, the one onboarding builds, is deployed, the person who connected Slack has their DMs bound to it automatically.
What the agent can do in Slack
Being routed into a channel lets the agent answer there. Wiring the Slack tools lets it act there: post on its own initiative, read back through a thread, open a channel, pull someone in.
| Tool | What it does |
|---|---|
slack_post_message | Posts into a channel or thread the agent can reach. |
slack_request_approval | Posts Approve / Decline buttons and ends the agent's turn. It does not block: when someone clicks, the same session resumes with the answer. This is the one that can actually get a decision. |
slack_conversation_history | Reads recent messages in a channel. |
slack_conversation_replies | Reads a single thread. |
slack_list_channels | Lists the channels the install can see. |
slack_get_channel_info | Reads one channel's metadata. |
slack_create_channel | Creates a channel. |
slack_invite_to_channel | Adds people to a channel by Slack user id. |
slack_lookup_user_by_email | Turns an email address into a Slack user id, for an invite or an @-mention. |
An agent gets only the Slack tools wired into its config, picked on the Connectors tab of its Tools panel. Slack is not reachable under /v1/connections/slack: these tools are the way to call it.
Three settings live on the Slack install itself rather than on any one agent:
| Setting | Effect |
|---|---|
| Default agent for DMs and mentions | The agent that answers anywhere no channel-specific route matches. |
| Escalation channel id | The channel workspace-level escalations are posted to, entered as a channel id such as C0123ABC rather than a name. |
| External-user policy | Reject external users (the default), allow listed users, or allow all users. The choice is saved, but incoming messages are not checked against it: who gets an answer is decided per Slack account, below. |
On a plan with a set number of seats, the agent answers only authorized Slack accounts. Someone whose Slack email matches a member of your organization is authorized automatically. Anyone else gets one full answer, then a notice in place of each later answer, until someone approves them from that notice or under Authorized Slack accounts in Settings. Approving says first whether it adds a paid seat or upgrades the plan, and an approved account with no superagnt login of its own takes a seat: see members and seats. On other plans there is no such check.
One install per Slack workspace
Slack connects with OAuth from Integrations in the superagnt app, so there is no API key to paste. Once it is connected, the Slack page there holds the three install settings above, and superagnt stores the bot token encrypted. A Slack workspace is connected to one superagnt workspace at a time: connecting it to a second while it is live in the first is refused, with a message to disconnect it there first.
The install asks Slack for these bot scopes:
| Bot scopes | What they are for |
|---|---|
app_mentions:read, assistant:write, chat:write, chat:write.public, commands, im:history, im:read, im:write, mpim:history, mpim:read, mpim:write, channels:history, groups:history | Chat: reading mentions, DMs, group DMs and channel messages, posting replies, showing the typing status, and the /agnt command. |
channels:read, channels:manage, channels:join, groups:read, groups:write | Channels: listing, creating and managing public and private channels for the channel tools. |
team:read, users:read, users:read.email | People: reading the Slack workspace and its members, by id or by email. |
The app adds one slash command, /agnt. /agnt list shows up to 20 of the workspace's agents, most recently changed first, each marked live or draft. /agnt help, or /agnt on its own, says how to reach the agent. Only the person who typed the command sees the answer.
Disconnecting Slack on its Integrations page removes the connection and its three settings. Slack tool calls then fail, and messages from that Slack workspace stop reaching agents. Each agent's channel routes are kept, and work again if the same Slack workspace is connected again. The app itself stays in Slack until someone removes it there.
A phone number your agent answers
iMessage runs through one shared agnt number. You bind a phone number to an agent, and from then on texts from that number reach that agent.
- 01
Register the number
Adding a number creates a binding inpendingstate. Nothing routes yet. Confirm the number with its owner first: it is somebody's real phone, and a number already bound elsewhere on the platform is refused. - 02
They text the agnt number
The binding flips toconfirmedonly when that person texts the agnt number. Texting first without a pending binding does nothing, so there is no way to be opted in by someone else.
reply-only
imessage_send_message, and it can only text confirmed contacts in your own workspace. An arbitrary or external number is rejected. The agent can start a text to a confirmed contact whenever it likes, but the relationship has to be opened by the human.Where it reaches you when nobody is in the room
Most of an agent's work happens with no chat attached: a schedule fires at 6am, a webhook arrives, another agent hands it a task. When it needs an approval or has to escalate, that request goes to its Slack home channel if it has one, and otherwise to the default channel.
There are three settings. Auto, the default, resolves live: a confirmed iMessage binding first, otherwise the Slack DM with the person who installed Slack. Picking iMessage or Slack pins the preference, but the concrete target still resolves at send time, so a removed binding degrades to the other channel instead of breaking. With neither connected, requests stay on the dashboard.
What the request looks like when it arrives, and how a reply or a button answers it, is on permissions and approvals.
The conversation continues
A Slack thread maps to a session, and so does a phone number. Replying continues the same conversation rather than starting a cold one, which is why an agent you have been talking to for a week still knows what you meant by "the second one". Channel chatter in a home channel rides one shared rolling session; DMs get a rolling session per person.
In Slack the agent answers in the thread of the message it is replying to, once its turn ends, with that turn's final message rather than a live stream. Anything it wrote earlier in the turn stays in the session, not in Slack.
Every one of those conversations is mirrored into the dashboard and opens read-only in the session inspector, so you can audit what the agent said in Slack without being in the channel. See sessions and observability.
Reaching a human is opt-in on purpose
The chat-route tools are the bindings family on the workspace MCP surface, and unlike most families they are never served unless you turn them on. Routing reaches into a real person's Slack and phone, so enabling it stays a deliberate act rather than something a freshly connected client inherits. Inbox management is opt-in for the same reason.
Every plan can use every channel. What a builder plan limits is how many messaging lines the organization holds at once: each iMessage binding that is pending or confirmed counts as one, and so does each active Slack route to an agent. Connected email inboxes are counted separately.
| Plan | Messaging lines | Email inboxes |
|---|---|---|
| Starter | 1 | 1 |
| Growth | 3 | 3 |
| Scale | 10 | 10 |
Adding a line past the cap comes back as an upgrade offer naming the next plan and a confirm URL a person taps. It is never a protocol error, and nothing already routed stops working. When a trial ends or a plan lapses, inbound messages stop starting agent sessions until a plan is active again; no route or binding is removed.
Connecting Slack in the dashboard is separate from enabling the tools: the connection is what makes routes possible, the family is what lets a client create them. See tools and tool families.