A Slack bot for a coding agent turns a message in Slack into a request for Claude Code or Codex running on someone’s machine and posts the result back in the thread. muti gives each agent its own bot with its own name. People in your workspace DM it or mention it in a channel; that message is the task. If the person asking is not the agent’s owner, the request waits, and the owner approves it with buttons in their own DM. Pushes, destructive deletes, spending and credential access never become automatic, for anyone.
This post explains how the connector works, what “Allow always” actually stores, and why treating Slack as untrusted input is the whole point.
What most bridges get wrong
The typical bridge stores a bot token, listens for mentions, and pipes the text to a local CLI. It works, and it has three problems: channel membership becomes the permission model, nobody approves the risky step, and progress floods the channel one message per tool call. None of those is a Slack problem. They are permission problems that happen to surface in Slack.
A channel thread shows the request and its status; the approval buttons live in the owner’s DM; the agent runs on the owner’s machine.
One bot per agent
You create the Slack app from a manifest muti generates for that agent, so the bot carries the agent’s name and its own event URLs. There is nothing to bind and no command to learn:
- DM the bot and the text is a task. The DM becomes a room shared by you and the agent’s owner.
- Mention it in a channel and that channel becomes a group room in muti on first use. The bot answers in the thread.
- Attach files and they arrive as room attachments the agent can read, like web uploads.
Slack users become muti users by the email Slack holds for them, verified by Slack inside the owner’s own workspace. If Slack hides the email, the bot sends a six-digit link code to redeem on the web once. Either way, permissions attach to the account, not to a display name.
The same gate as the web
Every request passes the gate the web uses. The owner’s own messages run at once. Anyone else waits for the owner, unless the owner has already allowed them always for this agent. Status lands in the thread: accepted with a request id, waiting, running with tool-call summaries, done with the result. One card, updated in place, rather than a message per step.
Approval buttons, and what “always” means
When a request from someone else arrives, or when a run reaches a tool call that needs a human, the owner gets a card in their DM with three buttons: Allow, Allow always, Deny.
Allow is for that single call. Allow always stores a rule for the agent that is exactly as narrow as the call: this domain for WebFetch, this command prefix for Bash, this skill by name, this read-only tool. Future matching calls are answered by muti without a prompt. The rules are listed and revocable in the agent’s dialog.
Calls in the dangerous classes never qualify for a rule and never match one: pushing to shared branches, destructive deletes, privilege escalation, publishing and deploys, and reads or writes of credential paths. They stay one call at a time, with only Allow and Deny. That is the connector’s version of the four actions that always ask. Unanswered approvals expire after 24 hours, like requests.
What the channel sees
Request text, status and id; tool-call summaries; diff paths and line counts; the tail of command output; produced files and links. Never: environment variables, key files, the working tree, or anything from another room. The Slack tokens are stored encrypted in muti; nothing Slack-related lives on the owner’s machine, which keeps its outbound-only daemon connection. See what the daemon uploads.
Setup
- In the console, open Slack for the agent you want to expose and create a Slack app from the generated manifest. Upload the agent’s avatar as the app icon if you like; the wizard renders it.
- Paste the two strings from the app’s settings. muti calls Slack once, finds you by email, and links you as the owner so approval buttons work immediately.
- Install the app to your workspace. DM the bot, or invite it to a channel and mention it.
- Approve the first request from a teammate in your DM. Use Allow always only for the narrow, boring calls; leave the dangerous ones to ask.
Frequently asked questions
Does the bot need my Slack admin? Installing an app into a workspace typically needs one admin approval. The app is yours, created from muti’s manifest, so no third-party app holds your workspace token.
Can channel members approve for themselves? No. Approval belongs to the agent’s owner and arrives in the owner’s DM. Members can cancel or add context.
What about Feishu, Lark and DingTalk? Feishu/Lark is next and follows the same room and approval model; see the Feishu design. DingTalk after that.
Is this the same as Claude Code Dispatch? Dispatch relays your Telegram messages to your own session. This connector is for other people, with approvals; see Dispatch vs a room.
The room does the permission work; Slack is one more door into it. Give your agent a room.
Published · Updated