UNPKG

maplestory-mcp-server

Version:

Official-style NEXON MapleStory MCP Server for Claude Desktop - Complete character info, union details, guild data, rankings, and game mechanics

235 lines 7.44 kB
"use strict"; /** * Base tool interface and abstract classes for MCP Maple tools * Provides common structure and functionality for all MapleStory API tools */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EnhancedBaseTool = exports.ToolCategory = exports.GuildTool = exports.CharacterTool = exports.BaseTool = void 0; const ajv_1 = __importDefault(require("ajv")); /** * Abstract base class for all MCP tools * Provides common functionality and structure */ class BaseTool { static ajv = new ajv_1.default({ allErrors: true }); /** * Execute the tool with given arguments */ async execute(args, context) { const startTime = Date.now(); try { // Validate input arguments if (!this.validate(args)) { throw new Error('Invalid arguments provided'); } context.logger.info(`Executing tool: ${this.name}`, { toolName: this.name, arguments: args, }); // Execute the tool-specific logic const result = await this.executeImpl(args, context); const executionTime = Date.now() - startTime; context.logger.info(`Tool execution completed: ${this.name}`, { toolName: this.name, executionTime, success: true, }); return result; } catch (error) { const executionTime = Date.now() - startTime; context.logger.error(`Tool execution failed: ${this.name}`, { toolName: this.name, executionTime, error: error instanceof Error ? error.message : String(error), }); throw error; } } /** * Validate input arguments against the schema */ validate(args) { try { const validate = BaseTool.ajv.compile(this.inputSchema); const isValid = validate(args); if (!isValid) { return false; } return this.validateImpl(args); } catch (error) { return false; } } /** * Tool-specific validation logic */ validateImpl(_args) { return true; // Override in subclasses for custom validation } /** * Helper method to format tool results consistently */ formatResult(data, metadata) { return { success: true, data, ...(metadata && { metadata }), }; } /** * Helper method to format error results consistently */ formatError(error, metadata) { return { success: false, error: error instanceof Error ? error.message : error, ...(metadata && { metadata }), }; } /** * Helper method to safely get required string parameter */ getRequiredString(args, key) { const value = args[key]; if (typeof value !== 'string' || value.trim() === '') { throw new Error(`Required parameter '${key}' must be a non-empty string`); } return value.trim(); } /** * Helper method to safely get optional string parameter */ getOptionalString(args, key, defaultValue) { const value = args[key]; if (value === undefined || value === null) { return defaultValue; } if (typeof value !== 'string') { throw new Error(`Parameter '${key}' must be a string`); } return value.trim(); } /** * Helper method to safely get required number parameter */ getRequiredNumber(args, key) { const value = args[key]; if (typeof value !== 'number' || isNaN(value)) { throw new Error(`Required parameter '${key}' must be a valid number`); } return value; } /** * Helper method to safely get optional number parameter */ getOptionalNumber(args, key, defaultValue = 0) { const value = args[key]; if (value === undefined || value === null) { return defaultValue; } if (typeof value !== 'number' || isNaN(value)) { throw new Error(`Parameter '${key}' must be a valid number`); } return value; } /** * Helper method to get optional boolean parameter with default value */ getOptionalBoolean(args, key, defaultValue = false) { const value = args[key]; if (value === undefined || value === null) { return defaultValue; } if (typeof value !== 'boolean') { throw new Error(`Parameter '${key}' must be a boolean`); } return value; } /** * Helper method to validate date format (YYYY-MM-DD) */ validateDateFormat(date) { const dateRegex = /^\d{4}-\d{2}-\d{2}$/; if (!dateRegex.test(date)) { return false; } const parsedDate = new Date(date); return parsedDate instanceof Date && !isNaN(parsedDate.getTime()); } /** * Helper method to format date to API format */ formatApiDate(date) { const targetDate = date || new Date(); const isoString = targetDate.toISOString(); const datePart = isoString.split('T')[0]; if (!datePart) { throw new Error('Invalid date format'); } return datePart; } /** * Helper method to handle API errors consistently */ handleApiError(error, operation) { if (error?.error) { throw new Error(`${operation} failed: ${error.error.message} (${error.error.name})`); } const message = error instanceof Error ? error.message : String(error); throw new Error(`${operation} failed: ${message}`); } } exports.BaseTool = BaseTool; /** * Abstract base class for character-related tools */ class CharacterTool extends BaseTool { async getCharacterOcid(characterName, context) { try { const result = await context.nexonClient.getCharacterOcid(characterName); return result.ocid; } catch (error) { this.handleApiError(error, 'Character lookup'); } } } exports.CharacterTool = CharacterTool; /** * Abstract base class for guild-related tools */ class GuildTool extends BaseTool { async getGuildId(guildName, worldName, context) { try { const result = await context.nexonClient.getGuildId(guildName, worldName); return result.oguild_id; } catch (error) { this.handleApiError(error, 'Guild lookup'); } } } exports.GuildTool = GuildTool; /** * Tool category enumeration */ var ToolCategory; (function (ToolCategory) { ToolCategory["CHARACTER"] = "character"; ToolCategory["UNION"] = "union"; ToolCategory["GUILD"] = "guild"; ToolCategory["RANKING"] = "ranking"; ToolCategory["UTILITY"] = "utility"; })(ToolCategory || (exports.ToolCategory = ToolCategory = {})); /** * Enhanced base tool class with metadata support */ class EnhancedBaseTool extends BaseTool { } exports.EnhancedBaseTool = EnhancedBaseTool; //# sourceMappingURL=base-tool.js.map