Skip to main content
Glama

discord_send_message

Send messages to a specific Discord channel using a channel ID, optionally including attachments (up to 10 files) and text-to-speech functionality. Use this tool to communicate directly within Discord via the Discord MCP Server.

Instructions

Send a message to a Discord channel, optionally with up to 10 files

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
channelIdYesThe Discord channel ID
contentNoMessage content (max 2000 characters)
filesNoFiles to attach to the message
replyToNoMessage ID to reply to
ttsNoSend as text-to-speech message

Implementation Reference

  • The handler function for the 'send-message' Discord tool, which validates input, finds the channel, checks permissions, sends the message with retry logic, and returns success or error response.
    private async handleSendMessage(request: McpRequest) { if (!isValidSendMessageArgs(request.params.arguments)) { throw new McpError( ErrorCode.InvalidParams, "Invalid arguments for send-message. Channel and message must be non-empty strings." ); } const { channel: channelInput, message } = request.params .arguments as SendMessageArgs; try { const channel = await this.findChannel(channelInput); if (!channel) { return { content: [ { type: "text", text: `Channel not found: ${channelInput}`, }, ], isError: true, }; } // Check if bot has permission to send messages if ( !channel.permissionsFor(this.discordClient.user?.id || "")?.has( PermissionsBitField.Flags.SendMessages ) ) { return { content: [ { type: "text", text: `Bot does not have permission to send messages in ${channel.name}`, }, ], isError: true, }; } // Use retry logic for API calls that might fail let attempt = 0; let sentMessage: Message | undefined = undefined; let lastError: Error | undefined = undefined; while (attempt < MAX_RETRY_ATTEMPTS && !sentMessage) { try { sentMessage = await channel.send(message); break; } catch (error) { lastError = error as Error; attempt++; if (attempt < MAX_RETRY_ATTEMPTS) { // Wait before retrying with exponential backoff await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, attempt - 1))); } } } if (!sentMessage) { throw lastError || new Error("Failed to send message after multiple attempts"); } return { content: [ { type: "text", text: `Message sent to #${channel.name} in server ${channel.guild.name}`, }, ], }; } catch (error) { console.error("Error sending message:", error); return { content: [ { type: "text", text: `Error sending message: ${(error as Error).message}`, }, ], isError: true, }; } }
  • The tool schema definition for 'send-message', including name, description, and input schema with channel and message properties.
    { name: "send-message", description: "Send a message to a Discord channel", inputSchema: { type: "object", properties: { channel: { type: "string", description: "Channel name or ID (use # for channel names, e.g. '#general')", }, message: { type: "string", description: "The message content to send", }, }, required: ["channel", "message"], }, },
  • src/index.ts:340-341 (registration)
    Registration of the 'send-message' tool handler in the CallToolRequestSchema switch statement.
    case "send-message": return await this.handleSendMessage(request);
  • Input validation function for send-message arguments.
    const isValidSendMessageArgs = (args: unknown): args is SendMessageArgs => typeof args === "object" && args !== null && typeof (args as SendMessageArgs).channel === "string" && (args as SendMessageArgs).channel.trim().length > 0 && typeof (args as SendMessageArgs).message === "string" && (args as SendMessageArgs).message.trim().length > 0;
  • Helper function to find and cache Discord TextChannel by name or ID, used by send-message and other tools.
    private async findChannel( channelInput: string ): Promise<TextChannel | null> { // Check cache first const cacheKey = channelInput.toLowerCase(); const cachedEntry = this.channelCache.get(cacheKey); if (cachedEntry && Date.now() - cachedEntry.timestamp < CHANNEL_CACHE_TTL) { return cachedEntry.channel; } // Remove # prefix if present const cleanChannelInput = channelInput.startsWith("#") ? channelInput.substring(1) : channelInput; // Try to find channel by ID first if (/^\d+$/.test(cleanChannelInput)) { try { const channel = await this.discordClient.channels.fetch( cleanChannelInput ); if (channel && channel.type === ChannelType.GuildText) { // Cache the result this.channelCache.set(cacheKey, { channel: channel as TextChannel, timestamp: Date.now() }); return channel as TextChannel; } } catch (error) { // Not a valid ID or channel not found } } // Search by name across all servers for (const guild of this.discordClient.guilds.cache.values()) { const channel = guild.channels.cache.find( (c) => c.type === ChannelType.GuildText && c.name.toLowerCase() === cleanChannelInput.toLowerCase() ); if (channel) { // Cache the result this.channelCache.set(cacheKey, { channel: channel as TextChannel, timestamp: Date.now() }); return channel as TextChannel; } } return null; }

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/RossH121/discord-mcp'

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