Skip to main content

Automatic Slack setup

Mesh can create a distinct Slack app for each agent, configure its permissions and events URL, upload its avatar, and collect its bot credentials through Slack OAuth. The manual connection flow remains available.

Once per Mesh instance

  1. Configure MESH_AGENT_MASTER_KEY and a stable, publicly reachable HTTPS PUBLIC_URL. Automatic setup requires an HTTPS origin without a path. Mesh uses HTTP Events API delivery; no Socket Mode app token is needed.
  2. In Slack’s Your Apps page, find Your App Configuration Tokens and generate a configuration token for the intended workspace. The Slack account must have permission to create apps. Workspace app-approval policies still apply.
  3. In Mesh Settings → Slack app provisioning, paste the refresh token. Mesh rotates it immediately, stores the resulting access/refresh pair encrypted, and refreshes it while the server runs. This credential belongs to a Slack user and workspace; it is not a universal Slack administrator key.
The implementation and research are available in PR #243. The first version supports one current provisioning workspace per Mesh instance. Replacing that connection changes the workspace used for new setup. Existing bot installations continue working. To update an app created in a previous workspace, reconnect provisioning for that workspace.

Creating an agent

  1. Name the agent and connect OpenRouter or Ramp Router, then choose its models.
  2. Write the persona or describe the agent’s purpose and select Draft a profile. Review and save the draft. Upload a PNG/JPEG avatar, keep the generated geometric default, or use Generate picture with an image model from OpenRouter’s current image catalog.
  3. Choose Slack and select Create Slack app. Mesh creates the app, saves its credentials, registers a signed events URL, configures permissions and OAuth, and attempts to upload the picture.
  4. Select Install in Slack and approve the installation. Slack may require workspace-admin approval. Mesh exchanges the authorization code on the server, validates the workspace and granted permissions, saves the bot credential, and activates the connection.
  5. Open the app in Slack and send a test message. Invite it to channels where it should participate.
Profile generation works through either text provider. Ramp Router image generation is not enabled because its image-output API has not been verified. OpenRouter image generation uses /images/models and /images; generation uses the agent’s saved provider credential and may incur provider charges. A failed generation does not block manual editing or upload. A wizard draft URL survives reload. Provisioning progress is stored on the server, so refreshing or resuming a draft does not create another Slack app. Credentials are never persisted in browser storage.

Recovery and maintenance

  • Creation outcome uncertain: Mesh will not retry app creation blindly. Inspect the apps in Slack and recover that app using the manual connection option. The creation intent remains blocked rather than risking duplicates. Automated orphan reconciliation/deletion is not implemented.
  • Configuration failure: resume setup against the saved app ID. Rate-limit errors expose Slack’s retry delay; retry after that interval.
  • Picture upload failure: installation remains available. Download the avatar and upload it through Slack’s app settings, or retry Sync profile picture.
  • Expired/cancelled OAuth: return to the saved setup and start a new installation attempt. OAuth state is single-use, session-bound, user-bound, and expires after ten minutes.
  • Saved installation awaiting activation: use Activate connection. The bot credential has already been saved; another OAuth approval is unnecessary.
  • Changed hostname or configuration: open the connection’s Manage automatic Slack setup and picture link and select Update Slack configuration. This updates the existing app’s event and OAuth callback URLs using the current PUBLIC_URL.
  • Changed avatar: use Sync profile picture on each managed Slack connection. Uploading/generating a new Mesh avatar marks app icons pending; it does not silently publish the new picture to every connected app.
  • Revoked or expired provisioning grant: reconnect it in Settings. Disconnecting provisioning removes its Mesh credential; it does not uninstall existing apps or revoke their bot tokens.
Mesh’s existing single-replica deployment model still applies. The database prevents competing creation attempts and serializes configuration-token rotation, but runtime registry reload is local to the serving process.

Implementation and verification

Migration 0041 adds durable Slack app intents, OAuth attempts and bounded PNG avatar storage. App client/signing credentials and OAuth bot credentials are encrypted with the existing secret store. Pending URL verification checks Slack’s timestamped HMAC before the app is installed; active events must also match the recorded app and workspace before entering the existing ingress. Automated checks cover encrypted persistence, concurrent token rotation, interrupted/ambiguous app creation, safe retries, pending signed challenges, OAuth session/workspace/scope validation and replay prevention. Browser coverage uses the real Go server and PostgreSQL with local Slack/OpenRouter fakes, and exercises both manual and automatic onboarding, identity generation, reload/resume, OAuth activation, configuration repair and expired authorization. No real Slack app was created during implementation, and no paid model request was made. Before rollout, smoke-test the full flow in an authorized disposable workspace, especially apps.icon.set authorization, public URL verification, app approval and actual DM behavior. Slack’s public icon documentation and CLI token behavior have inconsistencies; the fallback upload path is intentional. Test one real OpenRouter image response as well. This implementation does not include manager-app enrollment, unattended child-app installation, shared instance model billing, public-channel discovery/joining, uninstall/revocation event handling, automatic orphan cleanup, a dedicated provisioning audit UI, or bulk hostname repair. See the research and broader rollout plan.

Troubleshooting the configuration connection

An expired access token on Slack’s App Configuration Tokens page does not require pasting that access token into Mesh. Mesh uses the refresh token to obtain a new pair through tooling.tokens.rotate. If connecting returns Slack: invalid_arguments on an older build, upgrade to the fix that sends rotation requests as application/x-www-form-urlencoded. Slack’s live endpoint ignores JSON rotation bodies and reports a missing refresh_token, even though its reference lists JSON support. A rejected request of this kind does not rotate the token; retry with the refresh token after upgrading. If Slack instead returns invalid_refresh_token, generate a new configuration token pair in Slack and paste its refresh token. Unexpected provisioning failures (HTTP 5xx responses) now reach the configured error tracker with component admin.api, the route pattern, and a classified error code, including slack_invalid_arguments. Tokens, request bodies, URLs, and raw provider/database errors are excluded. Expected OAuth and setup-state conflicts are not reported as failures.