UNPKG

plaier-mcp-server

Version:

MCP Server for Plaier Football API - Advanced football analytics and predictions

338 lines 17 kB
import { validateInput, PlayerSearchSchema, PlayerDetailsSchema, PlayerRankingSchema, TeamPlayersSchema, TournamentPlayersSchema, } from '../utils/validation.js'; import { formatPlayerInfo, formatPlayerRanking, formatError, formatDataSummary } from '../utils/formatting.js'; export function createPlayerTools(client) { return [ { name: "search_players", description: "Search for football players by name using fuzzy search. Supports nicknames and can be narrowed by team.", inputSchema: { type: "object", properties: { player_name: { type: "string", description: "Player name to search for (minimum 3 characters). Supports nicknames and partial matches." }, team_name: { type: "string", description: "Optional team name to narrow the search results" }, show_details: { type: "boolean", description: "If true, returns full player details. If false, returns only player ID.", default: false } }, required: ["player_name"] } }, { name: "get_player_details", description: "Get detailed information about a specific player including stats, team, position, and market value.", inputSchema: { type: "object", properties: { player_id: { type: "number", description: "The unique ID of the player" } }, required: ["player_id"] } }, { name: "rank_players", description: "Get a ranked list of players with advanced filtering options. Can filter by tournament, team, age, nationality, position, and sort by different criteria.", inputSchema: { type: "object", properties: { tournament_ids: { type: "array", items: { type: "number" }, description: "Filter by specific tournament IDs" }, team_ids: { type: "array", items: { type: "number" }, description: "Filter by specific team IDs" }, age: { type: "number", description: "Filter by exact age (cannot use with min_age/max_age)" }, min_age: { type: "number", description: "Minimum age filter" }, max_age: { type: "number", description: "Maximum age filter" }, nationality_ids: { type: "array", items: { type: "number" }, description: "Filter by nationality IDs" }, position_ids: { type: "array", items: { type: "number" }, description: "Filter by specific position IDs" }, position_group_ids: { type: "array", items: { type: "number" }, description: "Filter by position group IDs (e.g., defenders, midfielders)" }, in_national_team: { type: "boolean", description: "Filter by national team status" }, sort_by: { type: "string", enum: ["score", "fair-market-value", "value-for-money"], description: "Sort criteria: score (default), fair-market-value, or value-for-money", default: "score" }, limit: { type: "number", description: "Maximum number of players to return (1-1000, default 50)", default: 50 } } } }, { name: "get_team_players", description: "Get all players from a specific team with their details.", inputSchema: { type: "object", properties: { team_id: { type: "number", description: "The unique ID of the team" } }, required: ["team_id"] } }, { name: "get_tournament_players", description: "Get all players from a specific tournament.", inputSchema: { type: "object", properties: { tournament_id: { type: "number", description: "The unique ID of the tournament" }, limit: { type: "number", description: "Maximum number of players to show in summary (default 20)", default: 20 } }, required: ["tournament_id"] } }, ]; } export async function handlePlayerTool(toolName, args, client) { try { switch (toolName) { case "search_players": { const params = validateInput(PlayerSearchSchema, args); try { // Build search parameters const searchParams = { player_name: params.player_name, show_details: params.show_details || false }; if (params.team_name) searchParams.team_name = params.team_name; const result = await client.searchPlayer(searchParams); if (params.show_details) { const player = result; return `Found player:\n\n${formatPlayerInfo(player)}`; } else { const playerId = result; return `Found player ID: ${playerId}\n\nUse get_player_details with this ID to get full player information.`; } } catch (error) { return formatError(`No player found matching "${params.player_name}". The search requires at least 3 characters and uses fuzzy matching.`); } } case "get_player_details": { const params = validateInput(PlayerDetailsSchema, args); try { const result = await client.getPlayers({ player_id: params.player_id }); if (!result) { return formatError(`No player found with ID ${params.player_id}`); } const player = result; return formatPlayerInfo(player); } catch (error) { return formatError(`Error retrieving player details for ID ${params.player_id}: ${error}`); } } case "rank_players": { const params = validateInput(PlayerRankingSchema, args); try { // Create clean params object without undefined values const rankingParams = {}; if (params.tournament_ids) rankingParams.tournament_ids = params.tournament_ids; if (params.team_ids) rankingParams.team_ids = params.team_ids; if (params.age !== undefined) rankingParams.age = params.age; if (params.min_age !== undefined) rankingParams.min_age = params.min_age; if (params.max_age !== undefined) rankingParams.max_age = params.max_age; if (params.nationality_ids) rankingParams.nationality_ids = params.nationality_ids; if (params.position_ids) rankingParams.position_ids = params.position_ids; if (params.position_group_ids) rankingParams.position_group_ids = params.position_group_ids; if (params.in_national_team !== undefined) rankingParams.in_national_team = params.in_national_team; if (params.sort_by) rankingParams.sort_by = params.sort_by; const players = await client.getPlayerRanking(rankingParams); if (players.length === 0) { return formatError('No players found matching the specified criteria.'); } const displayLimit = Math.min(params.limit || 50, 20); // Show max 20 in chat let result = formatPlayerRanking(players, displayLimit); // Add filter summary const filters = []; if (params.tournament_ids) filters.push(`tournaments: ${params.tournament_ids.length}`); if (params.team_ids) filters.push(`teams: ${params.team_ids.length}`); if (params.age) filters.push(`age: ${params.age}`); if (params.min_age || params.max_age) { const ageRange = `${params.min_age || 'any'}-${params.max_age || 'any'}`; filters.push(`age range: ${ageRange}`); } if (params.nationality_ids) filters.push(`nationalities: ${params.nationality_ids.length}`); if (params.position_ids) filters.push(`positions: ${params.position_ids.length}`); if (params.position_group_ids) filters.push(`position groups: ${params.position_group_ids.length}`); if (params.in_national_team !== undefined) { filters.push(`national team: ${params.in_national_team ? 'yes' : 'no'}`); } if (filters.length > 0) { result += `\n**Filters applied:** ${filters.join(', ')}\n`; } result += `**Sorted by:** ${params.sort_by || 'score'}\n`; result += formatDataSummary('Players', displayLimit, players.length); return result; } catch (error) { return formatError(`Error retrieving player rankings: ${error}`); } } case "get_team_players": { const params = validateInput(TeamPlayersSchema, args); try { const result = await client.getPlayers({ team_id: params.team_id }); const players = Array.isArray(result) ? result : [result]; if (players.length === 0) { return formatError(`No players found for team ID ${params.team_id}`); } // Get team name for better display let teamName = `Team ID ${params.team_id}`; if (players.length > 0 && players[0].team_name) { teamName = players[0].team_name; } // Sort players by score (highest first) const sortedPlayers = players.sort((a, b) => b.score - a.score); let resultText = `**Players in ${teamName} (${players.length} total):**\n\n`; // Show top 15 players with basic info const displayLimit = Math.min(sortedPlayers.length, 15); sortedPlayers.slice(0, displayLimit).forEach((player, index) => { resultText += `${index + 1}. **${player.player_name}** (${player.age})\n`; resultText += ` - Position: ${player.position} | Score: ${player.score} | Value: €${player.fair_market_value}M\n\n`; }); if (players.length > displayLimit) { resultText += `... and ${players.length - displayLimit} more players.\n\n`; } // Group by position for summary const byPosition = players.reduce((acc, player) => { if (!acc[player.position_group]) { acc[player.position_group] = 0; } acc[player.position_group]++; return acc; }, {}); resultText += `**Position Distribution:**\n`; Object.entries(byPosition).forEach(([position, count]) => { resultText += `- ${position}: ${count} players\n`; }); resultText += `\n💡 **Tip:** Use get_player_details with a player ID for complete information.`; return resultText; } catch (error) { return formatError(`Error retrieving players for team ID ${params.team_id}: ${error}`); } } case "get_tournament_players": { const params = validateInput(TournamentPlayersSchema, args); try { const result = await client.getPlayers({ tournament_id: params.tournament_id }); const players = Array.isArray(result) ? result : [result]; if (players.length === 0) { return formatError(`No players found for tournament ID ${params.tournament_id}`); } // Get tournament name for better display let tournamentName = `Tournament ID ${params.tournament_id}`; if (players.length > 0 && players[0].tournament_name) { tournamentName = players[0].tournament_name; } // Sort players by score (highest first) const sortedPlayers = players.sort((a, b) => b.score - a.score); const displayLimit = args.limit || 20; const topPlayers = sortedPlayers.slice(0, displayLimit); let resultText = `**Top ${displayLimit} Players in ${tournamentName} (${players.length} total):**\n\n`; topPlayers.forEach((player, index) => { resultText += `${index + 1}. **${player.player_name}** (${player.team_name})\n`; resultText += ` - Position: ${player.position} | Age: ${player.age} | Score: ${player.score}\n`; resultText += ` - Nationality: ${player.nationality} | Value: €${player.fair_market_value}M\n\n`; }); // Group by position for summary const byPosition = players.reduce((acc, player) => { if (!acc[player.position_group]) { acc[player.position_group] = 0; } acc[player.position_group]++; return acc; }, {}); resultText += `**Position Distribution:**\n`; Object.entries(byPosition).forEach(([position, count]) => { resultText += `- ${position}: ${count} players\n`; }); if (players.length > displayLimit) { resultText += `\n💡 **Tip:** Use rank_players with tournament_id filter for more advanced filtering and sorting.`; } return resultText; } catch (error) { return formatError(`Error retrieving players for tournament ID ${params.tournament_id}: ${error}`); } } default: throw new Error(`Unknown player tool: ${toolName}`); } } catch (error) { return formatError(`Tool execution failed: ${error}`); } } //# sourceMappingURL=player-tools.js.map