| title |
|
||||||||
|---|---|---|---|---|---|---|---|---|---|
| description |
|
||||||||
| keywords |
|
||||||||
| topics |
|
||||||||
| tags |
|
||||||||
| content |
|
||||||||
| status | published |
This guide walks through the one-time Slack app registration that this example needs: creating the app from the bundled manifest, enabling Socket Mode, installing it to your workspace, and capturing the two tokens. Once you have them, you populate .env and run bash scripts/bring-up.sh from the example root — see the example README for the full bring-up flow.
The agent uses Slack via Socket Mode — there's no public URL or webhook to expose. The Slack Bolt SDK inside the sandbox opens an outbound WebSocket to Slack and receives events on it. The credential proxy resolves SLACK_BOT_TOKEN (the xoxb- token) and SLACK_APP_TOKEN (the xapp- token) at runtime; neither is baked into the image.
- A Slack workspace where you have permission to create apps. (For most workspaces this means workspace-admin or App Manager rights; check your workspace settings if you're unsure.)
- A dedicated user account in that workspace (yours is fine for personal use). Its member ID can become
SLACK_ALLOWED_IDSif you want to restrict access; leave the variable empty to let anyone in the workspace message the bot.
The manifest at slack_app_manifest.json pre-configures the bot user, OAuth scopes, event subscriptions, and a slash command. You only need to customize three identifiers before pasting it into Slack.
Open slack_app_manifest.json in a text editor and replace these three placeholders with your own identifier (the slash command must be lowercase and hyphen-separated):
| Field | Placeholder | Example replacement |
|---|---|---|
display_information.name |
MyUser NemoClaw |
Alice NemoClaw |
features.bot_user.display_name |
MyUser NemoClaw |
Alice NemoClaw |
features.slash_commands[].command |
/myuser-nemoclaw |
/alice-nemoclaw |
Note your slash command — that's what users will type in Slack.
The bot's @-handle in Slack is derived from bot_user.display_name (e.g. Alice NemoClaw → @alice_nemoclaw). Note your handle — other docs (like the Collective Wisdom demo) reference it as @<your-bot> and expect you to substitute your actual value.
- Go to api.slack.com/apps and click Create New App.
- Choose From an app manifest.
- Select your workspace, then click Next.
- Paste your edited manifest JSON and click Next.
- Review the requested permissions and click Create.
The manifest configures:
- Socket Mode — no public URL required.
- Bot events:
message.im,message.channels,message.mpim,app_mention. - OAuth scopes (bot):
im:history,im:read,im:write,app_mentions:read,channels:history,channels:read,chat:write,commands,reactions:write,users:read,mpim:history,mpim:read,im:write.topic. - Slash command — your custom
/<name>-nemoclaw.
- In your new app's settings, click Socket Mode in the left sidebar.
- Toggle Enable Socket Mode on.
- When prompted, name the app-level token (for example
nemoclaw-socket). - Add the app-level scope
connections:write. Slack requires this scope forapps.connections.opento generate the Socket Mode WebSocket URL. - Click Generate, then copy the token. It starts with
xapp-.
Save it for the .env step below — this is SLACK_APP_TOKEN.
If Slack behaves oddly on this step (toggle won't persist, generate prompt doesn't appear), toggle Socket Mode off and back on once.
- In the left sidebar, click OAuth & Permissions.
- Click Install to Workspace and authorize.
- Copy the Bot User OAuth Token at the top of the page. It starts with
xoxb-.
Save it — this is SLACK_BOT_TOKEN.
SLACK_ALLOWED_IDS is an optional allowlist. Leaving it empty lets anyone in the workspace DM or @-mention the bot — fine for personal workspaces and small trusted teams. Set it when you need to restrict access to specific users.
- In the Slack desktop or web client, click your name or avatar.
- Click Profile.
- Click the ⋮ (more) menu, then Copy member ID.
- The ID looks like
U0887Q5UVV4.
To allow multiple users, comma-separate their IDs in .env (for example U0887Q5UVV4,U1XYZABC123).
Open .env at the example root and uncomment / set the three Slack values:
SLACK_BOT_TOKEN=xoxb-<your bot token from OAuth & Permissions>
SLACK_APP_TOKEN=xapp-<your app-level token from Socket Mode>
# Optional — leave empty to allow anyone in the workspace
SLACK_ALLOWED_IDS=U0887Q5UVV4
# Optional — set false for text-only output
NEMOCLAW_SLACK_RICH_BLOCKS=trueLeaving SLACK_BOT_TOKEN and SLACK_APP_TOKEN unset disables Slack entirely — the example runs Outlook-only. If you set the tokens, a single <sandbox>-slack provider is upserted by scripts/02-providers.sh with both credentials attached.
Hermes renders supported semantic Markdown with Slack Block Kit by default,
including native table blocks. Set NEMOCLAW_SLACK_RICH_BLOCKS=false for
text-only output. The setting accepts only true or false. Every message
keeps a text fallback for notifications, accessibility, old clients, and
renderer failure.
The recipe also renders two to four Hermes clarification choices as one-tap
buttons plus an Other option. The pinned Hermes base already provides the
clarification and authorization primitives; a feature-detected compatibility
shim adds the missing Slack presentation. It stands down when a future Hermes
base supplies native Slack clarification buttons. Rich Blocks and buttons use
the existing Slack credentials and require no additional OAuth scopes or app
reinstall. Rebuild the sandbox after changing the Rich Blocks setting.
From the example root:
$ bash scripts/bring-up.shThe script (auto-sources .env if needed) does the following for Slack:
- Calls
apps.connections.openwith a bounded request to verify that the app token is valid, hasconnections:write, and can create a Socket Mode URL. Setup stops before provider and sandbox creation when this check fails. - Creates an OpenShell provider
<sandbox>-slackwith bothSLACK_BOT_TOKENandSLACK_APP_TOKENcredentials (one v2 provider, two credentials). - Bakes
slackinto the sandbox image's channel list (NEMOCLAW_MESSAGING_CHANNELS_B64) alongsideoutlook. - Injects
SLACK_ALLOWED_IDSas the gateway'sSLACK_ALLOWED_USERSat sandbox-create time (runtime-- env, not baked into the image). An empty allowlist setsSLACK_ALLOW_ALL_USERS=trueso any workspace user can DM the bot. - Builds the sandbox image and launches it; the Hermes Slack channel opens its Socket Mode WebSocket on startup.
If you change Slack credentials after a sandbox already exists, run bash scripts/tear-down.sh && bash scripts/bring-up.sh so the providers and image are rebuilt with the new values.
After the sandbox is running, send a direct message to your bot in Slack from your allowlisted account. It should respond within a few seconds.
To inspect Hermes activity inside the sandbox:
$ openshell sandbox connect hermes-direct
# Inside the sandbox:
$ tail -f /sandbox/.hermes/logs/hermes.logIf the bot does not respond, verify that:
openshell provider listshows<sandbox>-slackwith bothSLACK_BOT_TOKENandSLACK_APP_TOKENin its credential keys.- If
SLACK_ALLOWED_IDSis set, your Slack member ID matches one of its entries exactly (Slack IDs are case-sensitive and start withU). If it's empty, this check doesn't apply — anyone in the workspace can message the bot. - The bot user is installed in your workspace (re-check OAuth & Permissions in your app's settings).
- Socket Mode is still enabled (re-check Socket Mode in your app's settings).
To rotate either token:
- Generate a new one in the Slack app settings (Socket Mode → regenerate, or OAuth & Permissions → reinstall).
- Update the matching value in
.env. - Run
bash scripts/tear-down.sh && bash scripts/bring-up.shto refresh the OpenShell provider and rebuild the sandbox image.
The old token continues to work until the new one is fully deployed, so there's no downtime if you do this in order.
