Manage your Linux servers directly from Slack. Get real-time alerts when agents come online or go offline, when tasks complete or fail, and approve new servers — all without leaving your workspace.
The ManageLM Slack plugin connects your infrastructure to Slack through the same portal API used by the Claude extension and n8n integration. It provides two-way communication:
Agent enrollment, online/offline, task completed/failed — posted as Block Kit messages the moment they happen.
/managelm status, approve, run, help — manage your fleet without opening the portal.
Approve pending agents and view task details with a single click, directly inside Slack messages.
Route critical alerts to #ops-alerts and informational events to #ops-general.
Every webhook delivery is signed with HMAC-SHA256 and verified before processing.
Develop locally with Socket Mode (no public URL required), deploy to production with HTTP.
The plugin runs two lightweight HTTP servers:
| Port | Purpose |
|---|---|
3100 | Slack Bolt app — slash commands, interactive buttons, Slack event verification |
3101 | ManageLM webhook receiver — event notifications from the portal |
Go to api.slack.com/apps and click Create New App > From an app manifest
Select your workspace
Paste the manifest below (YAML tab), replacing <YOUR_HOST> with your plugin's public URL
Click Create
display_information: name: ManageLM description: Manage Linux servers from Slack. features: bot_user: display_name: ManageLM always_online: true slash_commands: - command: /managelm description: Manage Linux servers with ManageLM usage_hint: status | approve <host> | run <host> <skill> <task> oauth_config: scopes: bot: - chat:write - commands settings: interactivity: is_enabled: true request_url: https://<YOUR_HOST>:3100/slack/events
Go to api.slack.com/apps > Create New App > From scratch
Under OAuth & Permissions, add bot scopes: chat:write, commands
Under Slash Commands, create /managelm with Request URL https://<your-host>:3100/slack/events
Under Interactivity, enable and set Request URL to https://<your-host>:3100/slack/events
Install the app to your workspace
Copy the Bot User OAuth Token (xoxb-...) from OAuth & Permissions
Copy the Signing Secret from Basic Information
Tip: For local development, enable Socket Mode in your app settings and generate an App-Level Token with connections:write scope. This way you don't need a public URL.
In the ManageLM portal, go to Settings > API Keys
Create a new key with the agents permission
Copy the key (mlm_ak_...)
Important: The API key determines what the Slack plugin can see and do. An admin key sees all agents; a member key only sees assigned agents. Choose the scope that fits your team.
Copy the example file and fill in your credentials:
# Slack credentials SLACK_BOT_TOKEN=xoxb-your-token SLACK_SIGNING_SECRET=your-signing-secret SLACK_APP_TOKEN=xapp-your-app-token # only for Socket Mode # ManageLM MANAGELM_PORTAL_URL=https://app.managelm.com MANAGELM_API_KEY=mlm_ak_your-key # Webhook MANAGELM_WEBHOOK_SECRET=your-webhook-secret # must match portal config PORT=3100 # Channel routing (optional) SLACK_CHANNEL_ALERTS=C0123456789 # agent.offline, task.failed SLACK_CHANNEL_INFO=C9876543210 # all other events
Self-hosted users: Set MANAGELM_PORTAL_URL to your own portal instance URL instead of app.managelm.com.
In the ManageLM portal, go to Settings > Webhooks and create a webhook:
| Field | Value |
|---|---|
| URL | https://<your-host>:3101/webhook |
| Events | Select all events you want notifications for |
| Secret | Same value as MANAGELM_WEBHOOK_SECRET in your .env |
The portal signs every delivery with HMAC-SHA256. The plugin verifies the X-Webhook-Signature header before processing any event.
npm install npm run build npm start
docker build -t managelm-slack . docker run --env-file .env -p 3100:3100 -p 3101:3101 managelm-slack
services: managelm-slack: build: . env_file: .env ports: - "3100:3100" - "3101:3101" restart: unless-stopped
Health check: Once running, visit http://<your-host>:3101/health to verify the webhook receiver is up. You should see {"status":"ok"}.
| Command | Description |
|---|---|
/managelm status | List all agents with online/offline status, sorted by state |
/managelm approve <hostname> | Approve a pending agent by hostname or display name |
/managelm run <host> <skill> <instruction> | Submit a task to an agent and get the result in Slack |
/managelm help | Show available commands |
/managelm status /managelm approve web-prod-03 /managelm run web-prod-01 packages List outdated packages /managelm run db-master security Run a full security audit /managelm run lb-01 services Restart nginx
The run command works exactly like submitting a task from Claude or the portal UI — it sends the instruction to the agent, waits for the result, and posts it back to the channel.
When a ManageLM webhook event fires, the plugin posts a rich Block Kit message to the configured Slack channel:
| Event | Notification |
|---|---|
agent.enrolled | Enrollment request with an Approve button |
agent.approved | Confirmation that the agent is now managed |
agent.online | Agent connected to the portal |
agent.offline | Agent disconnected (routed to alerts channel) |
task.completed | Task summary with a View Details button |
task.failed | Error message with a View Details button (routed to alerts) |
Route critical events to a dedicated alerts channel and informational events elsewhere:
SLACK_CHANNEL_ALERTS=C0123456789 # receives: agent.offline, task.failed SLACK_CHANNEL_INFO=C9876543210 # receives: all other events
If neither variable is set, events are posted to the bot's default conversation channel. Make sure to invite the bot to the target channels.
Finding channel IDs: Right-click a channel in Slack > View channel details > scroll to the bottom to find the Channel ID (starts with C).
| Variable | Required | Description |
|---|---|---|
SLACK_BOT_TOKEN | Yes | Bot OAuth token (xoxb-...) |
SLACK_SIGNING_SECRET | Yes | Slack app signing secret |
SLACK_APP_TOKEN | No | App-level token for Socket Mode (xapp-...) |
MANAGELM_PORTAL_URL | Yes | ManageLM portal URL |
MANAGELM_API_KEY | Yes | ManageLM API key (mlm_ak_...) |
MANAGELM_WEBHOOK_SECRET | No | HMAC secret for webhook verification |
MANAGELM_PORTAL_PUBLIC_URL | No | Public URL for "View in Portal" links |
PORT | No | Bolt app port (default: 3100, webhook on PORT+1) |
SLACK_CHANNEL_ALERTS | No | Channel ID for alert events |
SLACK_CHANNEL_INFO | No | Channel ID for informational events |
crypto.timingSafeEqual to verify signatures, preventing timing attacks.Slack cannot reach your plugin. Verify your Request URL in the Slack app settings points to https://<your-host>:3100/slack/events and the plugin is running. For local development, use Socket Mode instead.
SLACK_CHANNEL_ALERTS or SLACK_CHANNEL_INFO is set and the bot is invited to those channels[webhook] Received event: messagesMANAGELM_WEBHOOK_SECRETThe MANAGELM_WEBHOOK_SECRET in your .env does not match the secret configured on the webhook in the portal. Update one to match the other.
The hostname you typed doesn't match any agent. The plugin searches by partial match on both hostname and display_name. Use /managelm status to see exact names.
The task took longer than the portal's timeout (default 5 minutes). This can happen with large operations. Check the task status in the portal — the task may still complete on the agent.