@chinchillaenterprises/mcp-discord
Version:
Modular Discord MCP server with 45+ tools for comprehensive server management, featuring clean architecture and discord_ prefixed tools
133 lines • 8.61 kB
JavaScript
import { Client, GatewayIntentBits, ActivityType } from "discord.js";
/**
* Discord client factory and management service
*/
export class DiscordClientService {
/**
* Create a new Discord client with proper intents
*/
static createClient() {
return new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildVoiceStates,
GatewayIntentBits.GuildPresences,
GatewayIntentBits.MessageContent,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildModeration
]
});
}
/**
* Login to Discord with an account
*/
static async loginClient(client, account) {
try {
await client.login(account.token);
console.error(`[DiscordClient] Successfully logged in as ${client.user?.tag} for account ${account.id}`);
// Set bot presence
client.user?.setPresence({
activities: [{
name: 'MCP Discord Bot',
type: ActivityType.Watching
}],
status: 'online'
});
}
catch (error) {
console.error(`[DiscordClient] Failed to login account ${account.id}:`, error);
throw new Error(`Failed to login Discord account: ${error.message}`);
}
}
/**
* Get guild information for an account
*/
static async getGuildInfo(client, guildId) {
if (!client.isReady()) {
return null;
}
if (guildId) {
try {
return await client.guilds.fetch(guildId);
}
catch (error) {
console.error(`[DiscordClient] Failed to fetch guild ${guildId}:`, error);
return null;
}
}
// If no specific guild ID, return the first available guild
const guilds = client.guilds.cache;
return guilds.size > 0 ? guilds.first() : null;
}
/**
* Wait for client to be ready
*/
static async waitForReady(client, timeoutMs = 10000) {
if (client.isReady()) {
return;
}
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
reject(new Error('Client ready timeout'));
}, timeoutMs);
client.once('ready', () => {
clearTimeout(timeout);
resolve();
});
});
}
/**
* Safely destroy a client connection
*/
static async destroyClient(client) {
try {
if (client.isReady()) {
await client.destroy();
}
}
catch (error) {
console.error('[DiscordClient] Error destroying client:', error);
}
}
/**
* Check if client is connected and ready
*/
static isClientReady(client) {
return client.isReady();
}
/**
* Get client connection status
*/
static getClientStatus(client) {
return {
isReady: client.isReady(),
status: client.ws.status.toString(),
user: client.user?.tag,
guilds: client.guilds.cache.size
};
}
/**
* Initialize a client for an account
*/
static async initializeClient(account) {
const client = DiscordClientService.createClient();
try {
await DiscordClientService.loginClient(client, account);
await DiscordClientService.waitForReady(client);
// Update account with guild info if available
const guild = await DiscordClientService.getGuildInfo(client, account.guildId);
if (guild) {
account.guildName = guild.name;
}
return client;
}
catch (error) {
// Clean up on failure
await DiscordClientService.destroyClient(client);
throw error;
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzY29yZC1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvZGlzY29yZC1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLE1BQU0sRUFDTixpQkFBaUIsRUFDakIsWUFBWSxFQUdiLE1BQU0sWUFBWSxDQUFDO0FBR3BCOztHQUVHO0FBQ0gsTUFBTSxPQUFPLG9CQUFvQjtJQUUvQjs7T0FFRztJQUNILE1BQU0sQ0FBQyxZQUFZO1FBQ2pCLE9BQU8sSUFBSSxNQUFNLENBQUM7WUFDaEIsT0FBTyxFQUFFO2dCQUNQLGlCQUFpQixDQUFDLE1BQU07Z0JBQ3hCLGlCQUFpQixDQUFDLGFBQWE7Z0JBQy9CLGlCQUFpQixDQUFDLFlBQVk7Z0JBQzlCLGlCQUFpQixDQUFDLGdCQUFnQjtnQkFDbEMsaUJBQWlCLENBQUMsY0FBYztnQkFDaEMsaUJBQWlCLENBQUMsY0FBYztnQkFDaEMsaUJBQWlCLENBQUMsY0FBYztnQkFDaEMsaUJBQWlCLENBQUMsZUFBZTthQUNsQztTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQWMsRUFBRSxPQUF1QjtRQUM5RCxJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxLQUFLLENBQUMsNkNBQTZDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsR0FBRyxnQkFBZ0IsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFFekcsbUJBQW1CO1lBQ25CLE1BQU0sQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDO2dCQUN2QixVQUFVLEVBQUUsQ0FBQzt3QkFDWCxJQUFJLEVBQUUsaUJBQWlCO3dCQUN2QixJQUFJLEVBQUUsWUFBWSxDQUFDLFFBQVE7cUJBQzVCLENBQUM7Z0JBQ0YsTUFB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