Skip to main content
Glama

Discord Agent MCP

by aj-geddes
stickers.ts12.1 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { DiscordClientManager } from "../discord/client.js"; import { Logger } from "../utils/logger.js"; import { z } from "zod"; import { PermissionDeniedError, InvalidInputError } from "../errors/discord.js"; import { validateGuildAccess } from "../utils/guild-validation.js"; import { PermissionFlagsBits } from "discord.js"; export function registerStickerTools( server: McpServer, discordManager: DiscordClientManager, logger: Logger, ) { // List Guild Stickers Tool server.registerTool( "list_guild_stickers", { title: "List Guild Stickers", description: "Get all custom stickers for a guild", inputSchema: { guildId: z.string().describe("Guild ID"), }, outputSchema: { success: z.boolean(), stickers: z .array( z.object({ id: z.string(), name: z.string(), description: z.string().nullable(), tags: z.string().nullable(), format: z.string(), available: z.boolean(), creator: z .object({ id: z.string(), username: z.string(), }) .optional(), }), ) .optional(), count: z.number().optional(), error: z.string().optional(), }, }, async ({ guildId }) => { try { const client = discordManager.getClient(); const guild = await validateGuildAccess(client, guildId); // Fetch all stickers const stickers = await guild.stickers.fetch(); const stickerList = stickers.map((sticker) => ({ id: sticker.id, name: sticker.name, description: sticker.description || null, tags: sticker.tags || null, format: sticker.format === 1 ? "PNG" : sticker.format === 2 ? "APNG" : sticker.format === 3 ? "LOTTIE" : "UNKNOWN", available: sticker.available !== false, creator: sticker.user ? { id: sticker.user.id, username: sticker.user.username, } : undefined, })); const output = { success: true, stickers: stickerList, count: stickerList.length, }; logger.info("Listed guild stickers", { guildId, count: stickerList.length, }); return { content: [ { type: "text" as const, text: `Found ${stickerList.length} custom stickers in guild ${guild.name}`, }, ], structuredContent: output, }; } catch (error: any) { logger.error("Failed to list guild stickers", { error: error.message, guildId, }); return { content: [ { type: "text" as const, text: `Error: ${error.message}`, }, ], structuredContent: { success: false, error: error.message, }, }; } }, ); // Create Sticker Tool server.registerTool( "create_sticker", { title: "Create Guild Sticker", description: "Upload a custom sticker to the guild (PNG, APNG, or Lottie JSON)", inputSchema: { guildId: z.string().describe("Guild ID"), name: z .string() .min(2) .max(30) .describe("Sticker name (2-30 characters)"), description: z .string() .min(2) .max(100) .describe("Sticker description (2-100 characters)"), tags: z .string() .describe("Related emoji or keywords (comma-separated)"), file: z .string() .describe("File path or base64 data URI (PNG/APNG/Lottie JSON)"), reason: z.string().optional().describe("Audit log reason"), }, outputSchema: { success: z.boolean(), sticker: z .object({ id: z.string(), name: z.string(), description: z.string(), tags: z.string(), format: z.string(), }) .optional(), error: z.string().optional(), }, }, async ({ guildId, name, description, tags, file, reason }) => { try { const client = discordManager.getClient(); const guild = await validateGuildAccess(client, guildId); // Check permissions const botMember = await guild.members.fetch(client.user!.id); if ( !botMember.permissions.has(PermissionFlagsBits.ManageGuildExpressions) ) { throw new PermissionDeniedError( "ManageGuildExpressions", guildId, ); } // Check guild boost level for sticker creation // Stickers require guild level 2 boost or higher (or verified/partnered) const hasFeature = guild.features.includes("VERIFIED") || guild.features.includes("PARTNERED") || guild.premiumTier >= 2; if (!hasFeature) { throw new InvalidInputError( "guild", "Guild must be level 2 boosted, verified, or partnered to create stickers", ); } // Create sticker const sticker = await guild.stickers.create({ file: file, name: name, tags: tags, description: description, reason: reason, }); const output = { success: true, sticker: { id: sticker.id, name: sticker.name, description: sticker.description || "", tags: sticker.tags || "", format: sticker.format === 1 ? "PNG" : sticker.format === 2 ? "APNG" : sticker.format === 3 ? "LOTTIE" : "UNKNOWN", }, }; logger.info("Created sticker", { guildId, stickerId: sticker.id, name, }); return { content: [ { type: "text" as const, text: `Created sticker "${sticker.name}" in ${guild.name}`, }, ], structuredContent: output, }; } catch (error: any) { logger.error("Failed to create sticker", { error: error.message, guildId, name, }); return { content: [ { type: "text" as const, text: `Error: ${error.message}`, }, ], structuredContent: { success: false, error: error.message, }, }; } }, ); // Modify Sticker Tool server.registerTool( "modify_sticker", { title: "Modify Guild Sticker", description: "Update an existing custom sticker's name, description, or tags", inputSchema: { guildId: z.string().describe("Guild ID"), stickerId: z.string().describe("Sticker ID to modify"), name: z .string() .min(2) .max(30) .optional() .describe("New sticker name"), description: z .string() .min(2) .max(100) .optional() .describe("New description"), tags: z.string().optional().describe("New tags"), reason: z.string().optional().describe("Audit log reason"), }, outputSchema: { success: z.boolean(), sticker: z .object({ id: z.string(), name: z.string(), description: z.string(), tags: z.string(), }) .optional(), error: z.string().optional(), }, }, async ({ guildId, stickerId, name, description, tags, reason }) => { try { const client = discordManager.getClient(); const guild = await validateGuildAccess(client, guildId); // Check permissions const botMember = await guild.members.fetch(client.user!.id); if ( !botMember.permissions.has(PermissionFlagsBits.ManageGuildExpressions) ) { throw new PermissionDeniedError( "ManageGuildExpressions", guildId, ); } // Fetch sticker const sticker = await guild.stickers.fetch(stickerId); if (!sticker) { throw new InvalidInputError("stickerId", "Sticker not found"); } // Update sticker const updated = await sticker.edit({ name: name, description: description, tags: tags, reason: reason, }); const output = { success: true, sticker: { id: updated.id, name: updated.name, description: updated.description || "", tags: updated.tags || "", }, }; logger.info("Modified sticker", { guildId, stickerId, }); return { content: [ { type: "text" as const, text: `Updated sticker "${updated.name}" in ${guild.name}`, }, ], structuredContent: output, }; } catch (error: any) { logger.error("Failed to modify sticker", { error: error.message, guildId, stickerId, }); return { content: [ { type: "text" as const, text: `Error: ${error.message}`, }, ], structuredContent: { success: false, error: error.message, }, }; } }, ); // Delete Sticker Tool server.registerTool( "delete_sticker", { title: "Delete Guild Sticker", description: "Delete a custom sticker from the guild", inputSchema: { guildId: z.string().describe("Guild ID"), stickerId: z.string().describe("Sticker ID to delete"), reason: z.string().optional().describe("Audit log reason"), }, outputSchema: { success: z.boolean(), stickerId: z.string().optional(), error: z.string().optional(), }, }, async ({ guildId, stickerId, reason }) => { try { const client = discordManager.getClient(); const guild = await validateGuildAccess(client, guildId); // Check permissions const botMember = await guild.members.fetch(client.user!.id); if ( !botMember.permissions.has(PermissionFlagsBits.ManageGuildExpressions) ) { throw new PermissionDeniedError( "ManageGuildExpressions", guildId, ); } // Fetch sticker const sticker = await guild.stickers.fetch(stickerId); if (!sticker) { throw new InvalidInputError("stickerId", "Sticker not found"); } const stickerName = sticker.name; // Delete sticker await sticker.delete(reason); const output = { success: true, stickerId: stickerId, }; logger.info("Deleted sticker", { guildId, stickerId, }); return { content: [ { type: "text" as const, text: `Deleted sticker "${stickerName}" from ${guild.name}`, }, ], structuredContent: output, }; } catch (error: any) { logger.error("Failed to delete sticker", { error: error.message, guildId, stickerId, }); return { content: [ { type: "text" as const, text: `Error: ${error.message}`, }, ], structuredContent: { success: false, error: error.message, }, }; } }, ); }

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/aj-geddes/discord-agent-mcp'

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