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

345 lines 14.4 kB
"use strict"; /** * Union Information Tools for MCP Maple * Provides MCP tools for retrieving MapleStory union data and rankings */ Object.defineProperty(exports, "__esModule", { value: true }); exports.GetUnionRankingTool = exports.GetUnionRaiderTool = exports.GetUnionInfoTool = void 0; const base_tool_1 = require("./base-tool"); /** * Tool for getting union information */ class GetUnionInfoTool extends base_tool_1.EnhancedBaseTool { name = 'get_union_info'; description = 'Retrieve union information for a MapleStory character including level, grade, and artifact details'; inputSchema = { type: 'object', properties: { characterName: { type: 'string', description: 'The name of the character to look up union info for', minLength: 1, maxLength: 12, pattern: '^[a-zA-Z0-9가-힣]+$', }, date: { type: 'string', description: 'Date for union info in YYYY-MM-DD format (optional, defaults to yesterday)', pattern: '^\\d{4}-\\d{2}-\\d{2}$', }, }, required: ['characterName'], additionalProperties: false, }; metadata = { category: base_tool_1.ToolCategory.UNION, tags: ['union', 'level', 'grade', 'artifact'], examples: [ { description: 'Get union info for character', arguments: { characterName: '스카니아용사' }, }, { description: 'Get union info for specific date', arguments: { characterName: '스카니아용사', date: '2024-01-15' }, }, ], }; async executeImpl(args, context) { const characterName = this.getRequiredString(args, 'characterName'); const date = this.getOptionalString(args, 'date'); try { const startTime = Date.now(); // Get character OCID first context.logger.info('Looking up character OCID for union info', { characterName }); const ocidResult = await context.nexonClient.getCharacterOcid(characterName); const ocid = ocidResult.ocid; // Get union info context.logger.info('Fetching union information', { characterName, ocid }); const unionInfo = await context.nexonClient.getUnionInfo(ocid, date); const executionTime = Date.now() - startTime; context.logger.info('Union info retrieved successfully', { characterName, unionLevel: unionInfo.union_level, unionGrade: unionInfo.union_grade, artifactLevel: unionInfo.union_artifact_level, executionTime, }); return this.formatResult({ characterName, date: unionInfo.date || date || 'latest', unionLevel: unionInfo.union_level, unionGrade: unionInfo.union_grade, unionArtifact: { level: unionInfo.union_artifact_level, exp: unionInfo.union_artifact_exp, point: unionInfo.union_artifact_point, }, }, { executionTime, cacheHit: false, apiCalls: 2, // OCID lookup + union info }); } catch (error) { context.logger.error('Failed to get union info', { characterName, error: error instanceof Error ? error.message : String(error), }); return this.formatError(`Failed to get union info for character "${characterName}": ${error instanceof Error ? error.message : String(error)}`); } } } exports.GetUnionInfoTool = GetUnionInfoTool; /** * Tool for getting union raider information */ class GetUnionRaiderTool extends base_tool_1.EnhancedBaseTool { name = 'get_union_raider'; description = 'Retrieve union raider board information including block placement and stats'; inputSchema = { type: 'object', properties: { characterName: { type: 'string', description: 'The name of the character to look up union raider for', minLength: 1, maxLength: 12, pattern: '^[a-zA-Z0-9가-힣]+$', }, date: { type: 'string', description: 'Date for union raider in YYYY-MM-DD format (optional, defaults to yesterday)', pattern: '^\\d{4}-\\d{2}-\\d{2}$', }, }, required: ['characterName'], additionalProperties: false, }; metadata = { category: base_tool_1.ToolCategory.UNION, tags: ['union', 'raider', 'blocks', 'stats', 'board'], examples: [ { description: 'Get union raider info for character', arguments: { characterName: '스카니아용사' }, }, { description: 'Get union raider for specific date', arguments: { characterName: '스카니아용사', date: '2024-01-15' }, }, ], }; async executeImpl(args, context) { const characterName = this.getRequiredString(args, 'characterName'); const date = this.getOptionalString(args, 'date'); try { const startTime = Date.now(); // Get character OCID first context.logger.info('Looking up character OCID for union raider', { characterName }); const ocidResult = await context.nexonClient.getCharacterOcid(characterName); const ocid = ocidResult.ocid; // Get union raider info context.logger.info('Fetching union raider information', { characterName, ocid }); const raiderInfo = await context.nexonClient.getUnionRaider(ocid, date); const executionTime = Date.now() - startTime; // Process union blocks for better presentation const blocksByClass = raiderInfo.union_block?.reduce((acc, block) => { if (!acc[block.block_class]) { acc[block.block_class] = []; } acc[block.block_class].push({ type: block.block_type, level: block.block_level, controlPoint: block.block_control_point, positions: block.block_position, }); return acc; }, {}) || {}; context.logger.info('Union raider info retrieved successfully', { characterName, blockCount: raiderInfo.union_block?.length || 0, innerStatCount: raiderInfo.union_inner_stat?.length || 0, executionTime, }); return this.formatResult({ characterName, date: raiderInfo.date || date || 'latest', presetNo: raiderInfo.use_preset_no, raiderStats: raiderInfo.union_raider_stat || [], occupiedStats: raiderInfo.union_occupied_stat || [], innerStats: raiderInfo.union_inner_stat?.map((stat) => ({ fieldId: stat.stat_field_id, effect: stat.stat_field_effect, })) || [], blocks: { total: raiderInfo.union_block?.length || 0, byClass: blocksByClass, details: raiderInfo.union_block || [], }, }, { executionTime, cacheHit: false, apiCalls: 2, // OCID lookup + raider info }); } catch (error) { context.logger.error('Failed to get union raider info', { characterName, error: error instanceof Error ? error.message : String(error), }); return this.formatError(`Failed to get union raider info for character "${characterName}": ${error instanceof Error ? error.message : String(error)}`); } } } exports.GetUnionRaiderTool = GetUnionRaiderTool; /** * Tool for getting union ranking */ class GetUnionRankingTool extends base_tool_1.EnhancedBaseTool { name = 'get_union_ranking'; description = 'Retrieve union power rankings for a specific world or overall rankings'; inputSchema = { type: 'object', properties: { worldName: { type: 'string', description: 'World name to get rankings for (optional, gets all worlds if not specified)', enum: [ '스카니아', '베라', '루나', '제니스', '크로아', '유니온', '엘리시움', '이노시스', '레드', '오로라', '아케인', '노바', '리부트', '리부트2', ], }, characterName: { type: 'string', description: 'Specific character name to search for in rankings (optional)', minLength: 1, maxLength: 12, pattern: '^[a-zA-Z0-9가-힣]+$', }, page: { type: 'integer', description: 'Page number for pagination (1-based, optional, defaults to 1)', minimum: 1, maximum: 200, default: 1, }, date: { type: 'string', description: 'Date for rankings in YYYY-MM-DD format (optional, defaults to yesterday)', pattern: '^\\d{4}-\\d{2}-\\d{2}$', }, }, additionalProperties: false, }; metadata = { category: base_tool_1.ToolCategory.UNION, tags: ['union', 'ranking', 'power', 'leaderboard'], examples: [ { description: 'Get union rankings for all worlds', arguments: {}, }, { description: 'Get union rankings for specific world', arguments: { worldName: '스카니아' }, }, { description: 'Get union rankings for specific character', arguments: { characterName: '스카니아용사' }, }, { description: 'Get page 2 of union rankings', arguments: { worldName: '스카니아', page: 2 }, }, ], }; async executeImpl(args, context) { const worldName = this.getOptionalString(args, 'worldName'); const characterName = this.getOptionalString(args, 'characterName'); const page = this.getOptionalNumber(args, 'page', 1); const date = this.getOptionalString(args, 'date'); try { const startTime = Date.now(); let ocid; // If character name is provided, get OCID for search if (characterName) { context.logger.info('Looking up character OCID for union ranking search', { characterName, }); const ocidResult = await context.nexonClient.getCharacterOcid(characterName); ocid = ocidResult.ocid; } // Get union rankings context.logger.info('Fetching union rankings', { worldName: worldName || undefined, characterName: characterName || undefined, ocid: ocid ? `${ocid.substring(0, 8)}...` : undefined, page, }); const rankings = await context.nexonClient.getUnionRanking(worldName, ocid, page, date); const executionTime = Date.now() - startTime; const rankingData = rankings.ranking?.map((entry) => ({ rank: entry.ranking, characterName: entry.character_name, world: entry.world_name, class: entry.class_name, subClass: entry.sub_class_name, unionLevel: entry.union_level, unionPower: entry.union_power, date: entry.date, })) || []; context.logger.info('Union rankings retrieved successfully', { worldName: worldName || undefined, characterName: characterName || undefined, page, resultsCount: rankingData.length, executionTime, }); return this.formatResult({ page, pageSize: rankingData.length, worldName: worldName || 'all', searchCharacter: characterName || undefined, date: date || 'latest', rankings: rankingData, summary: { totalResults: rankingData.length, topUnionLevel: rankingData.length > 0 ? Math.max(...rankingData.map((r) => r.unionLevel)) : 0, topUnionPower: rankingData.length > 0 ? Math.max(...rankingData.map((r) => r.unionPower)) : 0, worldDistribution: rankingData.reduce((acc, entry) => { acc[entry.world] = (acc[entry.world] || 0) + 1; return acc; }, {}), }, }, { executionTime, cacheHit: false, apiCalls: characterName ? 2 : 1, // OCID lookup (if needed) + rankings }); } catch (error) { context.logger.error('Failed to get union rankings', { worldName: worldName || undefined, characterName: characterName || undefined, page, error: error instanceof Error ? error.message : String(error), }); return this.formatError(`Failed to get union rankings: ${error instanceof Error ? error.message : String(error)}`); } } } exports.GetUnionRankingTool = GetUnionRankingTool; //# sourceMappingURL=union-tools.js.map