Slack MCP: bot messages using legacy attachments return empty body
Summary
When reading Slack messages that use legacy attachments (the attachments[] format — visually rendered with a left colored border in Slack), both slack_search_public_and_private and slack_read_channel return an empty message body. The text field on these messages is empty at the API level; the actual content lives in attachments[].text or attachments[].fallback.
Steps to reproduce
- Find a Slack channel where an alert bot posts using legacy attachments (e.g. Grafana Alertmanager, PagerDuty, or a custom webhook that uses
attachments[]). - Call
slack_search_public_and_privateorslack_read_channeltargeting that channel/message. - Observe:
Text:field in the result is empty even though the message has visible content in the Slack UI.
Expected behavior
The MCP should surface attachments[].text and/or attachments[].fallback when message.text is empty, so alert content is readable without leaving the conversation.
Actual behavior
Text: is empty. Example (from slack_read_channel on a real alert message):
=== Message from (B0B514SM4RH) at 2026-06-10 20:39:00 CEST ===
Message TS: 1781116740.740189
The same message in the Slack UI shows:
[FIRING:1] OmsViewVsVenueDivergenceHigh
Service: trading | Severity: critical | Namespace: state | Pod: reconciler-7b96f77758-rssmd
nadex OMS view diverges from venue by 338 orders
...
Suggested fix
When message.text is empty (or blank), also extract and include:
attachments[].textattachments[].fallback(plain-text fallback, always present for legacy attachments)- Optionally
attachments[].pretext
fallback is the minimum viable fix — it is a required plain-text field in the Slack legacy attachment spec, designed precisely for clients that cannot render rich content.
Impact
Alert/monitoring bots (Grafana, PagerDuty, custom Alertmanager webhooks) almost universally use legacy attachments. This makes the Slack MCP unable to surface any production alert content, forcing users to fall back to CloudWatch or open Slack manually.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗