Shipwright Harness

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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.