Skip to main content
Glama
piekstra

Slack MCP Server

by piekstra

send_formatted_message

Send structured messages to Slack channels using Block Kit formatting. Include headers, text, fields, and context, or reply within threads for organized communication.

Instructions

Send a formatted message using Block Kit with common elements.

Args: channel: Channel ID or name title: Header text (optional) text: Main message text (optional) fields: Comma-separated fields for side-by-side display (optional) context: Context text at bottom (optional) thread_ts: Thread timestamp for replies (optional)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
channelYes
contextNo
fieldsNo
textNo
thread_tsNo
titleNo

Implementation Reference

  • The primary handler for the 'send_formatted_message' MCP tool. It is decorated with @mcp.tool() for registration, constructs Block Kit blocks conditionally based on input parameters, and sends the formatted message to Slack via SlackClient.send_message. Includes input validation, error handling, and JSON response formatting. The function signature and docstring define the input schema.
    @mcp.tool() async def send_formatted_message( channel: str, title: Optional[str] = None, text: Optional[str] = None, fields: Optional[str] = None, context: Optional[str] = None, thread_ts: Optional[str] = None ) -> str: """ Send a formatted message using Block Kit with common elements. Args: channel: Channel ID or name title: Header text (optional) text: Main message text (optional) fields: Comma-separated fields for side-by-side display (optional) context: Context text at bottom (optional) thread_ts: Thread timestamp for replies (optional) """ try: blocks = [] if title: blocks.append(BlockKitBuilder.header(title)) if text: blocks.append(BlockKitBuilder.section(text)) if fields: field_list = [field.strip() for field in fields.split(",")] blocks.append(BlockKitBuilder.fields_section(field_list)) if context: blocks.append(BlockKitBuilder.context([context])) if not blocks: return json.dumps({"error": "At least one of title, text, fields, or context must be provided"}, indent=2) fallback_text = title or text or "Formatted message" client = SlackClient() result = await client.send_message(channel, fallback_text, thread_ts, blocks) return json.dumps(result, indent=2) except Exception as e: return json.dumps({"error": str(e)}, indent=2)
  • BlockKitBuilder utility class providing static methods (header, section, fields_section, context, divider) used by send_formatted_message to construct the Slack Block Kit blocks dynamically.
    class BlockKitBuilder: """Utility class for building Block Kit elements.""" @staticmethod def header(text: str) -> Dict[str, Any]: """Create a header block.""" return { "type": "header", "text": { "type": "plain_text", "text": text } } @staticmethod def section(text: str, text_type: str = "mrkdwn") -> Dict[str, Any]: """Create a section block with text.""" return { "type": "section", "text": { "type": text_type, "text": text } } @staticmethod def divider() -> Dict[str, Any]: """Create a divider block.""" return {"type": "divider"} @staticmethod def fields_section(fields: List[str]) -> Dict[str, Any]: """Create a section block with multiple fields.""" return { "type": "section", "fields": [ { "type": "mrkdwn", "text": field } for field in fields ] } @staticmethod def context(elements: List[str]) -> Dict[str, Any]: """Create a context block with multiple text elements.""" return { "type": "context", "elements": [ { "type": "mrkdwn", "text": element } for element in elements ] } @staticmethod def image(image_url: str, alt_text: str, title: Optional[str] = None) -> Dict[str, Any]: """Create an image block.""" block = { "type": "image", "image_url": image_url, "alt_text": alt_text } if title: block["title"] = { "type": "plain_text", "text": title } return block @staticmethod def button(text: str, action_id: str, value: Optional[str] = None, url: Optional[str] = None, style: Optional[str] = None) -> Dict[str, Any]: """Create a button element.""" element = { "type": "button", "text": { "type": "plain_text", "text": text }, "action_id": action_id } if value: element["value"] = value if url: element["url"] = url if style in ["primary", "danger"]: element["style"] = style return element @staticmethod def actions(*elements) -> Dict[str, Any]: """Create an actions block with interactive elements.""" return { "type": "actions", "elements": list(elements) } @staticmethod def select_menu(placeholder: str, action_id: str, options: List[Dict[str, str]]) -> Dict[str, Any]: """Create a static select menu element.""" return { "type": "static_select", "placeholder": { "type": "plain_text", "text": placeholder }, "action_id": action_id, "options": [ { "text": { "type": "plain_text", "text": option["text"] }, "value": option["value"] } for option in options ] } @staticmethod def section_with_accessory(text: str, accessory: Dict[str, Any], text_type: str = "mrkdwn") -> Dict[str, Any]: """Create a section block with an accessory element.""" return { "type": "section", "text": { "type": text_type, "text": text }, "accessory": accessory } @staticmethod def code_block(code: str, language: Optional[str] = None) -> Dict[str, Any]: """Create a formatted code block.""" formatted_code = f"```{language + chr(10) if language else ''}{code}```" return { "type": "section", "text": { "type": "mrkdwn", "text": formatted_code } } @staticmethod def quote_block(text: str) -> Dict[str, Any]: """Create a quote block.""" return { "type": "section", "text": { "type": "mrkdwn", "text": f">{text}" } } @staticmethod def rich_text_block(elements: List[Dict[str, Any]]) -> Dict[str, Any]: """Create a rich text block with various formatting elements.""" return { "type": "rich_text", "elements": elements } @staticmethod def rich_text_section(*elements) -> Dict[str, Any]: """Create a rich text section with inline elements.""" return { "type": "rich_text_section", "elements": list(elements) } @staticmethod def rich_text_list(items: List[str], style: str = "bullet") -> Dict[str, Any]: """Create a rich text list (bullet or ordered).""" return { "type": "rich_text_list", "style": style, "elements": [ { "type": "rich_text_section", "elements": [{"type": "text", "text": item}] } for item in items ] }
  • SlackClient.send_message method called by the tool handler to post the formatted message to Slack API.
    async def send_message( self, channel: str, text: str, thread_ts: Optional[str] = None, blocks: Optional[List[Dict[str, Any]]] = None ) -> Dict[str, Any]: """Send a message to a channel.""" data = {"channel": channel, "text": text} if thread_ts: data["thread_ts"] = thread_ts if blocks: data["blocks"] = blocks return await self._make_request("POST", "chat.postMessage", json_data=data)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/piekstra/slack-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server