Slack

The Omnigent Slack integration (v0.6.0+) lets your team talk to agents directly from Slack. Mention the bot in a channel or DM it, and it starts an Omnigent session; replies stream into the thread live, and tool approvals show up as interactive Approve / Deny cards you can answer in place.

The core model is simple: one Slack thread ↔ one Omnigent session. Replying in a thread continues the same session; a new mention starts a new one.

The bot connects to a single Omnigent server chosen by the operator — users never enter a server URL. Each user still authenticates as their own Omnigent identity, so sessions run with per-user permissions and no shared credential ever passes through Slack.

What you can do

Setting it up (operator)

The bot is a Socket Mode Slack app — it opens an outbound WebSocket to Slack, so it needs no public HTTP endpoint and no request URLs.

1. Create the Slack app

  1. Create a Slack app with Socket Mode and Interactivity enabled (Socket Mode also delivers the button/modal payloads — no request URL needed).
  2. Add the OAuth scopes and event subscriptions listed below.
  3. Add a slash command /omnigent (Features → Slash Commands). In Socket Mode the request URL is ignored, so any placeholder works.
  4. Install the app into your workspace.

2. Grant scopes

Bot token scopes (OAuth & Permissions → Bot Token Scopes) — all required:

ScopeWhy
app_mentions:readReceive @mentions — how the bot joins a channel thread.
chat:writePost, delete, and stream replies (including ephemeral nudges).
im:writeOpen a DM to send the setup button and logout confirmation.
im:historyRead DMs — DMs are a first-class entry point.
commandsRegister and receive /omnigent.
team:readRead the workspace name to label the login request.

Channel history scopes — add only for the channel types where the bot will run: channels:history (public), groups:history (private), mpim:history (group DMs). If you only use DMs and channel @mentions, you can omit all three.

App-level token scope: connections:write (required for the Socket Mode connection).

Event subscriptions (Subscribe to bot events): app_mention, message.im, and message.channels / message.groups / message.mpim for the channel types you enabled above.

3. Install and configure the bot

The bot ships as the slack extra of Omnigent, in the same environment as the omni CLI:

uv tool install "omnigent[slack]"    # or, from a source checkout: uv sync --extra slack

Copy .env.example to .env and fill in:

VariableRequiredPurpose
OMNIGENT_SLACK_BOT_TOKENYesThe bot token (xoxb-…).
OMNIGENT_SLACK_APP_TOKENYesThe app-level token (xapp-…) for Socket Mode.
OMNIGENT_SERVER_URLYesThe one Omnigent server the bot talks to.
OMNIGENT_DEVICE_CLIENT_SECRETNoSet to the same value as the server's OMNIGENT_DEVICE_CLIENT_SECRET so only this bot can drive the device-grant login. Accounts mode only.
OMNIGENT_SLACK_TOKEN_ENCRYPTION_KEYNoA Fernet key that encrypts users' delegated tokens at rest. Without it, tokens live in memory only and users re-authenticate after a restart.
OMNIGENT_SLACK_DATABASE_PATHNoWhere the bot's SQLite store lives. Defaults to $OMNIGENT_DATA_DIR/omnigent_slack.sqlite3 (or ~/.omnigent/omnigent_slack.sqlite3).
LOG_LEVELNoSet to DEBUG when diagnosing why Slack events aren't producing replies.

Generate an encryption key with:

python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

4. Run it

The bot runs as a background daemon managed by the omni CLI:

omni integration slack           # run in the foreground (Ctrl-C to stop)
omni integration slack start     # run in the background (detached)
omni integration slack status    # is the background bot running?
omni integration slack stop      # stop the background bot
omni integration slack logs      # print the log path
omni integration slack logs -f   # follow the log

Running start while the bot is already up is a no-op that reports the existing process.

Per-user setup

The first time someone interacts with the bot without having configured it, the bot DMs them a Set up Omnigent button (and drops an ephemeral pointer in the thread for channel mentions). The button opens a modal that:

  1. Validates connectivity to the operator's server, and — if the server has authentication enabled — walks the user through login (see below).
  2. Lets them pick an agent and host (both required, populated from the server) and a workspace path — the absolute directory on the host where each session's runner starts. It defaults to the host's home directory.

The choice is saved per (Slack workspace, user). Run /omnigent any time to change agent, host, or workspace, and /omnigent logout to revoke your token and clear all saved settings.

Each new session launches a fresh runner on the chosen host, rooted at the configured workspace.

Authentication

For servers with authentication enabled, each Slack user logs in with their own Omnigent identity inside the /omnigent modal. The bot auto-detects the server's auth mode and picks the matching flow:

Tokens are stored encrypted at rest when OMNIGENT_SLACK_TOKEN_ENCRYPTION_KEY is set; otherwise they're kept in memory only and lost on restart (users simply re-authenticate).

Approvals and questions

When the agent needs you — a tool-call approval or a multiple-choice question — it appears in the thread:

Cards are visible to the whole channel, but only the thread owner can act on them. Answering from the web UI works too: the card in Slack finalizes automatically once the request is resolved anywhere.

Sharing a channel with your team

Slack channels are multi-user, so the bot enforces a per-thread owner model: a thread belongs to whoever started it. If someone else replies in your thread, they get a private note pointing them to start their own thread — they are never added to your session.

If you message a thread while the bot is still replying, it privately asks you to wait (or continue in the web UI). A message to an idle thread just continues the conversation.

Supported and not supported

Supported

Not supported

Troubleshooting