Skip to main content
Glama

get_team_years

Read-onlyIdempotent

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

TableJSON Schema
NameRequiredDescriptionDefault
teamNoTeam number (no prefix), e.g. 86
yearNoFour-digit year (2002 onwards)
countryNoCapitalized country name, e.g. USA or Canada.
stateNoCapitalized two-letter state code, e.g. NC.
districtNoDistrict abbreviation. One of: ca, fch, fim, fin, fit, fma, fnc, fsc, isr, ne, ont, pch, pnw, win.
metricNoHow to sort the returned values. Any column in the table is valid.
ascendingNoWhether to sort in ascending order. Default is ascending.
limitNoMaximum number of results to return (1-1000). Default is 1000.
offsetNoOffset from the first result to return.

Implementation Reference

  • 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) }],
      };
    }
  • 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),
    },
  • 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);
      }
    }
  • 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}` : '';
    }
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds the return structure (array of records with EPA, record, ranks, awards, district points) and pagination behavior, providing context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single paragraph with clear structure: main purpose, filter details, examples. No extraneous words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 9 parameters and no output schema, the description fully covers the tool's capabilities: filter combinations, sorting, pagination, and return structure. It is complete for the intended use cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds meaning by listing the fields in each record, explaining filter combinations, and clarifying that metric can be any column. This exceeds mere schema information.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists per-season FRC team statistics with flexible filters. It names the resource (team-year records) and distinguishes from sibling get_team_year by explicitly noting that team+year combination is equivalent to that tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use guidance: cross-team or cross-year analysis, with four example queries. It also notes when to use the sibling tool (get_team_year) for single team-year pairs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/withinfocus/statbotics-mcp-server'

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