Slack Message Formatter
A Claude Code skill that formats messages for Slack with pixel-perfect accuracy. Converts standard Markdown to Slack-compatible output with two delivery paths:
- Copy-paste — Rich HTML that preserves formatting when pasted into Slack's compose box
- API/Webhook — Slack mrkdwn syntax for bots, automation, and CI/CD
Why?
- Slack uses mrkdwn (not Markdown).
**bold** doesn't work — you need *bold*.
- Existing tools handle conversion well, but none combine generation + preview + copy-paste in one workflow.
- Programmatic clipboard doesn't preserve tables in Slack. Manual browser copy does.
- This skill gives you both paths: copy-paste for humans, webhook for bots.
Zero dependencies. 172+ tests. Built for Claude Code.

Install
Claude Code (recommended)
claude plugin marketplace add karanb192/slack-message-formatter
claude plugin install slack-message-formatter@slack-message-formatter
Codex
curl -sSL https://raw.githubusercontent.com/karanb192/slack-message-formatter/main/install.sh | bash -s codex
Manual install (curl)
# Claude Code global
curl -sSL https://raw.githubusercontent.com/karanb192/slack-message-formatter/main/install.sh | bash
# Codex global
curl -sSL https://raw.githubusercontent.com/karanb192/slack-message-formatter/main/install.sh | bash -s codex
# Current project only (auto-detects Claude Code or Codex)
curl -sSL https://raw.githubusercontent.com/karanb192/slack-message-formatter/main/install.sh | bash -s project
Updating
The marketplace tracks the main branch of this repo. Claude Code auto-updates marketplace plugins at startup, so most users will pick up changes on their next restart.
To refresh immediately without restarting:
/plugin marketplace update slack-message-formatter
/reload-plugins
Uninstall
# Claude Code
rm -rf ~/.claude/skills/slack-message-formatter
# Codex
rm -rf "${CODEX_HOME:-$HOME/.codex}/skills/slack-message-formatter"
Then in Claude Code, just ask:
- "Write a Slack message announcing our v2.5 release"
- "Format this for Slack"
/slack-message-formatter
Standalone CLI
echo '**bold** and *italic*' | node src/run.mjs html
# → <b>bold</b> and <i>italic</i>
echo '**bold** and *italic*' | node src/run.mjs mrkdwn
# → *bold* and _italic_
echo '## Announcement' | node src/run.mjs preview
# → Opens browser with Slack-themed preview + copy page
Features
Copy-Paste Path (Rich HTML)
- Opens a clean HTML page in your browser
Cmd+A, Cmd+C, then Cmd+V in Slack
- Preserves: bold, italic, strikethrough, links, lists, nested lists, code blocks, blockquotes, headings, task lists, tables (as code blocks), horizontal rules
API/Webhook Path (mrkdwn)
Conversion Reference
| Markdown | Slack mrkdwn | HTML (paste) |
|---|
**bold** | *bold* | <b>bold</b> |
*italic* | _italic_ | <i>italic</i> |
~~strike~~ | ~strike~ | <s>strike</s> |
`code` | `code` | <code>code</code> |
[text](url) | <url|text> | <a href="url">text</a> |
# Heading | *Heading* | <b>Heading</b> |
- [x] Done | :white_check_mark: Done | ✅ Done |
- [ ] Todo | :black_square_button: Todo | ⬜ Todo |
| Tables | Code block | Code block |
--- | ━━━━━━━━━━ | <hr> |
:tada: | :tada: (Slack renders) | 🎉 (Unicode) |
Commands
| Command | What it does |
|---|
preview | Opens browser with copy page + dark preview |
send | Sends via Slack webhook (mrkdwn) |
html | Outputs raw HTML to stdout |
mrkdwn | Outputs raw mrkdwn to stdout |
Configuration
| Env Variable | Default | Description |
|---|
SLACK_FORMATTER_PREVIEW_DIR | /tmp/slack-formatter | Directory for preview HTML files |
CCH_SLA_WEBHOOK | (none) | Slack webhook URL for send command |
How It Works
Markdown → Parser → Dual Renderer
├── Rich HTML → Browser → Cmd+C → Slack paste
└── mrkdwn → Webhook → Slack API
- You write Markdown (or Claude generates it)
- The converter transforms it deterministically — same input always produces same output
- Two outputs: Rich HTML for copy-paste, mrkdwn for API
Tables are rendered as aligned code blocks because Slack's paste handler breaks HTML <table> tags when mixed with other rich content.
Key Discovery: Slack Paste Limitations
Through extensive testing, we discovered: