# 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:

1. **mrkdwn**: Slack's version of Markdown for text formatting
2. **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:**

1. **`formatter.go`**: Main formatting logic and Block Kit generation
2. **`detector.go`**: Format detection and automatic conversion
3. **`formatter_test.go`**: Comprehensive test suite

**Key Functions:**

```go
// 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:

<table><thead><tr><th>Feature</th><th>Standard Markdown Syntax</th><th>Slack Syntax / Notes</th><th>Support</th></tr></thead><tbody><tr><td>Headings</td><td><code># Heading 1</code> <code>## Heading 2</code></td><td>Not supported in messages (Block Kit headers exist but not via <code>#</code>)</td><td>No</td></tr><tr><td>Paragraphs</td><td>Blank line separates paragraphs</td><td>No explicit paragraph syntax – use a blank line or Shift+Enter</td><td>No</td></tr><tr><td>Line breaks</td><td>Two spaces at end + </td><td>Shift+Enter (literal  not parsed in message UI)</td><td>No</td></tr><tr><td>Bold</td><td><code>**bold**</code></td><td><code>*bold*</code> (asterisks) - ✅ <strong>Auto-converted</strong></td><td>Yes</td></tr><tr><td>Italic</td><td><code>*italic*</code> or <code>_italic_</code></td><td><code>_italic_</code> (underscores only) - ✅ <strong>Auto-converted</strong></td><td>Partial</td></tr><tr><td>Strikethrough</td><td><code>~~strike~~</code></td><td><code>~strike~</code> - ✅ <strong>Auto-converted</strong></td><td>Partial</td></tr><tr><td>Blockquote</td><td><code>> quote</code></td><td><code>> quote</code></td><td>Yes</td></tr><tr><td>Ordered list</td><td><code>1. item</code></td><td><code>1. item</code></td><td>Yes</td></tr><tr><td>Unordered list</td><td><code>- item</code> or <code>* item</code></td><td><code>• item</code> or <code>- item</code> (bullets rendered automatically)</td><td>Yes</td></tr><tr><td>Inline code</td><td><code>`code`</code></td><td><code>`code`</code></td><td>Yes</td></tr><tr><td>Fenced code block</td><td><pre><code>code
</code></pre></td><td><code>code</code></td><td>Yes</td></tr><tr><td>Horizontal rule</td><td><code>---</code></td><td>Not supported</td><td>No</td></tr><tr><td>Links</td><td><code>[text](http://example.com)</code></td><td>`&#x3C;http://example.com</td><td>text>` - ✅ <strong>Auto-converted</strong></td></tr><tr><td>Images</td><td><code>![alt](http://img.png)</code></td><td>Not via Markdown – upload or drag-and-drop</td><td>No</td></tr><tr><td>Tables</td><td>`</td><td>col1 | col2</td><td>`</td></tr><tr><td>Definition lists</td><td><code>Term : Definition</code></td><td>Not supported</td><td>No</td></tr><tr><td>Footnotes</td><td><code>[^1]</code></td><td>Not supported</td><td>No</td></tr><tr><td>Task lists</td><td><code>- [ ] item</code></td><td>Not supported</td><td>No</td></tr><tr><td>HTML</td><td><code>&#x3C;br></code>, <code>&#x3C;em></code></td><td>Not supported</td><td>No</td></tr><tr><td>Emoji</td><td><code>:smile:</code> or Unicode 😄</td><td><code>:smile:</code> (auto-converted) or paste Unicode</td><td>Yes</td></tr><tr><td>Automatic URL linking</td><td><code>&#x3C;http://example.com></code></td><td>Paste URL – auto-linked</td><td>Yes</td></tr><tr><td>Disable auto-link</td><td>`&#x3C;http://example.com</td><td>http://...>`</td><td>Use <code>&#x3C;</code> `</td></tr><tr><td>Quoted Strings</td><td><code>"quoted text"</code></td><td>✅ <strong>Auto-converted to</strong> <code>`quoted text`</code></td><td>Yes</td></tr></tbody></table>

## Detailed mrkdwn Rules

### 1. General Markdown (`mrkdwn`) Rules

* Escape literal `&`, `<`, and `>` as `&amp;`, `&lt;`, `&gt;`.
* 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:alice@example.com|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:

```json
{
  "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 titles
* **Section**: `"type": "section"` - Main content with text and fields
* **Divider**: `"type": "divider"` - Visual separator
* **Actions**: `"type": "actions"` - Interactive buttons and elements
* **Context**: `"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?"\
\&#xNAN;*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."\
\&#xNAN;*Your response:*

```json
{
  "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."\
\&#xNAN;*Your response:*

```json
{
  "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:

```go
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:

```go
// Example from internal/slack/client.go
msgOptions := formatter.FormatMessage(response, formatter.FormatOptions{
    Format:     formatter.TextFormat,
    ThreadTS:   threadTS,
    EscapeText: false,
})
```

## 📊 Features Supported

| Feature              | Status | Description                            |
| -------------------- | ------ | -------------------------------------- |
| 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

1. **Always provide fallback text** for Block Kit messages
2. **Use mrkdwn for simple responses**, Block Kit for complex ones
3. **Keep field counts under 10** per section for optimal display
4. **Use emojis strategically** to convey status and improve readability
5. **Test interactive elements** like buttons and links
6. **Escape special characters** properly in mrkdwn
7. **Use headers** to organize complex information
8. **Provide clear visual hierarchy** with appropriate block types
9. **Use structured data** for tabular information that auto-converts to Block Kit
10. **Include fallback text** for accessibility and notification compatibility

## Troubleshooting

### Common Issues

1. **Text not formatting**: Check for proper escape sequences and syntax
2. **Block Kit validation errors**: Ensure JSON structure is correct and within Slack limits
3. **Links not working**: Verify URL format and accessibility
4. **Interactive elements failing**: Check button configurations and URLs
5. **Markdown not rendering**: Verify proper escape sequences and check for conflicting formatting

### Debug Mode

Enable debug logging to see formatting decisions:

```bash
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](https://api.slack.com/block-kit)
* **Slack mrkdwn**: [Slack Formatting Reference](https://api.slack.com/reference/surfaces/formatting)

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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tuannvm.com/slack-mcp-client/docs/format.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
