statbotics
Provides tools for accessing FIRST Robotics Competition statistical data, including team EPA ratings, event predictions, match analytics, and year-over-year performance data via the Statbotics API.
Statbotics MCP Server
A Model Context Protocol (MCP) server that provides access to the Statbotics API for FIRST Robotics Competition statistical data and predictions. Enables AI assistants and other MCP clients to retrieve FRC team EPA ratings, event predictions, and match analytics.
Features
Team Statistics: Get EPA ratings, win rates, and historical performance for FRC teams
Event Data: Access event details, predictions, and team performance at events
Match Analytics: Retrieve match predictions, results, and team-level match statistics
Year-over-Year Data: Query statistical trends from 2002 to the current year
Type Safety: All responses validated with Zod schemas
No API Key Required: Statbotics API is freely accessible
Related MCP server: StatsPlus MCP Server
Installation
npm (Recommended)
npm install -g @withinfocus/statbotics-mcp-serverDocker
Pull the image from GitHub Container Registry:
docker pull ghcr.io/withinfocus/statbotics-mcp-server:latestOr build locally:
git clone https://github.com/withinfocus/statbotics-mcp-server.git
cd statbotics-mcp-server
docker build -t statbotics-mcp-server .Usage
With npm
Add to your MCP client configuration (e.g., Claude Desktop):
{
"mcpServers": {
"statbotics": {
"command": "npx",
"args": ["-y", "@withinfocus/statbotics-mcp-server"]
}
}
}With Docker
Add to your MCP client configuration:
{
"mcpServers": {
"statbotics": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--init",
"ghcr.io/withinfocus/statbotics-mcp-server:latest"
]
}
}
}Available Tools
Year Tools (2 tools)
Query season-level statistical data.
Tools: get_year, get_years
Team Tools (2 tools)
Access team profiles and EPA ratings.
Tools: get_team, get_teams
Team Year Tools (2 tools)
Get team statistics for specific seasons.
Tools: get_team_year, get_team_years
Event Tools (2 tools)
Query event details and predictions.
Tools: get_event, get_events
Team Event Tools (2 tools)
Get team performance at specific events.
Tools: get_team_event, get_team_events
Match Tools (2 tools)
Retrieve match data and predictions.
Tools: get_match, get_matches
Team Match Tools (2 tools)
Get team-level match statistics.
Tools: get_team_match, get_team_matches
Quick Examples
Get team information
// Get team EPA ratings and statistics
get_team(team: 86)
// Get team's performance in a specific year
get_team_year(team: 86, year: 2024)Analyze an event
// Get event statistics
get_event(event: "2024flor")
// Get all team performances at an event
get_team_events(event: "2024flor")Get match data
// Get match predictions and results
get_match(match: "2024flor_qm20")
// Get team's performance in a match
get_team_match(team: 86, match: "2024flor_qm20")Contributing
Contributions are welcome! See CONTRIBUTING.md for development setup, testing guidelines, and how to add new tools.
Related Links
Statbotics - FRC statistical analysis
Statbotics API Documentation - Official API docs
Model Context Protocol - MCP specification
FIRST Robotics Competition - Official FRC site
Available Tools
14 toolsget_eventARead-onlyIdempotent
Look up a single FIRST Robotics Competition (FRC) event by its event key. Returns metadata (event name, year, week, type, location, dates, district), aggregate EPA stats for participating teams, qualification and playoff status, and Statbotics predictions for the event (e.g. winner probabilities). Event keys follow the format <year><event-code>, e.g. "2024flor" (FLOR = Orlando regional 2024), "2024necmp" (New England district championship 2024), "2024cmptx" (Houston champs 2024). Use this to answer "what happened at 2024flor?", "show predictions for 2024cmptx", or to get context (week, type, location) for an event you have the key for. For browsing events by season, district, or week, use get_events.
| Name | Required | Description | Default |
|---|---|---|---|
| event | Yes | Event key, e.g. 2024flor |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly=true, destructive=false, idempotent=true. Description adds details: returns metadata, aggregate EPA stats, qualification/playoff status, and Statbotics predictions, plus explains event key format. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise three-sentence structure. First sentence states purpose, second details what is returned, third gives usage examples and alternatives. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (single parameter, no output schema, strong annotations), the description fully covers input format, output contents, and when to choose alternatives. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with one required parameter 'event'. Description adds value by explaining event key format with examples and meaning, beyond the schema's brief description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'look up', resource 'single FRC event', and method 'by its event key'. It distinguishes from sibling get_events by specifying it's for a single event vs browsing multiple.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use examples: 'what happened at 2024flor?', 'show predictions', 'get context'. Also gives explicit when-not-to-use and alternative: 'For browsing events by season, district, or week, use get_events'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_eventsARead-onlyIdempotent
List FIRST Robotics Competition (FRC) events with optional filters - the discovery tool for finding event keys and browsing the season schedule. Returns an array of events with name, key, dates, location, week, type, EPA stats, and predictions. Filter by year (4-digit, >=2002), country, state, district, type (regional, district, district_cmp, champs_div, einstein, offseason), and week (0-8 of the season; 8 = championship). Sort with metric/ascending and paginate with limit/offset. Use this to answer "what regionals were in California in 2024?", "list all week 1 events this year", or "find the FRC championship divisions" (year=YEAR, type="champs_div"). If you need a single event you already know, use get_event.
| Name | Required | Description | Default |
|---|---|---|---|
| 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. | |
| type | No | One of: regional, district, district_cmp, champs_div, einstein, or offseason. | |
| week | No | Week of the competition season. 8 is CMP. | |
| 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true. The description adds value by specifying the return shape ('array of events with name, key, dates, location, week, type, EPA stats, and predictions') and behavior for sorting/pagination. No contradictions; it enriches understanding.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise yet comprehensive, using well-structured sentences: purpose, return fields, parameter guide, examples, and sibling comparison. No redundant text; each sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 10 optional parameters and no output schema, the description fully covers filters, sorting, pagination, return type, and provides interactive examples. It also references the sibling tool, making it complete for an AI agent to select and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions for each parameter, but the description adds extra meaning by grouping filters and explaining their purpose (e.g., 'week 0-8 of the season; 8 = championship'). It also details sorting and pagination parameters beyond the schema's basic descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List FIRST Robotics Competition (FRC) events' and positions it as a discovery tool. It differentiates from the sibling get_event by noting it's for finding event keys and browsing the season schedule, with examples like 'what regionals were in California in 2024?'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage scenarios with example queries and mentions when to use the sibling get_event instead ('If you need a single event you already know, use get_event.'). It explains the role of each filter parameter in context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_matchARead-onlyIdempotent
Look up a single FIRST Robotics Competition (FRC) match by its match key. Returns full match detail: red and blue alliance team lists, final scores by alliance and component (auto, teleop, endgame, fouls), ranking points awarded, win/tie outcome, the Statbotics pre-match win probability and predicted score, and elimination flag. Match keys follow the format <event-key>_<match-code>, e.g. "2024flor_qm20" (qualification match 20), "2024flor_sf2m1" (semifinal 2 match 1), "2024flor_f1m3" (finals match 3). Use this to answer "who won 2024flor_qm20?", "what was the predicted vs actual score?", or to get alliance compositions for a known match. For browsing many matches, use get_matches.
| Name | Required | Description | Default |
|---|---|---|---|
| match | Yes | Match key, e.g. 2024flor_qm20 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly and idempotent, so no contradiction. The description adds behavioral context by listing returned fields, match key format, and the Statbotics data, which is valuable 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with purpose, then output summary, then usage guidance, then sibling alternative. Every sentence adds value with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description thoroughly lists all return values. Combined with annotations and a well-documented single parameter, the definition is fully complete for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Parameter schema already describes the match key, but description adds detailed format and examples (e.g., '2024flor_qm20') that enhance understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool looks up a single FRC match by match key and returns full match detail. It explicitly distinguishes itself from the sibling tool get_matches which is for browsing many matches.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage examples and states when to use this tool versus get_matches. Gives concrete queries like 'who won 2024flor_qm20?' to guide the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_matchesARead-onlyIdempotent
List FIRST Robotics Competition (FRC) matches with optional filters. Returns an array of match records (alliances, scores, predictions, EPA-based win probabilities, elim flag). Filter by team (every match a team played in), year, event (every match at one event), week (0-8), and elim (true for playoff/elimination matches only, false for qualifications only). Sort with metric/ascending and paginate with limit/offset. Use this to answer "show all of team 254's matches in 2024", "list every elim match at 2024cmptx", or "find the highest-scoring matches of week 6". For per-team match contributions (a team's individual EPA in a match), use get_team_matches.
| Name | Required | Description | Default |
|---|---|---|---|
| team | No | Team number (no prefix), e.g. 86 | |
| year | No | Four-digit year (2002 onwards) | |
| event | No | Event key, e.g. 2024flor | |
| week | No | Week of the competition season. 8 is CMP. | |
| elim | No | Whether the match is an elimination match. | |
| 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=true. The description adds valuable behavioral context such as return structure (array of match records with specific fields) and filtering behavior. Does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single paragraph that is information-dense yet concise. Front-loads purpose, then lists filters, provides examples, and ends with alternative tool. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema, the description explains return format (array with fields), covers all 9 optional parameters with examples, and addresses sorting and pagination. Complete enough for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (all parameters described in schema). The description adds natural language explanations and usage examples (e.g., 'every match at one event' for event parameter), providing additional meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists FRC matches with filters. It specifies the resource (matches) and action (list), and distinguishes from sibling tools like get_match and get_team_matches by explicitly mentioning alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit examples of when to use (e.g., 'show all of team 254's matches in 2024') and when not to use (e.g., per-team match contributions should use get_team_matches). Gives clear context and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_teamARead-onlyIdempotent
Look up the Statbotics profile for a single FIRST Robotics Competition (FRC) team by team number. Returns lifetime/career data for that team: team name, rookie year, location (city, state/province, country), active status, current and historical EPA ratings, normalized EPA (norm_epa), career win/loss/tie record, and career win rate. Use this to answer "tell me about FRC team 254", "where is team 2056 based?", or "what is team 1678's career EPA?". The team number is the bare integer with no FRC/frc prefix (e.g. 86, not "frc86"). For per-season detail, use get_team_year. For filtering or browsing many teams, use get_teams.
| Name | Required | Description | Default |
|---|---|---|---|
| team | Yes | Team number (no prefix), e.g. 86 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, and the description adds valuable context about returned fields and input format constraints (no prefix), without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (about 100 words) and front-loaded with the primary function, but could be slightly more structured (e.g., separate examples). Each sentence contributes meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple parameter schema and no output schema, the description fully covers the tool's purpose, input requirements, output details, and usage context, leaving no critical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema coverage is 100% and already describes the parameter (integer team number, no prefix). The description reiterates this but adds no deeper semantics, so baseline score applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Look up') and resource ('Statbotics profile for a single FRC team'), and explicitly names sibling tools (get_team_year, get_teams) for alternative use cases, making the purpose clear and differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit when-to-use (lifetime/career data for a single team), when-not-to-use (per-season detail or browsing many teams) with named alternatives, and includes example queries to guide the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_team_eventARead-onlyIdempotent
Get one team's performance at one specific FIRST Robotics Competition (FRC) event. Returns the team's qualification rank, qualification record (W-L-T), playoff alliance and result, EPA at this event (start, end, mean, breakdown by score component), and award list. Requires both team (integer, no prefix) and event (event key like "2024flor"). Use this to answer "how did team 2056 do at 2024onham?", "what was team 254's EPA at champs?", or "what awards did team 1114 win at their district championship?". For browsing many team-event combinations, use get_team_events.
| Name | Required | Description | Default |
|---|---|---|---|
| team | Yes | Team number (no prefix), e.g. 86 | |
| event | Yes | Event key, e.g. 2024flor |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=true, destructiveHint=false, idempotentHint=true. Description adds value by detailing return fields, but no mention of error handling or edge cases. Still strong behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with purpose, then returned data, examples, and alternative. No unnecessary words. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but description fully explains return values (qual rank, record, playoff result, EPA breakdown, awards). Parameter requirements are clear. Complete for a single team-event lookup tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema already has 100% coverage with descriptions. Description adds examples and clarifications (team integer no prefix, event key format like '2024flor'), going beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Get one team's performance at one specific FRC event' and lists returned fields (qual rank, record, playoff result, EPA, awards). Distinguishes from sibling tool get_team_events.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit example queries ('how did team 2056 do at 2024onham?') and explicitly says to use get_team_events for browsing many combinations. Clear when-to-use and when-not-to-use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_team_eventsARead-onlyIdempotent
List FIRST Robotics Competition (FRC) team-event records with flexible filters. Each row represents one team's performance at one event (rank, record, EPA, awards). Filter any combination of team (one team across all events), year, event (all teams at one event - great for getting an event's full team list with stats), country, state, district, type (regional, district, district_cmp, champs_div, einstein, offseason), and week (0-8). Sort with metric/ascending and paginate with limit/offset. Use this to answer "show every event team 254 has attended in 2024", "list all teams at 2024flor with their ranks", or "rank teams by EPA across all 2024 district championships".
| Name | Required | Description | Default |
|---|---|---|---|
| team | No | Team number (no prefix), e.g. 86 | |
| year | No | Four-digit year (2002 onwards) | |
| event | No | Event key, e.g. 2024flor | |
| 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. | |
| type | No | One of: regional, district, district_cmp, champs_div, einstein, or offseason. | |
| week | No | Week of the competition season. 8 is CMP. | |
| 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, etc. Description adds crucial detail about output structure (rank, record, EPA, awards), sorting, and pagination. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence adds unique value: purpose, row definition, filter enumeration, sort/pagination, and example queries. No redundancy, well front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, description fully explains output structure, all filter options, sorting, pagination limits (1-1000), and includes three concrete example queries, making it self-contained for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all 12 parameters with descriptions (100% coverage). Description adds value by grouping filters, explaining sort metric flexibility, and providing concrete labeling ('district_cmp', 'week 8 is CMP').
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'List FIRST Robotics Competition (FRC) team-event records with flexible filters' and explains each row represents a team's performance at an event. Examples concretely differentiate from sibling tools like get_team or get_event by emphasizing team-event granularity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage scenarios ('Use this to answer...') and filter combinations. Lacks explicit when-not-to-use or comparison to siblings, but context is clear enough for appropriate selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_team_matchARead-onlyIdempotent
Get a single team's contribution to a single FIRST Robotics Competition (FRC) match - the per-robot view of one match. Returns which alliance the team was on (red/blue), the team's EPA going into the match, the team's predicted score contribution by component, and post-match outcome flags. Useful for scouting and post-match analysis: "how much did team 2056 contribute to alliance score in 2024onham_sf2m1?". Requires both team (integer, no prefix) and match (match key like "2024flor_qm20"). For listing many team-match rows, use get_team_matches.
| Name | Required | Description | Default |
|---|---|---|---|
| team | Yes | Team number (no prefix), e.g. 86 | |
| match | Yes | Match key, e.g. 2024flor_qm20 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds behavioral details about the return data (alliance, EPA, predicted score components, outcome flags) and parameter requirements. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (two sentences plus usage example) and front-loaded with the purpose. Every sentence adds value, no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with two parameters and no output schema, the description covers what the tool returns, how to use it, and when to use alternatives. It is complete enough for an agent to select and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and already describes parameters. The description adds clarity by explaining 'team (integer, no prefix)' and providing a match key example ('2024flor_qm20'), which aids agent understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Get'), identifies the resource ('single team's contribution to a single FRC match'), and distinguishes from the sibling tool 'get_team_matches' which lists many rows. It clearly states the per-robot view and provides an example query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool ('scouting and post-match analysis') and provides an alternative ('For listing many team-match rows, use get_team_matches'). It also specifies required parameters and format.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_team_matchesARead-onlyIdempotent
List per-team match contributions across many FIRST Robotics Competition (FRC) matches. Each row is one team's involvement in one match (alliance, pre-match EPA, predicted contribution, outcome). Filter by team (one team's entire match log), year, event, week (0-8), match (a single match key - returns one row per team in that match), and elim (true for elimination matches only). Sort with metric/ascending and paginate with limit/offset. Use this to build a scouting timeline ("every match team 254 played in 2024 with their EPA contribution"), compare alliance partners, or compute per-team averages over a range of matches.
| Name | Required | Description | Default |
|---|---|---|---|
| team | No | Team number (no prefix), e.g. 86 | |
| year | No | Four-digit year (2002 onwards) | |
| event | No | Event key, e.g. 2024flor | |
| week | No | Week of the competition season. 8 is CMP. | |
| match | No | Match key, e.g. 2024flor_qm20 | |
| elim | No | Whether the match is an elimination match. | |
| 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint, idempotentHint, and openWorldHint. The description adds context about return structure (each row is one team's involvement, includes alliance, EPA, contribution, outcome) and filtering logic. It does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: first sentence states purpose, then enumerates parameters and their effects, then provides example use cases. No redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (10 parameters, no output schema), the description covers all filters, sorting, pagination, and gives usage examples. Missing details like default behavior when no parameters or empty results, but overall complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 beyond schema by explaining 'week' values (0-8, 8 is CMP) and that 'match' returns one row per team. This improves clarity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists per-team match contributions across many FRC matches, with a specific verb (list) and resource (team-match contributions). It distinguishes from siblings like get_team_match by implying bulk retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit use cases (scouting timeline, comparing alliance partners, computing averages) and explains filters. However, it does not explicitly contrast with sibling tools or state when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_teamsARead-onlyIdempotent
List FIRST Robotics Competition (FRC) teams from the Statbotics database with optional filters. Returns an array of team profiles (number, name, location, rookie year, active flag, career EPA stats, career win rate). Filter by country (e.g. "USA", "Canada"), state (two-letter code, e.g. "NC", "CA"), district (one of ca, fch, fim, fin, fit, fma, fnc, fsc, isr, ne, ont, pch, pnw, win), and active (true to limit to teams that competed in the last year). Sort with metric/ascending (e.g. metric="norm_epa", ascending=false to find the strongest active teams) and paginate with limit/offset. Use this to answer "which teams in Texas are most successful?", "list all teams in the FIM district", or "find the top 50 teams by normalized EPA".
| Name | Required | Description | Default |
|---|---|---|---|
| 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. | |
| active | No | Whether the team has played in the last year. | |
| 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so no contradiction. Description adds value beyond annotations by detailing return fields (number, name, location, etc.) and filter semantics (e.g., active filter limits to teams in last year). Could mention rate limits or data freshness, but overall good.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single paragraph, front-loaded with purpose, then details filters and examples. Every sentence adds value; could be slightly more concise but clear and well-structured. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, so description fully compensates by explicitly listing return fields. All 8 parameters are explained with usage examples. Covers filtering, sorting, and pagination. Complete for a list/search tool with good annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds significant context: provides example values for country/state, lists all district options, explains how metric/ascending work with a concrete example, and clarifies pagination with limit/offset. This goes well beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List FIRST Robotics Competition (FRC) teams from the Statbotics database with optional filters,' using a specific verb and resource. It distinguishes from sibling tools like get_team by focusing on listing multiple teams with filters.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit example queries ('which teams in Texas are most successful?') that guide when to use this tool. Does not explicitly exclude single-team lookup, but sibling context implies it. The examples are clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_team_yearARead-onlyIdempotent
Get one team's performance summary for one specific FIRST Robotics Competition (FRC) season. Returns the team's EPA breakdown for that year (start, pre-playoffs, end, max, mean, ranks/percentiles), win/loss/tie record and win rate, count and list of events attended, district points, and award totals. Use this to answer "how did team 2056 do in 2023?", "what was team 254's peak EPA in 2018?", or "how many events did team 1114 attend in 2024?". Requires both team number (integer, no prefix) and a 4-digit year >= 2002. For multi-team or multi-year browsing, use get_team_years.
| Name | Required | Description | Default |
|---|---|---|---|
| team | Yes | Team number (no prefix), e.g. 86 | |
| year | Yes | Four-digit year (2002 onwards) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds value by clarifying the input constraints ('team number (integer, no prefix)' and '4-digit year >= 2002') and listing the output structure (EPA breakdown, win/loss, etc.), which agents need to understand behavior beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no wasted words. It front-loads the purpose, then gives concrete examples, and ends with requirements and an alternative. Every sentence serves a distinct purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter read tool with full schema descriptions and annotations, the description completely covers the tool's purpose, output, required parameters, and relationship to siblings. No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already has 100% coverage with descriptions for both parameters. The description adds nuance: clarifies that the team number has no prefix ('no prefix') and that the year must be a 4-digit year from 2002 onwards. This goes beyond the schema's minimum/maximum constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Get') and resource ('one team's performance summary for one specific FRC season'), and lists the exact data fields returned. It also explicitly distinguishes from the sibling tool 'get_team_years' by stating 'For multi-team or multi-year browsing, use get_team_years.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear example queries ('how did team 2056 do in 2023?') and explicitly states when to use an alternative ('For multi-team or multi-year browsing, use get_team_years.'), giving both usage context and exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_team_yearsARead-onlyIdempotent
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".
| 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. |
TDQS
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.
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.
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.
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.
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.
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.
get_yearARead-onlyIdempotent
Look up Statbotics season summary statistics for a single FIRST Robotics Competition (FRC) year. Returns aggregate metrics for the game played that year: EPA (Expected Points Added) percentile breakpoints (mean, median, 75th/90th/95th/99th), score component averages, foul rates, RP (ranking point) rates, and the count of teams, events, and matches recorded. Use this to answer questions like "what was the average score in the 2024 FRC season?", "what EPA put a team in the top 10% in 2019?", or to calibrate per-year scoring before comparing teams across seasons. Data is available for years 2002 onward; pre-2016 seasons have less detail because the EPA model was less granular. For comparing many seasons in one call, use get_years instead.
| Name | Required | Description | Default |
|---|---|---|---|
| year | Yes | Four-digit year (2002 onwards) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint, so no contradiction. Description adds useful behavioral context: results are aggregate metrics, and pre-2016 seasons have less detail due to EPA model granularity. This goes 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences efficiently cover purpose, examples, and caveats. No fluff; every sentence adds value. Front-loaded with the verb phrase 'Look up...'.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with robust annotations, the description fully explains what the tool returns, when to use it, and limitations. No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, the schema already describes the year parameter. The description adds value by clarifying the valid range (2002 onward) and noting that pre-2016 years return less detailed data, which is not in the schema description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it looks up season summary statistics for a single FRC year, listing specific metrics like EPA breakpoints and score averages. Distinguishes from sibling get_years by noting its single-year scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit example questions and directly states when to use get_years instead for multi-season comparison. Also mentions data availability from 2002 onward and the caveat for pre-2016 detail.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_yearsARead-onlyIdempotent
List Statbotics season summary statistics across multiple FIRST Robotics Competition (FRC) years in a single call. Returns the same per-season aggregates as get_year (EPA percentiles, scoring averages, foul/RP rates, counts) but as an array, with optional sorting and pagination. Use this to chart trends over time, e.g. "how have average match scores evolved from 2002 to today?", "which seasons had the highest top-1% EPA?", or to dump the full season catalog for downstream analysis. Sort with metric (any returned column name, e.g. epa_max, score_mean) and ascending; paginate with limit (1-1000, default 1000) and offset.
| Name | Required | Description | Default |
|---|---|---|---|
| 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint, destructiveHint, idempotentHint, and openWorldHint. The description adds that the tool returns an array with the same aggregates as get_year, and explains sorting/pagination behavior. This provides additional useful 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with a clear first sentence stating purpose and return type, and a second sentence providing usage examples and parameter details. No fluff, every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite missing output schema, the description explains the return type (array of per-season aggregates like get_year) and covers sorting, pagination, and use cases. It is comprehensive for a list tool of moderate complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover 100% of parameters. The description adds examples for metric (e.g., epa_max, score_mean), clarifies ascending defaults, and provides default values for limit (1000) and offset (0). This adds meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists season summary statistics across multiple FRC years, specifying it returns an array of per-season aggregates similar to get_year. It distinguishes itself from get_year (single year) by explicitly mentioning the array format and optional sorting/pagination.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit use cases such as charting trends over time and dumping the full season catalog. It implies when to use (multiple years) but does not explicitly state when not to use or name alternatives like get_year for single year. However, the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool targets a distinct entity or aggregation (event, events, match, matches, team, team_event, etc.) with no functional overlap. The 'single vs. list' pattern and team-entity combinations are clearly separated.
All tool names follow the 'get_' prefix with snake_case entity names, consistently using singular for single-item lookups and plural for list lookups. The pattern is uniform across all 14 tools.
14 tools is well-scoped for the FRC analytics domain. Each tool serves a necessary query pattern (single, list, team-specific, seasonal) without redundancy or bloat.
The tool surface covers all fundamental query patterns for the Statbotics API: individual and batch lookups for events, matches, teams, and team-specific data, plus seasonal summaries. No obvious gaps for a read-only stats service.
Maintenance
Related MCP Connectors
Live sports stats and pre-computed analysis for AI assistants across NBA, MLB, NFL, and NHL.
Provide detailed Pokémon data and information through a standardized MCP interface. Enable LLMs an…
MLB Stats API MCP — official MLB statistics (keyless).
Hosted MCP server for live public-data APIs and Skills for AI agents.
Related MCP Servers
- AlicenseAqualityAmaintenanceThe Blue Alliance MCP server using its API for FIRST Robotics Competition data. Retrieve comprehensive FRC team, event, and match information.61871MIT
- AlicenseAqualityCmaintenanceExposes the StatsPlus API as tools for MCP-compatible clients, enabling users to query player/team statistics, contracts, ratings, and game history via natural language.154MIT
- AlicenseNot gradedqualityCmaintenanceProvides access to official MLB statistics via a keyless API, enabling AI agents to query MLB data through natural language or direct tools.6MIT
- AlicenseNot gradedqualityAmaintenanceProvides verified NFL stats (2016–2025) and Sleeper league context through an MCP server, with tools for querying metrics, comparing entities, verifying claims, and accessing league data.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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