get_team_years
Retrieve per-season FRC team statistics across multiple years, filter by team, year, or location, and sort results by metrics like EPA or rank.
Instructions
List per-season FIRST Robotics Competition (FRC) team statistics with flexible filters - useful for cross-team or cross-year analysis. Returns an array of team-year records (each row is one team's stats for one season: EPA, record, ranks, awards, district points). Filter by team (a single team across many seasons), year (all teams in one season), country, state, and district. Combine filters - e.g. team+year is equivalent to get_team_year. Sort with metric/ascending and paginate with limit/offset. Use this to answer "show team 254 in every season", "rank all teams by EPA in 2023", or "find the strongest teams in the New England district in 2024".
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| team | No | Team number (no prefix), e.g. 86 | |
| year | No | Four-digit year (2002 onwards) | |
| country | No | Capitalized country name, e.g. USA or Canada. | |
| state | No | Capitalized two-letter state code, e.g. NC. | |
| district | No | District abbreviation. One of: ca, fch, fim, fin, fit, fma, fnc, fsc, isr, ne, ont, pch, pnw, win. | |
| metric | No | How to sort the returned values. Any column in the table is valid. | |
| ascending | No | Whether to sort in ascending order. Default is ascending. | |
| limit | No | Maximum number of results to return (1-1000). Default is 1000. | |
| offset | No | Offset from the first result to return. |
Implementation Reference
- src/handlers.ts:99-126 (handler)The handler function for the 'get_team_years' tool. It destructures input arguments (team, year, country, state, district, metric, ascending, limit, offset) validated via GetTeamYearsInputSchema, builds a query string, calls GET /v3/team_years on the Statbotics API, and returns JSON results.
case 'get_team_years': { const { team, year, country, state, district, metric, ascending, limit, offset, } = GetTeamYearsInputSchema.parse(args); const qs = buildQueryString({ team, year, country, state, district, metric, ascending, limit, offset, }); const data = await makeApiRequest(`/v3/team_years${qs}`); return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }], }; } - src/schemas.ts:126-135 (schema)The Zod input schema for get_team_years. Defines optional fields: team (number), year (number), country (string), state (string), district (string), plus pagination/sort fields (metric, ascending, limit, offset).
export const GetTeamYearsInputSchema = z.object({ team: TeamNumberSchema.optional().describe( 'Team number (no prefix), e.g. 86', ), year: YearSchema.optional().describe('Four-digit year (2002 onwards)'), country: CountrySchema, state: StateSchema, district: DistrictSchema, ...PaginationSortFields, }); - src/tools.ts:116-133 (registration)The tool registration entry for 'get_team_years'. Defines the tool name, description, read-only annotations, title, and links it to GetTeamYearsInputSchema for input validation.
{ name: 'get_team_years', description: 'List per-season FIRST Robotics Competition (FRC) team statistics with flexible filters - useful for ' + 'cross-team or cross-year analysis. ' + "Returns an array of team-year records (each row is one team's stats for one season: EPA, record, ranks, " + 'awards, district points). ' + 'Filter by `team` (a single team across many seasons), `year` (all teams in one season), `country`, ' + '`state`, and `district`. Combine filters - e.g. team+year is equivalent to get_team_year. ' + 'Sort with `metric`/`ascending` and paginate with `limit`/`offset`. ' + 'Use this to answer "show team 254 in every season", "rank all teams by EPA in 2023", or ' + '"find the strongest teams in the New England district in 2024".', annotations: { title: 'List/Search FRC Team Season Stats', ...readOnlyAnnotations, }, inputSchema: toMCPSchema(GetTeamYearsInputSchema), }, - src/utils.ts:23-50 (helper)The makeApiRequest helper used by the handler to call the Statbotics API. It takes an endpoint path, fetches from api.statbotics.io, and returns parsed JSON.
export async function makeApiRequest(endpoint: string): Promise<unknown> { try { const url = `https://api.statbotics.io${endpoint}`; const response = await fetch(url, { headers: { Accept: 'application/json', }, }); if (!response.ok) { const errorMessage = `Statbotics API request failed: ${response.status} ${response.statusText} for endpoint ${endpoint}`; await log('error', errorMessage); throw new Error(errorMessage); } return response.json(); } catch (error) { if (error instanceof Error) { const errorMessage = `API request error for endpoint ${endpoint}: ${error.message}`; await log('error', errorMessage); throw error; } const errorMessage = `Unknown error during API request for endpoint ${endpoint}`; await log('error', `${errorMessage}: ${error}`); throw new Error(errorMessage); } } - src/handlers.ts:19-28 (helper)The buildQueryString helper used to construct URL query parameters from the schema-filtered arguments.
function buildQueryString(params: Record<string, unknown>): string { const searchParams = new URLSearchParams(); for (const [key, value] of Object.entries(params)) { if (value !== undefined && value !== null) { searchParams.set(key, String(value)); } } const qs = searchParams.toString(); return qs ? `?${qs}` : ''; }