Slack Integration
The Shipwright agent communicates via Slack using the Bolt SDK in Socket Mode — no public HTTP
endpoint needed. The agent handles DMs, @mentions, reactions, file attachments, and voice
transcription. Cron jobs post their results to a configured Slack channel.
How it works
The agent connects to Slack via a persistent WebSocket (Socket Mode). Every incoming message arrives as a prompt; the agent runs Claude and posts the response back to the same thread.
Messages are prefixed with [Name]: where Name is the sender’s Slack display name, so the
agent knows who it’s talking to. Cron job results are posted to a configured channel automatically.
Connecting a Slack app
Slack provisioning is automated via the /admin/provision flow — one manual step (enabling
Socket Mode) is required at the end; everything else happens for you.
- Open the provisioning form
Navigate to /admin/provision in the Shipwright admin UI and fill in the agent to configure, GitHub credentials (a PAT or GitHub App installation), an optional Anthropic API key, an optional Claude Code OAuth token, and a Slack app configuration token — a personal xoxe.xoxp- token that Shipwright uses once to create the app and never stores. To obtain it, go to api.slack.com/apps, click Create New App → From scratch (not from a manifest) to spin up a placeholder app, then under that placeholder app's App-Level Tokens click Generate Token and Scopes with the admin scope to generate the xoxe.xoxp- token. Once you've copied it, delete the placeholder app — it was only needed to generate the token.
- Shipwright creates the Slack app
After you submit the form, Shipwright calls apps.manifest.create to create a new Slack bot app, then automatically stores SLACK_APP_ID, the SLACK_SIGNING_SECRET (a signing secret used to verify incoming Slack requests), SLACK_CLIENT_ID, and SLACK_CLIENT_SECRET in the agent's environment. No manual steps needed.
- Authorize the Slack app
Click the Authorize Slack App → button the form now shows. You're redirected to Slack's OAuth approval page, approve the app to post to your workspace, and land back on /admin/provision/complete. Shipwright automatically stores SLACK_BOT_TOKEN (the xoxb- bot user OAuth token) — you don't need to copy it manually.
- Enable Socket Mode and generate the app tokenManual step
Go to api.slack.com/apps, select the app that was just created, and open Socket Mode in the left sidebar. Enable it, then Generate Token and Scopes with the connections:write scope to produce an app-level token (starts with xapp-). Paste that xapp- token into the Socket Mode field back in the Shipwright admin UI and submit — the agent connects via Socket Mode on its next startup.
Required Slack environment variables
| Variable | Required | Description |
|---|---|---|
SLACK_BOT_TOKEN |
yes | Slack bot user OAuth token (xoxb-...) |
SLACK_APP_TOKEN |
yes | Slack app-level token for Socket Mode (xapp-...) |
SLACK_SIGNING_SECRET |
yes | Verifies incoming Slack request signatures |
SLACK_ADMIN_TOKEN |
no | Optional admin-level token for privileged Slack operations |
SLACK_ALERT_CHANNEL |
no | Channel ID to post system alerts (e.g. startup errors) |
SLACK_OWNER_USER |
no | Slack user ID of the agent owner, used for DM fallback |
Interacting with the agent
Direct messages
Send the agent a DM to start a private conversation. The agent replies in the same thread. Each session maintains conversation continuity — successive messages in a thread resume the same Claude conversation.
@Shipwright What's the status of the current task queue?
Mentions
Mention the agent in any channel where it has been invited:
@Shipwright run /shipwright:dev-task
The agent picks up the mention and responds in a thread on the same message.
Reactions
The agent can also respond to reaction_added events. This is useful for triggering workflows
from a thumbs-up or a custom emoji without sending a message.
Voice notes
Voice notes arrive pre-transcribed by Whisper STT as [voice transcript: <text>] in the prompt.
The agent replies with a [speak:text] marker to deliver a spoken response — conversational,
no bullet points, one to three sentences.
Voice support requires agent.voice.enabled=true in the Helm chart (see
Deploying to Cloud) or a WHISPER_SERVICE_URL / GROQ_API_KEY in
the agent environment.
Response markers
The agent embeds markers in its responses to trigger side effects. Markers are stripped from the visible message before posting:
| Marker | Effect |
|---|---|
[silent] |
Skip posting entirely (useful for cron jobs with nothing to report) |
[upload:/path/to/file] |
Attach a file to the message |
[react:emoji1,emoji2] |
Add emoji reactions to the agent’s reply |
[speak:text] |
Synthesize speech and upload as audio |
[plan:url] |
Post a plan link to the rendered planning artifact |
Cron job notifications
Cron jobs are scheduled prompts that run on a recurring schedule and post results to Slack. Most
crons are silent by default — they only post when there is something worth surfacing (a completed
PR, a failing check, or an error).
The channel field on a cron job controls where results are posted. When user is set instead of
channel, results are posted as a DM to that user.
To configure which channel receives cron results, set the channel on each cron job via the admin
UI or the /agents/:id/crons/:cronId API, or set SLACK_ALERT_CHANNEL as the global fallback for
system alerts.
Message format
Incoming Slack messages always arrive with the sender’s Slack display name prepended:
[Alice]: Please review the latest PR on the metrics service.
The agent uses this prefix to know who is making the request, which is especially useful in channels where multiple people may be interacting with the same agent.
Next steps
With Slack connected, the agent is fully operational as a 24/7 autonomous delivery system. Enable the opt-in cron jobs from the admin UI to automate review, patching, deployment, and maintenance — see The Agent for the full cron reference.