Slack Formatting Guide
This comprehensive guide explains how to format messages for Slack using both mrkdwn
(Markdown) and Block Kit structures, and documents the fully implemented Slack formatting features in the Slack MCP Client.
Overview
The Slack MCP Client includes a comprehensive message formatting system that supports two main approaches:
mrkdwn: Slack's version of Markdown for text formatting
Block Kit: Rich, interactive message layouts with JSON structure
The client automatically handles format conversion and detection, providing rich, interactive messages in Slack with full production-ready implementation.
✅ Implementation Status
The Slack formatting system is fully implemented and production-ready with the following features:
Automatic Format Detection
The client automatically detects and handles multiple message formats:
✅ Plain Text: Simple text messages with proper escaping
✅ Markdown Text: Messages with Markdown formatting (bold, italic, code blocks, etc.)
✅ JSON Block Kit: Messages in Block Kit JSON format
✅ Structured Data: Messages with key-value pairs automatically converted to Block Kit format
Current Implementation Architecture
The formatter is implemented in internal/slack/formatter/
with these components:
Core Files:
formatter.go
: Main formatting logic and Block Kit generationdetector.go
: Format detection and automatic conversionformatter_test.go
: Comprehensive test suite
Key Functions:
// FormatMessage - Main entry point for message formatting
func FormatMessage(text string, options FormatOptions) []slack.MsgOption
// CreateBlockMessage - Generate Block Kit messages programmatically
func CreateBlockMessage(text string, blockOptions BlockOptions) string
// FormatMarkdown - Convert standard Markdown to Slack mrkdwn
func FormatMarkdown(text string) string
// ConvertQuotedStringsToCode - Auto-convert quoted strings
func ConvertQuotedStringsToCode(text string) string
Markdown to Slack Mapping Reference
Below is a comprehensive table mapping common Markdown elements to their Slack equivalents:
Headings
# Heading 1
## Heading 2
Not supported in messages (Block Kit headers exist but not via #
)
No
Paragraphs
Blank line separates paragraphs
No explicit paragraph syntax – use a blank line or Shift+Enter
No
Line breaks
Two spaces at end +
Shift+Enter (literal not parsed in message UI)
No
Bold
**bold**
*bold*
(asterisks) - ✅ Auto-converted
Yes
Italic
*italic*
or _italic_
_italic_
(underscores only) - ✅ Auto-converted
Partial
Strikethrough
~~strike~~
~strike~
- ✅ Auto-converted
Partial
Blockquote
> quote
> quote
Yes
Ordered list
1. item
1. item
Yes
Unordered list
- item
or * item
• item
or - item
(bullets rendered automatically)
Yes
Inline code
`code`
`code`
Yes
Fenced code block
code
code
Yes
Horizontal rule
---
Not supported
No
Links
[text](http://example.com)
`<http://example.com
text>` - ✅ Auto-converted
Images

Not via Markdown – upload or drag-and-drop
No
Tables
`
col1 | col2
`
Definition lists
Term : Definition
Not supported
No
Footnotes
[^1]
Not supported
No
Task lists
- [ ] item
Not supported
No
HTML
<br>
, <em>
Not supported
No
Emoji
:smile:
or Unicode 😄
:smile:
(auto-converted) or paste Unicode
Yes
Automatic URL linking
<http://example.com>
Paste URL – auto-linked
Yes
Disable auto-link
`<http://example.com
http://...>`
Use <
`
Quoted Strings
"quoted text"
✅ Auto-converted to `quoted text`
Yes
Detailed mrkdwn Rules
1. General Markdown (mrkdwn
) Rules
mrkdwn
) RulesEscape literal
&
,<
, and>
as&
,<
,>
.Italic:
_italic text_
Bold:
*bold text*
Strikethrough:
~struck text~
Block quote (one or more lines):
> This is a quote. > Still quoted.
Inline code:
`code snippet`
Code block:
``` multiple lines of code ```
Bulleted list (use actual bullet character):
• Item one • Item two
Numbered list (manual numbering):
1. First 2. Second
Line breaks: insert where you want a new line.
2. Links, Mentions & Emoji
Automatic URL links: paste
http://example.com
.Manual links:
<http://example.com|Link Text>
User mention:
<@U12345678>
Channel mention:
<#C12345678|general>
Email link:
<mailto:[email protected]|Email Alice>
Emoji: include Unicode emoji (e.g. 😄) or colon syntax
:smile:
.
3. Special Parsing
Date formatting:
<!date^1622559600^{date_short} at {time}|Jun 1 2021 at 12:00 PM UTC>
Special mentions:
<!here>
,<!channel>
,<!everyone>
.
4. ✅ Automatic Quoted String Conversion
The formatter automatically converts double-quoted strings to inline code blocks for better visualization:
Input:
All of these were created on "2020-11-17T05:07:52Z" or "2020-11-17T05:07:54Z".
Among them, "kube-node-lease", "kube-public", and "kube-system" share the exact
same creation timestamp: "2020-11-17T05:07:52Z".
Output:
All of these were created on `2020-11-17T05:07:52Z` or `2020-11-17T05:07:54Z`.
Among them, `kube-node-lease`, `kube-public`, and `kube-system` share the exact
same creation timestamp: `2020-11-17T05:07:52Z`.
Block Kit Layouts
When to Use Block Kit
Use Block Kit layouts for complex responses that need:
Rich visual structure with headers, sections, and fields
Interactive elements like buttons
Organized data presentation
Multiple content types in one message
Block Kit Structure
Return a JSON payload with both a fallback text
and a blocks
array:
{
"text": "Summary: Job completed",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Job Status"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Result:*\nSuccess"
},
{
"type": "mrkdwn",
"text": "*Duration:*\n5m 32s"
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "View logs: <http://logs.example.com|Open Logs>"
}
}
]
}
Common Block Types
Header:
"type": "header"
- Large, prominent titlesSection:
"type": "section"
- Main content with text and fieldsDivider:
"type": "divider"
- Visual separatorActions:
"type": "actions"
- Interactive buttons and elementsContext:
"type": "context"
- Subtle contextual information
✅ Structured Data Auto-Conversion
The client automatically converts structured data to Block Kit format:
Input:
Status: Success
Duration: 5m 32s
Result: Passed
Output: Automatically formatted as a Block Kit message with fields.
Practical Examples
Example 1: Simple mrkdwn Response
User asks: "What's the server status?" Your response:
*Server Status* ✅
• CPU: 45% usage
• Memory: 60% usage
• Disk: 30% usage
• Last restart: <!date^1622559600^{date_short} at {time}|Jun 1 2021 at 12:00 PM UTC>
All systems operational!
Example 2: Block Kit Response
User asks: "Show me the latest build results." Your response:
{
"text": "Latest build results: Passed",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Build #123* _passed_ 🎉\n• Duration: 4m 12s\n• Triggered by: <@U23456789>"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Details"
},
"url": "http://ci.example.com/build/123"
}
]
}
]
}
Example 3: Structured Data
User asks: "List the database connections." Your response:
{
"text": "Database Connections",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Database Connections"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Primary DB:*\n✅ Connected"
},
{
"type": "mrkdwn",
"text": "*Replica DB:*\n✅ Connected"
},
{
"type": "mrkdwn",
"text": "*Cache DB:*\n⚠️ Degraded"
},
{
"type": "mrkdwn",
"text": "*Analytics DB:*\n❌ Disconnected"
}
]
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "Last checked: <!date^1622559600^{time}|12:00 PM>"
}
]
}
]
}
🔧 Configuration
The formatter supports various configuration options:
type FormatOptions struct {
Format MessageFormat // TextFormat or BlockFormat
ThreadTS string // For threading messages
EscapeText bool // Whether to escape special characters
}
type BlockOptions struct {
HeaderText string // Header text for Block Kit messages
Fields []Field // Key-value fields
Actions []Action // Action buttons
}
Usage in Slack Client
The Slack client automatically uses the formatter:
// Example from internal/slack/client.go
msgOptions := formatter.FormatMessage(response, formatter.FormatOptions{
Format: formatter.TextFormat,
ThreadTS: threadTS,
EscapeText: false,
})
📊 Features Supported
Text Formatting
✅
Bold, italic, strikethrough, code
Code Blocks
✅
Syntax highlighting support
Lists
✅
Bullet and numbered lists
Links
✅
Automatic URL detection and formatting
Block Kit
✅
Headers, sections, fields, actions
Auto-Detection
✅
Automatic format detection
Quoted Strings
✅
Auto-conversion to code blocks
Structured Data
✅
Auto-conversion to Block Kit
Interactive Elements
✅
Buttons and interactive components
Field Truncation
✅
Automatic handling of Slack limits
Best Practices
Always provide fallback text for Block Kit messages
Use mrkdwn for simple responses, Block Kit for complex ones
Keep field counts under 10 per section for optimal display
Use emojis strategically to convey status and improve readability
Test interactive elements like buttons and links
Escape special characters properly in mrkdwn
Use headers to organize complex information
Provide clear visual hierarchy with appropriate block types
Use structured data for tabular information that auto-converts to Block Kit
Include fallback text for accessibility and notification compatibility
Troubleshooting
Common Issues
Text not formatting: Check for proper escape sequences and syntax
Block Kit validation errors: Ensure JSON structure is correct and within Slack limits
Links not working: Verify URL format and accessibility
Interactive elements failing: Check button configurations and URLs
Markdown not rendering: Verify proper escape sequences and check for conflicting formatting
Debug Mode
Enable debug logging to see formatting decisions:
LOG_LEVEL=debug ./slack-mcp-client
Testing
Test your formatting by:
Sending test messages to a development Slack workspace
Using Slack's Block Kit Builder for complex layouts
Validating JSON structure before sending
Checking message rendering on different devices
📚 Reference
Implementation:
internal/slack/formatter/
Tests:
internal/slack/formatter/formatter_test.go
Slack Block Kit: Official Block Kit Documentation
Slack mrkdwn: Slack Formatting Reference
The Slack formatting system is production-ready and handles all common use cases for rich message formatting in Slack, whether using simple mrkdwn or rich Block Kit layouts.
Last updated
Was this helpful?