maplestory-mcp-server
Version:
Official-style NEXON MapleStory MCP Server for Claude Desktop - Complete character info, union details, guild data, rankings, and game mechanics
278 lines • 11.4 kB
JavaScript
;
/**
* Guild Information Tools for MCP Maple
* Provides MCP tools for retrieving MapleStory guild information
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.GetGuildRankingTool = exports.GetGuildInfoTool = void 0;
const base_tool_1 = require("./base-tool");
/**
* Tool for getting guild basic information
*/
class GetGuildInfoTool extends base_tool_1.EnhancedBaseTool {
name = 'get_guild_info';
description = 'Retrieve basic information about a MapleStory guild including level, members, and skills';
inputSchema = {
type: 'object',
properties: {
guildName: {
type: 'string',
description: 'The name of the guild to look up',
minLength: 1,
maxLength: 12,
},
worldName: {
type: 'string',
description: 'The world/server name where the guild exists',
enum: [
'스카니아',
'베라',
'루나',
'제니스',
'크로아',
'유니온',
'엘리시움',
'이노시스',
'레드',
'오로라',
'아케인',
'노바',
'리부트',
'리부트2',
],
},
date: {
type: 'string',
description: 'Date for guild info in YYYY-MM-DD format (optional, defaults to yesterday)',
pattern: '^\\d{4}-\\d{2}-\\d{2}$',
},
},
required: ['guildName', 'worldName'],
additionalProperties: false,
};
metadata = {
category: base_tool_1.ToolCategory.GUILD,
tags: ['guild', 'info', 'members', 'skills', 'level'],
examples: [
{
description: 'Get guild info',
arguments: { guildName: '길드명', worldName: '스카니아' },
},
{
description: 'Get guild info for specific date',
arguments: { guildName: '길드명', worldName: '스카니아', date: '2024-01-15' },
},
],
};
async executeImpl(args, context) {
const guildName = this.getRequiredString(args, 'guildName');
const worldName = this.getRequiredString(args, 'worldName');
const date = this.getOptionalString(args, 'date');
try {
const startTime = Date.now();
// Get guild ID first
context.logger.info('Looking up guild ID', { guildName, worldName });
const guildIdResult = await context.nexonClient.getGuildId(guildName, worldName);
const oguildId = guildIdResult.oguild_id;
// Get guild basic info
context.logger.info('Fetching guild basic info', { guildName, worldName, oguildId });
const guildInfo = await context.nexonClient.getGuildBasic(oguildId, date);
const executionTime = Date.now() - startTime;
// Process guild skills for better presentation
const regularSkills = guildInfo.guild_skill?.map((skill) => ({
name: skill.skill_name,
description: skill.skill_description,
level: skill.skill_level,
effect: skill.skill_effect,
icon: skill.skill_icon,
})) || [];
const noblesseSkills = guildInfo.guild_noblesse_skill?.map((skill) => ({
name: skill.skill_name,
description: skill.skill_description,
level: skill.skill_level,
effect: skill.skill_effect,
icon: skill.skill_icon,
})) || [];
context.logger.info('Guild info retrieved successfully', {
guildName: guildInfo.guild_name,
worldName: guildInfo.world_name,
level: guildInfo.guild_level,
memberCount: guildInfo.guild_member_count,
executionTime,
});
return this.formatResult({
guildName: guildInfo.guild_name,
worldName: guildInfo.world_name,
level: guildInfo.guild_level,
fame: guildInfo.guild_fame,
point: guildInfo.guild_point,
masterName: guildInfo.guild_master_name,
memberCount: guildInfo.guild_member_count,
members: guildInfo.guild_member || [],
skills: {
regular: regularSkills,
noblesse: noblesseSkills,
totalSkills: regularSkills.length + noblesseSkills.length,
},
date: guildInfo.date || date || 'latest',
}, {
executionTime,
cacheHit: false,
apiCalls: 2, // Guild ID lookup + basic info
});
}
catch (error) {
context.logger.error('Failed to get guild info', {
guildName,
worldName,
error: error instanceof Error ? error.message : String(error),
});
return this.formatError(`Failed to get info for guild "${guildName}" in world "${worldName}": ${error instanceof Error ? error.message : String(error)}`);
}
}
}
exports.GetGuildInfoTool = GetGuildInfoTool;
/**
* Tool for getting guild ranking
*/
class GetGuildRankingTool extends base_tool_1.EnhancedBaseTool {
name = 'get_guild_ranking';
description = 'Retrieve guild rankings for a specific world or overall rankings';
inputSchema = {
type: 'object',
properties: {
worldName: {
type: 'string',
description: 'World name to get guild rankings for (optional, gets all worlds if not specified)',
enum: [
'스카니아',
'베라',
'루나',
'제니스',
'크로아',
'유니온',
'엘리시움',
'이노시스',
'레드',
'오로라',
'아케인',
'노바',
'리부트',
'리부트2',
],
},
guildName: {
type: 'string',
description: 'Specific guild name to search for in rankings (optional)',
minLength: 1,
maxLength: 12,
},
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.GUILD,
tags: ['guild', 'ranking', 'leaderboard', 'level'],
examples: [
{
description: 'Get guild rankings for all worlds',
arguments: {},
},
{
description: 'Get guild rankings for specific world',
arguments: { worldName: '스카니아' },
},
{
description: 'Get guild rankings for specific guild',
arguments: { guildName: '길드명' },
},
{
description: 'Get page 2 of guild rankings',
arguments: { worldName: '스카니아', page: 2 },
},
],
};
async executeImpl(args, context) {
const worldName = this.getOptionalString(args, 'worldName');
const guildName = this.getOptionalString(args, 'guildName');
const page = this.getOptionalNumber(args, 'page', 1);
const date = this.getOptionalString(args, 'date');
try {
const startTime = Date.now();
// Note: Guild ranking API uses guild name directly, not oguild_id
// Get guild rankings
context.logger.info('Fetching guild rankings', {
worldName: worldName || undefined,
guildName: guildName || undefined,
page,
});
const rankings = await context.nexonClient.getGuildRanking(worldName || '전체', 0, // ranking_type: 0 for level ranking
guildName, page || 1, date);
const executionTime = Date.now() - startTime;
const rankingData = rankings.ranking?.map((entry) => ({
rank: entry.ranking,
guildName: entry.guild_name,
world: entry.world_name,
level: entry.guild_level,
masterName: entry.guild_master_name,
guildMark: entry.guild_mark,
guildPoint: entry.guild_point,
date: entry.date,
})) || [];
context.logger.info('Guild rankings retrieved successfully', {
worldName: worldName || undefined,
guildName: guildName || undefined,
page,
resultsCount: rankingData.length,
executionTime,
});
return this.formatResult({
page,
pageSize: rankingData.length,
worldName: worldName || 'all',
searchGuild: guildName || undefined,
date: date || 'latest',
rankings: rankingData,
summary: {
totalResults: rankingData.length,
topLevel: rankingData.length > 0 ? Math.max(...rankingData.map((r) => r.level)) : 0,
averageLevel: rankingData.length > 0
? Math.round(rankingData.reduce((sum, r) => sum + r.level, 0) / rankingData.length)
: 0,
topGuildPoint: rankingData.length > 0 ? Math.max(...rankingData.map((r) => r.guildPoint)) : 0,
worldDistribution: rankingData.reduce((acc, entry) => {
acc[entry.world] = (acc[entry.world] || 0) + 1;
return acc;
}, {}),
},
}, {
executionTime,
cacheHit: false,
apiCalls: 1, // Guild rankings only
});
}
catch (error) {
context.logger.error('Failed to get guild rankings', {
worldName: worldName || undefined,
guildName: guildName || undefined,
page,
error: error instanceof Error ? error.message : String(error),
});
return this.formatError(`Failed to get guild rankings: ${error instanceof Error ? error.message : String(error)}`);
}
}
}
exports.GetGuildRankingTool = GetGuildRankingTool;
//# sourceMappingURL=guild-tools.js.map