Skip to main content
Glama

MCP-Discord

channel.ts7.55 kB
import { z } from "zod"; import { ChannelType } from "discord.js"; import { ToolContext, ToolResponse } from "./types.js"; import { CreateTextChannelSchema, DeleteChannelSchema, ReadMessagesSchema, CreateCategorySchema, EditCategorySchema, DeleteCategorySchema } from "../schemas.js"; import { handleDiscordError } from "../errorHandler.js"; // Category creation handler export async function createCategoryHandler( args: unknown, context: ToolContext ): Promise<ToolResponse> { const { guildId, name, position, reason } = CreateCategorySchema.parse(args); try { if (!context.client.isReady()) { return { content: [{ type: "text", text: "Discord client not logged in." }], isError: true }; } const guild = await context.client.guilds.fetch(guildId); if (!guild) { return { content: [{ type: "text", text: `Cannot find guild with ID: ${guildId}` }], isError: true }; } const options: any = { name, type: ChannelType.GuildCategory }; if (typeof position === "number") options.position = position; if (reason) options.reason = reason; const category = await guild.channels.create(options); return { content: [{ type: "text", text: `Successfully created category "${name}" with ID: ${category.id}` }] }; } catch (error) { return handleDiscordError(error); } } // Category edit handler export async function editCategoryHandler( args: unknown, context: ToolContext ): Promise<ToolResponse> { const { categoryId, name, position, reason } = EditCategorySchema.parse(args); try { if (!context.client.isReady()) { return { content: [{ type: "text", text: "Discord client not logged in." }], isError: true }; } const category = await context.client.channels.fetch(categoryId); if (!category || category.type !== ChannelType.GuildCategory) { return { content: [{ type: "text", text: `Cannot find category with ID: ${categoryId}` }], isError: true }; } const update: any = {}; if (name) update.name = name; if (typeof position === "number") update.position = position; if (reason) update.reason = reason; await category.edit(update); return { content: [{ type: "text", text: `Successfully edited category with ID: ${categoryId}` }] }; } catch (error) { return handleDiscordError(error); } } // Category deletion handler export async function deleteCategoryHandler( args: unknown, context: ToolContext ): Promise<ToolResponse> { const { categoryId, reason } = DeleteCategorySchema.parse(args); try { if (!context.client.isReady()) { return { content: [{ type: "text", text: "Discord client not logged in." }], isError: true }; } const category = await context.client.channels.fetch(categoryId); if (!category || category.type !== ChannelType.GuildCategory) { return { content: [{ type: "text", text: `Cannot find category with ID: ${categoryId}` }], isError: true }; } await category.delete(reason || "Category deleted via API"); return { content: [{ type: "text", text: `Successfully deleted category with ID: ${categoryId}` }] }; } catch (error) { return handleDiscordError(error); } } // Text channel creation handler export async function createTextChannelHandler( args: unknown, context: ToolContext ): Promise<ToolResponse> { const { guildId, channelName, topic, reason } = CreateTextChannelSchema.parse(args); try { if (!context.client.isReady()) { return { content: [{ type: "text", text: "Discord client not logged in." }], isError: true }; } const guild = await context.client.guilds.fetch(guildId); if (!guild) { return { content: [{ type: "text", text: `Cannot find guild with ID: ${guildId}` }], isError: true }; } // Create the text channel const channelOptions: any = { name: channelName, type: ChannelType.GuildText }; if (topic) channelOptions.topic = topic; if (reason) channelOptions.reason = reason; const channel = await guild.channels.create(channelOptions); return { content: [{ type: "text", text: `Successfully created text channel "${channelName}" with ID: ${channel.id}` }] }; } catch (error) { return handleDiscordError(error); } } // Channel deletion handler export async function deleteChannelHandler( args: unknown, context: ToolContext ): Promise<ToolResponse> { const { channelId, reason } = DeleteChannelSchema.parse(args); try { if (!context.client.isReady()) { return { content: [{ type: "text", text: "Discord client not logged in." }], isError: true }; } const channel = await context.client.channels.fetch(channelId); if (!channel) { return { content: [{ type: "text", text: `Cannot find channel with ID: ${channelId}` }], isError: true }; } // Check if channel can be deleted (has delete method) if (!('delete' in channel)) { return { content: [{ type: "text", text: `This channel type does not support deletion or the bot lacks permissions` }], isError: true }; } // Delete the channel await channel.delete(reason || "Channel deleted via API"); return { content: [{ type: "text", text: `Successfully deleted channel with ID: ${channelId}` }] }; } catch (error) { return handleDiscordError(error); } } // Message reading handler export async function readMessagesHandler( args: unknown, context: ToolContext ): Promise<ToolResponse> { const { channelId, limit } = ReadMessagesSchema.parse(args); try { if (!context.client.isReady()) { return { content: [{ type: "text", text: "Discord client not logged in." }], isError: true }; } const channel = await context.client.channels.fetch(channelId); if (!channel) { return { content: [{ type: "text", text: `Cannot find channel with ID: ${channelId}` }], isError: true }; } // Check if channel has messages (text channel, thread, etc.) if (!channel.isTextBased() || !('messages' in channel)) { return { content: [{ type: "text", text: `Channel type does not support reading messages` }], isError: true }; } // Fetch messages const messages = await channel.messages.fetch({ limit }); if (messages.size === 0) { return { content: [{ type: "text", text: `No messages found in channel` }] }; } // Format messages const formattedMessages = messages.map(msg => ({ id: msg.id, content: msg.content, author: { id: msg.author.id, username: msg.author.username, bot: msg.author.bot }, timestamp: msg.createdAt, attachments: msg.attachments.size, embeds: msg.embeds.length, replyTo: msg.reference ? msg.reference.messageId : null })).sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime()); return { content: [{ type: "text", text: JSON.stringify({ channelId, messageCount: formattedMessages.length, messages: formattedMessages }, null, 2) }] }; } catch (error) { return handleDiscordError(error); } }

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

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