Skip to main content
Glama
event-tools.ts11.1 kB
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { z } from 'zod'; import { GuildScheduledEventEntityType, GuildScheduledEventPrivacyLevel, GuildScheduledEventStatus } from 'discord.js'; import { getDiscordClient } from '../utils/discord-client.js'; import { withErrorHandling } from '../utils/error-handler.js'; export function registerEventTools(server: McpServer): void { // List scheduled events server.tool( 'list_events', 'List all scheduled events in a server', { guildId: z.string().describe('The ID of the server (guild)'), withUserCount: z.boolean().optional().describe('Include user count (default true)'), }, async ({ guildId, withUserCount = true }) => { const result = await withErrorHandling(async () => { const client = await getDiscordClient(); const guild = await client.guilds.fetch(guildId); const events = await guild.scheduledEvents.fetch({ withUserCount }); return events.map((event) => ({ id: event.id, name: event.name, description: event.description, scheduledStartTime: event.scheduledStartAt?.toISOString(), scheduledEndTime: event.scheduledEndAt?.toISOString(), privacyLevel: GuildScheduledEventPrivacyLevel[event.privacyLevel], status: GuildScheduledEventStatus[event.status], entityType: GuildScheduledEventEntityType[event.entityType], entityId: event.entityId, channelId: event.channelId, creatorId: event.creatorId, userCount: event.userCount, location: event.entityMetadata?.location, image: event.coverImageURL(), url: event.url, })); }); if (!result.success) { return { content: [{ type: 'text', text: result.error }], isError: true }; } return { content: [{ type: 'text', text: JSON.stringify(result.data, null, 2) }] }; } ); // Get event info server.tool( 'get_event_info', 'Get detailed information about a scheduled event', { guildId: z.string().describe('The ID of the server (guild)'), eventId: z.string().describe('The ID of the event'), }, async ({ guildId, eventId }) => { const result = await withErrorHandling(async () => { const client = await getDiscordClient(); const guild = await client.guilds.fetch(guildId); const event = await guild.scheduledEvents.fetch(eventId); return { id: event.id, name: event.name, description: event.description, scheduledStartTime: event.scheduledStartAt?.toISOString(), scheduledEndTime: event.scheduledEndAt?.toISOString(), privacyLevel: GuildScheduledEventPrivacyLevel[event.privacyLevel], status: GuildScheduledEventStatus[event.status], entityType: GuildScheduledEventEntityType[event.entityType], entityId: event.entityId, channelId: event.channelId, creatorId: event.creatorId, creator: event.creator ? { id: event.creator.id, username: event.creator.username } : null, userCount: event.userCount, location: event.entityMetadata?.location, image: event.coverImageURL(), url: event.url, }; }); if (!result.success) { return { content: [{ type: 'text', text: result.error }], isError: true }; } return { content: [{ type: 'text', text: JSON.stringify(result.data, null, 2) }] }; } ); // Create scheduled event server.tool( 'create_event', 'Create a scheduled event in a server', { guildId: z.string().describe('The ID of the server (guild)'), name: z.string().describe('Name of the event'), description: z.string().optional().describe('Description of the event'), scheduledStartTime: z.string().describe('Start time in ISO 8601 format'), scheduledEndTime: z.string().optional().describe('End time in ISO 8601 format (required for external events)'), entityType: z.enum(['STAGE_INSTANCE', 'VOICE', 'EXTERNAL']).describe('Type of event'), channelId: z.string().optional().describe('Channel ID for voice/stage events'), location: z.string().optional().describe('Location for external events'), image: z.string().optional().describe('URL of the cover image'), reason: z.string().optional().describe('Reason for creating'), }, async ({ guildId, name, description, scheduledStartTime, scheduledEndTime, entityType, channelId, location, image, reason }) => { const result = await withErrorHandling(async () => { const client = await getDiscordClient(); const guild = await client.guilds.fetch(guildId); const entityTypeMap: Record<string, GuildScheduledEventEntityType> = { 'STAGE_INSTANCE': GuildScheduledEventEntityType.StageInstance, 'VOICE': GuildScheduledEventEntityType.Voice, 'EXTERNAL': GuildScheduledEventEntityType.External, }; const eventOptions: { name: string; scheduledStartTime: string; privacyLevel: GuildScheduledEventPrivacyLevel; entityType: GuildScheduledEventEntityType; description?: string; scheduledEndTime?: string; channel?: string; entityMetadata?: { location: string }; image?: string; reason?: string; } = { name, scheduledStartTime, privacyLevel: GuildScheduledEventPrivacyLevel.GuildOnly, entityType: entityTypeMap[entityType], }; if (description) eventOptions.description = description; if (scheduledEndTime) eventOptions.scheduledEndTime = scheduledEndTime; if (channelId) eventOptions.channel = channelId; if (location) eventOptions.entityMetadata = { location }; if (image) eventOptions.image = image; if (reason) eventOptions.reason = reason; const event = await guild.scheduledEvents.create(eventOptions); return { id: event.id, name: event.name, scheduledStartTime: event.scheduledStartAt?.toISOString(), entityType: GuildScheduledEventEntityType[event.entityType], url: event.url, message: 'Event created successfully', }; }); if (!result.success) { return { content: [{ type: 'text', text: result.error }], isError: true }; } return { content: [{ type: 'text', text: JSON.stringify(result.data, null, 2) }] }; } ); // Modify event server.tool( 'modify_event', 'Modify a scheduled event', { guildId: z.string().describe('The ID of the server (guild)'), eventId: z.string().describe('The ID of the event'), name: z.string().optional().describe('New name'), description: z.string().optional().describe('New description'), scheduledStartTime: z.string().optional().describe('New start time (ISO 8601)'), scheduledEndTime: z.string().optional().describe('New end time (ISO 8601)'), status: z.enum(['SCHEDULED', 'ACTIVE', 'COMPLETED', 'CANCELED']).optional().describe('New status'), location: z.string().optional().describe('New location'), reason: z.string().optional().describe('Reason for modifying'), }, async ({ guildId, eventId, name, description, scheduledStartTime, scheduledEndTime, status, location, reason }) => { const result = await withErrorHandling(async () => { const client = await getDiscordClient(); const guild = await client.guilds.fetch(guildId); const event = await guild.scheduledEvents.fetch(eventId); const statusMap: Record<string, GuildScheduledEventStatus> = { 'SCHEDULED': GuildScheduledEventStatus.Scheduled, 'ACTIVE': GuildScheduledEventStatus.Active, 'COMPLETED': GuildScheduledEventStatus.Completed, 'CANCELED': GuildScheduledEventStatus.Canceled, }; const editData: Record<string, unknown> = {}; if (name) editData.name = name; if (description) editData.description = description; if (scheduledStartTime) editData.scheduledStartTime = scheduledStartTime; if (scheduledEndTime) editData.scheduledEndTime = scheduledEndTime; if (status) editData.status = statusMap[status]; if (location) editData.entityMetadata = { location }; if (reason) editData.reason = reason; const updated = await event.edit(editData); return { id: updated.id, name: updated.name, status: GuildScheduledEventStatus[updated.status], message: 'Event updated successfully', }; }); if (!result.success) { return { content: [{ type: 'text', text: result.error }], isError: true }; } return { content: [{ type: 'text', text: JSON.stringify(result.data, null, 2) }] }; } ); // Delete event server.tool( 'delete_event', 'Delete a scheduled event', { guildId: z.string().describe('The ID of the server (guild)'), eventId: z.string().describe('The ID of the event to delete'), }, async ({ guildId, eventId }) => { const result = await withErrorHandling(async () => { const client = await getDiscordClient(); const guild = await client.guilds.fetch(guildId); const event = await guild.scheduledEvents.fetch(eventId); const eventName = event.name; await event.delete(); return { eventId, eventName, message: 'Event deleted successfully' }; }); if (!result.success) { return { content: [{ type: 'text', text: result.error }], isError: true }; } return { content: [{ type: 'text', text: JSON.stringify(result.data, null, 2) }] }; } ); // Get event subscribers server.tool( 'get_event_subscribers', 'Get users subscribed to a scheduled event', { guildId: z.string().describe('The ID of the server (guild)'), eventId: z.string().describe('The ID of the event'), limit: z.number().optional().describe('Max users to fetch (default 100)'), }, async ({ guildId, eventId, limit = 100 }) => { const result = await withErrorHandling(async () => { const client = await getDiscordClient(); const guild = await client.guilds.fetch(guildId); const event = await guild.scheduledEvents.fetch(eventId); const subscribers = await event.fetchSubscribers({ limit, withMember: true }); return subscribers.map((sub) => ({ id: sub.user.id, username: sub.user.username, member: sub.member ? { nickname: sub.member.nickname, joinedAt: sub.member.joinedAt?.toISOString(), } : null, })); }); if (!result.success) { return { content: [{ type: 'text', text: result.error }], isError: true }; } return { content: [{ type: 'text', text: JSON.stringify(result.data, null, 2) }] }; } ); }

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

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