Skip to main content
Glama
oregpt
by oregpt

conversations_add_message

Post messages to Slack channels, threads, or direct messages using markdown or plain text formatting. Requires OAuth authentication and channel targeting for secure message delivery.

Instructions

Posts a message to a channel, thread, or DM. Supports markdown and plain text. NOTE: Disabled by default for safety - set SLACK_MCP_ADD_MESSAGE_TOOL environment variable to enable.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
accessTokenYesSlack OAuth token (xoxp-... or xoxb-...) with chat:write scope
channel_idYesTarget channel ID, name (#general), or DM (@username)
thread_tsNoThread timestamp; omit to post to channel directly
payloadYesMessage content to post
content_typeNoContent format (default: text/markdown)

Implementation Reference

  • Primary execution handler for the conversations_add_message tool. Performs input validation, safety checks via environment variable, channel resolution, permission verification, and posts the message to Slack using chat.postMessage.
    export async function conversationsAddMessage(args: any): Promise<ToolResponse> { try { // Safety check - require explicit enable const enabledChannels = process.env.SLACK_MCP_ADD_MESSAGE_TOOL; if (!enabledChannels) { return { success: false, error: 'Message posting is disabled by default for safety. Set SLACK_MCP_ADD_MESSAGE_TOOL environment variable to enable.' }; } const validated = ConversationsAddMessageSchema.parse(args); const client = new WebClient(validated.accessToken); console.log('Posting message to channel:', validated.channel_id); // Resolve channel name/username to ID if needed const channelId = await resolveChannelId(client, validated.channel_id); // Check if channel is in enabled list (if not '*') if (enabledChannels !== '*') { const allowedChannels = enabledChannels.split(',').map(c => c.trim()); if (!allowedChannels.includes(channelId) && !allowedChannels.includes(validated.channel_id)) { return { success: false, error: `Message posting not enabled for channel: ${validated.channel_id}` }; } } // Post message const result = await client.chat.postMessage({ channel: channelId, text: validated.payload, thread_ts: validated.thread_ts, mrkdwn: validated.content_type === 'text/markdown' }); return { success: true, data: { ok: result.ok, channel: result.channel, ts: result.ts, message: result.message } }; } catch (error: any) { if (error.name === 'ZodError') { return { success: false, error: `Validation error: ${error.errors.map((e: any) => e.message).join(', ')}` }; } return handleSlackError(error); } }
  • Zod input schema for the conversations_add_message tool, defining required and optional parameters with descriptions.
    * Schema for conversations_add_message tool * Posts messages to channels, threads, or DMs * Note: Disabled by default for safety - requires configuration to enable */ export const ConversationsAddMessageSchema = z.object({ accessToken: z.string().describe("Slack OAuth token (xoxp-... or xoxb-...) with chat:write scope"), channel_id: z.string().describe("Target channel ID, name (#general), or DM (@username)"), thread_ts: z.string().optional().describe("Thread timestamp; omit to post to channel directly"), payload: z.string().describe("Message content to post"), content_type: z.enum(['text/markdown', 'text/plain']).optional().describe("Content format (default: text/markdown)") });
  • src/index.ts:106-109 (registration)
    Tool registration in the MCP server's listTools response, defining the tool's name, description, and input schema converted from Zod.
    name: 'conversations_add_message', description: 'Posts a message to a channel, thread, or DM. Supports markdown and plain text. NOTE: Disabled by default for safety - set SLACK_MCP_ADD_MESSAGE_TOOL environment variable to enable.', inputSchema: zodToMCPSchema(ConversationsAddMessageSchema) },
  • src/index.ts:137-139 (registration)
    Dispatcher case in the callTool handler that invokes the conversationsAddMessage function when the tool is called.
    case 'conversations_add_message': result = await conversationsAddMessage(args); break;
  • Helper function used by the handler to resolve channel names (#channel) or usernames (@user) to actual channel IDs.
    async function resolveChannelId(client: WebClient, channelInput: string): Promise<string> { // If already an ID (starts with C, D, or G), return as-is if (/^[CDG][A-Z0-9]+$/.test(channelInput)) { return channelInput; } // Handle #channel format if (channelInput.startsWith('#')) { const channelName = channelInput.slice(1); const result = await client.conversations.list({ types: 'public_channel,private_channel' }); const channel = result.channels?.find((ch: any) => ch.name === channelName); if (channel) { return channel.id!; } throw new Error(`Channel not found: ${channelInput}`); } // Handle @username format for DMs if (channelInput.startsWith('@')) { const username = channelInput.slice(1); const usersResult = await client.users.list({}); const user = usersResult.members?.find((u: any) => u.name === username); if (user) { // Open or get existing DM const dmResult = await client.conversations.open({ users: user.id! }); return dmResult.channel!.id!; } throw new Error(`User not found: ${channelInput}`); } return channelInput; // Return as-is if no special format }

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/oregpt/Agenticledger_MCP_Slack'

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