Skip to main content
Glama
piekstra

Slack MCP Server

by piekstra

send_message

Send messages to Slack channels with text, rich formatting using Block Kit, and threaded replies for organized team communication.

Instructions

Send a message to a Slack channel.

Args: channel: Channel ID or name text: Message text (fallback text for notifications) thread_ts: Thread timestamp for replies blocks: JSON string of Block Kit blocks for rich formatting

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
channelYes
textYes
thread_tsNo
blocksNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The main handler function for the 'send_message' MCP tool. It creates a SlackClient instance, parses optional blocks JSON parameter, calls the underlying SlackClient.send_message method, and returns the API response as formatted JSON or an error message.
    @mcp.tool()
    async def send_message(channel: str, text: str, thread_ts: Optional[str] = None, blocks: Optional[str] = None) -> str:
        """
        Send a message to a Slack channel.
    
        Args:
            channel: Channel ID or name
            text: Message text (fallback text for notifications)
            thread_ts: Thread timestamp for replies
            blocks: JSON string of Block Kit blocks for rich formatting
        """
        try:
            client = SlackClient()
            blocks_data = json.loads(blocks) if blocks else None
            result = await client.send_message(channel, text, thread_ts, blocks_data)
            return json.dumps(result, indent=2)
        except Exception as e:
            return json.dumps({"error": str(e)}, indent=2)
  • The underlying helper method in SlackClient class that constructs the request payload and calls the Slack chat.postMessage API endpoint via _make_request to send the message.
    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)
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but lacks critical behavioral details. It doesn't mention permissions needed, rate limits, whether messages are editable/deletable, or what happens on success/failure. The 'fallback text' hint is minimal context, insufficient for a mutation tool with zero annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded with the core purpose in the first sentence. The Args section is structured but slightly verbose; every sentence earns its place by explaining parameters, though it could be more streamlined (e.g., combining text and blocks explanations).

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given complexity (mutation tool with 4 params, no annotations) and an output schema (which reduces need to explain returns), the description is moderately complete. It covers parameters well but lacks behavioral context and usage guidelines, making it adequate but with clear gaps for safe invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It adds meaningful semantics for all 4 parameters: channel ID/name, text as fallback, thread_ts for replies, and blocks as JSON string for rich formatting. This clarifies usage beyond basic schema types, though it could detail format constraints (e.g., channel naming).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Send') and resource ('message to a Slack channel'), distinguishing it from siblings like send_announcement or send_formatted_message by focusing on basic message sending. It's not a tautology and provides meaningful context beyond the name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like send_formatted_message, send_interactive_message, or send_announcement. It mentions 'fallback text for notifications' but doesn't explain when this applies or what the alternatives are, leaving usage context unclear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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