@chinchillaenterprises/mcp-discord
Version:
Modular Discord MCP server with 45+ tools for comprehensive server management, featuring clean architecture and discord_ prefixed tools
104 lines (103 loc) • 7.51 kB
JavaScript
export const toolDefinition = {
name: "discord_add_account",
description: "Add a new Discord account configuration",
inputSchema: {
type: "object",
properties: {
id: {
type: "string",
description: "Unique account identifier (e.g., 'chinchilla-server', 'personal')",
},
name: {
type: "string",
description: "Human-friendly account name",
},
token: {
type: "string",
description: "Discord bot token",
},
guildId: {
type: "string",
description: "Discord guild ID (optional, for specific servers)",
},
setAsDefault: {
type: "boolean",
description: "Set as default account",
},
},
required: ["id", "name", "token"],
}
};
export const handler = async (args, services) => {
const { id, name, token, guildId, setAsDefault } = args;
const accountState = services.getAccountState();
const credentialManager = services.getCredentialManager();
// Validate token format
if (!validateTokenFormat(token)) {
throw new Error("Invalid Discord token format. Expected format: Bot token or standard bot token.");
}
// Check if account ID already exists
if (accountState.accounts.has(id)) {
throw new Error(`Account with ID '${id}' already exists. Use 'discord_update_account' to modify it or choose a different ID.`);
}
// Create account object
const account = {
id,
name,
token: token.startsWith('Bot ') ? token : `Bot ${token}`,
guildId,
isDefault: setAsDefault
};
// Test the token by initializing a client
let client;
try {
client = await services.initializeClient({ ...account });
}
catch (error) {
throw new Error(`Failed to verify Discord token: ${error.message}`);
}
// Save to persistent storage
try {
await credentialManager.saveAccount(account);
}
catch (error) {
// Clean up the client if save failed
client.destroy();
throw new Error(`Failed to save account: ${error.message}`);
}
// Add to in-memory state
accountState.accounts.set(id, account);
accountState.clients.set(id, client);
// If this is the first account or it's set as default, make it active
if (!accountState.activeAccountId || setAsDefault) {
accountState.activeAccountId = id;
}
// If set as default, update other accounts
if (setAsDefault) {
for (const [accId, acc] of accountState.accounts) {
if (accId !== id && acc.isDefault) {
acc.isDefault = false;
await credentialManager.updateAccount(acc);
}
}
}
return {
content: [
{
type: "text",
text: `Discord account '${name}' (${id}) has been added successfully!
Guild ID: ${guildId || 'Not specified'}
Status: ${accountState.activeAccountId === id ? '🟢 Active' : '⚪ Inactive'} ${setAsDefault ? '⭐ Default' : ''}
The bot is now connected and ready to use!`,
},
],
};
};
function validateTokenFormat(token) {
// Basic validation - Discord tokens are base64 encoded
const cleanToken = token.replace('Bot ', '');
// Check if it looks like a valid base64 string with dots
return /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(cleanToken);
}
export { AddAccountArgsSchema as schema } from "../../schemas/account.js";
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkLWFjY291bnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdG9vbHMvYWNjb3VudC9hZGQtYWNjb3VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFNQSxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQVM7SUFDbEMsSUFBSSxFQUFFLHFCQUFxQjtJQUMzQixXQUFXLEVBQUUseUNBQXlDO0lBQ3RELFdBQVcsRUFBRTtRQUNYLElBQUksRUFBRSxRQUFRO1FBQ2QsVUFBVSxFQUFFO1lBQ1YsRUFBRSxFQUFFO2dCQUNGLElBQUksRUFBRSxRQUFRO2dCQUNkLFdBQVcsRUFBRSxtRUFBbUU7YUFDakY7WUFDRCxJQUFJLEVBQUU7Z0JBQ0osSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsV0FBVyxFQUFFLDZCQUE2QjthQUMzQztZQUNELEtBQUssRUFBRTtnQkFDTCxJQUFJLEVBQUUsUUFBUTtnQkFDZCxXQUFXLEVBQUUsbUJBQW1CO2FBQ2pDO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLElBQUksRUFBRSxRQUFRO2dCQUNkLFdBQVcsRUFBRSxtREFBbUQ7YUFDakU7WUFDRCxZQUFZLEVBQUU7Z0JBQ1osSUFBSSxFQUFFLFNBQVM7Z0JBQ2YsV0FBVyxFQUFFLHdCQUF3QjthQUN0QztTQUNGO1FBQ0QsUUFBUSxFQUFFLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUM7S0FDbEM7Q0FDRixDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLEtBQUssRUFBRSxJQUFvQixFQUFFLFFBQTBCLEVBQUUsRUFBRTtJQUNoRixNQUFNLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxHQUFHLElBQUksQ0FBQztJQUN4RCxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDaEQsTUFBTSxpQkFBaUIsR0FBRyxRQUFRLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztJ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