Skip to content

Slack Bot minimal setup guide

Minimal Slack app permissions, events, and manifest settings required to run mikan through Socket Mode.

You can also create the app from an example manifest. There are two, because Slack offers two surfaces and mikan serves both:

ManifestSurfaceUse when
deploy/examples/slack-app-manifest.jsonClassic appPeople talk to mikan by @mentioning it in channels and by DM.
deploy/examples/slack-agent-manifest.jsonAgent (AI app)You also want mikan in the Agents & AI apps sidebar, with its own pane, greeting, suggested prompts, and a conversation list.

The agent manifest is the classic one plus three things: the agent_view feature, the assistant:write scope, and the assistant_thread_started / assistant_thread_context_changed events. Everything else — slash commands, Socket Mode, message events — is identical, and the same mikan process serves either. Start from the classic one if you are not sure; adding the agent surface later is an edit to the same app.

The agent surface needs a paid Slack plan. Slack’s own wording is that these features “require a paid plan, despite being visible in the app settings on any plan” — so on a free workspace every toggle turns on, the events save, the app reinstalls, and then nothing is ever delivered. There is no error to find; a listener that never fires is the only symptom. If you are only developing, the Slack Developer Program provisions a fully-featured sandbox for free, which is the cheaper answer than upgrading a real workspace. The classic app surface — mentions, DMs, slash commands, Block Kit — is unaffected and works on any plan.

Which is to say: mikan’s side of the agent surface is written, tested, and waiting — the greeting, the suggested prompts, the per-thread sessions, the conversation titles — and it has never once run against a real paid workspace, because the author’s is free. It has been verified the only way a free plan allows: by proving Slack sends nothing at all. If you are on a paid plan and want mikan as your team’s agent, open an issue. Getting that surface exercised against a workspace that actually delivers the events would be a good day, and the support will be enthusiastic.

agent_view and assistant_view are two surfaces, not two spellings of one. The events and the assistant.threads.* methods kept their names, but which events mean “someone opened a conversation” changed: agent_view uses app_home_opened (with tab: "messages") and app_context_changed, while assistant_view uses assistant_thread_started and assistant_thread_context_changed. mikan handles both, so either manifest works. New apps can only choose agent_view; assistant_view still works but Slack has said it will eventually be deprecated.

  1. Open https://api.slack.com/apps.
  2. Click Create New App.
  3. Choose From scratch.
  4. Pick an app name, for example mikan, and select your workspace.
  1. Go to Settings → Socket Mode.
  2. Turn on Enable Socket Mode.
  3. Create an app-level token with the connections:write scope.
  4. Store the token as SLACK_APP_TOKEN.

The token starts with xapp-.

Go to OAuth & Permissions → Scopes → Bot Token Scopes and add:

  • app_mentions:read
  • assistant:write (agent surface only — the assistant.threads.* methods that set the pane’s status, suggested prompts, and conversation title)
  • channels:history
  • channels:read
  • chat:write
  • commands (required only when using the optional slash commands below)
  • files:read
  • files:write
  • groups:history
  • groups:read
  • im:history
  • im:read
  • im:write
  • reactions:write
  • users:read

Then install or reinstall the app to your workspace and store the bot token as SLACK_BOT_TOKEN.

The token starts with xoxb-.

  1. Go to Features → App Home.
  2. Enable Home Tab.
  3. Enable Agent or Assistant under Agents & AI Apps.

This is what puts mikan in the Agents & AI apps sidebar with its own pane. Skip it for a classic app.

In the pane, mikan greets the person when they open a conversation, offers suggested prompts shaped by the channel they are viewing, shows a working status while it thinks, and names each conversation from its first message so the sidebar list is navigable. Each conversation there is a thread, and mikan gives every thread its own session — the sidebar is a list of separate conversations, not one transcript, and continuity across them comes from memory rather than from a shared session.

Go to Features → Event Subscriptions and enable events.

Subscribe to these bot events:

  • app_home_opened
  • app_mention
  • message.channels
  • message.groups
  • message.im

Plus, for the agent surface, the events that say someone opened the pane and where they are looking. Subscribe the pair that matches your manifest key — subscribing all four is harmless and covers either:

  • agent_view: app_context_changed (and app_home_opened, already above)
  • assistant_view: assistant_thread_started, assistant_thread_context_changed

Without them the pane has no suggested prompts and its conversations stay untitled in the sidebar.

Go to Features → Interactivity & Shortcuts and enable interactivity.

If you only use Socket Mode for local development, you do not need a public request URL, though Slack may still require one in some app settings.

The example manifest includes common control slash commands:

  • /pi-login → login portal
  • /pi-new → start a new DM session
  • /pi-session → session viewer
  • /pi-model → switch this conversation’s LLM (provider/model[:thinking], for example anthropic/claude-sonnet-4-6:off)
  • /pi-auto-reply → manage group/channel auto-reply rules
  • /pi-sandbox → inspect or tune this conversation’s sandbox
  • /pi-extensions → list installed extensions
  • /pi-admin → open the admin portal

Slash commands are optional because text commands also work in supported contexts. Keep stop as a text command (stop or /stop) so thread-local stop routing can point at the correct session.

mikan needs its global settings file and an LLM provider key once — mikan --onboard and export ANTHROPIC_API_KEY=...; see Quickstart — then:

Terminal window
export SLACK_APP_TOKEN=xapp-...
export SLACK_BOT_TOKEN=xoxb-...
mikan

The state directory defaults to ~/.mikan and the working directory to <state-dir>/workspace; pass --state-dir=<dir> or a path argument to change them. mikan --help lists all flags, and mikan env shows which variables are currently set.

The bot responds in DMs and when mentioned in channels. Triggered Slack thread work uses an isolated session whose key includes the thread timestamp. An ordinary unmentioned reply in a shared-channel thread is logged but does not start a run.

Without --sandbox, mikan runs tools directly on the host, and the default isolated door policy refuses that combination by design — the first message reports that host cannot provide an isolated conversation office. Pick one before your first real conversation:

  • Recommended. Use the managed sandbox, which gives each conversation its own container and satisfies the isolated policy with no settings change:

    Terminal window
    mikan --sandbox=image:ghcr.io/geminixiang/mikan-sandbox:latest
  • Host mode, only on a machine you already trust with the whole workspace: add a trusted door policy to ~/.mikan/settings.json.

    {
    "sandbox": {
    "workspace": { "doorPolicy": "trusted", "layout": "shared-support" }
    }
    }

See Sandbox for the full comparison.