Markdown for agents
Most model output needs no new syntax. slackmark accepts CommonMark and GFM (tables, task lists, strikethrough, and autolinks), plus footnotes and GitHub-style admonitions. It adds Slack-aware behavior on top: raw Slack entity tokens become native rich text elements, and supported Mermaid charts can become native visualizations.
Let the model write naturally and convert the output verbatim. The supported markdown reference has the complete matrix.
A typical agent answer
## Incident summary Root cause was a stale cache key in `billing-api`. Paging <!here>, details below. | Service | Errors | Status | | --- | ---: | --- | | billing-api | 412 | degraded | | checkout | 3 | ok | - [x] Cache key rotated - [ ] Postmortem scheduled > [!WARNING] > Retries are still elevated in `us-east-1`.
Block Kit JSON
…
Everything above is familiar GitHub-style Markdown plus one Slack token
(<!here>). With the default capability profile it becomes a header block, a
table block, a checkbox list, a styled warning quote, and an @here broadcast
element. Content that cannot use its preferred form falls back to the closest
supported form, reported in result.degradations. See
Validating output for the pattern
and known gaps.
What each construct becomes
| Your model writes | Slack renders |
|---|---|
# H1 … #### H4 | Native header block |
##### H5, ###### H6 | Bold rich text (Slack headers stop at level 4) |
Paragraphs, **bold**, *em*, ~~strike~~, `code` | Rich text with native styling |
[label](https://…) | Native link |
<@U…>, <#C…>, <!here>, :emoji: | Real mentions, channel links, broadcasts, emoji (details) |
| Bullet / numbered lists (nested) | Native rich text lists with indentation |
- [x] task lists | Checkbox list (markdown block) |
| GFM tables | Native table or data_table by size (details) |
| Code fences with a language tag | Configured image renderer, otherwise native code block with syntax highlighting |
mermaid pie / xychart fences | Native data_visualization charts (details) |
> quote and > [!NOTE] admonitions | Rich text quote, admonitions with emoji + bold title |
 | Native image block (public http(s) png/jpg/gif) |
--- | divider block |
Footnotes [^1] | Numbered markers with a trailing context block |
<details><summary> HTML | Collapsible container block (title and body as plain text) |
$…$ / $$…$$ math (opt-in) | Inline code-styled text; display math uses a configured renderer or preformatted fallback |
Prompting tips
You rarely need a long Markdown grammar in your system prompt. Two focused additions pay off:
- Mentions. If the model may notify people, give it only the user and channel IDs it is allowed to use, explain the raw token forms, and validate broadcast tokens before posting. IDs must come from trusted application context (for example, the incoming event); slackmark converts tokens but does not verify that the target exists or that a notification is authorized.
- Charts. Mention that
mermaidpieandxychart-betafences render as native charts. A Node bot can also rasterize flowcharts and display math as uploaded images.
Ask models to avoid raw block HTML: tags may be stripped. A diagram or display formula without a matching renderer degrades to readable text.
Long answers
A Slack message holds at most 50 blocks. By default convert() truncates
overflowing content; convertToMessages() with { overflow: "split" } turns
long answers into multiple messages instead. See
Long content and splitting.