Incident communication is where Slack MCP either proves itself or embarrasses you in front of the whole company — there's no lower-stakes practice ground, because everything happens in #incidents with everyone watching. This topic assembles the tools and prompt patterns from earlier lessons into one end-to-end workflow: opening a structured incident thread, posting live progress updates as the fix advances, and closing it out with a summary and action items that actually get followed up on.
This assumes an MCP setup like the one from the first topic — bot token auth, SLACK_CHANNEL_IDS scoped to your incidents channel, slack_post_message on manual approval — combined with a second MCP server (GitHub, Datadog, or whatever tracks your deploys and alerts) so the agent isn't relying on Slack alone for ground truth.
Workflow Overview: From Detection to Stakeholder Communication
The shape of a well-run incident, communication-wise, is consistent regardless of what actually broke: someone (or something) detects it, a thread opens with enough context that a second responder doesn't have to ask "wait, what's going on," progress gets posted at a predictable cadence so people stop DMing "any update?", and it closes with a summary that becomes the seed of the postmortem instead of a separate document written from scratch two days later.
Detection --> Open incident thread (structured context)
--> Investigate (agent pulls logs/metrics via other MCP servers)
--> Post progress updates at fixed intervals or on state change
--> Fix deployed --> Verify --> Post resolution
--> Generate closing summary + action items
--> (separately) Feed summary into postmortem doc
The agent's job spans the middle three stages well and the first and last stages only partially — opening a thread and generating a summary are good agent tasks; deciding an incident is over is a human call that should never be automated, because the cost of declaring victory too early (a flapping issue that looks fixed for ten minutes) is much higher than the cost of a slightly delayed all-clear.
Set this expectation explicitly in whatever system prompt or CLAUDE.md/rules file governs the workflow:
## Incident communication rules
- The agent may open incident threads and post progress updates.
- The agent must NOT post a resolution/all-clear message without an
explicit human instruction to do so, even if metrics look recovered.
- Every post must be reviewed before sending during business-hours
incidents; auto-post is only acceptable for structured status
updates with no free-text judgment calls (e.g., "still investigating").
Tips
- Never let the agent auto-post the "resolved" message — declaring an incident over is a human judgment call with asymmetric downside if it's premature.
- Keep a second MCP server (monitoring, CI) in the loop so incident communication is grounded in actual system state, not just what people typed in Slack.
- Write the automation boundary down explicitly in a rules file rather than trusting it to come up correctly in an ad-hoc prompt during a live incident, when nobody has time to phrase things carefully.
Step 1: Opening an Incident Thread with Structured Context
The opening message sets the tone for the entire incident — a vague "something's wrong with checkout" produces ten confused replies; a structured post with severity, impact, and current status produces people jumping straight to helping.
Open an incident thread in #incidents. Severity is SEV-2 (checkout
degraded, not fully down). Pull the last 3 alerts from Datadog for
the checkout-service monitor and include the p99 latency figure.
Include: what's affected, since when, who's the current owner
(that's me), and a link to the Datadog dashboard.
Resulting Block Kit payload, structured so a scanning responder gets the critical facts in the first two seconds:
{
"channel": "C0567INCIDENT",
"blocks": [
{
"type": "header",
"text": { "type": "plain_text", "text": "🔴 SEV-2: Checkout degraded" }
},
{
"type": "section",
"fields": [
{ "type": "mrkdwn", "text": "*Started:*\n14:02 UTC" },
{ "type": "mrkdwn", "text": "*Owner:*\n<@U0456DEF>" },
{ "type": "mrkdwn", "text": "*Impact:*\nCheckout p99 latency 2.1s (baseline 300ms)" },
{ "type": "mrkdwn", "text": "*Status:*\nInvestigating" }
]
},
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "<https://app.datadoghq.com/dashboard/abc-123|Datadog dashboard> · Alert fired 3x in last 10 min" }
]
}
]
}
Note the emoji here (🔴) is doing real signaling work, not decoration — a consistent severity-to-emoji mapping (🔴 SEV-1/2, 🟡 SEV-3, ✅ resolved) lets people scanning a busy #incidents channel triage by eye without reading every message. Define this mapping once, in the same rules file as the automation boundary, so it's consistent across every incident regardless of who or what opened the thread.
Immediately after opening, pin the thread's parent message — Slack pinning isn't exposed as a tool in the reference MCP server, so this is a manual step or requires a server with pins.add wrapped. Flag this explicitly in your prompt so the agent doesn't silently skip it or, worse, claim it pinned something it can't:
After posting, tell me you can't pin the message (pins.add isn't
available) so I can do it manually — don't skip mentioning this.
Tips
- Standardize a severity-to-emoji mapping across every incident so responders can triage a busy channel by eye, and keep it consistent regardless of who opened the thread.
- Pull hard numbers (p99 latency, alert count) from a monitoring MCP server into the opening message — "checkout is degraded" without a number invites five people asking "how degraded?"
- Have the agent explicitly flag capabilities it doesn't have (like pinning) rather than silently omitting the step or claiming success it can't verify.
Step 2: Posting Progress Updates Automatically as the Fix Advances
Progress updates are where a badly designed automation becomes actively harmful — too frequent, and the thread turns into noise that buries the signal; too infrequent, and people start DMing "any update?" which is exactly the interruption you were trying to prevent.
A workable cadence rule: post on state change, not on a fixed timer. "Still investigating, no new information" is not worth a message; "narrowed it to the connection pool" is.
Every time you learn something new about root cause or take an action
(ran a query, restarted a service, deployed a fix), post a one-line
update to the incident thread (thread_ts from the opening message).
Do not post "still investigating" with no new information — silence
is fine, a scheduled check-in every 15 minutes is not required.
A representative sequence, each posted as a threaded reply so the channel itself stays uncluttered while the full detail lives in the thread:
{ "channel": "C0567INCIDENT", "thread_ts": "1700000122.000100",
"text": "Pool stats show 20/20 connections held >30s. Checking for a long-running query." }
{ "channel": "C0567INCIDENT", "thread_ts": "1700000122.000100",
"text": "Found it: migration left a lock on the orders table. Killing the blocking query now." }
{ "channel": "C0567INCIDENT", "thread_ts": "1700000122.000100",
"text": "Lock cleared, pool draining. Watching p99 for the next 5 minutes before calling it." }
For longer incidents (an hour or more), it's worth having the agent also update the parent message's status field periodically — not just the thread — since a new person joining the channel reads the parent message first and shouldn't have to scroll a 40-reply thread to learn the current state:
Every time the status changes (investigating -> identified -> fix
deployed -> monitoring -> resolved), update the parent message's
Status field to match. Use chat.update via slack_post_message's
underlying API if the tool supports edits, otherwise post a
"STATUS UPDATE" reply and tell me the parent needs a manual edit.
That fallback instruction matters because the reference MCP server's slack_post_message tool wraps chat.postMessage, not chat.update — it can't edit an existing message, only post new ones. If your workflow genuinely needs message editing (updating that status field in place), you need a server that wraps chat.update explicitly, or accept the workaround of a fresh reply plus a manual edit.
Tips
- Post on state change, not on a timer — "no new information" updates train people to stop reading the channel, which defeats the purpose.
- Keep detailed progress in the thread and update the parent message's summary/status field periodically so someone joining late doesn't have to read the whole thread.
- Know that the reference server can only post new messages, not edit existing ones — plan your status-field-update workflow around that constraint or pick a server that wrapschat.update.
Step 3: Generating the Closing Summary and Follow-Up Action Items
Once a human has confirmed the incident is actually resolved (see the hard rule from Step 1), the agent's job shifts to producing a closing summary that's good enough to seed the postmortem without a rewrite.
The incident is confirmed resolved. Fetch the full thread with
slack_get_thread_replies. Write a closing summary:
- Timeline: detection, root cause found, fix deployed, verified stable
(pull exact timestamps from the messages)
- Root cause: one paragraph, plain language
- Impact: duration, what was affected, rough scope if mentioned
(e.g., "affected ~12% of checkout attempts")
- Action items: anything mentioned in the thread as a follow-up
("we should add an alert for pool exhaustion before it hits 100%"),
with an owner if one was volunteered, otherwise mark "owner: TBD"
Post this to the thread, and separately format it as a copy-pasteable
block for the postmortem doc.
The resolution post itself, kept short since the detail lives in the summary that follows:
{
"channel": "C0567INCIDENT",
"thread_ts": "1700000122.000100",
"text": "✅ Resolved. p99 latency back to 280ms, stable for 15 min. Full summary and action items below."
}
And the closing summary, structured so it drops into a postmortem template with minimal editing:
{
"channel": "C0567INCIDENT",
"thread_ts": "1700000122.000100",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Incident summary*\n*Duration:* 14:02–14:47 UTC (45 min)\n*Impact:* Checkout latency degraded (p99 2.1s vs 300ms baseline), no full outage\n*Root cause:* A schema migration left a long-running lock on the orders table, exhausting the DB connection pool"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Action items:*\n1. Add an alert at 80% pool utilization, not just 100% — owner: TBD\n2. Add a migration checklist step: verify no long-running locks before merging — owner: <@U0456DEF>\n3. Document the kill-query runbook step used here — owner: TBD"
}
}
]
}
The "owner: TBD" entries are worth surfacing loudly rather than silently leaving blank — an action item with no owner reliably never gets done. A useful closing habit: have the agent also draft (not send) a follow-up reminder message scheduled for a week later, asking about the TBD items, even if you're the one who has to actually schedule and send it since MCP Slack tooling has no native delay/schedule primitive:
Also draft a one-week-later follow-up message checking on the TBD
action items. I'll schedule it myself using Slack's native
"schedule message" feature since the MCP tool can't do that.
That last constraint is real and worth remembering as a pattern across this whole module: Slack's native client has scheduling, reminders, and message editing built into its UI that the MCP tool surface generally does not expose. Treat MCP as covering the "act now" half of Slack's feature set, and lean on the native client's UI for anything that needs to happen later or needs to be edited in place.
Tips
- Surface unowned action items explicitly ("owner: TBD") rather than letting them blend into the list — an unowned item is the single most predictable way a postmortem's lessons don't stick.
- Format the closing summary as a drop-in postmortem block from the start; writing it twice (once for Slack, once for the doc) is where good root-cause detail gets lost to time pressure.
- Remember MCP Slack tooling generally can't schedule, remind, or edit — plan those steps as manual follow-ups through Slack's native UI rather than assuming the agent can do it for you.
Tips
Tips
- Keep the human-in-the-loop boundary absolute for declaring resolution — automate detection-to-investigation and progress-posting, never the all-clear call.
- Design update cadence around state change, not a timer, and keep detailed back-and-forth in the thread while the parent message carries a scannable current-status summary.
- Build the closing summary as a reusable postmortem seed from the start, and treat scheduling/editing/reminders as manual steps the native Slack client handles, since the MCP tool surface generally doesn't cover them.