Skip to main content
Glama

MCP-Discord

server.ts8.36 kB
import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { Client } from "discord.js"; import { z } from "zod"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import { toolList } from './toolList.js'; import { createToolContext, loginHandler, sendMessageHandler, getForumChannelsHandler, createForumPostHandler, getForumPostHandler, replyToForumHandler, deleteForumPostHandler, createTextChannelHandler, deleteChannelHandler, readMessagesHandler, getServerInfoHandler, addReactionHandler, addMultipleReactionsHandler, removeReactionHandler, deleteMessageHandler, createWebhookHandler, sendWebhookMessageHandler, editWebhookHandler, deleteWebhookHandler, createCategoryHandler, editCategoryHandler, deleteCategoryHandler } from './tools/tools.js'; import { MCPTransport } from './transport.js'; import { info, error } from './logger.js'; export class DiscordMCPServer { private server: Server; private toolContext: ReturnType<typeof createToolContext>; private clientStatusInterval: NodeJS.Timeout | null = null; constructor( private client: Client, private transport: MCPTransport ) { this.server = new Server( { name: "MCP-Discord", version: "1.0.0" }, { capabilities: { tools: {} } } ); this.toolContext = createToolContext(client); this.setupHandlers(); } private setupHandlers() { // Set up the tool list this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: toolList }; }); // Handle tool execution requests this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { let toolResponse; switch (name) { case "discord_create_category": toolResponse = await createCategoryHandler(args, this.toolContext); return toolResponse; case "discord_edit_category": toolResponse = await editCategoryHandler(args, this.toolContext); return toolResponse; case "discord_delete_category": toolResponse = await deleteCategoryHandler(args, this.toolContext); return toolResponse; case "discord_login": toolResponse = await loginHandler(args, this.toolContext); this.logClientState("after discord_login handler"); return toolResponse; case "discord_send": this.logClientState("before discord_send handler"); toolResponse = await sendMessageHandler(args, this.toolContext); return toolResponse; case "discord_get_forum_channels": this.logClientState("before discord_get_forum_channels handler"); toolResponse = await getForumChannelsHandler(args, this.toolContext); return toolResponse; case "discord_create_forum_post": this.logClientState("before discord_create_forum_post handler"); toolResponse = await createForumPostHandler(args, this.toolContext); return toolResponse; case "discord_get_forum_post": this.logClientState("before discord_get_forum_post handler"); toolResponse = await getForumPostHandler(args, this.toolContext); return toolResponse; case "discord_reply_to_forum": this.logClientState("before discord_reply_to_forum handler"); toolResponse = await replyToForumHandler(args, this.toolContext); return toolResponse; case "discord_delete_forum_post": this.logClientState("before discord_delete_forum_post handler"); toolResponse = await deleteForumPostHandler(args, this.toolContext); return toolResponse; case "discord_create_text_channel": this.logClientState("before discord_create_text_channel handler"); toolResponse = await createTextChannelHandler(args, this.toolContext); return toolResponse; case "discord_delete_channel": this.logClientState("before discord_delete_channel handler"); toolResponse = await deleteChannelHandler(args, this.toolContext); return toolResponse; case "discord_read_messages": this.logClientState("before discord_read_messages handler"); toolResponse = await readMessagesHandler(args, this.toolContext); return toolResponse; case "discord_get_server_info": this.logClientState("before discord_get_server_info handler"); toolResponse = await getServerInfoHandler(args, this.toolContext); return toolResponse; case "discord_add_reaction": this.logClientState("before discord_add_reaction handler"); toolResponse = await addReactionHandler(args, this.toolContext); return toolResponse; case "discord_add_multiple_reactions": this.logClientState("before discord_add_multiple_reactions handler"); toolResponse = await addMultipleReactionsHandler(args, this.toolContext); return toolResponse; case "discord_remove_reaction": this.logClientState("before discord_remove_reaction handler"); toolResponse = await removeReactionHandler(args, this.toolContext); return toolResponse; case "discord_delete_message": this.logClientState("before discord_delete_message handler"); toolResponse = await deleteMessageHandler(args, this.toolContext); return toolResponse; case "discord_create_webhook": this.logClientState("before discord_create_webhook handler"); toolResponse = await createWebhookHandler(args, this.toolContext); return toolResponse; case "discord_send_webhook_message": this.logClientState("before discord_send_webhook_message handler"); toolResponse = await sendWebhookMessageHandler(args, this.toolContext); return toolResponse; case "discord_edit_webhook": this.logClientState("before discord_edit_webhook handler"); toolResponse = await editWebhookHandler(args, this.toolContext); return toolResponse; case "discord_delete_webhook": this.logClientState("before discord_delete_webhook handler"); toolResponse = await deleteWebhookHandler(args, this.toolContext); return toolResponse; default: throw new Error(`Unknown tool: ${name}`); } } catch (error) { if (error instanceof z.ZodError) { return { content: [{ type: "text", text: `Invalid arguments: ${error.errors .map((e: z.ZodIssue) => `${e.path.join(".")}: ${e.message}`) .join(", ")}` }], isError: true }; } const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { content: [{ type: "text", text: `Error executing tool: ${errorMessage}` }], isError: true }; } }); } private logClientState(context: string) { info(`Discord client state [${context}]: ${JSON.stringify({ isReady: this.client.isReady(), hasToken: !!this.client.token, user: this.client.user ? { id: this.client.user.id, tag: this.client.user.tag, } : null })}`); } async start() { // Add client to server context so transport can access it (this.server as any)._context = { client: this.client }; (this.server as any).client = this.client; // Setup periodic client state logging this.clientStatusInterval = setInterval(() => { this.logClientState("periodic check"); }, 10000); await this.transport.start(this.server); } async stop() { // Clear the periodic check interval if (this.clientStatusInterval) { clearInterval(this.clientStatusInterval); this.clientStatusInterval = null; } await this.transport.stop(); } }

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