Skip to main content
Glama

optimize_lineup

Generate optimal fantasy football lineups using player projections and analytics to maximize weekly scoring potential based on league type and week.

Instructions

Suggest optimal lineup based on projections

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
leagueNoLeague name (ROAD_TO_GLORY or DYNASTY), defaults to configured default
weekNoWeek number (defaults to current week)

Implementation Reference

  • The main execute method implementing the optimize_lineup tool logic: fetches roster, projections, groups players, optimizes lineup, and returns analysis.
    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 || this.getCurrentWeek(); const season = new Date().getFullYear().toString(); try { // Fetch league settings, roster, and player data const [leagueResponse, rostersResponse, usersResponse, playersResponse] = await Promise.all([ fetch(`${config.api.baseUrl}/league/${leagueConfig.id}`), fetch(`${config.api.baseUrl}/league/${leagueConfig.id}/rosters`), fetch(`${config.api.baseUrl}/league/${leagueConfig.id}/users`), fetch(`${config.api.baseUrl}/players/nfl`) ]); if (!leagueResponse.ok || !rostersResponse.ok || !usersResponse.ok || !playersResponse.ok) { throw new Error('Failed to fetch lineup optimization data'); } const league = await leagueResponse.json(); const rosters = await rostersResponse.json(); const users = await usersResponse.json(); const players = await playersResponse.json(); const userMap = new Map(users.map((user: any) => [user.user_id, user])); // Find user's roster 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) { throw new Error(`Could not find roster for user: ${config.username}`); } // Get league roster positions (lineup requirements) const rosterPositions = league.roster_positions; // Fetch individual projections for roster players const projectionPromises = myRoster.players.map(async (playerId: string) => { try { const projectionResponse = await fetch( `https://api.sleeper.app/projections/nfl/player/${playerId}?season=${season}&season_type=regular&week=${week}` ); if (projectionResponse.ok) { const data = await projectionResponse.json(); return { playerId, projectedPoints: data.stats?.pts_ppr || 0 }; } return { playerId, projectedPoints: 0 }; } catch (error) { console.warn(`Failed to fetch projection for player ${playerId}:`, error); return { playerId, projectedPoints: 0 }; } }); const projectionResults = await Promise.all(projectionPromises); const playerProjections = new Map( projectionResults.map(r => [r.playerId, r.projectedPoints]) ); // Create player pool with projections const playerPool = myRoster.players.map((playerId: string) => { const player = players[playerId]; if (!player) return null; const projectedPoints = playerProjections.get(playerId) || 0; return { playerId, name: `${player.first_name} ${player.last_name}`, position: player.position, team: player.team, status: player.status, projectedPoints: Number(projectedPoints.toFixed(2)), eligiblePositions: player.fantasy_positions || [player.position] }; }).filter(Boolean).filter((p: any) => p.status === 'Active'); // Sort players by projected points within each position const playersByPosition = this.groupPlayersByPosition(playerPool); // Optimize lineup based on roster positions const optimizedLineup = this.optimizeLineup(playersByPosition, rosterPositions); const currentStarters = myRoster.starters; // Calculate current vs optimal projections const currentProjection = currentStarters.reduce((sum: number, playerId: string) => { return sum + (playerProjections.get(playerId) || 0); }, 0); const optimalProjection = optimizedLineup.reduce((sum: number, player: any) => sum + player.projectedPoints, 0); // Find suggested changes const changes = this.findLineupChanges(currentStarters, optimizedLineup, players); const result = { week, season, league: args.league || config.defaultLeague, currentLineup: { starters: currentStarters.map((playerId: string) => { const player = players[playerId]; const projectedPoints = playerProjections.get(playerId) || 0; return { playerId, name: player ? `${player.first_name} ${player.last_name}` : 'Unknown', position: player?.position || 'UNK', team: player?.team || 'UNK', projectedPoints: Number(projectedPoints.toFixed(2)) }; }), totalProjected: currentProjection.toFixed(1) }, optimizedLineup: { starters: optimizedLineup, totalProjected: optimalProjection.toFixed(1) }, analysis: { projectedImprovement: (optimalProjection - currentProjection).toFixed(1), isOptimal: Math.abs(optimalProjection - currentProjection) < 0.1, suggestedChanges: changes, rosterPositions: rosterPositions } }; return { content: [ { type: "text", text: JSON.stringify(result, null, 2), }, ], }; } catch (error) { throw new Error(`Failed to optimize lineup: ${error instanceof Error ? error.message : String(error)}`); } }
  • Input schema for the tool, defining optional league and week parameters.
    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 (defaults to current week)", minimum: 1, maximum: 18 } } };
  • src/index.ts:82-83 (registration)
    Registration in the CallToolRequestSchema handler switch statement, routing calls to the tool instance.
    case "optimize_lineup": return await lineupOptimizerTool.execute(args);
  • src/index.ts:48-63 (registration)
    Registration of the tool instance in the ListToolsRequestSchema handler for tool discovery.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ leagueTool, rosterTool, matchupTool, playerTool, projectionsTool, matchupProjectionsTool, lineupOptimizerTool, trendingTool, historicalScoresTool, playerNewsTool, transactionsTool, stateScheduleTool, ], }));
  • Core helper function that selects the optimal players for each roster position based on projections, handling FLEX and SUPER_FLEX specially.
    private optimizeLineup(playersByPosition: { [key: string]: any[] }, rosterPositions: string[]) { const lineup: any[] = []; const usedPlayers = new Set<string>(); // Fill specific positions first rosterPositions.forEach(position => { if (position === 'BN') return; // Skip bench slots let bestPlayer: any = null; if (position === 'FLEX') { // For FLEX, consider RB, WR, TE const flexEligible = ['RB', 'WR', 'TE']; flexEligible.forEach(pos => { if (playersByPosition[pos]) { playersByPosition[pos].forEach(player => { if (!usedPlayers.has(player.playerId) && (!bestPlayer || player.projectedPoints > bestPlayer.projectedPoints)) { bestPlayer = player; } }); } }); } else if (position === 'SUPER_FLEX') { // For SUPER_FLEX, consider all positions Object.keys(playersByPosition).forEach(pos => { playersByPosition[pos].forEach(player => { if (!usedPlayers.has(player.playerId) && (!bestPlayer || player.projectedPoints > bestPlayer.projectedPoints)) { bestPlayer = player; } }); }); } else { // Regular position if (playersByPosition[position]) { bestPlayer = playersByPosition[position].find(player => !usedPlayers.has(player.playerId) ); } } if (bestPlayer) { lineup.push({ ...bestPlayer, lineupPosition: position }); usedPlayers.add(bestPlayer.playerId); } }); return lineup; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/justfeltlikerunning/sleeper-fantasy-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server