get_historical_scores
Retrieve historical fantasy football player scores for specific weeks and seasons from Sleeper leagues to analyze past performance trends.
Instructions
Get actual historical fantasy points scored by players
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| league | No | League name (ROAD_TO_GLORY or DYNASTY), defaults to configured default | |
| players | No | Array of player IDs to get historical scores for (optional - gets your roster if not provided) | |
| position | No | Filter by position (QB, RB, WR, TE, K, DEF) | |
| season | No | Season year (defaults to current NFL season) | |
| week | Yes | Week number to get historical scores for |
Implementation Reference
- src/tools/HistoricalScoresTool.ts:41-230 (handler)Main handler function that executes the tool: determines league, fetches user roster if needed, retrieves NFL stats for the week/season, matches player stats, computes fantasy points (PPR, half, std), detailed stats, efficiency metrics, and returns formatted results.async execute(args: any) { const leagueConfig = getLeagueConfig(args.league); if (!leagueConfig) { throw new Error(`League configuration not found for: ${args.league}`); } const week = args.week; const season = args.season || this.getCurrentNflSeason(); try { let playerIds = args.players; // If no specific players requested, get user's roster if (!playerIds) { const [rostersResponse, usersResponse] = await Promise.all([ fetch(`${config.api.baseUrl}/league/${leagueConfig.id}/rosters`), fetch(`${config.api.baseUrl}/league/${leagueConfig.id}/users`) ]); if (!rostersResponse.ok || !usersResponse.ok) { throw new Error('Failed to fetch roster data'); } const rosters = await rostersResponse.json(); const users = await usersResponse.json(); const userMap = new Map(users.map((user: any) => [user.user_id, user])); const myRoster = rosters.find((roster: any) => { const user: any = userMap.get(roster.owner_id); return user?.display_name === config.username || user?.username === config.username || user?.display_name === leagueConfig.teamName || user?.username === leagueConfig.teamName; }); if (myRoster) { playerIds = myRoster.players; } } if (!playerIds || playerIds.length === 0) { throw new Error('No players found to get historical scores for'); } // Fetch historical stats for the specified week/season const statsResponse = await fetch(`${config.api.baseUrl}/stats/nfl/regular/${season}/${week}`); if (!statsResponse.ok) { throw new Error(`Failed to fetch stats for week ${week} of ${season} season`); } const allStats = await statsResponse.json(); // Fetch player data for player names and info const playersResponse = await fetch(`${config.api.baseUrl}/players/nfl`); if (!playersResponse.ok) { throw new Error('Failed to fetch player data'); } const players = await playersResponse.json(); // Process player historical scores const playerScores = []; for (const playerId of playerIds) { const player = players[playerId]; if (!player) continue; // Apply position filter if specified if (args.position && player.position !== args.position) { continue; } const playerStats = allStats[playerId] || {}; playerScores.push({ playerId, name: `${player.first_name} ${player.last_name}`, position: player.position, team: player.team, status: player.status, week: week, season: season, actualPoints: { ppr: Number((playerStats.pts_ppr || 0).toFixed(2)), halfPpr: Number((playerStats.pts_half_ppr || 0).toFixed(2)), standard: Number((playerStats.pts_std || 0).toFixed(2)) }, detailedStats: { // Passing Stats passingYards: playerStats.pass_yd || 0, passingTDs: playerStats.pass_td || 0, passingInterceptions: playerStats.pass_int || 0, passingAttempts: playerStats.pass_att || 0, passingCompletions: playerStats.pass_cmp || 0, completionPercentage: Number((playerStats.cmp_pct || 0).toFixed(1)), passerRating: Number((playerStats.pass_rtg || 0).toFixed(1)), yardsPerAttempt: Number((playerStats.pass_ypa || 0).toFixed(2)), airYards: playerStats.pass_air_yd || 0, sacksTaken: playerStats.pass_sack || 0, passingFirstDowns: playerStats.pass_fd || 0, // Rushing Stats rushingYards: playerStats.rush_yd || 0, rushingTDs: playerStats.rush_td || 0, rushingAttempts: playerStats.rush_att || 0, rushingYardsPerAttempt: Number((playerStats.rush_ypa || 0).toFixed(2)), rushingYardsAfterContact: playerStats.rush_yac || 0, brokenTackles: playerStats.rush_btkl || 0, longestRush: playerStats.rush_lng || 0, rushingFirstDowns: playerStats.rush_fd || 0, // Receiving Stats receivingYards: playerStats.rec_yd || 0, receivingTDs: playerStats.rec_td || 0, receptions: playerStats.rec || 0, targets: playerStats.rec_tgt || 0, receivingAirYards: playerStats.rec_air_yd || 0, yardsAfterCatch: playerStats.rec_yac || 0, yardsPerReception: Number((playerStats.rec_ypr || 0).toFixed(2)), yardsPerTarget: Number((playerStats.rec_ypt || 0).toFixed(2)), drops: playerStats.rec_drop || 0, longestReception: playerStats.rec_lng || 0, receivingFirstDowns: playerStats.rec_fd || 0, // Kicking Stats fieldGoalsMade: playerStats.fgm || 0, fieldGoalsAttempted: playerStats.fga || 0, fieldGoalPercentage: playerStats.fgm_pct || 0, longestFieldGoal: playerStats.fgm_lng || 0, extraPointsMade: playerStats.xpm || 0, extraPointsAttempted: playerStats.xpa || 0, // Miscellaneous fumbles: playerStats.fum || 0, fumblesLost: playerStats.fum_lost || 0, penalties: playerStats.penalty || 0, penaltyYards: playerStats.penalty_yd || 0 }, snapCounts: { offensiveSnaps: playerStats.off_snp || 0, teamOffensiveSnaps: playerStats.tm_off_snp || 0, teamDefensiveSnaps: playerStats.tm_def_snp || 0, teamSpecialTeamsSnaps: playerStats.tm_st_snp || 0, specialTeamsSnaps: playerStats.st_snp || 0 }, efficiencyMetrics: { catchRate: playerStats.rec_tgt > 0 ? Number(((playerStats.rec || 0) / playerStats.rec_tgt * 100).toFixed(1)) : 0, snapPercentage: playerStats.tm_off_snp > 0 ? Number(((playerStats.off_snp || 0) / playerStats.tm_off_snp * 100).toFixed(1)) : 0, touchdownRate: (playerStats.rush_att || 0) + (playerStats.rec_tgt || 0) > 0 ? Number((((playerStats.rush_td || 0) + (playerStats.rec_td || 0)) / ((playerStats.rush_att || 0) + (playerStats.rec_tgt || 0)) * 100).toFixed(1)) : 0, redZoneTargets: playerStats.rec_rz_tgt || 0, redZoneCarries: playerStats.rush_rz_att || 0 }, rankings: { ppr: playerStats.pos_rank_ppr || 999, halfPpr: playerStats.pos_rank_half_ppr || 999, standard: playerStats.pos_rank_std || 999 } }); } // Sort by PPR points (highest first) playerScores.sort((a: any, b: any) => b.actualPoints.ppr - a.actualPoints.ppr); const result = { week, season, league: args.league || config.defaultLeague, totalPlayers: playerScores.length, historicalScores: playerScores, summary: { totalPprPoints: playerScores.reduce((sum: number, p: any) => sum + p.actualPoints.ppr, 0), averageScore: playerScores.length > 0 ? (playerScores.reduce((sum: number, p: any) => sum + p.actualPoints.ppr, 0) / playerScores.length).toFixed(1) : 0, topScorer: playerScores[0] || null, playersWhoScored: playerScores.filter((p: any) => p.actualPoints.ppr > 0).length } }; return { content: [ { type: "text", text: JSON.stringify(result, null, 2), }, ], }; } catch (error) { throw new Error(`Failed to get historical scores: ${error instanceof Error ? error.message : String(error)}`); } }
- Defines the input schema for the tool parameters including league, week (required), season, players array, and position filter.inputSchema = { type: "object", properties: { league: { type: "string", description: "League name (ROAD_TO_GLORY or DYNASTY), defaults to configured default", enum: ["ROAD_TO_GLORY", "DYNASTY"] }, week: { type: "number", description: "Week number to get historical scores for", minimum: 1, maximum: 18 }, season: { type: "string", description: "Season year (defaults to current NFL season)", pattern: "^[0-9]{4}$" }, players: { type: "array", description: "Array of player IDs to get historical scores for (optional - gets your roster if not provided)", items: { type: "string" } }, position: { type: "string", description: "Filter by position (QB, RB, WR, TE, K, DEF)", enum: ["QB", "RB", "WR", "TE", "K", "DEF"] } }, required: ["week"] };
- src/index.ts:86-87 (registration)Registers the tool handler in the main switch statement for CallToolRequestSchema, delegating execution to the HistoricalScoresTool instance.case "get_historical_scores": return await historicalScoresTool.execute(args);
- src/index.ts:48-63 (registration)Registers the tool instance in the list of available tools returned by ListToolsRequestSchema.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ leagueTool, rosterTool, matchupTool, playerTool, projectionsTool, matchupProjectionsTool, lineupOptimizerTool, trendingTool, historicalScoresTool, playerNewsTool, transactionsTool, stateScheduleTool, ], }));
- Helper method to determine the current NFL season based on the date (September onwards uses current year, otherwise previous).private getCurrentNflSeason(): string { const now = new Date(); const currentYear = now.getFullYear(); const currentMonth = now.getMonth() + 1; // getMonth() returns 0-11 // NFL season typically starts in September and runs through February of next year // If we're in Jan-July, we're still in the previous year's NFL season // If we're in Aug-Dec, we're in the current year's NFL season if (currentMonth >= 8) { return currentYear.toString(); } else { return (currentYear - 1).toString(); } } }