Skip to main content
Glama

getcompetitive

npm version CI license node Glama

A Model Context Protocol (MCP) server that gives AI agents what they need to build, analyze, and validate Pokémon Champions teams: the official Regulation Sets, the usage-derived meta, and the battle math behind them.

Champions is the only game here. The server speaks its terms — doubles, level 50, Mega Evolution once per battle, 66 stat points, no Terastallization — and the Smogon-tier and archetype surface that used to sit alongside it is gone.

What it provides

  • 30 tools across six domains: data, team analysis, team workflows (paste in, diagnose, prepare matchups, learn from replays, scout sets, fill slots), meta (usage-derived), battle mechanics, and official regulation sets

  • Six workflow prompts/team-doctor, /matchup-prep, /build-around, /tournament-prep, /learn-my-team, /meta-report — server-provided templates that chain the deterministic tools, so compound workflows stay discoverable without a 40-tool surface

  • Structured, agent-first definitions — every tool declares MCP annotations and an output schema, returns structuredContent alongside JSON text, and documents all of its parameters; the deterministic half of the TDQS checklist is linted in CI

  • Full Pokémon Showdown dataset — species, alternate forms, stats, moves, items, abilities, natures, learnsets, types

  • Battle math from Smogon's calculator — stat calculation and full damage calculation (weather, terrain, boosts, items)

  • Both EV scales — the 0-252 EVs the calculator takes and Pokémon Champions' own 66 stat points, accepted on input and reported alongside every spread

  • Official Regulation Sets (M-A → M-C) with seasonal legal rosters and team legality checking

Built on @pkmn/dex (Showdown data) and @smogon/calc (battle math).

Related MCP server: Pokémon MCP Server

Tools

Data

Tool

Purpose

get_pokemon

Types, base stats, BST, abilities, forms, weight, gender, evolutions

list_forms

All forms of a species (alternate, cosmetic, battle-only)

get_sprites

Sprite URLs for a whole team in one call (artwork or icon), from a committed PokéAPI id table — URLs only, the server does no network I/O

search_dex

Fuzzy name search across species / moves / items / abilities / natures

get_move

Type, category, power, accuracy, PP, priority, target, secondary effects

get_item

Effect, flags, mega stone, Z-move, Fling, boosts

get_ability

Effect description, flags

get_nature

Boosts / lowers which stat

get_learnset

All learnable moves grouped by method (level-up, TM, egg, tutor, event)

get_type

Defensive weaknesses, resistances, immunities

get_type_matchup

Matchup multiplier, offensive coverage, or defensive chart (defender can be a species)

Team analysis

Tool

Purpose

analyze_team

Team synergy: stacked defensive weaknesses, offensive coverage gaps, speed placement, a heuristic score, and — with a regulation — coverage against the meta's real sets

Team workflows

Tool

Purpose

parse_team

Turn a Showdown/Pokepaste block (or a species @ item | ability | nature | EVs | moves one-liner) into the canonical team every tool takes; unknown names become warnings, not errors

format_team

Render a canonical team back into paste text, round-tripping through parse_team

diagnose_team

"Fix my team": weaknesses with evidence, then concrete spread, move, item and member changes, each backed by exact math or usage data

prepare_matchup

"Prepare me": their likely sets by usage, speed races with margins, key damage rolls, bring-four, leads, and win/loss conditions

analyze_replay

Post-match read of a battle log: teams, KOs with causes, observed Speed order, damage percentages, and a type-coverage read

infer_set

Reverse constraint solving: battle observations (who moved first, damage dealt/taken) narrow the opponent's likely set, ranked against the meta

optimize_team

Fill open team slots against constraints — cover these types, answer these threats — with reasons for every recommendation

Meta (usage-derived)

Tool

Purpose

list_threats

Most-used Pokemon of a regulation, ranked by measured usage (role, tier, usage share) with the sample and sources behind it

compare_meta

What is changing: last 7 days of usage vs the 7 before, per species and per two-species core, from a committed build-time aggregation

get_set

Most-played set for one or several species (item, ability, nature, EVs, 4 moves), with the Mega form and ability where relevant; covers each regulation's ranked species, which list_threats lists

Regulations (Pokémon Champions / VGC)

Tool

Purpose

list_regulations

Official Regulation Sets with dates, status, roster size, and how many species have usage-derived sets

get_regulation

Full set rules: battle rules, clauses, Mega rules, and roster sizes; the name rosters come back with includeRoster

check_legality

Validate a team against a set: illegal species, Species/Item Clause, illegal moves, team size, Mega eligibility

Battle mechanics

Tool

Purpose

calculate_stats

Final 6 stats at a level with EVs/IVs/nature (in-game formula)

calculate_damage

Full damage calc (sets, item, ability, boosts, weather, terrain, hazards)

calculate_matchups

Batch damage: one attacker vs many defenders — best move, damage range, KO chance, who moves first

check_speed

Final Speed (nature/EV/IV/boost/Scarf) vs a regulation roster's invested/uninvested speeds

optimize_evs

EV spread solver: min EVs to survive / outspeed / guarantee a KO, then maximize a stat

Install

npm

npm install -g getcompetitive   # or: npx getcompetitive

Docker

No Node.js or npm install required — the image builds the server from source:

docker build -t getcompetitive .
docker run -i --rm getcompetitive   # speaks MCP over stdio

From source

git clone https://github.com/mriver15/getcompetitive.git
cd getcompetitive
npm install
npm run build
npm start                       # starts the MCP server on stdio

Configure an MCP client

With npm:

{
  "mcpServers": {
    "getcompetitive": {
      "command": "npx",
      "args": ["getcompetitive"]
    }
  }
}

With Docker (after docker build -t getcompetitive .):

{
  "mcpServers": {
    "getcompetitive": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "getcompetitive"]
    }
  }
}

For Claude Desktop, add one of the same entries under mcpServers in claude_desktop_config.json.

Remote endpoint

The same surface runs over Streamable HTTP — the stateless remote mode, one request per transport, safe behind a load balancer:

node dist/http-server.js            # http://127.0.0.1:3000/mcp
PORT=8080 node dist/http-server.js

Connect a client with the URL http://<host>:<port>/mcp. TLS, auth and rate limiting are the deployer's concern: the server itself remains a pure offline read.

Workflow prompts

Six server-provided prompts make the compound workflows discoverable without adding a tool per workflow — each chains the deterministic tools, and each follows the same doctrine: the model explains, getcompetitive proves.

Prompt

What it chains

/team-doctor

parse_teamdiagnose_teamformat_team ("fix my team")

/matchup-prep

parse_teamprepare_matchup ("here is my opponent")

/build-around

get_setanalyze_teamdiagnose_teamcheck_legalityformat_team

/tournament-prep

get_regulationlist_threatsget_set (a pre-event briefing)

/learn-my-team

parse_teamanalyze_teamdiagnose_teamget_set (a team guide)

/meta-report

list_threatsget_set on the top five (a data-dated meta report)

Verify

npm test   # builds and drives every tool over real MCP stdio, plus the HTTP entrypoint

Example queries

  • get_pokemon { "species": "Ogerpon-Wellspring" }

  • get_type_matchup { "attacker": "Ice", "defender": "Garchomp" } → 4x super effective

  • calculate_stats { "species": "Garchomp", "level": 50, "nature": "Jolly", "evs": { "atk": 252, "spe": 252 } }

  • calculate_damage { "attacker": { "species": "Garchomp", "level": 50, "nature": "Jolly", "evs": { "atk": 252, "spe": 252 }, "item": "Choice Band" }, "defender": { "species": "Corviknight", "level": 50, "nature": "Impish", "evs": { "hp": 252, "def": 252 } }, "move": "Dragon Claw" }

  • check_legality { "regulation": "m-c", "team": [ { "species": "Garchomp", "item": "Choice Band" } ] }

  • analyze_team { "team": [ { "species": "Garchomp", "moves": ["Earthquake", "Dragon Claw", "Rock Slide"] } ], "regulation": "m-c" }

  • parse_team { "text": "Garchomp @ Choice Scarf | Rough Skin | Jolly | 252 Atk / 252 Spe | Earthquake / Dragon Claw" }

  • diagnose_team { "team": [ { "species": "Garchomp", "nature": "Jolly", "evs": { "atk": 252, "spe": 252 } } ], "goal": "improve against the current meta" }

  • prepare_matchup { "team": [ { "species": "Garchomp" } ], "opponent": ["Sneasler", "Salamence-Mega", "Gholdengo"] }

Data freshness

The Showdown dataset and battle math track @pkmn/dex / @smogon/calc. Official Regulation Sets change seasonally; the legal rosters are regenerated with node scripts/extract-regs.mjs, the threat list / standard sets (src/threats.ts) with node scripts/build-threats.mjs <regulation>, and the two-window usage history behind compare_meta with node scripts/build-meta-history.mjs <regulation> (it refuses to write unless every tournament in the window was fetched). All generated data files are committed, so the tools stay offline at runtime. See CONTRIBUTING.

Contributing

Pull requests welcome. See CONTRIBUTING for setup and conventions, and CODE_OF_CONDUCT for community standards.

License

MIT. Data is sourced from the Pokémon Showdown ecosystem and Bulbapedia; usage statistics come from Limitless TCG tournaments and the in-game ranked ladder as aggregated by MunchStats, cross-checked against Pikalytics. Pokémon is © Nintendo / Game Freak.

Available Tools

21 tools
analyze_teamAnalyze team synergyA
Read-onlyIdempotent

Analyze a whole team’s type synergy: per-type weak, resist, and immune counts with the types at risk, super-effective coverage from STAB and supplied moves, speed placement, and a transparent 0-100 heuristic score — a quick signal, not a metagame rating. With regulation it also reports threatCoverage: how the team fares against that regulation’s most-used sets, each threat’s real nature, EVs and Mega form included, listing the threats nothing on the team hits super-effectively. With opponent it reports bringFour: which four of your six to bring against that team, scored on the types team preview shows, plus the types that leaves stacked. Use get_type_matchup or get_type for one matchup. Each entry is a species with optional moves, nature, evs/championsPoints and item; unknown moves are collected into unknownMoves, unknown species error. Read-only and offline over the bundled dataset.

ParametersJSON Schema
NameRequiredDescriptionDefault
teamYesTeam of up to 6 members, each a species with optional moves and a set.
opponentNoOptional opponent team as species names, e.g. ["Salamence", "Sneasler", "Kingambit"]; the reply then recommends which four of your six to bring. This is what team preview gives you — species only, no sets — so the read is type-based. Unknown names return an isError.
regulationNoOptional regulation set id, e.g. "m-c"; when given, the reply also lists legal threats whose base speed beats your fastest member. Unknown ids return an isError.

Output Schema

ParametersJSON Schema
NameRequiredDescription
teamYesThe analysed team in the order it was supplied, each member with the typing actually used for the analysis.
scoreYesTransparent heuristic 0-100 scoring of the team.
speedYesWhere the team sits on the speed spectrum, plus legal faster threats when a regulation was given.
bringFourNoWhich four of the six to bring; present only when `opponent` was supplied.
atRiskTypesYesThe stacked-weakness types: at least two members weak to it and nobody resisting or immune. Empty means no such hole.
unknownMovesNoDeduplicated move names that were not found in the dataset and so contributed no coverage; omitted entirely when every move resolved.
threatCoverageNoHow the team fares against the regulation’s most-used sets; present only when a regulation with a usage-derived threat list was supplied.
offensiveCoverageYesSuper-effective coverage of all 18 defending types.
defensiveWeaknessesYesOne entry for each of the 18 classic types (keyed by type name, e.g. "Fire"), tallying how the team fares defensively against that type.

TDQS

A4.9/5.0
Behavior5/5

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

The description discloses important behaviors beyond the annotations: it is read-only and offline, unknown moves are collected into `unknownMoves`, unknown species or regulation ids produce errors, Speed-related set details affect coverage, and the score is explicitly 'a quick signal, not a metagame rating.' This is unusually transparent.

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

Conciseness4/5

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

The purpose is front-loaded and every clause adds useful information, but the description is a single dense run-on paragraph. Better paragraph breaks would improve scanability without adding length.

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?

For a complex analysis tool, the description covers inputs, optional modes, error behavior, limitation of the score, and read-only/offline nature. With an output schema present, nothing essential is left unexplained.

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

Parameters5/5

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

Even though schema coverage is 100%, the description adds real meaning to all three parameters: `regulation` triggers `threatCoverage`, `opponent` triggers `bringFour`, and team entries allow optional moves/set details whose unknown values are handled gracefully. It also clarifies that only Speed matters for EV/nature/item effects.

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 names the specific resource ('a whole team') and the analysis performed: per-type weak/resist/immune counts, coverage, speed placement, and a 0-100 heuristic score. It further distinguishes optional modes for regulation and opponent, and explicitly contrasts itself with get_type_matchup/get_type for single matchups.

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?

It says directly to use `get_type_matchup` or `get_type` for one matchup, implying this tool is for whole-team analysis. It also explains when the `regulation` and `opponent` parameters change the report, giving an agent clear situational routing.

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

calculate_damageCalculate damage for one matchupA
Read-onlyIdempotent

Simulate one attack end to end: one attacker set, one defender set, one named move, optionally under weather, terrain, game type, or side conditions. Use calculate_matchups when one attacker must be tested against several defenders, and calculate_stats for stat tables with no battle. field.weather takes Sand/Sun/Rain/Hail/Snow and field.terrain Electric/Grassy/Psychic/Misty; attackerSide/defenderSide take calc flags (isReflect, isLightScreen, isAuroraVeil, spikes 0-3, isSR), and set levels default to 100 here. Species and move names are validated first, so typos return an isError. Returns every damage roll, damageRange, koChance text, a description line, and both sets’ computed stats. Read-only and offline.

ParametersJSON Schema
NameRequiredDescriptionDefault
moveYesMove used by the attacker, e.g. "Earthquake", "Make It Rain"; must be a real move name.
fieldNoBattlefield conditions applied to the calc; omit it for a neutral Singles field with no weather, terrain, or hazards.
attackerYesThe attacking Pokémon: species plus optional level, nature, IVs, EVs, item, ability, boosts, status, and current HP.
defenderYesThe defending Pokémon, same fields as `attacker`; its Defense/SpD, HP, typing, and ability drive the result.

Output Schema

ParametersJSON Schema
NameRequiredDescription
moveYesCanonical move name that was calculated, e.g. "Dragon Claw".
fieldYesThe battlefield the calc ran under, echoed back with its defaults filled in.
damageYesDamage dealt by the attack: a single number for a straight-damage move (0 when the defender is immune), a flat list of rolls for a move that rolls its own damage (e.g. False Swipe), or one roll list per hit for a multi-hit move (e.g. Population Bomb, Dragon Darts).
attackerYesThe attacking set as the calc resolved it, including the six stats it swung with.
defenderYesThe defending set as the calc resolved it, including the six stats it was hit on.
koChanceNoHuman-readable KO chance, e.g. "guaranteed OHKO" or "31.3% chance to 2HKO"; an empty string when no KO is possible (e.g. False Swipe), and absent when the calc could not describe the matchup at all, which is the immunity case.
damageRangeYes[minimum, maximum] damage: `calculate_damage` totals every roll (multi-hit moves are summed), while `calculate_matchups` reports the flattened per-hit rolls, so its bounds stay single-hit values. [0, 0] means nothing could be calculated.
descriptionYesOne-line summary of the whole matchup, e.g. "252 Atk Choice Band Garchomp Dragon Claw vs. 252 HP / 252+ Def Corviknight: 64-76 (16.4 - 19.5%) -- possible 6HKO"; an explicit 0-damage note when the calc could not describe it.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context beyond that: name validation with isError on typos, level defaults, and the exact contents of the return value.

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 dense but every sentence adds value: what the tool does, when to use siblings, side-condition flag examples, validation behavior, output contents, and its read-only nature. It is front-loaded with the core action and does not waste 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?

For a tool with nested objects, required parameters, and an output schema, the description provides enough standalone context: inputs, defaults, sibling disambiguation, validation behavior, return contents, and safety. The structured schema and output schema fill the remaining mechanical details.

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?

The schema already covers nearly all parameters, but the description adds meaning for side flags by listing isReflect, isLightScreen, isAuroraVeil, spikes 0-3, and isSR, which the schema does not enumerate. It also clarifies level default and the battlefield togls, going beyond the baseline schema coverage.

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 states a specific verb and resource: 'Simulate one attack end to end' with one attacker, one defender, and one named move. It also distinguishes itself from calculate_matchups (one attacker vs many defenders) and calculate_stats (no battle), making tool selection unambiguous.

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?

It explicitly tells the agent when to use alternatives: use calculate_matchups when one attacker must be tested against several defenders, and calculate_stats for stat tables with no battle. It also gives defaults like level 100 and notes the optional field conditions.

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

calculate_matchupsBatch damage matchupsA
Read-onlyIdempotent

Run one attacker against 1-30 defenders in a single call, picking the hardest-hitting move per defender from move or attacker.moves and reporting each matchup’s damage range, KO chance, immunity, and who moves first. Rows carry only those fields — they are structured rather than prose, so that 30 defenders do not cost thirty rendered sentences; call calculate_damage for the single matchup rendered as a Showdown-format line. Use calculate_damage too when side screens and hazards matter (this tool’s field has only gameType, weather, and terrain); use analyze_team for type-synergy, not damage, and calculate_stats for a stat table with no battle. Supply move or a non-empty attacker.moves, else the call errors; defender levels default to 100. Read-only, offline, deterministic; unknown species or move names return an isError naming the offender.

ParametersJSON Schema
NameRequiredDescriptionDefault
moveNoPin the matchup to this one move, e.g. "Close Combat"; when omitted, `attacker.moves` is searched instead.
fieldNoShared battlefield conditions for every matchup; omit for a neutral Singles field. Side hazards and screens are only available on `calculate_damage`.
attackerYesThe single attacking Pokémon; set `moves` to let the tool choose the best move against each defender.
defendersYes1-30 defender sets, each with the same fields as `attacker`; every entry is scored against the same attacker, move set, and field.

Output Schema

ParametersJSON Schema
NameRequiredDescription
moveYesThe fixed move both sides were scored with, or the literal "best of moveset" when the tool picked the hardest-hitting move per defender.
attackerYesCanonical species name of the single attacker every matchup was run with.
matchupsYesOne entry per defender, in the order the defenders were supplied.
attackerSpeedYesThe attacker’s final Speed stat; hoisted here because it is the same for every matchup, and `speed.attackerMovesFirst` compares it against each row’s `speed.defender`.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already provide readOnly/idempotent/destructive hints, and the description adds context beyond them: 'offline, deterministic', error behavior ('unknown species or move names return an isError naming the offender'), output shape ('rows are structured rather than prose'), and a field limitation (only gameType/weather/terrain, no side screens/hazards). No contradiction with 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?

Front-loaded with the core action in the first sentence, then output format, sibling routing, prerequisites, and error behavior in tight sequence. Every sentence carries distinct information; there is no filler or redundant elaboration despite the description's length.

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?

For a complex nested-parameter tool, the description covers selection logic, batch size, output fields, defaults, error behavior, and exactly which sibling to use in each situation. An output schema exists, so return-value detail is unnecessary; nothing an agent needs to invoke this safely is missing.

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

Parameters3/5

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

Schema coverage is 100%, so the baseline is 3. The description mostly restates schema details ('defender levels default to 100', field contains only gameType/weather/terrain) rather than adding new parameter meaning; the move-vs-attacker.moves selection logic is also already in the schema. It provides no significant extra parameter semantics beyond what the schema documents.

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?

States a precise verb+resource: 'Run one attacker against 1-30 defenders in a single call, picking the hardest-hitting move per defender from move or attacker.moves' and enumerates exact outputs (damage range, KO chance, immunity, who moves first). It also names sibling tools (calculate_damage, analyze_team, calculate_stats) to draw clear boundaries, so an agent can distinguish this tool without opening schemas.

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?

Explicitly routes usage: 'call calculate_damage for the single matchup rendered as a Showdown-format line', 'Use calculate_damage too when side screens and hazards matter', and 'use analyze_team for type-synergy, not damage, and calculate_stats for a stat table with no battle.' It also states a hard prerequisite: 'Supply move or a non-empty attacker.moves, else the call errors.'

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

calculate_statsCalculate final statsA
Read-onlyIdempotent

Compute one Pokémon’s final six stats at a level from its nature, IVs, and EVs, returning the stat table plus base stats and BST. Stats only, never a battle: use calculate_damage or calculate_matchups for damage rolls, check_speed to place the Speed stat against a regulation roster, and optimize_evs when the spread must be derived from a goal. EVs are 0-252 per stat with a 510 total cap, IVs 0-31, level defaults to 50 and nature to Serious. Read-only and offline; unknown species or nature names return an isError.

ParametersJSON Schema
NameRequiredDescriptionDefault
evsNoEVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-252 in steps of 4; omitted stats are 0, and a total above 510 is rejected.
ivsNoIVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.
levelNoLevel 1-100; default 50.
natureNoNature name, e.g. "Jolly", "Modest"; default Serious (raises and lowers nothing).
speciesYesSpecies or form name, e.g. "Garchomp", "Ogerpon-Wellspring".
championsPointsNoPokémon Champions stat points keyed by stat id (hp, atk, def, spa, spd, spe): whole numbers, each 0-32, totalling at most 66. This is the spread the game’s training screen takes, and an alternative to `evs` — give one or the other, not both. One point is worth 8 EVs, so a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces.

Output Schema

ParametersJSON Schema
NameRequiredDescription
bstYesBase stat total: the sum of the six base stats, a rough measure of the species’ overall power.
evsYesThe EVs actually used per stat; all six keys are present, 0 for stats the call left uninvested.
ivsYesThe IVs actually used per stat; all six keys are present, defaulting to 31.
levelYesLevel the stats were computed at, 1-100.
statsYesThe six in-game stats this species reaches at this level, nature, IVs, and EVs; `hp` is the full HP stat, not a percentage.
natureYesNature applied to the non-HP stats, e.g. "Jolly"; Serious when the call omitted one.
speciesYesCanonical species name the stats belong to, e.g. "Garchomp".
baseStatsYesThe species’ unmodified base stats, the same for every set of that species.
championsPointsYesThe spread as Pokémon Champions stat points (whole numbers, at most 32 in a stat, 66 total) — what the game’s training screen takes; stats left uninvested are omitted and a maxed stat reads 32. The two systems budget differently (510 EVs against 66 points), so a spread trimmed to fit the EV cap reads back a point or two under what was asked: this is the nearest point spread for the stats actually computed, not a copy of the input.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already cover read-only, idempotent, and non-destructive behavior. The description adds valuable context beyond the annotations: the tool is offline, unknown species or nature names return an isError, and constraints like the 510 EV cap are enforced. This enriches the behavioral profile without contradicting 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.

Conciseness5/5

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

The description is three sentences with a clear structure: purpose/output first, sibling routing second, constraints and behavior last. Every sentence carries necessary information, and there is no fluff or repetition that weakens the message.

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?

Given the rich input schema, output schema, and annotations, the description covers everything needed to select and invoke the tool correctly: purpose, exclusions, parameter constraints, defaults, error behavior, and offline/read-only guarantees. Nothing essential is missing.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already fully documents all six parameters, including the championsPoints alternative and its relationship to EVs. The description reiterates caps and defaults (EVs 0-252, IVs 0-31, level 50, nature Serious) but adds no meaning beyond the schema, so the baseline 3 is appropriate.

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 opens with a specific verb and resource: 'Compute one Pokémon’s final six stats at a level from its nature, IVs, and EVs.' It also states the output ('stat table plus base stats and BST') and explicitly distinguishes itself from battle-focused siblings with 'Stats only, never a battle.'

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?

The description gives explicit when-to-use and when-not-to-use guidance, naming sibling tools: calculate_damage/calculate_matchups for damage rolls, check_speed for Speed placement, and optimize_evs when deriving a spread from a goal. This leaves no ambiguity about tool selection.

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

check_legalityCheck team legalityA
Read-onlyIdempotent

Validate up to 6 team members against a Pokémon Champions / VGC Regulation Set, reporting illegal or unknown species, duplicate National Pokédex numbers (Species Clause), duplicate items (Item Clause), unlearnable moves, team size (must be exactly 6), and who may Mega Evolve (one per battle). Species resolve case-insensitively to base species (any form of a legal base qualifies). A move is legal when any species in the evolution line knows it — the form, its base species, or a pre-evolution — because egg and level-up moves carry up on evolution: Rillaboom may hold Fake Out, which is Grookey’s egg move. get_learnset lists one species’ own learnset rather than this union, get_regulation gives the roster, and for stat values rather than legality use calculate_stats. Unknown ids return an isError listing them. Read-only and offline; returns valid, violations, and per-member checks.

ParametersJSON Schema
NameRequiredDescriptionDefault
teamYesTeam members, 1-6 of them; a VGC Battle Team must be exactly 6, so any other length adds a team-size violation.
regulationYesRegulation Set id or name, matched case- and punctuation-insensitively: "M-A", "m-a", "mc", and "Regulation Set M-C" all resolve to the same set.

Output Schema

ParametersJSON Schema
NameRequiredDescription
megaYesMega Evolution summary for the checked team.
validYesTrue only when `violations` is empty; false when any member is illegal or unknown, a clause is broken, or the team is not exactly 6.
statusYesThat set’s status relative to today.
membersYesOne entry per supplied team member, in the order supplied.
teamSizeYesHow many members were supplied (1-6).
regulationYesDisplay name of the set the team was checked against, e.g. "Regulation Set M-C".
violationsYesEvery violation found, as human-readable text (illegal/unknown species, Species Clause, unknown item, Item Clause, illegal/unknown moves, team size); empty when the team is legal.

TDQS

A5/5.0
Behavior5/5

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

Annotations already mark readOnlyHint, idempotentHint, destructiveHint, and openWorldHint. The description adds significant behavioral context beyond these: case-insensitive species resolution, the evolution-line move legality rule (egg/level-up carry), team-size exactness, and the return structure ('returns valid, violations, and per-member checks'). It also discloses that unknown ids produce an isError listing. 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.

Conciseness5/5

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

The description is well-structured and front-loaded with the core purpose, then details, then alternatives. Each sentence contributes new information—no filler or redundancy. Despite its length, it remains efficient given the tool's complexity, and it flows logically from what → how → when-not.

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?

For a tool with 2 required parameters, full schema coverage, an output schema, and rich annotations, the description is complete. It explains all validation rules, edge cases (unknown ids, case-insensitivity), and the return shape. An agent would have everything needed to call it correctly without additional lookups.

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

Parameters5/5

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

Schema coverage is 100%, so baseline is 3, but the description adds substantial meaning to the parameters: it explains that species are resolved case-insensitively to base species (forms qualify), that moves are checked against the union of form/base/pre-evolution learnsets, and that team size must be exactly 6. It also clarifies how the regulation id is matched (case- and punctuation-insensitive). This goes well beyond the raw schema descriptions.

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 opens with a precise verb–resource pair: 'Validate up to 6 team members against a Pokémon Champions / VGC Regulation Set' and enumerates the specific checks performed (species, duplicates, moves, team size, Mega Evolution). It clearly distinguishes this from siblings like get_learnset, get_regulation, and calculate_stats by stating what each alternative does instead.

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?

Explicitly names alternatives and the conditions that select them: 'get_learnset lists one species’ own learnset rather than this union, get_regulation gives the roster, and for stat values rather than legality use calculate_stats.' It also states the read-only/offline nature, leaving no ambiguity about when to call this tool versus others.

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

check_speedCheck Speed against a regulationA
Read-onlyIdempotent

Compute one Pokémon’s final Speed and, given a Regulation Set, rank it against that roster at its fastest (252 EV, +Spe nature) and uninvested reference speeds. Speed only: for damage use calculate_damage or calculate_matchups, and to find the Speed EVs that beat a target use optimize_evs. Applies boosts.spe (-6..+6) and Choice Scarf ×1.5; other items are reported as Speed-neutral, and regulation is optional. Returns finalSpeed, modifiers, and outspeeds/conditional/losesTo counts with up to 15 threats each. Read-only and offline; unknown names return an isError.

ParametersJSON Schema
NameRequiredDescriptionDefault
evsNoEVs keyed by stat id; only `spe` (0-252) changes the result, e.g. { spe: 252 }.
ivsNoIVs keyed by stat id; only `spe` (0-31) changes the result, and it defaults to 31.
itemNoHeld item, e.g. "Choice Scarf"; only Choice Scarf multiplies Speed (×1.5), other items are listed as speed-neutral.
levelNoLevel 1-100; default 50, matching VGC play.
boostsNoStat stages; only `spe` (-6..+6) is applied, e.g. { spe: 1 } for a +1 Speed stage.
natureNoNature name, e.g. "Jolly", "Timid"; default Serious (neutral Speed).
speciesYesSpecies or form name, e.g. "Dragapult", "Ogerpon-Wellspring".
regulationNoRegulation Set name or id from `list_regulations` to compare against, e.g. "Regulation Set G"; omit to get the raw Speed only.
championsPointsNoThe same Speed investment in Pokémon Champions stat points, e.g. { spe: 32 } for a maxed Speed stat; give this or `evs`, not both.

Output Schema

ParametersJSON Schema
NameRequiredDescription
evSpeYesSpeed EVs invested, 0-252.
ivSpeYesSpeed IV used, 0-31.
levelYesLevel the Speed was computed at, 1-100.
natureYesNature applied Speed, e.g. "Jolly" for +Spe; Serious when the call omitted one.
baseSpeYesThe species’ base Speed stat, before level, IVs, EVs, nature, item, and boosts.
speciesYesCanonical species name the Speed belongs to, e.g. "Dragapult".
modifiersYesHuman-readable list of everything that changed the Speed stat, e.g. ["Speed stage +1", "Choice Scarf x1.5"]; a speed-neutral item is noted here too, and the list is empty when nothing applied.
comparisonNoPresent only when `regulation` was supplied: how this Speed places against that roster, whose threat lists are each capped at 15 entries.
finalSpeedYesThe final Speed stat after level, IVs, EVs, nature, Speed stage, and item; this is the number turn order compares.

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint, idempotentHint, destructiveHint), the description discloses key calculation behaviors: it applies only `boosts.spe` (-6..+6) and Choice Scarf ×1.5, treats other items as Speed-neutral, and returns an `isError` for unknown names. It summarizes the return shape (finalSpeed, modifiers, outspeeds/conditional/losesTo counts) without contradicting any annotation.

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 compact and front-loaded: the main purpose is stated in the first sentence, followed by explicit alternatives, calculation rules, and return summary. Each sentence adds distinct, necessary information with no redundancy or filler.

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?

Given the tool's complexity (9 params, nested objects) and the rich output schema, the description is complete. It covers scope, optionality, error behavior, and decision routing to siblings, leaving no critical ambiguity for an agent to call and interpret the tool correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so the baseline is 3. The description repeats what the schema already states: only `spe` EV/IV/boosts affect the result, only Choice Scarf modifies Speed, and `regulation` is optional. It adds no new parameter meaning beyond a concise summary, so it does not exceed the baseline.

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 opens with a specific verb-resource pair: 'Compute one Pokémon’s final Speed and, given a Regulation Set, rank it against that roster.' It also explicitly differentiates from siblings by stating 'Speed only: for damage use `calculate_damage` or `calculate_matchups`' and points to `optimize_evs` for EV tuning, making the tool's unique role unmistakable.

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?

The description gives concrete when-to-use guidance ('Speed only', 'given a Regulation Set', 'regulation is optional') and explicit when-not-to-use guidance with named alternatives for damage and EV optimization. It also notes the tool is read-only and offline, which helps an agent decide when it is safe to invoke.

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

get_abilityGet ability dataA
Read-onlyIdempotent

Get one ability's effect text, flags, and the generations it exists in. Use it before relying on an ability in damage or speed reasoning; the set inputs of calculate_damage and check_speed take the ability or item name and apply it themselves. Accepts ability names case-insensitively; unknown abilities return an isError with near matches. Read-only and offline.

ParametersJSON Schema
NameRequiredDescriptionDefault
abilityYesAbility name, e.g. "Intimidate", "Protosynthesis".

Output Schema

ParametersJSON Schema
NameRequiredDescription
genYesGeneration the ability was introduced in; 0 for the "No Ability" placeholder.
numYesAbility number in the dataset; 0 for abilities that have none.
descYesFull effect description.
nameYesAbility name, e.g. "Intimidate".
flagsYesFlags the ability carries, as {"<flag>": 1}; any flag not listed does not apply. Possible keys: "breakable", "cantsuppress", "failroleplay", "failskillswap", "noentrain", "noreceiver", "notrace", "notransform".
shortDescYesOne-line effect summary.
isNonstandardYes"Past", "Future", "Unobtainable", or "CAP" when the ability is not available in the current games; null when it is standard.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already cover read-only and idempotent hints. The description adds 'offline' (extra context) and case-insensitive matching with near-match errors on unknown abilities, which go beyond the annotations. It also repeats 'Read-only' which is already annotated, but the additional behavioral details are valuable.

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 three sentences with no redundancy. It front-loads the purpose, then gives usage guidance and behavioral details in a logical order. Every sentence earns its place.

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?

For a simple one-parameter getter with a rich output schema and comprehensive annotations, the description covers everything an agent needs: purpose, usage context, input behavior, and offline nature. Nothing essential is missing.

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% and the parameter description includes an example. The description adds meaningful semantics: case-insensitive input handling and error response with near matches. This goes beyond the schema, so a score of 4 is appropriate.

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's function: getting an ability's effect text, flags, and generations. It also differentiates from sibling tools by explicitly mentioning how calculate_damage and check_speed handle ability names themselves, making it easy to distinguish from those calculation tools.

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?

It provides explicit when-to-use guidance ('Use it before relying on an ability in damage or speed reasoning') and explains that calculate_damage and check_speed already apply the ability, which implicitly tells the agent when not to call this tool. It also covers case-insensitivity and error behavior, making usage conditions clear.

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

get_itemGet item dataA
Read-onlyIdempotent

Get one held item's data: effect text, category flags (Berry, Choice, Mega Stone, …), Z-move, Natural Gift, Fling, and flat stat boosts. Use it to confirm what an item actually does before recommending it; get_set returns the item a curated meta set runs. Accepts item names case-insensitively; unknown items return an isError with near matches. Read-only and offline.

ParametersJSON Schema
NameRequiredDescriptionDefault
itemYesItem name, e.g. "Choice Band", "Assault Vest", "Leftovers".

Output Schema

ParametersJSON Schema
NameRequiredDescription
genYesGeneration the item was introduced in.
numYesItem number in the dataset; 0 for items that have none.
descYesFull effect description.
nameYesItem name, e.g. "Choice Band".
flingNoFling data, present only for items that can be flung.
isGemNotrue when the item is a one-use type Gem that boosts a matching move; absent otherwise.
zMoveNoFor Z-Crystals: the Z-Move it unlocks, or true for crystals whose move depends on the held move; absent when the item is not a Z-Crystal.
boostsNoFlat stat stages the item grants while held, keyed by stat id, e.g. {"atk": 2} for Choice Band; absent for items that do not change stats directly.
isBerryNotrue when the item is a Berry (held and eaten on a trigger); absent otherwise.
isChoiceNotrue when the item is a Choice item that locks the holder into one move; absent otherwise.
itemUserNoSpecies that can use the item where it is restricted to them; absent when any species can hold it.
megaStoneNoMega Stone holders: species name to the Mega forme it unlocks, e.g. {"Garchomp": "Garchomp-Mega"}; absent when the item is not a Mega Stone.
shortDescYesOne-line effect summary.
isPokeballNotrue when the item is a Poké Ball used for catching; absent otherwise.
forcedFormeNoForme this item forces on its holder, e.g. "Dialga-Origin" for Adamant Crystal; absent when the item changes no forme.
naturalGiftNoNatural Gift data, present only for Berries (the items Natural Gift can consume).
isNonstandardYes"Past", "Future", "Unobtainable", or "CAP" when the item is not available in the current games; null when it is standard.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already mark this as read-only, idempotent, and non-destructive, and the description reinforces this with 'Read-only and offline.' It adds valuable behavioral details beyond the annotations: case-insensitive item matching, unknown items returning an isError with near matches, and the item data categories returned. No contradiction with 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?

Three concise sentences each earn their place: the first defines scope and outputs, the second gives usage guidance and the sibling contrast, the third covers input behavior and operational traits. No filler or repetition of the schema.

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?

Given only one parameter, a rich output schema, and annotations covering safety and idempotency, the description fully covers what an agent needs: purpose, usage context, input behavior, error handling, and read-only/offline nature. Nothing material is missing.

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?

The schema already documents the single 'item' parameter with examples and 100% coverage, so the baseline is strong. The description additionally clarifies case-insensitivity and the error behavior for unknown items, which enhances parameter understanding beyond the schema.

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 states a specific action and resource: 'Get one held item's data' and enumerates the exact contents (effect text, category flags, Z-move, Natural Gift, Fling, stat boosts). It also distinguishes itself from the sibling get_set, which returns the item on a curated meta set, so an agent can clearly tell them apart.

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?

Explicitly says to use it 'to confirm what an item actually does before recommending it' and names the alternative get_set as the tool that returns the item a set runs. This gives an agent a concrete selection rule with an exclusion and a sibling comparison.

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

get_learnsetGet a Pokémon learnsetA
Read-onlyIdempotent

List every move a Pokémon can learn, grouped by acquisition method (level-up with the level, TM/TR, egg, tutor, event, and so on). This is the species’ own learnset: a move it inherits from a pre-evolution — an egg move such as Grookey’s Fake Out — is filed against that pre-evolution, so use check_legality to decide whether a set’s move is legal in a regulation. Accepts any species or form name; unknown species return an isError with near matches, and a species with no learnset data errors instead of returning an empty list. Read-only and offline.

ParametersJSON Schema
NameRequiredDescriptionDefault
speciesYesSpecies or form name, e.g. "Garchomp", "Ogerpon-Wellspring".

Output Schema

ParametersJSON Schema
NameRequiredDescription
existsYestrue when the dataset has learnset data for the species; a species without data errors instead of returning false.
speciesYesName of the species whose learnset this is, resolved from the argument, e.g. "Garchomp".
eventDataNoEvent distributions that granted this species, when it has any; absent for species with no event history.
eventOnlyYestrue when the species is only obtainable through events, so most of its moves come from the event list.
totalMovesYesNumber of distinct moves the species can learn, counted before grouping by source.
movesBySourceYesLearned moves grouped by how they are acquired, keyed by "Level-up", "TM", "Egg", "Tutor", "Event", "Raid/Event", "Virtual Console transfer", "Dream World", "Pre-evolution", or "Other"; a move learned more than one way appears under each. Each list is sorted by move name and holds display names, e.g. {"TM": ["Earthquake"], "Level-up": ["Dragon Claw"]}. Empty when the dataset records no moves.

TDQS

A4.8/5.0
Behavior5/5

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

The description adds substantial behavioral context beyond the read-only annotation: it explains that inherited egg moves are filed under the pre-evolution, that unknown species return an isError with near matches, and that species with no learnset data error instead of returning an empty list. It also adds the offline behavior, which is not in annotations. No contradiction with annotations.

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

Conciseness4/5

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

The description is dense and front-loaded with the main purpose, but it runs to three sentences and includes an illustrative example (Grookey's Fake Out). Every sentence earns its place, though it could be slightly tighter; it remains well-structured and efficient.

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?

For a one-parameter read-only tool with an output schema and annotations covering safety, the description covers input acceptance, error behavior, output grouping, and the critical pre-evolution nuance. Nothing an agent needs to invoke and interpret the tool correctly appears missing.

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% for the single `species` parameter, so the baseline is 3. The description adds value beyond the schema by stating that any species or form name is accepted and by detailing the error behavior for unknown species and species with no learnset data, which helps the agent anticipate failure modes when passing the parameter.

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 starts with a specific verb and resource: "List every move a Pokémon can learn," and immediately distinguishes this tool from siblings by noting it is the species' own learnset and that legality is handled by check_legality. An agent can clearly tell it apart from get_pokemon, get_move, get_set, and check_legality without inspecting their schemas.

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?

The description explicitly routes the agent to an alternative tool: "so use `check_legality` to decide whether a set’s move is legal in a regulation." This gives an explicit when-not-to-use condition and names the sibling that should be selected instead, satisfying the highest bar for usage guidance.

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

get_moveGet move dataA
Read-onlyIdempotent

Get one move's battle data: type, damage class, base power, accuracy, PP, priority, target, flags, secondary effect, Z/Max variants, and effect text. Use get_learnset to check which Pokémon learn it and calculate_damage to apply it in a matchup, rather than reasoning about damage from these fields. Accepts Showdown move names case- and punctuation-insensitively ("make it rain"); unknown moves return an isError with near matches. Read-only and offline.

ParametersJSON Schema
NameRequiredDescriptionDefault
moveYesMove name, e.g. "Earthquake", "Make It Rain", "Dragon Claw".

Output Schema

ParametersJSON Schema
NameRequiredDescription
ppYesBase PP, before PP Ups.
genYesGeneration the move was introduced in.
isZNoZ-Crystal id that turns this move into a Z-Move; absent when the move has no dedicated Z-Move.
numYesMove number in the dataset, which is also the sort key `search_dex` returns moves by.
descYesFull effect description.
nameYesMove name, e.g. "Earthquake".
typeYesMove type. One of "Bug", "Dark", "Dragon", "Electric", "Fairy", "Fighting", "Fire", "Flying", "Ghost", "Grass", "Ground", "Ice", "Normal", "Poison", "Psychic", "Rock", "Steel", "Water".
drainNoHP the user recovers as a [numerator, denominator] fraction of damage dealt, e.g. [1, 2] for half; absent when the move does not drain.
flagsYesFlags the move carries, as {"<flag>": 1}; any flag not listed does not apply. Possible keys: "allyanim", "bite", "bullet", "bypasssub", "cantusetwice", "charge", "contact", "dance", "defrost", "distance", "failcopycat", "failencore", "failinstruct", "failmefirst", "failmimic", "futuremove", "gravity", "heal", "metronome", "minimize", "mirror", "mustpressure", "noassist", "nonsky", "noparentalbond", "nosketch", "nosleeptalk", "pledgecombo", "powder", "protect", "pulse", "punch", "recharge", "reflectable", "slicing", "snatch", "sound", "wind".
isMaxNoSpecies name when this is a G-Max move, true for generic Max Moves; absent when the move is not a Max Move.
zMoveNoThe Z-Move this move becomes when a Z-Crystal is held; absent when it does not become one.
recoilNoRecoil to the user as a [numerator, denominator] fraction of damage dealt, e.g. [33, 100]; absent when the move has no recoil.
targetYesTargeting mode, e.g. "normal", "self", "allAdjacent", "allAdjacentFoes", "allySide".
maxMoveNoThe Max Move this move becomes under Dynamax; absent when it does not become one.
accuracyYesAccuracy as a percentage, or true when the move cannot miss.
categoryYesDamage class: "Physical", "Special", or "Status".
multihitNoHit count when the move hits multiple times: a fixed number, or a [min, max] range as [2, 5]; absent for single-hit moves.
priorityYesPriority bracket: positive moves act first, negative moves last.
alwaysHitNotrue when the dataset marks the move as never missing; absent from every other move.
basePowerYesBase power; 0 for status moves and for moves whose power is computed rather than fixed (e.g. Seismic Toss, Low Kick).
secondaryNoSecondary effect attached to the move itself, when it has one (absent for moves with none).
shortDescYesOne-line effect summary.
secondariesNoList of secondary effects, present for moves that carry more than one (e.g. a different effect per hit); absent for moves with none.
breaksProtectNotrue when the move hits through Protect and similar protection; absent when it does not.
isNonstandardYes"Past", "Future", "Unobtainable", or "CAP" when the move is not available in the current games; null when it is standard.

TDQS

A5/5.0
Behavior5/5

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

Annotations already declare read-only, idempotent, and non-destructive behavior; the description adds further behavioral detail: input is normalized case- and punctuation-insensitively, and unknown moves return an isError with near matches. This goes meaningfully beyond annotation coverage.

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 tight and front-loaded: the first sentence states the resource and content, the second gives sibling routing, and the third covers input/error behavior. Every sentence earns its place despite the dense field list.

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?

Given the output schema already exists, the description does not need to explain return structure. It covers what data is included, how to use sibling tools instead, input normalization, error behavior, and offline/read-only nature. Nothing needed for correct invocation is missing.

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

Parameters5/5

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

The schema describes the move parameter with examples, and the description adds important operational semantics: acceptable input format ('Make It Rain' vs 'make it rain'), and the error behavior for unknown move names. Since there is only one parameter and it is fully documented, this is excellent coverage.

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 uses a specific verb and resource ('Get one move's battle data') and enumerates the exact fields returned. It clearly distinguishes the tool from siblings like get_learnset and calculate_damage by naming those alternatives and their purpose.

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?

Explicitly instructs when to use this tool versus siblings: use get_learnset to check which Pokémon learn a move and calculate_damage to apply it in a matchup. It also warns not to reason about damage from these fields, providing clear routing guidance.

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

get_natureGet nature effectA
Read-onlyIdempotent

Get one nature's stat effect: the stat it raises 10% and the stat it lowers 10%, or a neutral effect for the five natures that change nothing (Hardy, Docile, Serious, Bashful, Quirky). Use it when assembling a set, since calculate_stats, calculate_damage, check_speed, and optimize_evs all take a nature name rather than a numeric modifier. Accepts nature names case-insensitively; unknown natures return an isError. Read-only and offline.

ParametersJSON Schema
NameRequiredDescriptionDefault
natureYesNature name, e.g. "Jolly", "Timid", "Impish".

Output Schema

ParametersJSON Schema
NameRequiredDescription
genYesGeneration the nature system was introduced in.
nameYesNature name, e.g. "Jolly".
plusNoStat raised 10%, as a stat id such as "spe"; absent for the five neutral natures that change nothing.
minusNoStat lowered 10%, as a stat id such as "spa"; absent for the five neutral natures that change nothing.

TDQS

A4.9/5.0
Behavior5/5

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

Beyond the annotations (readOnly, idempotent, non-destructive), the description discloses case-insensitive matching, error returns for unknown natures, offline behavior, and the exact neutral-nature list. No statement contradicts 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.

Conciseness5/5

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

Three sentences front-load the core mechanic, then provide usage context, then input behavior. Every sentence earns its place with no redundancy or filler.

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 one parameter, a rich output schema, and detailed annotations, the description fully equips an agent to call the tool correctly. It covers the tool's scope, relevant sibling context, input handling, and the distinct neutral 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?

The schema already covers the single parameter with 100% documentation. The description adds behavioral semantics beyond the schema: nature names are accepted case-insensitively and unknown natures produce an error flag, which is useful for an agent constructing valid calls.

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 states a specific verb and resource: 'Get one nature's stat effect,' with clear details on the 10% raise/lower and the five neutral natures. It also distinguishes this tool from calculation siblings by explaining it returns nature effects rather than numeric modifiers.

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?

The description explicitly says to use it 'when assembling a set' and names calculate_stats, calculate_damage, check_speed, and optimize_evs as tools that consume nature names, making the integration context clear. It also notes case-insensitivity and error behavior, which helps an agent decide when calling is appropriate.

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

get_pokemonGet Pokémon dataA
Read-onlyIdempotent

Look up one Pokémon and return its competitive profile: types, base stats and BST, abilities by slot, weight, gender ratio, egg groups, and evolutions. Accepts any Showdown name or form, case- and punctuation-insensitive ("garchomp", "Ogerpon-Wellspring", "rotom wash"); unknown names return an isError listing near matches. Use search_dex when you only have a partial name, list_forms for alternate or cosmetic forms, and calculate_stats when you need stats computed from EVs, IVs, and nature. Read-only and offline over the bundled Showdown dataset — no network, auth, or rate limits.

ParametersJSON Schema
NameRequiredDescriptionDefault
speciesYesSpecies or form name, e.g. "Garchomp", "Ogerpon-Wellspring", "Rotom-Wash".

Output Schema

ParametersJSON Schema
NameRequiredDescription
bstYesBase stat total — the sum of `baseStats`.
genYesGeneration this entry was introduced in; 0 for entries outside the numbered generations (e.g. MissingNo.).
nfeYestrue when the species can still evolve (not fully evolved).
numYesNational Dex number; 0 for entries that have none.
evosYesSpecies this one evolves into; empty when it does not evolve.
nameYesDisplay name of the entry, e.g. "Garchomp" or "Ogerpon-Wellspring".
tagsYesDataset tags such as ["Sub-Legendary"] or ["Mythical"]; empty when the entry is untagged.
formeNoForme label when this entry is an alternate forme, e.g. "Mega", "Wash"; absent for the base forme.
prevoNoSpecies this one evolves from; absent for base evolutions.
typesYesTyping, in order, e.g. ["Dragon", "Ground"]. One of "Bug", "Dark", "Dragon", "Electric", "Fairy", "Fighting", "Fire", "Flying", "Ghost", "Grass", "Ground", "Ice", "Normal", "Poison", "Psychic", "Rock", "Steel", "Water".
genderNo"M", "F", or "N" (genderless) for species that are not a mix of both; absent when the species has a mixed gender ratio.
isMegaNotrue for Mega Evolutions; absent otherwise.
evoItemNoItem required to evolve, when the evolution is item-based.
evoMoveNoMove the species must know to evolve, when the evolution is move-based.
canHatchYestrue when the species can hatch from an Egg.
evoLevelNoLevel required to evolve, when the evolution is level-based.
isPrimalNotrue for Primal Reversions; absent otherwise.
weightkgYesWeight in kilograms, as used by weight-based moves such as Heavy Slam.
abilitiesYesAbilities keyed by Showdown slot: "0" primary, "1" secondary, "H" hidden, "S" special.
baseFormeNoLabel of the species' default forme when it has formes, e.g. "Teal" for Ogerpon; absent otherwise.
baseStatsYesAll six stats keyed by stat id ("hp", "atk", "def", "spa", "spd", "spe").
eggGroupsYesEgg groups, e.g. ["Monster", "Dragon"]; empty for species that cannot breed.
battleOnlyNoThe species this entry transforms from during battle, e.g. "Garchomp" for Garchomp-Mega, or a list when it can come from more than one (Wishiwashi); absent for normally selectable entries.
formeOrderNoDataset display order of the species and its formes; absent when the species has no formes.
baseSpeciesYesName of the species this entry belongs to; equal to `name` for a base forme.
genderRatioYesGender odds at encounter; both 0 for genderless species.
otherFormesNoNames of the non-cosmetic alternate formes; null or absent when the species has none.
evoConditionNoFree-text condition for evolutions that are not plain level, item, or move evolutions, e.g. "Level up with 999 Coins in the bag".
canGigantamaxNoName of the G-Max move, when this entry is a Gigantamax-capable forme; absent otherwise.
cannotDynamaxYestrue when the species cannot Dynamax.
isNonstandardYes"Past", "Future", "Unobtainable", or "CAP" when the entry is not available in the current games; null when it is standard.
cosmeticFormesNoNames of cosmetic-only formes (different look, identical mechanics); null or absent when there are none.
isCosmeticFormeYestrue when this entry is a cosmetic forme rather than a mechanically distinct one.
unreleasedHiddenNotrue when the hidden ability has not been released; absent otherwise.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare readOnlyHint/idempotentHint/destructiveHint, and the description adds substantial context beyond them: offline operation over the bundled Showdown dataset, no network/auth/rate limits, case- and punctuation-insensitive matching, acceptance of any Showdown form, and isError behavior listing near matches for unknown names. No contradiction with 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?

Three sentences carry a dense but fully-signaled payload: purpose+returns, matching semantics+error behavior, sibling routing, and operational constraints. Every clause earns its place and the core purpose is front-loaded before the routing and operational details.

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?

For a one-parameter lookup tool with an output schema and safety-bearing annotations, nothing needed to invoke it correctly is missing: name variants, error behavior, relationship to three siblings, and resource/network characteristics are all covered. The output schema relieves the description of explaining return structures.

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 the baseline is 3, but the description adds value beyond the schema: it specifies that the species parameter accepts any Showdown name or form in a case- and punctuation-insensitive manner, gives three contrasting examples, and discloses the error behavior for unknown inputs. This exceeds what the schema alone communicates.

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 states a specific verb ('Look up') and resource ('one Pokémon'), and enumerates the exact return contract: types, base stats and BST, abilities by slot, weight, gender ratio, egg groups, and evolutions. It clearly differentiates from siblings by naming search_dex, list_forms, and calculate_stats with their distinct purposes.

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?

Explicit routing is provided: 'Use `search_dex` when you only have a partial name, `list_forms` for alternate or cosmetic forms, and `calculate_stats` when you need stats computed from EVs, IVs, and nature.' This gives the agent concrete selection conditions rather than leaving when-to-use to inference.

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

get_regulationGet regulation setA
Read-onlyIdempotent

Get one Pokémon Champions / VGC Regulation Set in full: battle rules (level 50 doubles, timers, bring 4 of 6), team clauses (Species, Item, auto-level 50), Mega Evolution rules, and the size of the legal roster. The two name rosters — every legal base species, and every species allowed to Mega Evolve — are about two thirds of the response and come back only with includeRoster; the eligibleCount/megaCount sizes are always there. Accepts the id or name case- and punctuation-insensitively ("M-A", "m-a", "mc", "Regulation Set M-C"); an unknown id is an isError listing the valid names. Use list_regulations to discover ids and check_legality to test a team. Read-only and offline; returns dates, status, counts, clauses, and source.

ParametersJSON Schema
NameRequiredDescriptionDefault
regulationYesRegulation Set id or name, matched case- and punctuation-insensitively: "M-A", "m-a", "mc", and "Regulation Set M-C" all resolve to the same set.
includeRosterNoInclude the two name rosters — every legal base species and every species allowed to Mega Evolve — which together are about two thirds of the response. Omitted, the rules and the `eligibleCount`/`megaCount` sizes come back without them; pass true when you actually need the names.

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYesRegulation id, e.g. "m-a", "m-b", "m-c".
endYesLast day the set is in force, ISO 8601 (inclusive).
gameYesGame the set belongs to ("Pokémon Champions").
nameYesDisplay name, e.g. "Regulation Set M-C".
levelYesLevel every Pokémon is set to (50).
notesYesCurator summary of the format and what it changed over the previous set.
startYesFirst day the set is in force, ISO 8601 (inclusive).
roundsYesTournament round structure, e.g. "BO1/BO3 Swiss, BO3 top cut".
sourceYesURL of the source the rosters were taken from.
statusYesStatus relative to today: "past", "current", or "upcoming".
timersYesMatch clock limits.
clausesYesTeam-construction clauses in force for this set.
bringPickYesTeam preview rule ("4 of 6"): register six Pokémon, pick four for each match.
megaCountYesHow many base species on the roster may Mega Evolve.
battleTypeYesBattle format this set is played in ("Double Battles").
sourceAsOfYesISO date the rosters were last refreshed.
eligibleCountYesHow many base species are on the legal roster.
megaEvolutionYesMega Evolution rules.
eligibleSpeciesNoThe full legal base-species roster; every form of a listed species is legal. Present only when `includeRoster` was set — `eligibleCount` gives the size either way.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false. The description reinforces this ('Read-only and offline') and adds crucial behavioral context: error handling ('unknown id is an isError listing valid names'), the conditional roster inclusion, and that eligibleCount/megaCount are always present. This goes well 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.

Conciseness4/5

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

The description is a single dense paragraph, longer than average, but every sentence contributes: purpose, rosters, error, siblings, read-only. It is front-loaded with the primary purpose and then layers details. Minor verbosity but no filler.

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?

For a moderately complex read tool with an output schema, the description covers the main operational aspects: what is returned, the conditional roster, error behavior, sibling tools, and read-only status. It is fully adequate for an agent to call it correctly.

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% with both parameters described in the schema, so the baseline is 3. The description adds value by explaining that rosters are about two thirds of the response and only come with includeRoster, and by re-emphasizing case- and punctuation-insensitivity. It enriches the parameter meaning beyond the schema.

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?

States a specific verb ('Get') and resource ('Regulation Set') with concrete content: battle rules, team clauses, Mega Evolution rules, roster size. It also names the two sibling tools it is not (list_regulations, check_legality) and explains how it differs, so an agent can distinguish it without opening schemas.

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?

Explicitly directs to list_regulations for discovery and check_legality for team testing, and clarifies the read-only, offline nature. It also explains when to pass includeRoster ('when you actually need the names'), which is practical usage guidance.

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

get_setGet standard competitive setA
Read-onlyIdempotent

Return one species’ most-played competitive set: item, ability (with the Mega form and ability for Mega sets), nature, EVs, the four most-played moves, role, tier, usage share, the usage figures behind it, and the set as a Showdown-format paste ready to copy into a team builder or paste host, with EVs in Champions stat points. Pass an array of species to fetch several sets in one call, which answers as sets — use that rather than calling once per species. Reach for it when asked what a species usually runs; list_threats gives the ranked species of a regulation and check_legality validates teams. Species match is case-insensitive and ignores punctuation, and resolves forms, so "Indeedee-F" and "Salamence-Mega" find the same sets as "Indeedee" and "Salamence"; pass regulation (e.g. "m-c") to scope to one list; unknown species return an isError. Usage-derived from Limitless VGC tournament teams, not editorial opinion; read-only, offline, no network or auth.

ParametersJSON Schema
NameRequiredDescriptionDefault
speciesYesBase species or form name, e.g. "Garchomp", "Indeedee-F" (case- and punctuation-insensitive). Pass an array to fetch several sets in one call, which returns `sets` instead of the flat set.
regulationNoOptional regulation set id, e.g. "m-c"; omit to search every list.

Output Schema

ParametersJSON Schema
NameRequiredDescription
evsNoMost-played spread, keyed by Showdown stat and scaled to the 0-252 EVs `calculate_stats` and `calculate_damage` take; only invested stats are listed, everything omitted is 0. Absent when the source published no spread for that species.
formNoForm the set is played as when that is not the default one, e.g. "Arcanine-Hisui"; absent otherwise.
itemNoMost-played held item, e.g. "Salamencite".
rankNoPosition by usage in this list; 1 is the most used.
roleNoRole read off the set’s ability and moves, e.g. "Rain setter", "Mega Intimidate pivot".
setsNoOne entry per requested species, in the order supplied; present only when `species` was an array.
tierNoUsage band: S is the top 5 by usage, A the next 7, B the rest of the list.
movesNoThe four most-played moves, most played first.
notesNoThe usage figures this set was derived from; absent when the list carries none.
pasteNoThe whole set as a Showdown-format paste, ready to copy into a team builder or paste host: `species @ item`, ability, level 50, nature, EVs in Pokémon Champions stat points (0-32 each, 66 total — what the game’s training screen takes), then the four moves. A Mega set names the base species holding its stone.
usageNoShare of the sampled teams carrying this species, in percent.
natureNoMost-played nature, e.g. "Timid".
abilityNoMost-played ability on the form that was led, i.e. before Mega Evolving on a Mega set.
speciesNoBase species name in Showdown spelling, e.g. "Garchomp"; every form collapses into it because Species Clause is per National Pokédex number.
megaFormNoMega form this set evolves into, e.g. "Salamence-Mega"; absent when the set is not a Mega set.
regulationNoDisplay name of the list the set came from, e.g. "Regulation Set M-C"; present only when a single species was requested.
sourceAsOfNoISO date of the newest data point behind that list; present only when a single species was requested.
megaAbilityNoAbility after Mega Evolving; absent when the set is not a Mega set.
championsPointsNoThe same spread in Pokémon Champions stat points (whole numbers, at most 32 in a stat, 66 total), which is what the game’s training screen takes and the form the source publishes; `evs` is this converted to the 0-252 scale the calculate_* tools take. Absent when the source published no spread.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already mark this read-only, idempotent, and non-destructive, and the description reinforces and expands that with additional behavioral facts: species matching is case-insensitive and form-resolving, unknown species return an isError, and the data comes from Limitless VGC tournament teams rather than editorial opinion. It also states no network or auth is needed, which is useful context 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.

Conciseness4/5

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

The description is long but well organized: core purpose first, then array batching, usage guidance, matching rules, regulation, errors, and provenance. Every section adds operational value, though a few details like "read-only, offline, no network or auth" are repeated in spirit by the annotations and could be trimmed.

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?

Given the output schema exists, the return values need no further explanation. The description covers purpose, when to use it, sibling differences, batching, species normalization, regulation scoping, error behavior, and data provenance. There is no critical gap an agent would need to guess about before calling the tool.

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?

The input schema already covers both parameters at 100%, so the baseline is 3. The description adds value by explaining why to pass an array — "use that rather than calling once per species" — and by clarifying how `regulation` scopes the search. It also provides error behavior for unknown species.

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 opens with a specific verb and resource: "Return one species’ most-played competitive set," and enumerates exactly what the set contains. It also distinguishes itself from siblings by saying `list_threats` gives ranked species and `check_legality` validates teams, so an agent can tell this tool apart without guessing.

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?

It gives explicit when-to-use guidance: "Reach for it when asked what a species usually runs." It also names alternatives with contrasting purposes, and even advises batching array calls rather than calling once per species, which is concrete operational guidance.

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

get_typeGet type matchup chart entryA
Read-onlyIdempotent

Get the defensive profile of one type: what it is weak to, what it resists, what it is immune to, plus the Hidden Power IVs for that type. Use it for a type's own matchups; for one specific pairing pass attacker and defender to get_type_matchup, and for a Pokémon's combined defensive chart give get_type_matchup the species name instead. Accepts type names case-insensitively; unknown types return an isError. Read-only and offline.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesType name, e.g. "Steel", "Fairy", "Ground".

Output Schema

ParametersJSON Schema
NameRequiredDescription
genYesAlways 0 in the bundled dataset — types are not stamped with the generation they were introduced in.
nameYesType name, e.g. "Steel".
HPivsYesIVs needed to make Hidden Power come out as this type, keyed by stat id; only the stats this type pins down are listed.
immunitiesYesAttacking types this type takes 0x from, e.g. ["Poison"] for Steel; empty when it has none.
weaknessesYesAttacking types this type takes 2x from, e.g. ["Fire", "Ground"] for Steel; empty when it has none.
damageTakenYesMultiplier this type takes from each attacking type, keyed by attacking type name. Values: 0 (immune), 0.5 (resisted), 1 (neutral), 2 (weak). Keys are "Bug", "Dark", "Dragon", "Electric", "Fairy", "Fighting", "Fire", "Flying", "Ghost", "Grass", "Ground", "Ice", "Normal", "Poison", "Psychic", "Rock", "Steel", "Water"; e.g. {"Fire": 2, "Ground": 2, "Water": 0.5} for Steel.
resistancesYesAttacking types this type takes 0.5x from; empty when it has none.
isNonstandardYes"Future" when the type does not exist in the dataset (e.g. Dark in generation 1) and "Past" when it no longer exists; null for types that are standard in that generation.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds practical behavioral context beyond those: input is case-insensitive, unknown types return an isError, and the operation is read-only and offline.

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?

Three sentences, each earning their place: one states the function and outputs, one gives usage routing, and one covers input behavior and errors. The most important information is front-loaded and there is no filler.

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 one required parameter, full schema coverage, annotations covering safety, and an output schema present, the description is complete. It also covers error behavior, case sensitivity, and alternative tools, leaving no practical gap for an agent deciding whether and how to invoke it.

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 for the single parameter is 100%, so the baseline is 3. The description adds value by specifying case-insensitive acceptance and the isError behavior for unknown type names, which are not present in the schema.

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 states a specific verb ('Get the defensive profile') and resource ('one type'), and enumerates what it returns: weaknesses, resistances, immunities, and Hidden Power IVs. It also explicitly contrasts itself with the sibling get_type_matchup, so an agent can distinguish the two without opening schemas.

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?

The description gives clear when-to-use guidance: use it for a type's own matchups, use get_type_matchup for a specific attacking/defending pairing, and use get_type_matchup with a species name for a Pokémon's combined defensive chart. This is explicit routing to alternatives with no ambiguity.

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

get_type_matchupResolve type effectivenessA
Read-onlyIdempotent

Resolve type effectiveness in the mode the arguments imply: attacker + defender returns the single multiplier (the defender may be a type or a species, whose current-generation typing is used); attacker alone returns that type's offensive coverage against all 18 types; defender alone returns everything the defender takes, including 4x weaknesses and immunities; neither returns the complete 18x18 matrix. Use get_type for a type's own defensive entry, and analyze_team when the question spans a whole team. Names are case-insensitive; an unknown type or species returns an isError. Read-only and offline.

ParametersJSON Schema
NameRequiredDescriptionDefault
attackerNoAttacking type name; omit to read the chart from the defender's side or to get the full matrix.
defenderNoDefending type or species name; a species contributes its current-generation types.

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNoPresent only alongside `chart`, spelling out how to read the full matrix (rows are attackers, columns are defenders) and the multiplier scale.
chartNoPresent only when neither argument was given: the full type chart as `chart[attackingType][defendingType] = multiplier`, each inner map keyed by the 18 defending type names with values 0, 0.25, 0.5, 1, 2, or 4.
labelNo`effectiveness` in words, e.g. "2x super effective", "neutral", "immune"; present only when both attacker and defender were given.
attackerNoThe attacker as supplied, echoed back; absent when no attacker argument was given.
coverageNoPresent only when an attacker was given without a defender: how that attacking type lands against each of the 18 defending types, keyed by defending type name ("Bug", "Dark", "Dragon", "Electric", "Fairy", "Fighting", "Fire", "Flying", "Ghost", "Grass", "Ground", "Ice", "Normal", "Poison", "Psychic", "Rock", "Steel", "Water").
defenderNoResolved defender name — the type or species the multipliers were computed against; present in the matchup and defender-only replies.
damageTakenNoPresent only when a defender was given without an attacker: everything the defender takes, keyed by attacking type name. Combined typing is folded in, so 4x and 0.25x entries appear for dual types and 0 marks immunities.
defenderTypesNoThe defending typing the multiplier was computed from, e.g. ["Dragon", "Ground"] for Garchomp or ["Steel"] for a type; present in the matchup and defender-only replies.
effectivenessNoSingle multiplier for attacker against defender (0, 0.25, 0.5, 1, 2, or 4); present only when both attacker and defender were given.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond the annotations: it states that species names resolve to current-generation typing, that unknown names return an isError, that names are case-insensitive, and that the tool is offline. It does not detail the exact output shape, but the output schema exists and covers that.

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 dense paragraph that front-loads the core purpose, then enumerates the four modes in order of complexity, and ends with the sibling routing and error behavior. Every sentence earns its place; there is no filler or repetition of schema content.

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?

For a read-only, offline tool with an output schema and 100% parameter coverage, the description covers all the decision-relevant context: the four invocation modes, the species-to-typing resolution, case-insensitivity, error behavior, and the sibling tools to use instead. Nothing an agent needs to select and invoke the tool correctly is missing.

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 description coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by explaining how the two parameters interact: attacker alone returns offensive coverage, defender alone returns defensive coverage, and neither returns the full matrix. It also clarifies that defender accepts a species name and resolves its current-generation typing, which is not in the schema.

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 opens with a specific verb and resource ('Resolve type effectiveness') and immediately distinguishes the tool from siblings by enumerating the four argument modes (attacker+defender, attacker alone, defender alone, neither). It also names the sibling tools get_type and analyze_team, making the differentiation explicit.

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?

The description explicitly states when to use this tool versus alternatives: 'Use `get_type` for a type's own defensive entry, and `analyze_team` when the question spans a whole team.' It also clarifies the mode selection rule ('in the mode the arguments imply'), so an agent knows exactly which call shape to choose.

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

list_formsList Pokémon formsA
Read-onlyIdempotent

List every form of one species — base, alternate, cosmetic, and battle-only — with each form's types, base stats, abilities, plus the total count. Forms that have no data are returned with a note rather than dropped, so a missing entry is visible. Use it before assuming a form exists; for a single species' full profile use get_pokemon, and to search names across species use search_dex. Read-only and offline; unknown species return an isError with near matches.

ParametersJSON Schema
NameRequiredDescriptionDefault
speciesYesBase species to expand, e.g. "Rotom", "Ogerpon", "Gholdengo".

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNumber of entries in `forms`, including placeholders for forms with no data.
formsYesOne entry per known form name of the species — base, alternate, cosmetic, and battle-only — either a full form profile or a `{name, note}` placeholder.
baseSpeciesYesName of the base species whose forms are listed, e.g. "Rotom" when asked for "Rotom-Wash".

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already cover readOnly, idempotent, and non-destructive behavior. The description adds valuable behavioral context beyond this: missing forms are returned with a note instead of dropped, unknown species return isError with near matches, and the operation is offline.

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?

Three sentences deliver purpose, output contents, error behavior, usage guidance, and alternatives with no filler. Key scope is front-loaded, and every clause earns its place.

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?

Given an output schema exists, the description need not recreate return formatting, yet it still covers edge cases: data-less forms, missing entries, unknown species, and error behavior. An agent has everything needed to invoke and interpret the tool correctly.

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

Parameters3/5

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

Schema coverage is 100% and the schema parameter description already explains the base-species meaning with examples. The description reinforces that the operation is per-species but does not add meaningful new parameter semantics beyond what the schema provides.

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?

States a specific verb and resource: list all forms of one species, naming the categories included (base, alternate, cosmetic, battle-only). It also names sibling tools get_pokemon and search_dex as different operations, so an agent can distinguish them without opening schemas.

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?

Explicitly says when to use: before assuming a form exists. It also gives direct alternatives, get_pokemon for a full species profile and search_dex for cross-species name search, leaving no ambiguity about tool selection.

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

list_regulationsList regulation setsA
Read-onlyIdempotent

List every Pokémon Champions / VGC Regulation Set with its id, dates, status, and roster size. Takes no arguments; status is relative to today and the active set is also returned as currentSet (null when none is). Use get_regulation for one set's full rules and roster, check_legality to validate a team. Read-only and offline over the bundled regulation data — no network, auth, or rate limits; returns game, currentSet, and one summary per set (id, name, status, start, end, eligibleCount, megaCount, notes).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
gameYesGame every listed set belongs to ("Pokémon Champions").
noteYesStanding note on how Regulation Sets work: the roster is seasonal and eligibility is by base species, so every form of a listed species is legal.
setsYesOne summary per bundled Regulation Set, in chronological order (M-A through M-C).
currentSetYesId of the one set whose status is "current" today, or null when no set is active.

TDQS

A4.9/5.0
Behavior5/5

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

Even though annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, the description adds meaningful behavioral detail: status is relative to today, `currentSet` is null when none exists, and the tool is offline over bundled data with no network, auth, or rate limits. This goes well beyond what annotations provide and shapes caller expectations.

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?

Three tightly written sentences: purpose, no-args/status behavior, then alternatives and safety/offline guarantees. Every clause earns its place; no filler or repetition of schema fields.

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?

The description covers the tool's scope, output summary fields, status timing, currentSet semantics, offline/no-auth behavior, and routes to sibling tools for related needs. The output schema covers detailed return structure, so nothing essential is missing for correct invocation.

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?

With zero parameters, the input schema is already exhaustive. The description reinforces this by stating 'Takes no arguments,' which is a small but useful confirmation for an agent deciding whether any optional inputs exist. Baseline 4 applies because there are no parameter semantics to elaborate.

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 opens with 'List every Pokémon Champions / VGC Regulation Set' — a specific verb and resource with the exact fields returned (id, dates, status, roster size). It also distinguishes itself from `get_regulation` and `check_legality`, so an agent can identify this as the list/summary tool without opening other definitions.

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?

The description explicitly states when to use alternatives: 'Use `get_regulation` for one set's full rules and roster, `check_legality` to validate a team.' It also tells the agent that the tool takes no arguments, making the call context unambiguous.

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

list_threatsList meta threatsA
Read-onlyIdempotent

List the most-used Pokémon of one Pokémon Champions regulation, ranked by measured usage: each threat’s species, role, tier (S/A/B by usage rank) and usage share, plus the sample and sources the list was derived from; omit regulation to get every available list. This is the ranking only — for a threat’s standard set call get_set, which takes several species at once, and use list_regulations to discover regulation ids. Regulation ids match case- and punctuation-insensitively ("M-C", "mc"); an unknown one returns an isError naming the available lists. Usage-derived from Limitless VGC tournament teams, not editorial opinion. Read-only and offline; no network, auth, or rate limits.

ParametersJSON Schema
NameRequiredDescriptionDefault
regulationNoOptional regulation set id, e.g. "m-c" (matched case- and punctuation-insensitively); omit to list every regulation with its threat count.

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameNoDisplay name of the returned list, e.g. "Regulation Set M-C"; present only when `regulation` was supplied.
noteNoHow that list was derived and what it leaves out; present only when `regulation` was supplied.
listsNoOne summary per regulation; present only when `regulation` was omitted.
sampleNoSize and window of the sample the list was derived from; present only when `regulation` was supplied.
sourceNoProvenance of the returned list ("usage"); present only when `regulation` was supplied.
sourcesNoEvery dataset behind the list, with what each one supplies; present only when `regulation` was supplied.
threatsNoEvery threat in this regulation, most used first — species, role, tier and usage only; present only when `regulation` was supplied. Fetch the sets you need with `get_set`, which takes several species in one call.
regulationNoId of the returned list, e.g. "m-c"; present only when `regulation` was supplied.
sourceAsOfNoISO date of the newest data point behind that list; present only when `regulation` was supplied.
corroborationNoIndependent second ranking used to check the ordering; absent when the cross-check was unavailable, or when `regulation` was omitted.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and idempotentHint=true; the description goes beyond them by disclosing data provenance ('Usage-derived from Limitless VGC tournament teams, not editorial opinion'), offline behavior ('no network, auth, or rate limits'), and error semantics ('an unknown one returns an isError naming the available lists'). No contradiction with annotations.

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

Conciseness4/5

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

The core purpose is front-loaded in the first sentence, and every subsequent sentence earns its place: sibling routing, parameter behavior, provenance, safety. It is on the verbose side for a one-parameter list tool, but there is no filler or repetition of schema text.

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?

Complete for a read-only list tool with a single optional parameter and an output schema present. It covers return contents, omit-parameter behavior, error handling, data source, and safety profile — nothing an agent needs to call it correctly is missing.

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% and the schema already documents the regulation param including case/punctuation-insensitive matching and omit behavior, so baseline is 3. The description adds value on top by disclosing the error response for an unknown regulation ('isError naming the available lists'), which the schema does not state.

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?

States a specific verb and resource ('List the most-used Pokémon of one Pokémon Champions regulation, ranked by measured usage') and enumerates the output contents (species, role, tier, usage share, sample, sources). It also distinguishes itself from siblings by explicitly calling itself 'the ranking only' and naming get_set as the alternative for standard sets.

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 routing: 'for a threat’s standard set call get_set, which takes several species at once' and 'use list_regulations to discover regulation ids.' It also gives the omit-parameter behavior ('omit regulation to get every available list') and error behavior for unknown ids. An agent knows exactly when to pick this tool over its siblings.

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

optimize_evsOptimize EVs for a goalA
Read-onlyIdempotent

Derive a minimal EV spread for one Pokémon satisfying up to three goals: survive a named attack, outspeed a target Speed, and guarantee a KO in 1-4 hits. Use it when EVs must come from a goal — calculate_stats evaluates a spread you already have, check_speed ranks Speed without deriving EVs, and get_set returns a curated spread. Supplying none of survive/outspeed/kill errors; outspeed takes a set target or a raw speed, and leftover EVs fill maximize (default spe). Returns the spread, resulting stats, totalEVs/unusedEVs of the 508 usable, and a verification line per goal. Read-only and offline; an unreachable goal returns an isError.

ParametersJSON Schema
NameRequiredDescriptionDefault
ivsNoIVs to hold fixed while searching, keyed by stat id; omitted stats default to 31 (use 0 for a Trick Room Speed IV).
itemNoItem held while solving, e.g. "Assault Vest"; it changes the bulk or Speed the goals are tested against.
killNoAdd a KO goal: minimizes Atk or SpA so that even the lowest damage roll reaches the per-hit HP threshold.
fieldNoBattlefield conditions applied while testing the survive and kill goals; omit for a neutral Singles field.
levelNoLevel 1-100; default 50 (VGC), where bulk and Speed benchmarks are tightest.
natureNoNature used for every stat calculation, e.g. "Adamant", "Calm"; default Serious. Change it to trade one stat for another.
abilityNoAbility assumed active while solving, e.g. "Intimidate", "Protosynthesis".
speciesYesSpecies or form name to optimize, e.g. "Garchomp", "Incineroar".
surviveNoAdd a "always live this hit" goal: the search minimizes HP plus the relevant Defense EVs that keep the worst roll below max HP.
maximizeNoStat that receives leftover EVs after the goals are met, capped at 252 (default spe); EVs are added in steps of 4.spe
outspeedNoAdd an outspeed goal: supply `target` or `speed` (one is required here, otherwise that goal errors).

Output Schema

ParametersJSON Schema
NameRequiredDescription
evsYesThe solved spread: all six keys, each a multiple of 4 from 0 to 252, with the `maximize` stat holding the leftover EVs.
itemNoHeld item assumed while solving, as supplied; absent when the call gave none.
noteYesCaveat about how the spread was built: EVs come in steps of 4 (508 usable of 510), the maximize stat is capped at 252, and unused EVs can be reallocated by hand.
levelYesLevel every stat was computed at, 1-100.
statsYesThe six stats this exact spread reaches at this level and nature; recompute with `calculate_stats` to check a different spread.
natureYesNature the spread was solved with, e.g. "Adamant"; Serious when the call omitted one.
speciesYesCanonical species name the spread was solved for.
totalEVsYesSum of the six solved EVs, spent in multiples of 4 so 508 is the practical maximum.
unusedEVsYesEVs left over after the goals and the maximize step: 508 minus `totalEVs`, never negative.
verificationYesOne line per goal that was solved, e.g. "survive: Dragapult Dragon Darts -> 96-114 vs 175 HP (max 65%)" or "kill: 132 ATK EVs -> 187-221 vs 175 HP (min 100%)"; the evidence that the spread meets each goal.
championsPointsYesThe spread as Pokémon Champions stat points (whole numbers, at most 32 in a stat, 66 total) — what the game’s training screen takes; stats left uninvested are omitted and a maxed stat reads 32. The two systems budget differently (510 EVs against 66 points), so a spread trimmed to fit the EV cap reads back a point or two under what was asked: this is the nearest point spread for the stats actually computed, not a copy of the input.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds valuable behavioral context beyond that: it is 'read-only and offline', an unreachable goal returns an isError, and the return payload includes spread, stats, totalEVs/unusedEVs of the 508 usable, and a verification line per goal. This goes beyond the annotations without contradicting them, though it could further clarify behavior around conflicting goals or edge cases.

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 compact paragraph of five sentences, each serving a distinct purpose: core function, when-to-use, input constraint and outspeed modes, return values, and behavioral safety. It is front-loaded with the primary purpose and contains no filler or redundancy.

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?

Given the tool's complexity (11 params, nested objects, output schema), the description covers the essential context: what the tool does, when to use it, what inputs are required, what it returns, and its read-only/offline behavior. The presence of a rich output schema means return-value details are already structured, and the description still summarizes them adequately. Nothing an agent needs to invoke correctly is missing.

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?

With 100% schema description coverage, the schema already documents every parameter. The description adds meaningful cross-parameter semantics: it explains the relationship among survive/outspeed/kill (at least one required), clarifies that outspeed accepts either a target set or a raw speed, and explains that leftover EVs go to maximize (default spe). This is genuinely useful beyond the schema.

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 states a specific verb and resource ('Derive a minimal EV spread') and precisely enumerates the three goal types (survive, outspeed, KO in 1-4 hits). It also distinguishes the tool from siblings by naming calculate_stats, check_speed, and get_set and contrasting their behavior. An agent can immediately tell what this tool does and how it differs.

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?

The description gives explicit when-to-use guidance ('Use it when EVs must come from a goal') and explains why each alternative is not appropriate (calculate_stats evaluates an existing spread, check_speed ranks without deriving EVs, get_set returns a curated spread). It also states an important usage constraint: supplying none of survive/outspeed/kill errors. This fully equips the agent to choose correctly.

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

search_dexSearch the dataset by nameA
Read-onlyIdempotent

Find species, moves, items, abilities, or natures by case-insensitive substring of name or Showdown id, sorted by National Dex number and truncated to limit. Use it when the exact name is uncertain, then call the matching lookup (get_pokemon, get_move, get_item, get_ability, get_nature) with the name it returns. Exactly one kind is searched per call; and the reply echoes kind, query, and total match count. Read-only and offline; a blank query is rejected as an error instead of dumping the dataset.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoTable to search; one per call (default "species").species
limitNoMaximum results returned, 1-100 (default 20).
queryYesSubstring to match against name and Showdown id, e.g. "oger", "sword".

Output Schema

ParametersJSON Schema
NameRequiredDescription
kindYesThe table that was searched, echoed back from the `kind` argument.
countYesTotal number of matches the query found, before truncation to `limit` — compare against `results.length` to see whether the list was cut short.
queryYesThe query exactly as it was supplied (not lower-cased or trimmed).
resultsYesMatching entries sorted by `num` ascending and truncated to `limit`; empty when nothing matched.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds substantial behavioral context: case-insensitive matching, sorting by National Dex number, truncation to limit, the echoed response fields (kind, query, total match count), offline operation, and blank-query rejection. Nothing contradicts 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.

Conciseness5/5

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

Three sentences with no wasted words: the first states the core function, the second gives usage and routing, the third covers constraints and response behavior. It is front-loaded with the main purpose and every sentence earns its place.

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?

Given the output schema exists and annotations cover the safety profile, the description covers all agent-relevant details: what is searched, how matches are ordered and truncated, the one-kind constraint, blank-query error, and the follow-up lookup workflow. Nothing essential is missing for correct invocation and interpretation.

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 description coverage is 100%, so the baseline is 3. The description adds value by clarifying the query semantics (case-insensitive substring over name or Showdown id), reinforcing that exactly one kind is searched per call, and explaining that limit truncates the sorted result. This is above baseline but not a full replacement for the schema's explicit enum and range details.

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 uses a specific verb ('Find'), names the exact resources (species, moves, items, abilities, or natures), and states the matching method (case-insensitive substring of name or Showdown id) plus ordering and truncation. It also distinguishes itself from the lookup siblings by explicitly directing the agent to call get_pokemon, get_move, etc., afterward. This leaves no ambiguity about what the tool does.

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?

It explicitly says when to use it ('Use it when the exact name is uncertain') and names the exact alternative lookups (get_pokemon, get_move, get_item, get_ability, get_nature) that should be called with the returned name. It also states the one-kind-per-call restriction and the blank-query error behavior. This is strong routing guidance with no inference required.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 23 tool updatesv3.2.0
    • Changedanalyze_team15 fields changed
      • addedInput schema / properties / opponent
        Added value: +{
        +  "description": "Optional opponent team as species names, e.g. [\"Salamence\", \"Sneasler\", \"Kingambit\"]; the reply then recommends which four of your six to bring. This is what team preview gives you — species only, no sets — so the read is type-based. Unknown names return an isError.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "maxItems": 6,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • changedInput schema / properties / team / description
        Previous value: -"Team of up to 6 members, each a species with optional Tera type and moves."New value: +"Team of up to 6 members, each a species with optional moves and a set."
      • removedInput schema / properties / team / items / properties / teraType
        Removed value: -{
        -  "description": "Optional Tera type, e.g. \"Steel\"; when set it replaces the member’s defensive typing in the weakness tally.",
        -  "type": "string"
        -}
      • addedOutput schema / properties / bringFour
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Which four of the six to bring; present only when `opponent` was supplied.",
        +  "properties": {
        +    "atRiskTypes": {
        +      "description": "Types at least two of the recommended four are weak to with none of them resisting or immune — the cost of the cut, worth knowing before you commit to it.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "leftBehind": {
        +      "description": "The members not recommended; empty when the team has four or fewer.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "defensive": {
        +            "description": "Opponent species that hit this member super-effectively on their STAB alone — team preview shows no sets.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "offensive": {
        +            "description": "Opponent species this member hits super-effectively, from STAB or a supplied move.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "score": {
        +            "description": "`offensive` minus `defensive`: the ranking key.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "species": {
        +            "description": "Species name of the member.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "species",
        +          "offensive",
        +          "defensive",
        +          "score"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "note": {
        +      "description": "How the pick is scored, and what it cannot see.",
        +      "type": "string"
        +    },
        +    "opponent": {
        +      "description": "The opponent team as resolved species names, in the order supplied.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "picks": {
        +      "description": "Up to four members to bring, best first — fewer only when the team itself has fewer than four.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "defensive": {
        +            "description": "Opponent species that hit this member super-effectively on their STAB alone — team preview shows no sets.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "offensive": {
        +            "description": "Opponent species this member hits super-effectively, from STAB or a supplied move.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "score": {
        +            "description": "`offensive` minus `defensive`: the ranking key.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "species": {
        +            "description": "Species name of the member.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "species",
        +          "offensive",
        +          "defensive",
        +          "score"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "opponent",
        +    "picks",
        +    "leftBehind",
        +    "atRiskTypes",
        +    "note"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / properties / defensiveWeaknesses / description
        Previous value: -"One entry for each of the 18 classic types (keyed by type name, e.g. \"Fire\"), tallying how the team fares defensively against that type. A member is counted on its Tera type instead of its own types when a Tera type was supplied."New value: +"One entry for each of the 18 classic types (keyed by type name, e.g. \"Fire\"), tallying how the team fares defensively against that type."
      • changedOutput schema / properties / offensiveCoverage / properties / coveredBy / description
        Previous value: -"One entry for each of the 18 classic types (keyed by the defending type), listing the team members that hit it super-effectively from STAB, Tera type, or a supplied move type; an empty array means nobody does."New value: +"One entry for each of the 18 classic types (keyed by the defending type), listing the team members that hit it super-effectively from STAB or a supplied move type; an empty array means nobody does."
      • changedOutput schema / properties / speed / properties / fasterThreatCount / description
        Previous value: -"How many legal species outspeed the fastest member; present only when `regulation` was supplied."New value: +"How many legal species have a higher base Speed than the team’s fastest member; present only when `regulation` was supplied. A base-stat count only — `threatCoverage` applies each threat’s real nature, EVs and Mega form."
      • removedOutput schema / properties / speed / properties / fasterThreats
        Removed value: -{
        -  "description": "Up to 20 of those threats, fastest first, cut off at that limit; present only when `regulation` was supplied — compare with `fasterThreatCount` for the full total.",
        -  "items": {
        -    "additionalProperties": false,
        -    "properties": {
        -      "baseSpe": {
        -        "description": "Its base Speed stat, higher than the team’s fastest.",
        -        "maximum": 9007199254740991,
        -        "minimum": -9007199254740991,
        -        "type": "integer"
        -      },
        -      "species": {
        -        "description": "Legal species name.",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "species",
        -      "baseSpe"
        -    ],
        -    "type": "object"
        -  },
        -  "type": "array"
        -}
      • removedOutput schema / properties / speed / properties / note
        Removed value: -{
        -  "description": "Caveat that threats are base-speed comparisons only; present only when `regulation` was supplied.",
        -  "type": "string"
        -}
      • removedOutput schema / properties / team / items / properties / teraType
        Removed value: -{
        -  "description": "Tera type supplied for this member; when set it replaces the member’s typing defensively and is added to its attacking types. Absent when none was given.",
        -  "type": "string"
        -}
      • addedOutput schema / properties / threatCoverage / properties / fastestSpeed
        Added value: +{
        +  "description": "Your fastest member’s Speed at level 50 with the sets you supplied — the value every `outspeed` below is judged against.",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • removedOutput schema / properties / threatCoverage / properties / threats / items / properties / fastestSpeed
        Removed value: -{
        -  "description": "Your fastest member’s Speed at level 50 with the sets you supplied.",
        -  "maximum": 9007199254740991,
        -  "minimum": -9007199254740991,
        -  "type": "integer"
        -}
      • changedOutput schema / properties / threatCoverage / properties / threats / items / properties / hitMultiplier / description
        Previous value: -"Best type multiplier your team has against it, from STAB, Tera type and supplied moves; 0 when nothing can hit it at all."New value: +"Best type multiplier your team has against it, from STAB and supplied moves; 0 when nothing can hit it at all."
      • changedOutput schema / properties / threatCoverage / properties / threats / items / required
        Previous value: -[
        -  "species",
        -  "usage",
        -  "threatSpeed",
        -  "fastestSpeed",
        -  "outspeed",
        -  "hitMultiplier",
        -  "answered"
        -]New value: +[
        +  "species",
        +  "usage",
        +  "threatSpeed",
        +  "outspeed",
        +  "hitMultiplier",
        +  "answered"
        +]
      • changedOutput schema / properties / threatCoverage / required
        Previous value: -[
        -  "regulation",
        -  "sourceAsOf",
        -  "threats",
        -  "unanswered",
        -  "unansweredCount",
        -  "note"
        -]New value: +[
        +  "regulation",
        +  "sourceAsOf",
        +  "fastestSpeed",
        +  "threats",
        +  "unanswered",
        +  "unansweredCount",
        +  "note"
        +]
    • Changedcalculate_damage16 fields changed
      • changedInput schema / properties / attacker / description
        Previous value: -"The attacking Pokémon: species plus optional level, nature, IVs, EVs, item, ability, boosts, status, Tera type, and current HP."New value: +"The attacking Pokémon: species plus optional level, nature, IVs, EVs, item, ability, boosts, status, and current HP."
      • removedInput schema / properties / attacker / properties / teraType
        Removed value: -{
        -  "description": "Tera type to use when the move is Terastallized, e.g. \"Fairy\".",
        -  "type": "string"
        -}
      • removedInput schema / properties / defender / properties / teraType
        Removed value: -{
        -  "description": "Tera type to use when the move is Terastallized, e.g. \"Fairy\".",
        -  "type": "string"
        -}
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • changedOutput schema / properties / attacker / properties / boosts / description
        Previous value: -"Stat stages in effect for the calculation; all six keys are present with 0 for unboosted stats."New value: +"Stat stages in effect for the calculation; absent when none were supplied, since every omitted stage is 0."
      • changedOutput schema / properties / attacker / properties / evs / description
        Previous value: -"EVs the set was calculated with, keyed by stat id (hp, atk, def, spa, spd, spe) with stats left at 0 omitted; generations 1-2 fix all six at 252 when the call supplies none."New value: +"EVs the set was calculated with, keyed by stat id (hp, atk, def, spa, spd, spe) with stats left at 0 omitted."
      • changedOutput schema / properties / attacker / properties / ivs / description
        Previous value: -"IVs the set was calculated with; all six keys are present, defaulting to 31."New value: +"IVs the set was calculated with; present only when the call supplied a non-default one, since an all-31 spread is what every omitted IV gives."
      • removedOutput schema / properties / attacker / properties / teraType
        Removed value: -{
        -  "description": "Tera type echoed back when the call supplied one; absent otherwise.",
        -  "type": "string"
        -}
      • changedOutput schema / properties / attacker / required
        Previous value: -[
        -  "species",
        -  "level",
        -  "nature",
        -  "evs",
        -  "championsPoints",
        -  "ivs",
        -  "boosts",
        -  "stats"
        -]New value: +[
        +  "species",
        +  "level",
        +  "nature",
        +  "evs",
        +  "championsPoints",
        +  "stats"
        +]
      • changedOutput schema / properties / defender / properties / boosts / description
        Previous value: -"Stat stages in effect for the calculation; all six keys are present with 0 for unboosted stats."New value: +"Stat stages in effect for the calculation; absent when none were supplied, since every omitted stage is 0."
      • changedOutput schema / properties / defender / properties / evs / description
        Previous value: -"EVs the set was calculated with, keyed by stat id (hp, atk, def, spa, spd, spe) with stats left at 0 omitted; generations 1-2 fix all six at 252 when the call supplies none."New value: +"EVs the set was calculated with, keyed by stat id (hp, atk, def, spa, spd, spe) with stats left at 0 omitted."
      • changedOutput schema / properties / defender / properties / ivs / description
        Previous value: -"IVs the set was calculated with; all six keys are present, defaulting to 31."New value: +"IVs the set was calculated with; present only when the call supplied a non-default one, since an all-31 spread is what every omitted IV gives."
      • removedOutput schema / properties / defender / properties / teraType
        Removed value: -{
        -  "description": "Tera type echoed back when the call supplied one; absent otherwise.",
        -  "type": "string"
        -}
      • changedOutput schema / properties / defender / required
        Previous value: -[
        -  "species",
        -  "level",
        -  "nature",
        -  "evs",
        -  "championsPoints",
        -  "ivs",
        -  "boosts",
        -  "stats"
        -]New value: +[
        +  "species",
        +  "level",
        +  "nature",
        +  "evs",
        +  "championsPoints",
        +  "stats"
        +]
      • removedOutput schema / properties / generation
        Removed value: -{
        -  "description": "Generation whose data and mechanics were used, 1-9.",
        -  "maximum": 9007199254740991,
        -  "minimum": -9007199254740991,
        -  "type": "integer"
        -}
      • changedOutput schema / required
        Previous value: -[
        -  "generation",
        -  "attacker",
        -  "defender",
        -  "move",
        -  "field",
        -  "damage",
        -  "damageRange",
        -  "description"
        -]New value: +[
        +  "attacker",
        +  "defender",
        +  "move",
        +  "field",
        +  "damage",
        +  "damageRange",
        +  "description"
        +]
    • Changedcalculate_matchups12 fields changed
      • removedInput schema / properties / attacker / properties / teraType
        Removed value: -{
        -  "description": "Tera type to use when the move is Terastallized, e.g. \"Fairy\".",
        -  "type": "string"
        -}
      • removedInput schema / properties / defenders / items / properties / teraType
        Removed value: -{
        -  "description": "Tera type to use when the move is Terastallized, e.g. \"Fairy\".",
        -  "type": "string"
        -}
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • addedOutput schema / properties / attackerSpeed
        Added value: +{
        +  "description": "The attacker’s final Speed stat; hoisted here because it is the same for every matchup, and `speed.attackerMovesFirst` compares it against each row’s `speed.defender`.",
        +  "type": "number"
        +}
      • removedOutput schema / properties / generation
        Removed value: -{
        -  "description": "Generation whose data and mechanics were used, 1-9.",
        -  "maximum": 9007199254740991,
        -  "minimum": -9007199254740991,
        -  "type": "integer"
        -}
      • changedOutput schema / properties / matchups / items / properties / bestMove / description
        Previous value: -"The hardest-hitting move of the supplied move set against this defender, or null when none of them could be calculated (e.g. every move is unsupported in this generation)."New value: +"The hardest-hitting move of the supplied move set against this defender, or null when none of them could be calculated (e.g. every move is unsupported in the dataset)."
      • removedOutput schema / properties / matchups / items / properties / description
        Removed value: -{
        -  "description": "One-line summary of `bestMove` against this defender, e.g. \"252 Atk Garchomp Earthquake vs. 252 HP / 252+ Def Corviknight: 108-128 (27.9 - 33.1%)\"; when no move resolved it explains that instead.",
        -  "type": "string"
        -}
      • changedOutput schema / properties / matchups / items / properties / speed / description
        Previous value: -"Who moves first in this matchup, from the two Speed stats alone."New value: +"Who moves first in this matchup, from the two Speed stats alone; the attacker’s side of the comparison is the top-level `attackerSpeed`."
      • removedOutput schema / properties / matchups / items / properties / speed / properties / attacker
        Removed value: -{
        -  "description": "The attacker’s final Speed stat, the same number in every matchup.",
        -  "type": "number"
        -}
      • changedOutput schema / properties / matchups / items / properties / speed / required
        Previous value: -[
        -  "attacker",
        -  "defender",
        -  "attackerMovesFirst"
        -]New value: +[
        +  "defender",
        +  "attackerMovesFirst"
        +]
      • changedOutput schema / properties / matchups / items / required
        Previous value: -[
        -  "defender",
        -  "bestMove",
        -  "damageRange",
        -  "description",
        -  "immune",
        -  "speed"
        -]New value: +[
        +  "defender",
        +  "bestMove",
        +  "damageRange",
        +  "immune",
        +  "speed"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "generation",
        -  "attacker",
        -  "move",
        -  "matchups"
        -]New value: +[
        +  "attacker",
        +  "attackerSpeed",
        +  "move",
        +  "matchups"
        +]
    • Changedcalculate_stats3 fields changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • removedOutput schema / properties / generation
        Removed value: -{
        -  "description": "Generation whose base stats and mechanics were used, 1-9.",
        -  "maximum": 9007199254740991,
        -  "minimum": -9007199254740991,
        -  "type": "integer"
        -}
      • changedOutput schema / required
        Previous value: -[
        -  "species",
        -  "generation",
        -  "level",
        -  "nature",
        -  "baseStats",
        -  "bst",
        -  "evs",
        -  "championsPoints",
        -  "ivs",
        -  "stats"
        -]New value: +[
        +  "species",
        +  "level",
        +  "nature",
        +  "baseStats",
        +  "bst",
        +  "evs",
        +  "championsPoints",
        +  "ivs",
        +  "stats"
        +]
    • Changedcheck_speed3 fields changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • removedOutput schema / properties / generation
        Removed value: -{
        -  "description": "Generation whose base stats and mechanics were used, 1-9.",
        -  "maximum": 9007199254740991,
        -  "minimum": -9007199254740991,
        -  "type": "integer"
        -}
      • changedOutput schema / required
        Previous value: -[
        -  "species",
        -  "generation",
        -  "level",
        -  "nature",
        -  "baseSpe",
        -  "evSpe",
        -  "ivSpe",
        -  "finalSpeed",
        -  "modifiers"
        -]New value: +[
        +  "species",
        +  "level",
        +  "nature",
        +  "baseSpe",
        +  "evSpe",
        +  "ivSpe",
        +  "finalSpeed",
        +  "modifiers"
        +]
    • Changedget_ability1 field changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
    • Removedget_archetype
    • Changedget_item1 field changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
    • Changedget_learnset2 fields changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • changedOutput schema / properties / movesBySource / description
        Previous value: -"Learned moves grouped by how they are acquired, keyed by \"Level-up\", \"TM\", \"Egg\", \"Tutor\", \"Event\", \"Raid/Event\", \"Virtual Console transfer\", \"Dream World\", \"Pre-evolution\", or \"Other\"; a move learned more than one way appears under each. Each list is sorted by move name and holds display names, e.g. {\"TM\": [\"Earthquake\"], \"Level-up\": [\"Dragon Claw\"]}. Empty when the generation records no moves."New value: +"Learned moves grouped by how they are acquired, keyed by \"Level-up\", \"TM\", \"Egg\", \"Tutor\", \"Event\", \"Raid/Event\", \"Virtual Console transfer\", \"Dream World\", \"Pre-evolution\", or \"Other\"; a move learned more than one way appears under each. Each list is sorted by move name and holds display names, e.g. {\"TM\": [\"Earthquake\"], \"Level-up\": [\"Dragon Claw\"]}. Empty when the dataset records no moves."
    • Changedget_move1 field changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
    • Changedget_nature1 field changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
    • Changedget_pokemon7 fields changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • removedOutput schema / properties / doublesTier
        Removed value: -{
        -  "description": "Doubles (VGC) tier label from the bundled dataset.",
        -  "type": "string"
        -}
      • removedOutput schema / properties / natDexTier
        Removed value: -{
        -  "description": "National Dex tier label; the empty string when the entry has none.",
        -  "type": "string"
        -}
      • removedOutput schema / properties / requiredTeraType
        Removed value: -{
        -  "description": "Tera type this entry is locked to (e.g. an Ogerpon mask); absent when the Tera type is freely chosen.",
        -  "type": "string"
        -}
      • removedOutput schema / properties / tier
        Removed value: -{
        -  "description": "Singles tier label from the bundled dataset, e.g. \"OU\", \"UU\", \"LC\".",
        -  "type": "string"
        -}
      • changedOutput schema / properties / types / description
        Previous value: -"Typing in the requested generation, in order, e.g. [\"Dragon\", \"Ground\"]. One of \"Bug\", \"Dark\", \"Dragon\", \"Electric\", \"Fairy\", \"Fighting\", \"Fire\", \"Flying\", \"Ghost\", \"Grass\", \"Ground\", \"Ice\", \"Normal\", \"Poison\", \"Psychic\", \"Rock\", \"Steel\", \"Water\"."New value: +"Typing, in order, e.g. [\"Dragon\", \"Ground\"]. One of \"Bug\", \"Dark\", \"Dragon\", \"Electric\", \"Fairy\", \"Fighting\", \"Fire\", \"Flying\", \"Ghost\", \"Grass\", \"Ground\", \"Ice\", \"Normal\", \"Poison\", \"Psychic\", \"Rock\", \"Steel\", \"Water\"."
      • changedOutput schema / required
        Previous value: -[
        -  "name",
        -  "num",
        -  "gen",
        -  "types",
        -  "baseStats",
        -  "bst",
        -  "abilities",
        -  "tier",
        -  "doublesTier",
        -  "natDexTier",
        -  "baseSpecies",
        -  "isCosmeticForme",
        -  "weightkg",
        -  "genderRatio",
        -  "eggGroups",
        -  "nfe",
        -  "canHatch",
        -  "evos",
        -  "cannotDynamax",
        -  "isNonstandard",
        -  "tags"
        -]New value: +[
        +  "name",
        +  "num",
        +  "gen",
        +  "types",
        +  "baseStats",
        +  "bst",
        +  "abilities",
        +  "baseSpecies",
        +  "isCosmeticForme",
        +  "weightkg",
        +  "genderRatio",
        +  "eggGroups",
        +  "nfe",
        +  "canHatch",
        +  "evos",
        +  "cannotDynamax",
        +  "isNonstandard",
        +  "tags"
        +]
    • Changedget_regulation5 fields changed
      • addedInput schema / properties / includeRoster
        Added value: +{
        +  "description": "Include the two name rosters — every legal base species and every species allowed to Mega Evolve — which together are about two thirds of the response. Omitted, the rules and the `eligibleCount`/`megaCount` sizes come back without them; pass true when you actually need the names.",
        +  "type": "boolean"
        +}
      • changedOutput schema / properties / eligibleSpecies / description
        Previous value: -"The full legal base-species roster (large); every form of a listed species is legal."New value: +"The full legal base-species roster; every form of a listed species is legal. Present only when `includeRoster` was set — `eligibleCount` gives the size either way."
      • changedOutput schema / properties / megaEvolution / properties / species / description
        Previous value: -"Base species allowed to Mega Evolve; every form of each is covered."New value: +"Base species allowed to Mega Evolve; every form of each is covered. Present only when `includeRoster` was set — `megaCount` gives the size either way."
      • changedOutput schema / properties / megaEvolution / required
        Previous value: -[
        -  "allowed",
        -  "perBattle",
        -  "species"
        -]New value: +[
        +  "allowed",
        +  "perBattle"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "id",
        -  "name",
        -  "game",
        -  "status",
        -  "start",
        -  "end",
        -  "eligibleCount",
        -  "megaCount",
        -  "notes",
        -  "battleType",
        -  "level",
        -  "bringPick",
        -  "timers",
        -  "rounds",
        -  "clauses",
        -  "megaEvolution",
        -  "eligibleSpecies",
        -  "source",
        -  "sourceAsOf"
        -]New value: +[
        +  "id",
        +  "name",
        +  "game",
        +  "status",
        +  "start",
        +  "end",
        +  "eligibleCount",
        +  "megaCount",
        +  "notes",
        +  "battleType",
        +  "level",
        +  "bringPick",
        +  "timers",
        +  "rounds",
        +  "clauses",
        +  "megaEvolution",
        +  "source",
        +  "sourceAsOf"
        +]
    • Changedget_set9 fields changed
      • addedInput schema / properties / species / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "items": {
        +      "type": "string"
        +    },
        +    "maxItems": 24,
        +    "minItems": 1,
        +    "type": "array"
        +  }
        +]
      • changedInput schema / properties / species / description
        Previous value: -"Base species or form name, e.g. \"Garchomp\", \"Indeedee-F\" (case- and punctuation-insensitive)."New value: +"Base species or form name, e.g. \"Garchomp\", \"Indeedee-F\" (case- and punctuation-insensitive). Pass an array to fetch several sets in one call, which returns `sets` instead of the flat set."
      • removedInput schema / properties / species / type
        Removed value: -"string"
      • addedOutput schema / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "The same spread in Pokémon Champions stat points (whole numbers, at most 32 in a stat, 66 total), which is what the game’s training screen takes and the form the source publishes; `evs` is this converted to the 0-252 scale the calculate_* tools take. Absent when the source published no spread.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / paste
        Added value: +{
        +  "description": "The whole set as a Showdown-format paste, ready to copy into a team builder or paste host: `species @ item`, ability, level 50, nature, EVs in Pokémon Champions stat points (0-32 each, 66 total — what the game’s training screen takes), then the four moves. A Mega set names the base species holding its stone.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / regulation / description
        Previous value: -"Display name of the list the set came from, e.g. \"Regulation Set M-C\"."New value: +"Display name of the list the set came from, e.g. \"Regulation Set M-C\"; present only when a single species was requested."
      • addedOutput schema / properties / sets
        Added value: +{
        +  "description": "One entry per requested species, in the order supplied; present only when `species` was an array.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "ability": {
        +        "description": "Most-played ability on the form that was led, i.e. before Mega Evolving on a Mega set.",
        +        "type": "string"
        +      },
        +      "championsPoints": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "The same spread in Pokémon Champions stat points (whole numbers, at most 32 in a stat, 66 total), which is what the game’s training screen takes and the form the source publishes; `evs` is this converted to the 0-252 scale the calculate_* tools take. Absent when the source published no spread.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "evs": {
        +        "additionalProperties": false,
        +        "description": "Most-played spread, keyed by Showdown stat and scaled to the 0-252 EVs `calculate_stats` and `calculate_damage` take; only invested stats are listed, everything omitted is 0. Absent when the source published no spread for that species.",
        +        "properties": {
        +          "atk": {
        +            "description": "Attack EVs.",
        +            "type": "number"
        +          },
        +          "def": {
        +            "description": "Defense EVs.",
        +            "type": "number"
        +          },
        +          "hp": {
        +            "description": "HP EVs.",
        +            "type": "number"
        +          },
        +          "spa": {
        +            "description": "Special Attack EVs.",
        +            "type": "number"
        +          },
        +          "spd": {
        +            "description": "Special Defense EVs.",
        +            "type": "number"
        +          },
        +          "spe": {
        +            "description": "Speed EVs.",
        +            "type": "number"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "form": {
        +        "description": "Form the set is played as when that is not the default one, e.g. \"Arcanine-Hisui\"; absent otherwise.",
        +        "type": "string"
        +      },
        +      "item": {
        +        "description": "Most-played held item, e.g. \"Salamencite\".",
        +        "type": "string"
        +      },
        +      "megaAbility": {
        +        "description": "Ability after Mega Evolving; absent when the set is not a Mega set.",
        +        "type": "string"
        +      },
        +      "megaForm": {
        +        "description": "Mega form this set evolves into, e.g. \"Salamence-Mega\"; absent when the set is not a Mega set.",
        +        "type": "string"
        +      },
        +      "moves": {
        +        "description": "The four most-played moves, most played first.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "nature": {
        +        "description": "Most-played nature, e.g. \"Timid\".",
        +        "type": "string"
        +      },
        +      "notes": {
        +        "description": "The usage figures this set was derived from; absent when the list carries none.",
        +        "type": "string"
        +      },
        +      "paste": {
        +        "description": "The whole set as a Showdown-format paste, ready to copy into a team builder or paste host: `species @ item`, ability, level 50, nature, EVs in Pokémon Champions stat points (0-32 each, 66 total — what the game’s training screen takes), then the four moves. A Mega set names the base species holding its stone.",
        +        "type": "string"
        +      },
        +      "rank": {
        +        "description": "Position by usage in this list; 1 is the most used.",
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "regulation": {
        +        "description": "Display name of the list the set came from.",
        +        "type": "string"
        +      },
        +      "role": {
        +        "description": "Role read off the set’s ability and moves, e.g. \"Rain setter\", \"Mega Intimidate pivot\".",
        +        "type": "string"
        +      },
        +      "sourceAsOf": {
        +        "description": "ISO date of the newest data point behind that list.",
        +        "type": "string"
        +      },
        +      "species": {
        +        "description": "Base species name in Showdown spelling, e.g. \"Garchomp\"; every form collapses into it because Species Clause is per National Pokédex number.",
        +        "type": "string"
        +      },
        +      "tier": {
        +        "description": "Usage band: S is the top 5 by usage, A the next 7, B the rest of the list.",
        +        "enum": [
        +          "S",
        +          "A",
        +          "B"
        +        ],
        +        "type": "string"
        +      },
        +      "usage": {
        +        "description": "Share of the sampled teams carrying this species, in percent.",
        +        "type": "number"
        +      }
        +    },
        +    "required": [
        +      "regulation",
        +      "sourceAsOf",
        +      "species",
        +      "role",
        +      "tier",
        +      "rank",
        +      "usage",
        +      "item",
        +      "ability",
        +      "nature",
        +      "moves",
        +      "paste"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / properties / sourceAsOf / description
        Previous value: -"ISO date of the newest data point behind that list."New value: +"ISO date of the newest data point behind that list; present only when a single species was requested."
      • removedOutput schema / required
        Removed value: -[
        -  "regulation",
        -  "sourceAsOf",
        -  "species",
        -  "role",
        -  "tier",
        -  "rank",
        -  "usage",
        -  "item",
        -  "ability",
        -  "nature",
        -  "moves"
        -]
    • Changedget_type2 fields changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • changedOutput schema / properties / isNonstandard / description
        Previous value: -"\"Future\" when the type does not exist yet in the requested generation (e.g. Dark in generation 1) and \"Past\" when it no longer exists; null for types that are standard in that generation."New value: +"\"Future\" when the type does not exist in the dataset (e.g. Dark in generation 1) and \"Past\" when it no longer exists; null for types that are standard in that generation."
    • Changedget_type_matchup1 field changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
    • Removedlist_archetypes
    • Changedlist_forms3 fields changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • changedOutput schema / properties / count / description
        Previous value: -"Number of entries in `forms`, including placeholders for forms missing in this generation."New value: +"Number of entries in `forms`, including placeholders for forms with no data."
      • changedOutput schema / properties / forms / items / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "description": "A form that exists in the requested generation, carrying the same fields as `get_pokemon` (minus evolutions and the long tail of dataset metadata).",
        -    "properties": {
        -      "abilities": {
        -        "additionalProperties": false,
        -        "description": "Abilities keyed by Showdown slot: \"0\" primary, \"1\" secondary, \"H\" hidden, \"S\" special.",
        -        "properties": {
        -          "0": {
        -            "description": "Primary ability.",
        -            "type": "string"
        -          },
        -          "1": {
        -            "description": "Secondary ability; absent from species with only one normal ability.",
        -            "type": "string"
        -          },
        -          "H": {
        -            "description": "Hidden ability; absent from species that have none.",
        -            "type": "string"
        -          },
        -          "S": {
        -            "description": "Special slot, used by abilities that come with a forme (Battle Bond, Power Construct); absent for species that have none.",
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "0"
        -        ],
        -        "type": "object"
        -      },
        -      "baseStats": {
        -        "additionalProperties": false,
        -        "description": "All six stats keyed by stat id (\"hp\", \"atk\", \"def\", \"spa\", \"spd\", \"spe\").",
        -        "properties": {
        -          "atk": {
        -            "description": "Attack.",
        -            "type": "number"
        -          },
        -          "def": {
        -            "description": "Defense.",
        -            "type": "number"
        -          },
        -          "hp": {
        -            "description": "Hit Points.",
        -            "type": "number"
        -          },
        -          "spa": {
        -            "description": "Special Attack.",
        -            "type": "number"
        -          },
        -          "spd": {
        -            "description": "Special Defense.",
        -            "type": "number"
        -          },
        -          "spe": {
        -            "description": "Speed.",
        -            "type": "number"
        -          }
        -        },
        -        "required": [
        -          "hp",
        -          "atk",
        -          "def",
        -          "spa",
        -          "spd",
        -          "spe"
        -        ],
        -        "type": "object"
        -      },
        -      "battleOnly": {
        -        "anyOf": [
        -          {
        -            "type": "string"
        -          },
        -          {
        -            "items": {
        -              "type": "string"
        -            },
        -            "type": "array"
        -          }
        -        ],
        -        "description": "The species this form transforms from in battle; absent for normally selectable forms."
        -      },
        -      "bst": {
        -        "description": "Base stat total of the form.",
        -        "type": "number"
        -      },
        -      "doublesTier": {
        -        "description": "Doubles (VGC) tier label of the form; may be empty.",
        -        "type": "string"
        -      },
        -      "isCosmetic": {
        -        "description": "true when the form differs only cosmetically.",
        -        "type": "boolean"
        -      },
        -      "isMega": {
        -        "description": "true for Mega Evolutions; absent otherwise.",
        -        "type": "boolean"
        -      },
        -      "isPrimal": {
        -        "description": "true for Primal Reversions; absent otherwise.",
        -        "type": "boolean"
        -      },
        -      "name": {
        -        "description": "Form name, e.g. \"Rotom-Wash\".",
        -        "type": "string"
        -      },
        -      "tier": {
        -        "description": "Singles tier label of the form; may be empty for untiered forms.",
        -        "type": "string"
        -      },
        -      "types": {
        -        "description": "Typing of the form, e.g. [\"Electric\", \"Water\"]. One of \"Bug\", \"Dark\", \"Dragon\", \"Electric\", \"Fairy\", \"Fighting\", \"Fire\", \"Flying\", \"Ghost\", \"Grass\", \"Ground\", \"Ice\", \"Normal\", \"Poison\", \"Psychic\", \"Rock\", \"Steel\", \"Water\".",
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      }
        -    },
        -    "required": [
        -      "name",
        -      "types",
        -      "baseStats",
        -      "bst",
        -      "abilities",
        -      "tier",
        -      "doublesTier",
        -      "isCosmetic"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": false,
        -    "description": "Placeholder for a form name the dataset knows about but that does not exist in the requested generation; distinguishes \"no such form\" from \"form missing here\".",
        -    "properties": {
        -      "name": {
        -        "description": "Form name that has no data in the requested generation.",
        -        "type": "string"
        -      },
        -      "note": {
        -        "description": "Why the entry is empty — currently always \"unavailable in this generation\".",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "name",
        -      "note"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "description": "A form that exists in the dataset, carrying the same fields as `get_pokemon` (minus evolutions and the long tail of dataset metadata).",
        +    "properties": {
        +      "abilities": {
        +        "additionalProperties": false,
        +        "description": "Abilities keyed by Showdown slot: \"0\" primary, \"1\" secondary, \"H\" hidden, \"S\" special.",
        +        "properties": {
        +          "0": {
        +            "description": "Primary ability.",
        +            "type": "string"
        +          },
        +          "1": {
        +            "description": "Secondary ability; absent from species with only one normal ability.",
        +            "type": "string"
        +          },
        +          "H": {
        +            "description": "Hidden ability; absent from species that have none.",
        +            "type": "string"
        +          },
        +          "S": {
        +            "description": "Special slot, used by abilities that come with a forme (Battle Bond, Power Construct); absent for species that have none.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "0"
        +        ],
        +        "type": "object"
        +      },
        +      "baseStats": {
        +        "additionalProperties": false,
        +        "description": "All six stats keyed by stat id (\"hp\", \"atk\", \"def\", \"spa\", \"spd\", \"spe\").",
        +        "properties": {
        +          "atk": {
        +            "description": "Attack.",
        +            "type": "number"
        +          },
        +          "def": {
        +            "description": "Defense.",
        +            "type": "number"
        +          },
        +          "hp": {
        +            "description": "Hit Points.",
        +            "type": "number"
        +          },
        +          "spa": {
        +            "description": "Special Attack.",
        +            "type": "number"
        +          },
        +          "spd": {
        +            "description": "Special Defense.",
        +            "type": "number"
        +          },
        +          "spe": {
        +            "description": "Speed.",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "hp",
        +          "atk",
        +          "def",
        +          "spa",
        +          "spd",
        +          "spe"
        +        ],
        +        "type": "object"
        +      },
        +      "battleOnly": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          }
        +        ],
        +        "description": "The species this form transforms from in battle; absent for normally selectable forms."
        +      },
        +      "bst": {
        +        "description": "Base stat total of the form.",
        +        "type": "number"
        +      },
        +      "isCosmetic": {
        +        "description": "true when the form differs only cosmetically.",
        +        "type": "boolean"
        +      },
        +      "isMega": {
        +        "description": "true for Mega Evolutions; absent otherwise.",
        +        "type": "boolean"
        +      },
        +      "isPrimal": {
        +        "description": "true for Primal Reversions; absent otherwise.",
        +        "type": "boolean"
        +      },
        +      "name": {
        +        "description": "Form name, e.g. \"Rotom-Wash\".",
        +        "type": "string"
        +      },
        +      "types": {
        +        "description": "Typing of the form, e.g. [\"Electric\", \"Water\"]. One of \"Bug\", \"Dark\", \"Dragon\", \"Electric\", \"Fairy\", \"Fighting\", \"Fire\", \"Flying\", \"Ghost\", \"Grass\", \"Ground\", \"Ice\", \"Normal\", \"Poison\", \"Psychic\", \"Rock\", \"Steel\", \"Water\".",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "types",
        +      "baseStats",
        +      "bst",
        +      "abilities",
        +      "isCosmetic"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": false,
        +    "description": "Placeholder for a form name the dataset knows about but that distinguishes \"no such form\" from \"form missing here\"; distinguishes \"no such form\" from \"form missing here\".",
        +    "properties": {
        +      "name": {
        +        "description": "Form name that has no data in the dataset.",
        +        "type": "string"
        +      },
        +      "note": {
        +        "description": "Why the entry is empty — currently always \"unavailable in the dataset\".",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "note"
        +    ],
        +    "type": "object"
        +  }
        +]
    • Removedlist_speed_tiers
    • Changedlist_threats15 fields changed
      • changedOutput schema / properties / threats / description
        Previous value: -"Every threat in this regulation, most used first, with its standard set; present only when `regulation` was supplied."New value: +"Every threat in this regulation, most used first — species, role, tier and usage only; present only when `regulation` was supplied. Fetch the sets you need with `get_set`, which takes several species in one call."
      • removedOutput schema / properties / threats / items / properties / ability
        Removed value: -{
        -  "description": "Most-played ability on the form that was led, i.e. before Mega Evolving on a Mega set.",
        -  "type": "string"
        -}
      • removedOutput schema / properties / threats / items / properties / evs
        Removed value: -{
        -  "additionalProperties": false,
        -  "description": "Most-played spread, keyed by Showdown stat and scaled to the 0-252 EVs `calculate_stats` and `calculate_damage` take; only invested stats are listed, everything omitted is 0. Absent when the source published no spread for that species.",
        -  "properties": {
        -    "atk": {
        -      "description": "Attack EVs.",
        -      "type": "number"
        -    },
        -    "def": {
        -      "description": "Defense EVs.",
        -      "type": "number"
        -    },
        -    "hp": {
        -      "description": "HP EVs.",
        -      "type": "number"
        -    },
        -    "spa": {
        -      "description": "Special Attack EVs.",
        -      "type": "number"
        -    },
        -    "spd": {
        -      "description": "Special Defense EVs.",
        -      "type": "number"
        -    },
        -    "spe": {
        -      "description": "Speed EVs.",
        -      "type": "number"
        -    }
        -  },
        -  "type": "object"
        -}
      • removedOutput schema / properties / threats / items / properties / form
        Removed value: -{
        -  "description": "Form the set is played as when that is not the default one, e.g. \"Arcanine-Hisui\"; absent otherwise.",
        -  "type": "string"
        -}
      • removedOutput schema / properties / threats / items / properties / item
        Removed value: -{
        -  "description": "Most-played held item, e.g. \"Salamencite\".",
        -  "type": "string"
        -}
      • removedOutput schema / properties / threats / items / properties / megaAbility
        Removed value: -{
        -  "description": "Ability after Mega Evolving; absent when the set is not a Mega set.",
        -  "type": "string"
        -}
      • removedOutput schema / properties / threats / items / properties / megaForm
        Removed value: -{
        -  "description": "Mega form this set evolves into, e.g. \"Salamence-Mega\"; absent when the set is not a Mega set.",
        -  "type": "string"
        -}
      • removedOutput schema / properties / threats / items / properties / moves
        Removed value: -{
        -  "description": "The four most-played moves, most played first.",
        -  "items": {
        -    "type": "string"
        -  },
        -  "type": "array"
        -}
      • removedOutput schema / properties / threats / items / properties / nature
        Removed value: -{
        -  "description": "Most-played nature, e.g. \"Timid\".",
        -  "type": "string"
        -}
      • removedOutput schema / properties / threats / items / properties / notes
        Removed value: -{
        -  "description": "The usage figures this set was derived from; absent when the list carries none.",
        -  "type": "string"
        -}
      • removedOutput schema / properties / threats / items / properties / rank
        Removed value: -{
        -  "description": "Position by usage in this list; 1 is the most used.",
        -  "maximum": 9007199254740991,
        -  "minimum": -9007199254740991,
        -  "type": "integer"
        -}
      • changedOutput schema / properties / threats / items / properties / role / description
        Previous value: -"Role read off the set’s ability and moves, e.g. \"Rain setter\", \"Mega Intimidate pivot\"."New value: +"Role read off the set."
      • changedOutput schema / properties / threats / items / properties / species / description
        Previous value: -"Base species name in Showdown spelling, e.g. \"Garchomp\"; every form collapses into it because Species Clause is per National Pokédex number."New value: +"Base species name, e.g. \"Rillaboom\"."
      • changedOutput schema / properties / threats / items / properties / tier / description
        Previous value: -"Usage band: S is the top 5 by usage, A the next 7, B the rest of the list."New value: +"Usage band within that regulation."
      • changedOutput schema / properties / threats / items / required
        Previous value: -[
        -  "species",
        -  "role",
        -  "tier",
        -  "rank",
        -  "usage",
        -  "item",
        -  "ability",
        -  "nature",
        -  "moves"
        -]New value: +[
        +  "species",
        +  "role",
        +  "tier",
        +  "usage"
        +]
    • Removedlist_tiers
    • Changedoptimize_evs6 fields changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • removedInput schema / properties / kill / properties / target / properties / teraType
        Removed value: -{
        -  "description": "Tera type to use when the move is Terastallized, e.g. \"Fairy\".",
        -  "type": "string"
        -}
      • removedInput schema / properties / outspeed / properties / target / properties / teraType
        Removed value: -{
        -  "description": "Tera type to use when the move is Terastallized, e.g. \"Fairy\".",
        -  "type": "string"
        -}
      • removedInput schema / properties / survive / properties / attacker / properties / teraType
        Removed value: -{
        -  "description": "Tera type to use when the move is Terastallized, e.g. \"Fairy\".",
        -  "type": "string"
        -}
      • removedOutput schema / properties / generation
        Removed value: -{
        -  "description": "Generation whose data and mechanics were used, 1-9.",
        -  "maximum": 9007199254740991,
        -  "minimum": -9007199254740991,
        -  "type": "integer"
        -}
      • changedOutput schema / required
        Previous value: -[
        -  "species",
        -  "generation",
        -  "level",
        -  "nature",
        -  "evs",
        -  "championsPoints",
        -  "stats",
        -  "totalEVs",
        -  "unusedEVs",
        -  "verification",
        -  "note"
        -]New value: +[
        +  "species",
        +  "level",
        +  "nature",
        +  "evs",
        +  "championsPoints",
        +  "stats",
        +  "totalEVs",
        +  "unusedEVs",
        +  "verification",
        +  "note"
        +]
    • Changedsearch_dex2 fields changed
      • removedInput schema / properties / generation
        Removed value: -{
        -  "default": 9,
        -  "description": "Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet.",
        -  "maximum": 9,
        -  "minimum": 1,
        -  "type": "integer"
        -}
      • removedOutput schema / properties / results / items / properties / tier
        Removed value: -{
        -  "description": "Competitive tier — present only when `kind` is \"species\"; absent for moves, items, abilities, and natures.",
        -  "type": "string"
        -}
  2. 6 tool updatesv2.0.2
    • Changedanalyze_team5 fields changed
      • addedInput schema / properties / team / items / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "Optional Champions stat points, e.g. { spe: 32 }; only Speed affects this analysis, and it is an alternative to `evs`.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / team / items / properties / evs
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "Optional spread in the 0-252 scale; only Speed affects this analysis.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / team / items / properties / item
        Added value: +{
        +  "description": "Optional held item, e.g. \"Choice Scarf\"; Choice Scarf multiplies the member’s Speed by 1.5 in the threat coverage.",
        +  "type": "string"
        +}
      • addedInput schema / properties / team / items / properties / nature
        Added value: +{
        +  "description": "Optional nature, e.g. \"Jolly\"; with a spread it sets the member’s real Speed for the threat coverage, otherwise Speed is left neutral and uninvested.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / threatCoverage
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "How the team fares against the regulation’s most-used sets; present only when a regulation with a usage-derived threat list was supplied.",
        +  "properties": {
        +    "note": {
        +      "description": "How the comparison is made, and what it does not model.",
        +      "type": "string"
        +    },
        +    "regulation": {
        +      "description": "Display name of the regulation whose threat list was used, e.g. \"Regulation Set M-C\".",
        +      "type": "string"
        +    },
        +    "sourceAsOf": {
        +      "description": "ISO date of the newest data point behind that threat list.",
        +      "type": "string"
        +    },
        +    "threats": {
        +      "description": "One entry per threat in the regulation’s list, most used first.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "answered": {
        +            "description": "True when the team has a super-effective (≥2x) hit on it.",
        +            "type": "boolean"
        +          },
        +          "fastestSpeed": {
        +            "description": "Your fastest member’s Speed at level 50 with the sets you supplied.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "hitBy": {
        +            "description": "The member providing that best hit; absent when nothing hits it super-effectively.",
        +            "type": "string"
        +          },
        +          "hitMultiplier": {
        +            "description": "Best type multiplier your team has against it, from STAB, Tera type and supplied moves; 0 when nothing can hit it at all.",
        +            "type": "number"
        +          },
        +          "hitVia": {
        +            "description": "The attacking type providing it; absent when nothing hits it super-effectively.",
        +            "type": "string"
        +          },
        +          "outspeed": {
        +            "description": "True when your fastest member moves first.",
        +            "type": "boolean"
        +          },
        +          "species": {
        +            "description": "The threat as the meta plays it, e.g. \"Salamence-Mega\".",
        +            "type": "string"
        +          },
        +          "threatSpeed": {
        +            "description": "Its Speed at level 50 with its own nature, EVs and Mega form.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "usage": {
        +            "description": "Share of the sampled teams carrying it, in percent.",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "species",
        +          "usage",
        +          "threatSpeed",
        +          "fastestSpeed",
        +          "outspeed",
        +          "hitMultiplier",
        +          "answered"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "unanswered": {
        +      "description": "Threats with no super-effective hit from this team — the coverage holes to fix first.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "unansweredCount": {
        +      "description": "How many threats are unanswered.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "regulation",
        +    "sourceAsOf",
        +    "threats",
        +    "unanswered",
        +    "unansweredCount",
        +    "note"
        +  ],
        +  "type": "object"
        +}
    • Changedcalculate_damage6 fields changed
      • addedInput schema / properties / attacker / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "Pokémon Champions stat points keyed by stat id (hp, atk, def, spa, spd, spe): whole numbers, each 0-32, totalling at most 66. This is the spread the game’s training screen takes, and an alternative to `evs` — give one or the other, not both. One point is worth 8 EVs, so a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / defender / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "Pokémon Champions stat points keyed by stat id (hp, atk, def, spa, spd, spe): whole numbers, each 0-32, totalling at most 66. This is the spread the game’s training screen takes, and an alternative to `evs` — give one or the other, not both. One point is worth 8 EVs, so a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / attacker / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "The spread as Pokémon Champions stat points (whole numbers, at most 32 in a stat, 66 total) — what the game’s training screen takes; stats left uninvested are omitted and a maxed stat reads 32. The two systems budget differently (510 EVs against 66 points), so a spread trimmed to fit the EV cap reads back a point or two under what was asked: this is the nearest point spread for the stats actually computed, not a copy of the input.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • changedOutput schema / properties / attacker / required
        Previous value: -[
        -  "species",
        -  "level",
        -  "nature",
        -  "evs",
        -  "ivs",
        -  "boosts",
        -  "stats"
        -]New value: +[
        +  "species",
        +  "level",
        +  "nature",
        +  "evs",
        +  "championsPoints",
        +  "ivs",
        +  "boosts",
        +  "stats"
        +]
      • addedOutput schema / properties / defender / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "The spread as Pokémon Champions stat points (whole numbers, at most 32 in a stat, 66 total) — what the game’s training screen takes; stats left uninvested are omitted and a maxed stat reads 32. The two systems budget differently (510 EVs against 66 points), so a spread trimmed to fit the EV cap reads back a point or two under what was asked: this is the nearest point spread for the stats actually computed, not a copy of the input.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • changedOutput schema / properties / defender / required
        Previous value: -[
        -  "species",
        -  "level",
        -  "nature",
        -  "evs",
        -  "ivs",
        -  "boosts",
        -  "stats"
        -]New value: +[
        +  "species",
        +  "level",
        +  "nature",
        +  "evs",
        +  "championsPoints",
        +  "ivs",
        +  "boosts",
        +  "stats"
        +]
    • Changedcalculate_matchups2 fields changed
      • addedInput schema / properties / attacker / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "Pokémon Champions stat points keyed by stat id (hp, atk, def, spa, spd, spe): whole numbers, each 0-32, totalling at most 66. This is the spread the game’s training screen takes, and an alternative to `evs` — give one or the other, not both. One point is worth 8 EVs, so a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / defenders / items / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "Pokémon Champions stat points keyed by stat id (hp, atk, def, spa, spd, spe): whole numbers, each 0-32, totalling at most 66. This is the spread the game’s training screen takes, and an alternative to `evs` — give one or the other, not both. One point is worth 8 EVs, so a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
    • Changedcalculate_stats3 fields changed
      • addedInput schema / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "Pokémon Champions stat points keyed by stat id (hp, atk, def, spa, spd, spe): whole numbers, each 0-32, totalling at most 66. This is the spread the game’s training screen takes, and an alternative to `evs` — give one or the other, not both. One point is worth 8 EVs, so a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "The spread as Pokémon Champions stat points (whole numbers, at most 32 in a stat, 66 total) — what the game’s training screen takes; stats left uninvested are omitted and a maxed stat reads 32. The two systems budget differently (510 EVs against 66 points), so a spread trimmed to fit the EV cap reads back a point or two under what was asked: this is the nearest point spread for the stats actually computed, not a copy of the input.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "species",
        -  "generation",
        -  "level",
        -  "nature",
        -  "baseStats",
        -  "bst",
        -  "evs",
        -  "ivs",
        -  "stats"
        -]New value: +[
        +  "species",
        +  "generation",
        +  "level",
        +  "nature",
        +  "baseStats",
        +  "bst",
        +  "evs",
        +  "championsPoints",
        +  "ivs",
        +  "stats"
        +]
    • Changedcheck_speed1 field changed
      • addedInput schema / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "The same Speed investment in Pokémon Champions stat points, e.g. { spe: 32 } for a maxed Speed stat; give this or `evs`, not both.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
    • Changedoptimize_evs5 fields changed
      • addedInput schema / properties / kill / properties / target / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "Pokémon Champions stat points keyed by stat id (hp, atk, def, spa, spd, spe): whole numbers, each 0-32, totalling at most 66. This is the spread the game’s training screen takes, and an alternative to `evs` — give one or the other, not both. One point is worth 8 EVs, so a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / outspeed / properties / target / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "Pokémon Champions stat points keyed by stat id (hp, atk, def, spa, spd, spe): whole numbers, each 0-32, totalling at most 66. This is the spread the game’s training screen takes, and an alternative to `evs` — give one or the other, not both. One point is worth 8 EVs, so a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / survive / properties / attacker / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "Pokémon Champions stat points keyed by stat id (hp, atk, def, spa, spd, spe): whole numbers, each 0-32, totalling at most 66. This is the spread the game’s training screen takes, and an alternative to `evs` — give one or the other, not both. One point is worth 8 EVs, so a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / championsPoints
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "The spread as Pokémon Champions stat points (whole numbers, at most 32 in a stat, 66 total) — what the game’s training screen takes; stats left uninvested are omitted and a maxed stat reads 32. The two systems budget differently (510 EVs against 66 points), so a spread trimmed to fit the EV cap reads back a point or two under what was asked: this is the nearest point spread for the stats actually computed, not a copy of the input.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "species",
        -  "generation",
        -  "level",
        -  "nature",
        -  "evs",
        -  "stats",
        -  "totalEVs",
        -  "unusedEVs",
        -  "verification",
        -  "note"
        -]New value: +[
        +  "species",
        +  "generation",
        +  "level",
        +  "nature",
        +  "evs",
        +  "championsPoints",
        +  "stats",
        +  "totalEVs",
        +  "unusedEVs",
        +  "verification",
        +  "note"
        +]
  3. 15 tool updatesv2.0.0
    • Removedcalc_matchups
    • Changedcalculate_damage3 fields changed
      • changedInput schema / properties / attacker / properties / moves / description
        Previous value: -"Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calc_matchups` to pick the hardest-hitting move per defender."New value: +"Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender."
      • changedInput schema / properties / defender / properties / moves / description
        Previous value: -"Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calc_matchups` to pick the hardest-hitting move per defender."New value: +"Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender."
      • changedOutput schema / properties / damageRange / description
        Previous value: -"[minimum, maximum] damage: `calculate_damage` totals every roll (multi-hit moves are summed), while `calc_matchups` reports the flattened per-hit rolls, so its bounds stay single-hit values. [0, 0] means nothing could be calculated."New value: +"[minimum, maximum] damage: `calculate_damage` totals every roll (multi-hit moves are summed), while `calculate_matchups` reports the flattened per-hit rolls, so its bounds stay single-hit values. [0, 0] means nothing could be calculated."
    • Addedcalculate_matchups
    • Addedcheck_speed
    • Changedget_move1 field changed
      • changedOutput schema / properties / num / description
        Previous value: -"Move number in the dataset, which is also the sort key `search` returns moves by."New value: +"Move number in the dataset, which is also the sort key `search_dex` returns moves by."
    • Changedget_set19 fields changed
      • changedInput schema / properties / regulation / description
        Previous value: -"Optional regulation set id, e.g. \"m-c\"; omit to search every curated list."New value: +"Optional regulation set id, e.g. \"m-c\"; omit to search every list."
      • changedInput schema / properties / species / description
        Previous value: -"Base species name as curated, e.g. \"Garchomp\", \"Incineroar\" (case-insensitive)."New value: +"Base species or form name, e.g. \"Garchomp\", \"Indeedee-F\" (case- and punctuation-insensitive)."
      • changedOutput schema / properties / ability / description
        Previous value: -"Ability on the base form, i.e. before Mega Evolving."New value: +"Most-played ability on the form that was led, i.e. before Mega Evolving on a Mega set."
      • changedOutput schema / properties / evs / description
        Previous value: -"EV spread keyed by Showdown stat; only the invested stats are listed, everything omitted is 0."New value: +"Most-played spread, keyed by Showdown stat and scaled to the 0-252 EVs `calculate_stats` and `calculate_damage` take; only invested stats are listed, everything omitted is 0. Absent when the source published no spread for that species."
      • addedOutput schema / properties / form
        Added value: +{
        +  "description": "Form the set is played as when that is not the default one, e.g. \"Arcanine-Hisui\"; absent otherwise.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / item / description
        Previous value: -"The set’s standard held item, e.g. \"Garchompite\"."New value: +"Most-played held item, e.g. \"Salamencite\"."
      • changedOutput schema / properties / megaForm / description
        Previous value: -"Mega form this set evolves into, e.g. \"Mega Garchomp\"; absent when the set is not a Mega set."New value: +"Mega form this set evolves into, e.g. \"Salamence-Mega\"; absent when the set is not a Mega set."
      • changedOutput schema / properties / moves / description
        Previous value: -"The four recommended moves."New value: +"The four most-played moves, most played first."
      • changedOutput schema / properties / nature / description
        Previous value: -"Recommended nature, e.g. \"Jolly\"."New value: +"Most-played nature, e.g. \"Timid\"."
      • changedOutput schema / properties / notes / description
        Previous value: -"Curator commentary on how the set is played; absent when the curated set has none."New value: +"The usage figures this set was derived from; absent when the list carries none."
      • addedOutput schema / properties / rank
        Added value: +{
        +  "description": "Position by usage in this list; 1 is the most used.",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • changedOutput schema / properties / regulation / description
        Previous value: -"Display name of the curated list the set came from, e.g. \"Regulation Set M-C\"."New value: +"Display name of the list the set came from, e.g. \"Regulation Set M-C\"."
      • changedOutput schema / properties / role / description
        Previous value: -"Short competitive role, e.g. \"Mega sweeper / wallbreaker\"."New value: +"Role read off the set’s ability and moves, e.g. \"Rain setter\", \"Mega Intimidate pivot\"."
      • changedOutput schema / properties / sourceAsOf / description
        Previous value: -"ISO date that list was last reviewed."New value: +"ISO date of the newest data point behind that list."
      • changedOutput schema / properties / species / description
        Previous value: -"Curated base species name in Showdown spelling, e.g. \"Garchomp\"."New value: +"Base species name in Showdown spelling, e.g. \"Garchomp\"; every form collapses into it because Species Clause is per National Pokédex number."
      • removedOutput schema / properties / teraType
        Removed value: -{
        -  "description": "Recommended Tera type; absent when the curated set does not specify one.",
        -  "type": "string"
        -}
      • changedOutput schema / properties / tier / description
        Previous value: -"Curated tier within the regulation: S (format-defining), A, or B — editorial, not usage data."New value: +"Usage band: S is the top 5 by usage, A the next 7, B the rest of the list."
      • addedOutput schema / properties / usage
        Added value: +{
        +  "description": "Share of the sampled teams carrying this species, in percent.",
        +  "type": "number"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "regulation",
        -  "sourceAsOf",
        -  "species",
        -  "role",
        -  "tier",
        -  "item",
        -  "ability",
        -  "nature",
        -  "evs",
        -  "moves"
        -]New value: +[
        +  "regulation",
        +  "sourceAsOf",
        +  "species",
        +  "role",
        +  "tier",
        +  "rank",
        +  "usage",
        +  "item",
        +  "ability",
        +  "nature",
        +  "moves"
        +]
    • Addedget_type_matchup
    • Addedlist_speed_tiers
    • Changedlist_threats31 fields changed
      • changedInput schema / properties / regulation / description
        Previous value: -"Optional regulation set id, e.g. \"m-c\" (matched case- and punctuation-insensitively); omit to list every curated regulation with its threat count."New value: +"Optional regulation set id, e.g. \"m-c\" (matched case- and punctuation-insensitively); omit to list every regulation with its threat count."
      • addedOutput schema / properties / corroboration
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Independent second ranking used to check the ordering; absent when the cross-check was unavailable, or when `regulation` was omitted.",
        +  "properties": {
        +    "dataDate": {
        +      "description": "That source’s own data-revision label, which lags the regulation itself.",
        +      "type": "string"
        +    },
        +    "source": {
        +      "description": "The independent source that was compared against, e.g. \"Pikalytics\".",
        +      "type": "string"
        +    },
        +    "top10Overlap": {
        +      "description": "How many of this list’s top 10 that source also ranks in its top 10, out of 10.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "url": {
        +      "description": "Where that source publishes its ranking.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "source",
        +    "url",
        +    "dataDate",
        +    "top10Overlap"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / properties / lists / description
        Previous value: -"One summary per curated regulation; present only when `regulation` was omitted."New value: +"One summary per regulation; present only when `regulation` was omitted."
      • changedOutput schema / properties / lists / items / properties / sourceAsOf / description
        Previous value: -"ISO date the list was last reviewed."New value: +"ISO date of the newest data point behind that list."
      • changedOutput schema / properties / lists / items / properties / threats / description
        Previous value: -"Reduced projection of that regulation’s threats — species, role, and tier only; call again with `regulation`, or use `get_set`, for the full standard sets."New value: +"Reduced projection of that regulation’s threats — species, role, tier and usage only; call again with `regulation`, or use `get_set`, for the full standard sets."
      • changedOutput schema / properties / lists / items / properties / threats / items / properties / role / description
        Previous value: -"Short competitive role."New value: +"Role read off the set."
      • changedOutput schema / properties / lists / items / properties / threats / items / properties / species / description
        Previous value: -"Curated base species name, e.g. \"Incineroar\"."New value: +"Base species name, e.g. \"Rillaboom\"."
      • changedOutput schema / properties / lists / items / properties / threats / items / properties / tier / description
        Previous value: -"Curated tier within that regulation."New value: +"Usage band within that regulation."
      • addedOutput schema / properties / lists / items / properties / threats / items / properties / usage
        Added value: +{
        +  "description": "Share of the sampled teams carrying this species, in percent.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / lists / items / properties / threats / items / required
        Previous value: -[
        -  "species",
        -  "role",
        -  "tier"
        -]New value: +[
        +  "species",
        +  "role",
        +  "tier",
        +  "usage"
        +]
      • changedOutput schema / properties / note / description
        Previous value: -"Standing disclaimer for that list (editorial, not usage-derived); present only when `regulation` was supplied."New value: +"How that list was derived and what it leaves out; present only when `regulation` was supplied."
      • addedOutput schema / properties / sample
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Size and window of the sample the list was derived from; present only when `regulation` was supplied.",
        +  "properties": {
        +    "minPlayers": {
        +      "description": "Minimum players per tournament for inclusion.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "teams": {
        +      "description": "Teams sampled.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "through": {
        +      "description": "ISO date of the newest tournament in the sample.",
        +      "type": "string"
        +    },
        +    "tournaments": {
        +      "description": "Tournaments those teams came from.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "windowDays": {
        +      "description": "How far back the source looked, in days.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "teams",
        +    "tournaments",
        +    "minPlayers",
        +    "windowDays",
        +    "through"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / properties / source / description
        Previous value: -"Provenance of the returned list (\"curated\"); present only when `regulation` was supplied."New value: +"Provenance of the returned list (\"usage\"); present only when `regulation` was supplied."
      • changedOutput schema / properties / sourceAsOf / description
        Previous value: -"ISO date that list was last reviewed; present only when `regulation` was supplied."New value: +"ISO date of the newest data point behind that list; present only when `regulation` was supplied."
      • addedOutput schema / properties / sources
        Added value: +{
        +  "description": "Every dataset behind the list, with what each one supplies; present only when `regulation` was supplied.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "name": {
        +        "description": "Dataset name, e.g. \"Data from Limitless TCG\".",
        +        "type": "string"
        +      },
        +      "scope": {
        +        "description": "Which fields of a threat it supplies.",
        +        "type": "string"
        +      },
        +      "url": {
        +        "description": "Where that dataset is published.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "url",
        +      "scope"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / properties / threats / description
        Previous value: -"Every curated threat in full, with its standard set; present only when `regulation` was supplied."New value: +"Every threat in this regulation, most used first, with its standard set; present only when `regulation` was supplied."
      • changedOutput schema / properties / threats / items / properties / ability / description
        Previous value: -"Ability on the base form, i.e. before Mega Evolving."New value: +"Most-played ability on the form that was led, i.e. before Mega Evolving on a Mega set."
      • changedOutput schema / properties / threats / items / properties / evs / description
        Previous value: -"EV spread keyed by Showdown stat; only the invested stats are listed, everything omitted is 0."New value: +"Most-played spread, keyed by Showdown stat and scaled to the 0-252 EVs `calculate_stats` and `calculate_damage` take; only invested stats are listed, everything omitted is 0. Absent when the source published no spread for that species."
      • addedOutput schema / properties / threats / items / properties / form
        Added value: +{
        +  "description": "Form the set is played as when that is not the default one, e.g. \"Arcanine-Hisui\"; absent otherwise.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / threats / items / properties / item / description
        Previous value: -"The set’s standard held item, e.g. \"Garchompite\"."New value: +"Most-played held item, e.g. \"Salamencite\"."
      • changedOutput schema / properties / threats / items / properties / megaForm / description
        Previous value: -"Mega form this set evolves into, e.g. \"Mega Garchomp\"; absent when the set is not a Mega set."New value: +"Mega form this set evolves into, e.g. \"Salamence-Mega\"; absent when the set is not a Mega set."
      • changedOutput schema / properties / threats / items / properties / moves / description
        Previous value: -"The four recommended moves."New value: +"The four most-played moves, most played first."
      • changedOutput schema / properties / threats / items / properties / nature / description
        Previous value: -"Recommended nature, e.g. \"Jolly\"."New value: +"Most-played nature, e.g. \"Timid\"."
      • changedOutput schema / properties / threats / items / properties / notes / description
        Previous value: -"Curator commentary on how the set is played; absent when the curated set has none."New value: +"The usage figures this set was derived from; absent when the list carries none."
      • addedOutput schema / properties / threats / items / properties / rank
        Added value: +{
        +  "description": "Position by usage in this list; 1 is the most used.",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • changedOutput schema / properties / threats / items / properties / role / description
        Previous value: -"Short competitive role, e.g. \"Mega sweeper / wallbreaker\"."New value: +"Role read off the set’s ability and moves, e.g. \"Rain setter\", \"Mega Intimidate pivot\"."
      • changedOutput schema / properties / threats / items / properties / species / description
        Previous value: -"Curated base species name in Showdown spelling, e.g. \"Garchomp\"."New value: +"Base species name in Showdown spelling, e.g. \"Garchomp\"; every form collapses into it because Species Clause is per National Pokédex number."
      • removedOutput schema / properties / threats / items / properties / teraType
        Removed value: -{
        -  "description": "Recommended Tera type; absent when the curated set does not specify one.",
        -  "type": "string"
        -}
      • changedOutput schema / properties / threats / items / properties / tier / description
        Previous value: -"Curated tier within the regulation: S (format-defining), A, or B — editorial, not usage data."New value: +"Usage band: S is the top 5 by usage, A the next 7, B the rest of the list."
      • addedOutput schema / properties / threats / items / properties / usage
        Added value: +{
        +  "description": "Share of the sampled teams carrying this species, in percent.",
        +  "type": "number"
        +}
      • changedOutput schema / properties / threats / items / required
        Previous value: -[
        -  "species",
        -  "role",
        -  "tier",
        -  "item",
        -  "ability",
        -  "nature",
        -  "evs",
        -  "moves"
        -]New value: +[
        +  "species",
        +  "role",
        +  "tier",
        +  "rank",
        +  "usage",
        +  "item",
        +  "ability",
        +  "nature",
        +  "moves"
        +]
    • Changedoptimize_evs3 fields changed
      • changedInput schema / properties / kill / properties / target / properties / moves / description
        Previous value: -"Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calc_matchups` to pick the hardest-hitting move per defender."New value: +"Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender."
      • changedInput schema / properties / outspeed / properties / target / properties / moves / description
        Previous value: -"Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calc_matchups` to pick the hardest-hitting move per defender."New value: +"Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender."
      • changedInput schema / properties / survive / properties / attacker / properties / moves / description
        Previous value: -"Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calc_matchups` to pick the hardest-hitting move per defender."New value: +"Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender."
    • Removedsearch
    • Addedsearch_dex
    • Removedspeed_check
    • Removedspeed_tiers
    • Removedtype_chart
  4. 25 tool updatesv1.1.1
    • Changedanalyze_team6 fields changed
      • addedInput schema / properties / regulation / description
        Added value: +"Optional regulation set id, e.g. \"m-c\"; when given, the reply also lists legal threats whose base speed beats your fastest member. Unknown ids return an isError."
      • addedInput schema / properties / team / description
        Added value: +"Team of up to 6 members, each a species with optional Tera type and moves."
      • addedInput schema / properties / team / items / properties / moves / description
        Added value: +"Optional move names, e.g. [\"Knock Off\"]; their types widen offensive coverage. Unknown names are reported, not fatal."
      • addedInput schema / properties / team / items / properties / species / description
        Added value: +"Species name as it appears in Showdown, e.g. \"Incineroar\", \"Garchomp\"."
      • addedInput schema / properties / team / items / properties / teraType / description
        Added value: +"Optional Tera type, e.g. \"Steel\"; when set it replaces the member’s defensive typing in the weakness tally."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "atRiskTypes": {
        +      "description": "The stacked-weakness types: at least two members weak to it and nobody resisting or immune. Empty means no such hole.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "defensiveWeaknesses": {
        +      "additionalProperties": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "immune": {
        +            "description": "How many members are immune to it.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "resist": {
        +            "description": "How many members resist it (damage below neutral).",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "weak": {
        +            "description": "How many members take super-effective damage from this attacking type.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "weakBy": {
        +            "description": "Species names of the members weak to it, in team order; empty when none are.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          }
        +        },
        +        "required": [
        +          "weak",
        +          "resist",
        +          "immune",
        +          "weakBy"
        +        ],
        +        "type": "object"
        +      },
        +      "description": "One entry for each of the 18 classic types (keyed by type name, e.g. \"Fire\"), tallying how the team fares defensively against that type. A member is counted on its Tera type instead of its own types when a Tera type was supplied.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "offensiveCoverage": {
        +      "additionalProperties": false,
        +      "description": "Super-effective coverage of all 18 defending types.",
        +      "properties": {
        +        "coveredBy": {
        +          "additionalProperties": {
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "description": "One entry for each of the 18 classic types (keyed by the defending type), listing the team members that hit it super-effectively from STAB, Tera type, or a supplied move type; an empty array means nobody does.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "note": {
        +          "description": "Reminder of which attacking types this coverage was computed from.",
        +          "type": "string"
        +        },
        +        "uncoveredSuperEffectively": {
        +          "description": "Defending types no member hits super-effectively.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "coveredBy",
        +        "uncoveredSuperEffectively",
        +        "note"
        +      ],
        +      "type": "object"
        +    },
        +    "score": {
        +      "additionalProperties": false,
        +      "description": "Transparent heuristic 0-100 scoring of the team.",
        +      "properties": {
        +        "coverage": {
        +          "description": "0-100 share of the 18 types the team hits super-effectively.",
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        "defensive": {
        +          "description": "0-100 score penalising stacked weaknesses, floored at 0.",
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        "note": {
        +          "description": "What each component means and the reminder that this is a heuristic, not a metagame rating.",
        +          "type": "string"
        +        },
        +        "overall": {
        +          "description": "Rounded mean of the component scores, 0-100.",
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        "speed": {
        +          "description": "0-100 score dropping 2 points per legal faster threat; present only when `regulation` was supplied.",
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "overall",
        +        "defensive",
        +        "coverage",
        +        "note"
        +      ],
        +      "type": "object"
        +    },
        +    "speed": {
        +      "additionalProperties": false,
        +      "description": "Where the team sits on the speed spectrum, plus legal faster threats when a regulation was given.",
        +      "properties": {
        +        "fasterThreatCount": {
        +          "description": "How many legal species outspeed the fastest member; present only when `regulation` was supplied.",
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        "fasterThreats": {
        +          "description": "Up to 20 of those threats, fastest first, cut off at that limit; present only when `regulation` was supplied — compare with `fasterThreatCount` for the full total.",
        +          "items": {
        +            "additionalProperties": false,
        +            "properties": {
        +              "baseSpe": {
        +                "description": "Its base Speed stat, higher than the team’s fastest.",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "species": {
        +                "description": "Legal species name.",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "species",
        +              "baseSpe"
        +            ],
        +            "type": "object"
        +          },
        +          "type": "array"
        +        },
        +        "fastest": {
        +          "additionalProperties": false,
        +          "description": "The fastest member of the team.",
        +          "properties": {
        +            "baseSpe": {
        +              "description": "Its base Speed stat.",
        +              "maximum": 9007199254740991,
        +              "minimum": -9007199254740991,
        +              "type": "integer"
        +            },
        +            "species": {
        +              "description": "Species name of the team’s fastest member by base Speed.",
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "species",
        +            "baseSpe"
        +          ],
        +          "type": "object"
        +        },
        +        "note": {
        +          "description": "Caveat that threats are base-speed comparisons only; present only when `regulation` was supplied.",
        +          "type": "string"
        +        },
        +        "regulation": {
        +          "description": "Display name of the regulation that was checked; present only when `regulation` was supplied.",
        +          "type": "string"
        +        },
        +        "slowest": {
        +          "additionalProperties": false,
        +          "description": "The slowest member of the team.",
        +          "properties": {
        +            "baseSpe": {
        +              "description": "Its base Speed stat.",
        +              "maximum": 9007199254740991,
        +              "minimum": -9007199254740991,
        +              "type": "integer"
        +            },
        +            "species": {
        +              "description": "Species name of the team’s slowest member by base Speed.",
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "species",
        +            "baseSpe"
        +          ],
        +          "type": "object"
        +        }
        +      },
        +      "required": [
        +        "fastest",
        +        "slowest"
        +      ],
        +      "type": "object"
        +    },
        +    "team": {
        +      "description": "The analysed team in the order it was supplied, each member with the typing actually used for the analysis.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "baseSpe": {
        +            "description": "Base Speed stat of the species, used for the speed placement below.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "moveTypes": {
        +            "description": "Types of the supplied moves that were recognised, e.g. [\"Dark\"]; unrecognised move names are left out here and listed in `unknownMoves`.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "species": {
        +            "description": "Resolved species name, e.g. \"Great Tusk\".",
        +            "type": "string"
        +          },
        +          "teraType": {
        +            "description": "Tera type supplied for this member; when set it replaces the member’s typing defensively and is added to its attacking types. Absent when none was given.",
        +            "type": "string"
        +          },
        +          "types": {
        +            "description": "The species’ types as the dataset defines them, e.g. [\"Ground\", \"Fighting\"].",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          }
        +        },
        +        "required": [
        +          "species",
        +          "types",
        +          "baseSpe",
        +          "moveTypes"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "unknownMoves": {
        +      "description": "Deduplicated move names that were not found in the dataset and so contributed no coverage; omitted entirely when every move resolved.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "team",
        +    "defensiveWeaknesses",
        +    "atRiskTypes",
        +    "offensiveCoverage",
        +    "speed",
        +    "score"
        +  ],
        +  "type": "object"
        +}
    • Addedcalc_matchups
    • Changedcalculate_damage39 fields changed
      • addedInput schema / properties / attacker / description
        Added value: +"The attacking Pokémon: species plus optional level, nature, IVs, EVs, item, ability, boosts, status, Tera type, and current HP."
      • addedInput schema / properties / attacker / properties / ability / description
        Added value: +"Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability."
      • addedInput schema / properties / attacker / properties / abilityOn / description
        Added value: +"Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc."
      • addedInput schema / properties / attacker / properties / boosts / description
        Added value: +"Stat stages keyed by stat id (hp, atk, def, spa, spd, spe), each -6..+6; omitted stats are 0 (e.g. { atk: 2 } = +2 Attack)."
      • addedInput schema / properties / attacker / properties / curHP / description
        Added value: +"Current HP when entering damaged, e.g. 120; defaults to full HP."
      • addedInput schema / properties / attacker / properties / evs / description
        Added value: +"EVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-252 in steps of 4; omitted stats are 0, and a total above 510 is rejected."
      • addedInput schema / properties / attacker / properties / isDynamaxed / description
        Added value: +"Treat this Pokémon as Dynamaxed (doubles HP and alters several moves)."
      • addedInput schema / properties / attacker / properties / item / description
        Added value: +"Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect."
      • addedInput schema / properties / attacker / properties / ivs / description
        Added value: +"IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31."
      • addedInput schema / properties / attacker / properties / level / description
        Added value: +"Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools."
      • addedInput schema / properties / attacker / properties / moves
        Added value: +{
        +  "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calc_matchups` to pick the hardest-hitting move per defender.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / attacker / properties / nature / description
        Added value: +"Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted."
      • addedInput schema / properties / attacker / properties / species / description
        Added value: +"Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\"."
      • addedInput schema / properties / attacker / properties / status / description
        Added value: +"Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed."
      • addedInput schema / properties / attacker / properties / teraType / description
        Added value: +"Tera type to use when the move is Terastallized, e.g. \"Fairy\"."
      • addedInput schema / properties / defender / description
        Added value: +"The defending Pokémon, same fields as `attacker`; its Defense/SpD, HP, typing, and ability drive the result."
      • addedInput schema / properties / defender / properties / ability / description
        Added value: +"Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability."
      • addedInput schema / properties / defender / properties / abilityOn / description
        Added value: +"Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc."
      • addedInput schema / properties / defender / properties / boosts / description
        Added value: +"Stat stages keyed by stat id (hp, atk, def, spa, spd, spe), each -6..+6; omitted stats are 0 (e.g. { atk: 2 } = +2 Attack)."
      • addedInput schema / properties / defender / properties / curHP / description
        Added value: +"Current HP when entering damaged, e.g. 120; defaults to full HP."
      • addedInput schema / properties / defender / properties / evs / description
        Added value: +"EVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-252 in steps of 4; omitted stats are 0, and a total above 510 is rejected."
      • addedInput schema / properties / defender / properties / isDynamaxed / description
        Added value: +"Treat this Pokémon as Dynamaxed (doubles HP and alters several moves)."
      • addedInput schema / properties / defender / properties / item / description
        Added value: +"Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect."
      • addedInput schema / properties / defender / properties / ivs / description
        Added value: +"IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31."
      • addedInput schema / properties / defender / properties / level / description
        Added value: +"Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools."
      • addedInput schema / properties / defender / properties / moves
        Added value: +{
        +  "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calc_matchups` to pick the hardest-hitting move per defender.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / defender / properties / nature / description
        Added value: +"Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted."
      • addedInput schema / properties / defender / properties / species / description
        Added value: +"Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\"."
      • addedInput schema / properties / defender / properties / status / description
        Added value: +"Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed."
      • addedInput schema / properties / defender / properties / teraType / description
        Added value: +"Tera type to use when the move is Terastallized, e.g. \"Fairy\"."
      • addedInput schema / properties / field / description
        Added value: +"Battlefield conditions applied to the calc; omit it for a neutral Singles field with no weather, terrain, or hazards."
      • addedInput schema / properties / field / properties / attackerSide / description
        Added value: +"Attacker-side flags, e.g. { isHelpingHand: true, isTailwind: true, spikes: 2 }."
      • addedInput schema / properties / field / properties / defenderSide / description
        Added value: +"Defender-side flags, e.g. { isReflect: true, isLightScreen: true, isAuroraVeil: true, isSR: true }."
      • addedInput schema / properties / field / properties / gameType / description
        Added value: +"Doubles spreads damage across targets; default Singles."
      • addedInput schema / properties / field / properties / terrain / description
        Added value: +"Terrain: \"Electric\", \"Grassy\", \"Psychic\", or \"Misty\"; default none."
      • addedInput schema / properties / field / properties / weather / description
        Added value: +"Weather: \"Sand\", \"Sun\", \"Rain\", \"Hail\", \"Snow\", \"Harsh Sunshine\", \"Heavy Rain\", or \"Strong Winds\"; default none."
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • addedInput schema / properties / move / description
        Added value: +"Move used by the attacker, e.g. \"Earthquake\", \"Make It Rain\"; must be a real move name."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "attacker": {
        +      "additionalProperties": false,
        +      "description": "The attacking set as the calc resolved it, including the six stats it swung with.",
        +      "properties": {
        +        "ability": {
        +          "description": "Ability used: the one supplied, else the species’ first ability; absent for a species with no abilities.",
        +          "type": "string"
        +        },
        +        "boosts": {
        +          "additionalProperties": false,
        +          "description": "Stat stages in effect for the calculation; all six keys are present with 0 for unboosted stats.",
        +          "properties": {
        +            "atk": {
        +              "description": "Stat stage for Attack: the stat behind physical damage dealt.",
        +              "type": "number"
        +            },
        +            "def": {
        +              "description": "Stat stage for Defense: the stat behind physical damage taken.",
        +              "type": "number"
        +            },
        +            "hp": {
        +              "description": "Stat stage for HP: hit points, which decide how much damage the set can take.",
        +              "type": "number"
        +            },
        +            "spa": {
        +              "description": "Stat stage for Special Attack: the stat behind special damage dealt.",
        +              "type": "number"
        +            },
        +            "spd": {
        +              "description": "Stat stage for Special Defense: the stat behind special damage taken.",
        +              "type": "number"
        +            },
        +            "spe": {
        +              "description": "Stat stage for Speed: turn order; the higher Speed moves first.",
        +              "type": "number"
        +            }
        +          },
        +          "required": [
        +            "hp",
        +            "atk",
        +            "def",
        +            "spa",
        +            "spd",
        +            "spe"
        +          ],
        +          "type": "object"
        +        },
        +        "evs": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "EVs the set was calculated with, keyed by stat id (hp, atk, def, spa, spd, spe) with stats left at 0 omitted; generations 1-2 fix all six at 252 when the call supplies none.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "item": {
        +          "description": "Held item echoed back as supplied, e.g. \"Choice Band\", whose effect the calc applied; absent when the set carried none.",
        +          "type": "string"
        +        },
        +        "ivs": {
        +          "additionalProperties": false,
        +          "description": "IVs the set was calculated with; all six keys are present, defaulting to 31.",
        +          "properties": {
        +            "atk": {
        +              "description": "Individual value for Attack: the stat behind physical damage dealt.",
        +              "type": "number"
        +            },
        +            "def": {
        +              "description": "Individual value for Defense: the stat behind physical damage taken.",
        +              "type": "number"
        +            },
        +            "hp": {
        +              "description": "Individual value for HP: hit points, which decide how much damage the set can take.",
        +              "type": "number"
        +            },
        +            "spa": {
        +              "description": "Individual value for Special Attack: the stat behind special damage dealt.",
        +              "type": "number"
        +            },
        +            "spd": {
        +              "description": "Individual value for Special Defense: the stat behind special damage taken.",
        +              "type": "number"
        +            },
        +            "spe": {
        +              "description": "Individual value for Speed: turn order; the higher Speed moves first.",
        +              "type": "number"
        +            }
        +          },
        +          "required": [
        +            "hp",
        +            "atk",
        +            "def",
        +            "spa",
        +            "spd",
        +            "spe"
        +          ],
        +          "type": "object"
        +        },
        +        "level": {
        +          "description": "Level the set was calculated at; the damage tools default nested sets to level 100.",
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        "nature": {
        +          "description": "Nature the stats were computed with, e.g. \"Jolly\"; Serious when the call omitted one.",
        +          "type": "string"
        +        },
        +        "species": {
        +          "description": "Canonical species name used in the calculation, e.g. \"Garchomp\".",
        +          "type": "string"
        +        },
        +        "stats": {
        +          "additionalProperties": false,
        +          "description": "The six stats of this set at its level, IVs, EVs, and nature; stat stages are applied inside the damage mechanics, so they are not folded in here.",
        +          "properties": {
        +            "atk": {
        +              "description": "Final Attack: the stat behind physical damage dealt.",
        +              "type": "number"
        +            },
        +            "def": {
        +              "description": "Final Defense: the stat behind physical damage taken.",
        +              "type": "number"
        +            },
        +            "hp": {
        +              "description": "Final HP: hit points, which decide how much damage the set can take.",
        +              "type": "number"
        +            },
        +            "spa": {
        +              "description": "Final Special Attack: the stat behind special damage dealt.",
        +              "type": "number"
        +            },
        +            "spd": {
        +              "description": "Final Special Defense: the stat behind special damage taken.",
        +              "type": "number"
        +            },
        +            "spe": {
        +              "description": "Final Speed: turn order; the higher Speed moves first.",
        +              "type": "number"
        +            }
        +          },
        +          "required": [
        +            "hp",
        +            "atk",
        +            "def",
        +            "spa",
        +            "spd",
        +            "spe"
        +          ],
        +          "type": "object"
        +        },
        +        "status": {
        +          "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; absent when the set entered healthy.",
        +          "type": "string"
        +        },
        +        "teraType": {
        +          "description": "Tera type echoed back when the call supplied one; absent otherwise.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "species",
        +        "level",
        +        "nature",
        +        "evs",
        +        "ivs",
        +        "boosts",
        +        "stats"
        +      ],
        +      "type": "object"
        +    },
        +    "damage": {
        +      "anyOf": [
        +        {
        +          "type": "number"
        +        },
        +        {
        +          "items": {
        +            "type": "number"
        +          },
        +          "type": "array"
        +        },
        +        {
        +          "items": {
        +            "items": {
        +              "type": "number"
        +            },
        +            "type": "array"
        +          },
        +          "type": "array"
        +        }
        +      ],
        +      "description": "Damage dealt by the attack: a single number for a straight-damage move (0 when the defender is immune), a flat list of rolls for a move that rolls its own damage (e.g. False Swipe), or one roll list per hit for a multi-hit move (e.g. Population Bomb, Dragon Darts)."
        +    },
        +    "damageRange": {
        +      "additionalItems": false,
        +      "description": "[minimum, maximum] damage: `calculate_damage` totals every roll (multi-hit moves are summed), while `calc_matchups` reports the flattened per-hit rolls, so its bounds stay single-hit values. [0, 0] means nothing could be calculated.",
        +      "items": [
        +        {
        +          "type": "number"
        +        },
        +        {
        +          "type": "number"
        +        }
        +      ],
        +      "maxItems": 2,
        +      "minItems": 2,
        +      "type": "array"
        +    },
        +    "defender": {
        +      "additionalProperties": false,
        +      "description": "The defending set as the calc resolved it, including the six stats it was hit on.",
        +      "properties": {
        +        "ability": {
        +          "description": "Ability used: the one supplied, else the species’ first ability; absent for a species with no abilities.",
        +          "type": "string"
        +        },
        +        "boosts": {
        +          "additionalProperties": false,
        +          "description": "Stat stages in effect for the calculation; all six keys are present with 0 for unboosted stats.",
        +          "properties": {
        +            "atk": {
        +              "description": "Stat stage for Attack: the stat behind physical damage dealt.",
        +              "type": "number"
        +            },
        +            "def": {
        +              "description": "Stat stage for Defense: the stat behind physical damage taken.",
        +              "type": "number"
        +            },
        +            "hp": {
        +              "description": "Stat stage for HP: hit points, which decide how much damage the set can take.",
        +              "type": "number"
        +            },
        +            "spa": {
        +              "description": "Stat stage for Special Attack: the stat behind special damage dealt.",
        +              "type": "number"
        +            },
        +            "spd": {
        +              "description": "Stat stage for Special Defense: the stat behind special damage taken.",
        +              "type": "number"
        +            },
        +            "spe": {
        +              "description": "Stat stage for Speed: turn order; the higher Speed moves first.",
        +              "type": "number"
        +            }
        +          },
        +          "required": [
        +            "hp",
        +            "atk",
        +            "def",
        +            "spa",
        +            "spd",
        +            "spe"
        +          ],
        +          "type": "object"
        +        },
        +        "evs": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "EVs the set was calculated with, keyed by stat id (hp, atk, def, spa, spd, spe) with stats left at 0 omitted; generations 1-2 fix all six at 252 when the call supplies none.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "item": {
        +          "description": "Held item echoed back as supplied, e.g. \"Choice Band\", whose effect the calc applied; absent when the set carried none.",
        +          "type": "string"
        +        },
        +        "ivs": {
        +          "additionalProperties": false,
        +          "description": "IVs the set was calculated with; all six keys are present, defaulting to 31.",
        +          "properties": {
        +            "atk": {
        +              "description": "Individual value for Attack: the stat behind physical damage dealt.",
        +              "type": "number"
        +            },
        +            "def": {
        +              "description": "Individual value for Defense: the stat behind physical damage taken.",
        +              "type": "number"
        +            },
        +            "hp": {
        +              "description": "Individual value for HP: hit points, which decide how much damage the set can take.",
        +              "type": "number"
        +            },
        +            "spa": {
        +              "description": "Individual value for Special Attack: the stat behind special damage dealt.",
        +              "type": "number"
        +            },
        +            "spd": {
        +              "description": "Individual value for Special Defense: the stat behind special damage taken.",
        +              "type": "number"
        +            },
        +            "spe": {
        +              "description": "Individual value for Speed: turn order; the higher Speed moves first.",
        +              "type": "number"
        +            }
        +          },
        +          "required": [
        +            "hp",
        +            "atk",
        +            "def",
        +            "spa",
        +            "spd",
        +            "spe"
        +          ],
        +          "type": "object"
        +        },
        +        "level": {
        +          "description": "Level the set was calculated at; the damage tools default nested sets to level 100.",
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        "nature": {
        +          "description": "Nature the stats were computed with, e.g. \"Jolly\"; Serious when the call omitted one.",
        +          "type": "string"
        +        },
        +        "species": {
        +          "description": "Canonical species name used in the calculation, e.g. \"Garchomp\".",
        +          "type": "string"
        +        },
        +        "stats": {
        +          "additionalProperties": false,
        +          "description": "The six stats of this set at its level, IVs, EVs, and nature; stat stages are applied inside the damage mechanics, so they are not folded in here.",
        +          "properties": {
        +            "atk": {
        +              "description": "Final Attack: the stat behind physical damage dealt.",
        +              "type": "number"
        +            },
        +            "def": {
        +              "description": "Final Defense: the stat behind physical damage taken.",
        +              "type": "number"
        +            },
        +            "hp": {
        +              "description": "Final HP: hit points, which decide how much damage the set can take.",
        +              "type": "number"
        +            },
        +            "spa": {
        +              "description": "Final Special Attack: the stat behind special damage dealt.",
        +              "type": "number"
        +            },
        +            "spd": {
        +              "description": "Final Special Defense: the stat behind special damage taken.",
        +              "type": "number"
        +            },
        +            "spe": {
        +              "description": "Final Speed: turn order; the higher Speed moves first.",
        +              "type": "number"
        +            }
        +          },
        +          "required": [
        +            "hp",
        +            "atk",
        +            "def",
        +            "spa",
        +            "spd",
        +            "spe"
        +          ],
        +          "type": "object"
        +        },
        +        "status": {
        +          "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; absent when the set entered healthy.",
        +          "type": "string"
        +        },
        +        "teraType": {
        +          "description": "Tera type echoed back when the call supplied one; absent otherwise.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "species",
        +        "level",
        +        "nature",
        +        "evs",
        +        "ivs",
        +        "boosts",
        +        "stats"
        +      ],
        +      "type": "object"
        +    },
        +    "description": {
        +      "description": "One-line summary of the whole matchup, e.g. \"252 Atk Choice Band Garchomp Dragon Claw vs. 252 HP / 252+ Def Corviknight: 64-76 (16.4 - 19.5%) -- possible 6HKO\"; an explicit 0-damage note when the calc could not describe it.",
        +      "type": "string"
        +    },
        +    "field": {
        +      "additionalProperties": false,
        +      "description": "The battlefield the calc ran under, echoed back with its defaults filled in.",
        +      "properties": {
        +        "gameType": {
        +          "description": "How many targets the move hit; \"Singles\" unless the call asked for Doubles.",
        +          "enum": [
        +            "Singles",
        +            "Doubles"
        +          ],
        +          "type": "string"
        +        },
        +        "terrain": {
        +          "description": "Terrain in effect, e.g. \"Electric\", \"Grassy\"; absent when the field had none.",
        +          "type": "string"
        +        },
        +        "weather": {
        +          "description": "Weather in effect, e.g. \"Sun\", \"Rain\", \"Sand\"; absent when the field had none.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "gameType"
        +      ],
        +      "type": "object"
        +    },
        +    "generation": {
        +      "description": "Generation whose data and mechanics were used, 1-9.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "koChance": {
        +      "description": "Human-readable KO chance, e.g. \"guaranteed OHKO\" or \"31.3% chance to 2HKO\"; an empty string when no KO is possible (e.g. False Swipe), and absent when the calc could not describe the matchup at all, which is the immunity case.",
        +      "type": "string"
        +    },
        +    "move": {
        +      "description": "Canonical move name that was calculated, e.g. \"Dragon Claw\".",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "generation",
        +    "attacker",
        +    "defender",
        +    "move",
        +    "field",
        +    "damage",
        +    "damageRange",
        +    "description"
        +  ],
        +  "type": "object"
        +}
    • Changedcalculate_stats7 fields changed
      • addedInput schema / properties / evs / description
        Added value: +"EVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-252 in steps of 4; omitted stats are 0, and a total above 510 is rejected."
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • addedInput schema / properties / ivs / description
        Added value: +"IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31."
      • addedInput schema / properties / level / description
        Added value: +"Level 1-100; default 50."
      • addedInput schema / properties / nature / description
        Added value: +"Nature name, e.g. \"Jolly\", \"Modest\"; default Serious (raises and lowers nothing)."
      • addedInput schema / properties / species / description
        Added value: +"Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "baseStats": {
        +      "additionalProperties": false,
        +      "description": "The species’ unmodified base stats, the same for every set of that species.",
        +      "properties": {
        +        "atk": {
        +          "description": "Base Attack: the stat behind physical damage dealt.",
        +          "type": "number"
        +        },
        +        "def": {
        +          "description": "Base Defense: the stat behind physical damage taken.",
        +          "type": "number"
        +        },
        +        "hp": {
        +          "description": "Base HP: hit points, which decide how much damage the set can take.",
        +          "type": "number"
        +        },
        +        "spa": {
        +          "description": "Base Special Attack: the stat behind special damage dealt.",
        +          "type": "number"
        +        },
        +        "spd": {
        +          "description": "Base Special Defense: the stat behind special damage taken.",
        +          "type": "number"
        +        },
        +        "spe": {
        +          "description": "Base Speed: turn order; the higher Speed moves first.",
        +          "type": "number"
        +        }
        +      },
        +      "required": [
        +        "hp",
        +        "atk",
        +        "def",
        +        "spa",
        +        "spd",
        +        "spe"
        +      ],
        +      "type": "object"
        +    },
        +    "bst": {
        +      "description": "Base stat total: the sum of the six base stats, a rough measure of the species’ overall power.",
        +      "type": "number"
        +    },
        +    "evs": {
        +      "additionalProperties": false,
        +      "description": "The EVs actually used per stat; all six keys are present, 0 for stats the call left uninvested.",
        +      "properties": {
        +        "atk": {
        +          "description": "EV applied to Attack: the stat behind physical damage dealt.",
        +          "type": "number"
        +        },
        +        "def": {
        +          "description": "EV applied to Defense: the stat behind physical damage taken.",
        +          "type": "number"
        +        },
        +        "hp": {
        +          "description": "EV applied to HP: hit points, which decide how much damage the set can take.",
        +          "type": "number"
        +        },
        +        "spa": {
        +          "description": "EV applied to Special Attack: the stat behind special damage dealt.",
        +          "type": "number"
        +        },
        +        "spd": {
        +          "description": "EV applied to Special Defense: the stat behind special damage taken.",
        +          "type": "number"
        +        },
        +        "spe": {
        +          "description": "EV applied to Speed: turn order; the higher Speed moves first.",
        +          "type": "number"
        +        }
        +      },
        +      "required": [
        +        "hp",
        +        "atk",
        +        "def",
        +        "spa",
        +        "spd",
        +        "spe"
        +      ],
        +      "type": "object"
        +    },
        +    "generation": {
        +      "description": "Generation whose base stats and mechanics were used, 1-9.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "ivs": {
        +      "additionalProperties": false,
        +      "description": "The IVs actually used per stat; all six keys are present, defaulting to 31.",
        +      "properties": {
        +        "atk": {
        +          "description": "Individual value for Attack: the stat behind physical damage dealt.",
        +          "type": "number"
        +        },
        +        "def": {
        +          "description": "Individual value for Defense: the stat behind physical damage taken.",
        +          "type": "number"
        +        },
        +        "hp": {
        +          "description": "Individual value for HP: hit points, which decide how much damage the set can take.",
        +          "type": "number"
        +        },
        +        "spa": {
        +          "description": "Individual value for Special Attack: the stat behind special damage dealt.",
        +          "type": "number"
        +        },
        +        "spd": {
        +          "description": "Individual value for Special Defense: the stat behind special damage taken.",
        +          "type": "number"
        +        },
        +        "spe": {
        +          "description": "Individual value for Speed: turn order; the higher Speed moves first.",
        +          "type": "number"
        +        }
        +      },
        +      "required": [
        +        "hp",
        +        "atk",
        +        "def",
        +        "spa",
        +        "spd",
        +        "spe"
        +      ],
        +      "type": "object"
        +    },
        +    "level": {
        +      "description": "Level the stats were computed at, 1-100.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "nature": {
        +      "description": "Nature applied to the non-HP stats, e.g. \"Jolly\"; Serious when the call omitted one.",
        +      "type": "string"
        +    },
        +    "species": {
        +      "description": "Canonical species name the stats belong to, e.g. \"Garchomp\".",
        +      "type": "string"
        +    },
        +    "stats": {
        +      "additionalProperties": false,
        +      "description": "The six in-game stats this species reaches at this level, nature, IVs, and EVs; `hp` is the full HP stat, not a percentage.",
        +      "properties": {
        +        "atk": {
        +          "description": "Final Attack: the stat behind physical damage dealt.",
        +          "type": "number"
        +        },
        +        "def": {
        +          "description": "Final Defense: the stat behind physical damage taken.",
        +          "type": "number"
        +        },
        +        "hp": {
        +          "description": "Final HP: hit points, which decide how much damage the set can take.",
        +          "type": "number"
        +        },
        +        "spa": {
        +          "description": "Final Special Attack: the stat behind special damage dealt.",
        +          "type": "number"
        +        },
        +        "spd": {
        +          "description": "Final Special Defense: the stat behind special damage taken.",
        +          "type": "number"
        +        },
        +        "spe": {
        +          "description": "Final Speed: turn order; the higher Speed moves first.",
        +          "type": "number"
        +        }
        +      },
        +      "required": [
        +        "hp",
        +        "atk",
        +        "def",
        +        "spa",
        +        "spd",
        +        "spe"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "species",
        +    "generation",
        +    "level",
        +    "nature",
        +    "baseStats",
        +    "bst",
        +    "evs",
        +    "ivs",
        +    "stats"
        +  ],
        +  "type": "object"
        +}
    • Changedcheck_legality6 fields changed
      • addedInput schema / properties / regulation / description
        Added value: +"Regulation Set id or name, matched case- and punctuation-insensitively: \"M-A\", \"m-a\", \"mc\", and \"Regulation Set M-C\" all resolve to the same set."
      • addedInput schema / properties / team / description
        Added value: +"Team members, 1-6 of them; a VGC Battle Team must be exactly 6, so any other length adds a team-size violation."
      • addedInput schema / properties / team / items / properties / item / description
        Added value: +"Held item; a duplicate across the team is an Item Clause violation and an unknown item is reported as a violation."
      • addedInput schema / properties / team / items / properties / moves
        Added value: +{
        +  "description": "Moves to verify against the form and base-species learnsets; each is reported with legal true/false and, when illegal, a reason.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / team / items / properties / species / description
        Added value: +"Species name in any form; resolved case-insensitively and matched to the set roster by base species, so alternate forms of an eligible species pass."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "mega": {
        +      "additionalProperties": false,
        +      "description": "Mega Evolution summary for the checked team.",
        +      "properties": {
        +        "capable": {
        +          "description": "Species on this team that may Mega Evolve; empty when none can.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "note": {
        +          "description": "Reminder that a player may Mega Evolve only once per battle.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "capable",
        +        "note"
        +      ],
        +      "type": "object"
        +    },
        +    "members": {
        +      "description": "One entry per supplied team member, in the order supplied.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "baseSpecies": {
        +            "description": "The base species the roster and Species Clause checks used (eligibility is by National Pokédex number); absent when the species is unknown.",
        +            "type": "string"
        +          },
        +          "item": {
        +            "description": "Held item exactly as supplied; absent when the member had none.",
        +            "type": "string"
        +          },
        +          "itemValid": {
        +            "description": "Whether the supplied item is a known item; absent when the member had no item.",
        +            "type": "boolean"
        +          },
        +          "legal": {
        +            "description": "True when the species exists and its base species is on this set’s roster.",
        +            "type": "boolean"
        +          },
        +          "megaCapable": {
        +            "description": "True when this member’s base species may Mega Evolve in this set (false for unknown species).",
        +            "type": "boolean"
        +          },
        +          "moves": {
        +            "description": "One entry per supplied move, in order; present only when the member listed moves and its species was known.",
        +            "items": {
        +              "additionalProperties": false,
        +              "properties": {
        +                "legal": {
        +                  "description": "True when the move is in either the form’s or the base species’ learnset.",
        +                  "type": "boolean"
        +                },
        +                "move": {
        +                  "description": "Resolved move name, or the name as supplied when the move is unknown.",
        +                  "type": "string"
        +                },
        +                "note": {
        +                  "description": "Why the move failed (\"unknown move\" or \"not in learnset\"); absent for legal moves.",
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "move",
        +                "legal"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "species": {
        +            "description": "Resolved species name, or the name as supplied when the species is unknown.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "species",
        +          "legal",
        +          "megaCapable"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "regulation": {
        +      "description": "Display name of the set the team was checked against, e.g. \"Regulation Set M-C\".",
        +      "type": "string"
        +    },
        +    "status": {
        +      "description": "That set’s status relative to today.",
        +      "enum": [
        +        "past",
        +        "current",
        +        "upcoming"
        +      ],
        +      "type": "string"
        +    },
        +    "teamSize": {
        +      "description": "How many members were supplied (1-6).",
        +      "type": "number"
        +    },
        +    "valid": {
        +      "description": "True only when `violations` is empty; false when any member is illegal or unknown, a clause is broken, or the team is not exactly 6.",
        +      "type": "boolean"
        +    },
        +    "violations": {
        +      "description": "Every violation found, as human-readable text (illegal/unknown species, Species Clause, unknown item, Item Clause, illegal/unknown moves, team size); empty when the team is legal.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "regulation",
        +    "status",
        +    "teamSize",
        +    "valid",
        +    "violations",
        +    "members",
        +    "mega"
        +  ],
        +  "type": "object"
        +}
    • Changedget_ability3 fields changed
      • addedInput schema / properties / ability / description
        Added value: +"Ability name, e.g. \"Intimidate\", \"Protosynthesis\"."
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "desc": {
        +      "description": "Full effect description.",
        +      "type": "string"
        +    },
        +    "flags": {
        +      "additionalProperties": {
        +        "type": "number"
        +      },
        +      "description": "Flags the ability carries, as {\"<flag>\": 1}; any flag not listed does not apply. Possible keys: \"breakable\", \"cantsuppress\", \"failroleplay\", \"failskillswap\", \"noentrain\", \"noreceiver\", \"notrace\", \"notransform\".",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "gen": {
        +      "description": "Generation the ability was introduced in; 0 for the \"No Ability\" placeholder.",
        +      "type": "number"
        +    },
        +    "isNonstandard": {
        +      "description": "\"Past\", \"Future\", \"Unobtainable\", or \"CAP\" when the ability is not available in the current games; null when it is standard.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "name": {
        +      "description": "Ability name, e.g. \"Intimidate\".",
        +      "type": "string"
        +    },
        +    "num": {
        +      "description": "Ability number in the dataset; 0 for abilities that have none.",
        +      "type": "number"
        +    },
        +    "shortDesc": {
        +      "description": "One-line effect summary.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "num",
        +    "gen",
        +    "shortDesc",
        +    "desc",
        +    "flags",
        +    "isNonstandard"
        +  ],
        +  "type": "object"
        +}
    • Changedget_archetype2 fields changed
      • addedInput schema / properties / name / description
        Added value: +"Archetype id or display name, case-insensitive, e.g. \"hyper-offense\" or \"Trick Room\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "counters": {
        +      "description": "How opponents beat it.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "description": {
        +      "description": "Full prose description of how the archetype wins.",
        +      "type": "string"
        +    },
        +    "format": {
        +      "description": "Format the archetype is written for; \"both\" means it applies to either.",
        +      "enum": [
        +        "singles",
        +        "doubles",
        +        "both"
        +      ],
        +      "type": "string"
        +    },
        +    "id": {
        +      "description": "Stable slug id, e.g. \"hyper-offense\"; accepted by `get_archetype`.",
        +      "type": "string"
        +    },
        +    "keyRoles": {
        +      "description": "Roles a build of this archetype must fill, e.g. \"Hazard setter\".",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "members": {
        +      "description": "Typical members paired with the role each fills — fuller than `list_archetypes`, which lists species only.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "role": {
        +            "description": "The job that member does in this archetype, e.g. \"Physical wall + Rapid Spin remover\".",
        +            "type": "string"
        +          },
        +          "species": {
        +            "description": "Typical member species name, e.g. \"Great Tusk\".",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "species",
        +          "role"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "name": {
        +      "description": "Display name, e.g. \"Hyper Offense\"; also accepted by `get_archetype`.",
        +      "type": "string"
        +    },
        +    "playstyle": {
        +      "description": "Broad playstyle family the archetype belongs to.",
        +      "enum": [
        +        "offense",
        +        "defense",
        +        "balance",
        +        "weather",
        +        "room",
        +        "gimmick"
        +      ],
        +      "type": "string"
        +    },
        +    "strengths": {
        +      "description": "What the archetype does well.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "summary": {
        +      "description": "One-sentence description of the game plan.",
        +      "type": "string"
        +    },
        +    "tips": {
        +      "description": "Teambuilding advice for running it.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "weaknesses": {
        +      "description": "Where the archetype is vulnerable.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "name",
        +    "format",
        +    "playstyle",
        +    "summary",
        +    "description",
        +    "keyRoles",
        +    "strengths",
        +    "weaknesses",
        +    "counters",
        +    "tips",
        +    "members"
        +  ],
        +  "type": "object"
        +}
    • Changedget_item3 fields changed
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • addedInput schema / properties / item / description
        Added value: +"Item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "boosts": {
        +      "additionalProperties": {
        +        "type": "number"
        +      },
        +      "description": "Flat stat stages the item grants while held, keyed by stat id, e.g. {\"atk\": 2} for Choice Band; absent for items that do not change stats directly.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "desc": {
        +      "description": "Full effect description.",
        +      "type": "string"
        +    },
        +    "fling": {
        +      "additionalProperties": false,
        +      "description": "Fling data, present only for items that can be flung.",
        +      "properties": {
        +        "basePower": {
        +          "description": "Base power Fling gains from this item.",
        +          "type": "number"
        +        },
        +        "status": {
        +          "description": "Major status Fling inflicts on the target, when the item does (e.g. \"par\").",
        +          "type": "string"
        +        },
        +        "volatileStatus": {
        +          "description": "Volatile status Fling inflicts on the target, when the item does (e.g. \"flinch\").",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "basePower"
        +      ],
        +      "type": "object"
        +    },
        +    "forcedForme": {
        +      "description": "Forme this item forces on its holder, e.g. \"Dialga-Origin\" for Adamant Crystal; absent when the item changes no forme.",
        +      "type": "string"
        +    },
        +    "gen": {
        +      "description": "Generation the item was introduced in.",
        +      "type": "number"
        +    },
        +    "isBerry": {
        +      "description": "true when the item is a Berry (held and eaten on a trigger); absent otherwise.",
        +      "type": "boolean"
        +    },
        +    "isChoice": {
        +      "description": "true when the item is a Choice item that locks the holder into one move; absent otherwise.",
        +      "type": "boolean"
        +    },
        +    "isGem": {
        +      "description": "true when the item is a one-use type Gem that boosts a matching move; absent otherwise.",
        +      "type": "boolean"
        +    },
        +    "isNonstandard": {
        +      "description": "\"Past\", \"Future\", \"Unobtainable\", or \"CAP\" when the item is not available in the current games; null when it is standard.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "isPokeball": {
        +      "description": "true when the item is a Poké Ball used for catching; absent otherwise.",
        +      "type": "boolean"
        +    },
        +    "itemUser": {
        +      "description": "Species that can use the item where it is restricted to them; absent when any species can hold it.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "megaStone": {
        +      "additionalProperties": {
        +        "type": "string"
        +      },
        +      "description": "Mega Stone holders: species name to the Mega forme it unlocks, e.g. {\"Garchomp\": \"Garchomp-Mega\"}; absent when the item is not a Mega Stone.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "name": {
        +      "description": "Item name, e.g. \"Choice Band\".",
        +      "type": "string"
        +    },
        +    "naturalGift": {
        +      "additionalProperties": false,
        +      "description": "Natural Gift data, present only for Berries (the items Natural Gift can consume).",
        +      "properties": {
        +        "basePower": {
        +          "description": "Base power Natural Gift gains from this item.",
        +          "type": "number"
        +        },
        +        "type": {
        +          "description": "Type Natural Gift becomes with this item, e.g. \"Fire\".",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "basePower",
        +        "type"
        +      ],
        +      "type": "object"
        +    },
        +    "num": {
        +      "description": "Item number in the dataset; 0 for items that have none.",
        +      "type": "number"
        +    },
        +    "shortDesc": {
        +      "description": "One-line effect summary.",
        +      "type": "string"
        +    },
        +    "zMove": {
        +      "description": "For Z-Crystals: the Z-Move it unlocks, or true for crystals whose move depends on the held move; absent when the item is not a Z-Crystal.",
        +      "type": [
        +        "string",
        +        "boolean"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "num",
        +    "gen",
        +    "shortDesc",
        +    "desc",
        +    "isNonstandard"
        +  ],
        +  "type": "object"
        +}
    • Changedget_learnset3 fields changed
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • addedInput schema / properties / species / description
        Added value: +"Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "eventData": {
        +      "description": "Event distributions that granted this species, when it has any; absent for species with no event history.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "abilities": {
        +            "description": "Ability ids the event Pokémon can come with.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "emeraldEventEgg": {
        +            "description": "true when the event is the Emerald event egg; absent otherwise.",
        +            "type": "boolean"
        +          },
        +          "gender": {
        +            "description": "Gender the event forces, \"M\" or \"F\"; absent when the event does not fix it.",
        +            "type": "string"
        +          },
        +          "generation": {
        +            "description": "Generation the event ran in.",
        +            "type": "number"
        +          },
        +          "isHidden": {
        +            "description": "true when the event grants the hidden ability; absent otherwise.",
        +            "type": "boolean"
        +          },
        +          "ivs": {
        +            "additionalProperties": false,
        +            "description": "IVs the event fixes, keyed by stat id; only the stats the event pins down are listed.",
        +            "properties": {
        +              "atk": {
        +                "description": "Attack IV.",
        +                "type": "number"
        +              },
        +              "def": {
        +                "description": "Defense IV.",
        +                "type": "number"
        +              },
        +              "hp": {
        +                "description": "HP IV.",
        +                "type": "number"
        +              },
        +              "spa": {
        +                "description": "Special Attack IV.",
        +                "type": "number"
        +              },
        +              "spd": {
        +                "description": "Special Defense IV.",
        +                "type": "number"
        +              },
        +              "spe": {
        +                "description": "Speed IV.",
        +                "type": "number"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "japan": {
        +            "description": "true when the event was Japan-only; absent otherwise.",
        +            "type": "boolean"
        +          },
        +          "level": {
        +            "description": "Level the event Pokémon is distributed at.",
        +            "type": "number"
        +          },
        +          "moves": {
        +            "description": "Move ids the event Pokémon comes with.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "nature": {
        +            "description": "Nature the event fixes; absent when the nature is not fixed.",
        +            "type": "string"
        +          },
        +          "perfectIVs": {
        +            "description": "Number of stats guaranteed to be perfect (31 IVs); absent when the event guarantees none.",
        +            "type": "number"
        +          },
        +          "pokeball": {
        +            "description": "Ball the Pokémon is distributed in, as an id such as \"cherishball\".",
        +            "type": "string"
        +          },
        +          "shiny": {
        +            "description": "true (or 1) when the distributed Pokémon is shiny; absent when it is not.",
        +            "type": [
        +              "boolean",
        +              "number"
        +            ]
        +          },
        +          "source": {
        +            "description": "Source game the event belongs to, e.g. \"gen8bdsp\".",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "generation",
        +          "level",
        +          "moves"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "eventOnly": {
        +      "description": "true when the species is only obtainable through events, so most of its moves come from the event list.",
        +      "type": "boolean"
        +    },
        +    "exists": {
        +      "description": "true when the dataset has learnset data for the species; a species without data errors instead of returning false.",
        +      "type": "boolean"
        +    },
        +    "movesBySource": {
        +      "additionalProperties": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "description": "Learned moves grouped by how they are acquired, keyed by \"Level-up\", \"TM\", \"Egg\", \"Tutor\", \"Event\", \"Raid/Event\", \"Virtual Console transfer\", \"Dream World\", \"Pre-evolution\", or \"Other\"; a move learned more than one way appears under each. Each list is sorted by move name and holds display names, e.g. {\"TM\": [\"Earthquake\"], \"Level-up\": [\"Dragon Claw\"]}. Empty when the generation records no moves.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "species": {
        +      "description": "Name of the species whose learnset this is, resolved from the argument, e.g. \"Garchomp\".",
        +      "type": "string"
        +    },
        +    "totalMoves": {
        +      "description": "Number of distinct moves the species can learn, counted before grouping by source.",
        +      "type": "number"
        +    }
        +  },
        +  "required": [
        +    "species",
        +    "exists",
        +    "eventOnly",
        +    "movesBySource",
        +    "totalMoves"
        +  ],
        +  "type": "object"
        +}
    • Changedget_move3 fields changed
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • addedInput schema / properties / move / description
        Added value: +"Move name, e.g. \"Earthquake\", \"Make It Rain\", \"Dragon Claw\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "accuracy": {
        +      "description": "Accuracy as a percentage, or true when the move cannot miss.",
        +      "type": [
        +        "number",
        +        "boolean"
        +      ]
        +    },
        +    "alwaysHit": {
        +      "description": "true when the dataset marks the move as never missing; absent from every other move.",
        +      "type": "boolean"
        +    },
        +    "basePower": {
        +      "description": "Base power; 0 for status moves and for moves whose power is computed rather than fixed (e.g. Seismic Toss, Low Kick).",
        +      "type": "number"
        +    },
        +    "breaksProtect": {
        +      "description": "true when the move hits through Protect and similar protection; absent when it does not.",
        +      "type": "boolean"
        +    },
        +    "category": {
        +      "description": "Damage class: \"Physical\", \"Special\", or \"Status\".",
        +      "type": "string"
        +    },
        +    "desc": {
        +      "description": "Full effect description.",
        +      "type": "string"
        +    },
        +    "drain": {
        +      "description": "HP the user recovers as a [numerator, denominator] fraction of damage dealt, e.g. [1, 2] for half; absent when the move does not drain.",
        +      "items": {
        +        "type": "number"
        +      },
        +      "type": "array"
        +    },
        +    "flags": {
        +      "additionalProperties": {
        +        "type": "number"
        +      },
        +      "description": "Flags the move carries, as {\"<flag>\": 1}; any flag not listed does not apply. Possible keys: \"allyanim\", \"bite\", \"bullet\", \"bypasssub\", \"cantusetwice\", \"charge\", \"contact\", \"dance\", \"defrost\", \"distance\", \"failcopycat\", \"failencore\", \"failinstruct\", \"failmefirst\", \"failmimic\", \"futuremove\", \"gravity\", \"heal\", \"metronome\", \"minimize\", \"mirror\", \"mustpressure\", \"noassist\", \"nonsky\", \"noparentalbond\", \"nosketch\", \"nosleeptalk\", \"pledgecombo\", \"powder\", \"protect\", \"pulse\", \"punch\", \"recharge\", \"reflectable\", \"slicing\", \"snatch\", \"sound\", \"wind\".",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "gen": {
        +      "description": "Generation the move was introduced in.",
        +      "type": "number"
        +    },
        +    "isMax": {
        +      "description": "Species name when this is a G-Max move, true for generic Max Moves; absent when the move is not a Max Move.",
        +      "type": [
        +        "string",
        +        "boolean"
        +      ]
        +    },
        +    "isNonstandard": {
        +      "description": "\"Past\", \"Future\", \"Unobtainable\", or \"CAP\" when the move is not available in the current games; null when it is standard.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "isZ": {
        +      "description": "Z-Crystal id that turns this move into a Z-Move; absent when the move has no dedicated Z-Move.",
        +      "type": "string"
        +    },
        +    "maxMove": {
        +      "additionalProperties": false,
        +      "description": "The Max Move this move becomes under Dynamax; absent when it does not become one.",
        +      "properties": {
        +        "basePower": {
        +          "description": "Base power of the Max Move under Dynamax.",
        +          "type": "number"
        +        }
        +      },
        +      "required": [
        +        "basePower"
        +      ],
        +      "type": "object"
        +    },
        +    "multihit": {
        +      "anyOf": [
        +        {
        +          "type": "number"
        +        },
        +        {
        +          "items": {
        +            "type": "number"
        +          },
        +          "type": "array"
        +        }
        +      ],
        +      "description": "Hit count when the move hits multiple times: a fixed number, or a [min, max] range as [2, 5]; absent for single-hit moves."
        +    },
        +    "name": {
        +      "description": "Move name, e.g. \"Earthquake\".",
        +      "type": "string"
        +    },
        +    "num": {
        +      "description": "Move number in the dataset, which is also the sort key `search` returns moves by.",
        +      "type": "number"
        +    },
        +    "pp": {
        +      "description": "Base PP, before PP Ups.",
        +      "type": "number"
        +    },
        +    "priority": {
        +      "description": "Priority bracket: positive moves act first, negative moves last.",
        +      "type": "number"
        +    },
        +    "recoil": {
        +      "description": "Recoil to the user as a [numerator, denominator] fraction of damage dealt, e.g. [33, 100]; absent when the move has no recoil.",
        +      "items": {
        +        "type": "number"
        +      },
        +      "type": "array"
        +    },
        +    "secondaries": {
        +      "description": "List of secondary effects, present for moves that carry more than one (e.g. a different effect per hit); absent for moves with none.",
        +      "items": {
        +        "additionalProperties": false,
        +        "description": "One secondary effect of the move; only the fields that apply to that effect are present.",
        +        "properties": {
        +          "boosts": {
        +            "additionalProperties": {
        +              "type": "number"
        +            },
        +            "description": "Stat changes applied to the target, e.g. {\"spd\": -1} for a Special Defense drop.",
        +            "propertyNames": {
        +              "type": "string"
        +            },
        +            "type": "object"
        +          },
        +          "chance": {
        +            "description": "Percent chance the effect triggers; absent when it is guaranteed.",
        +            "type": "number"
        +          },
        +          "self": {
        +            "additionalProperties": false,
        +            "description": "Effect applied to the user instead of the target, e.g. a self-boost or self-drop.",
        +            "properties": {
        +              "boosts": {
        +                "additionalProperties": {
        +                  "type": "number"
        +                },
        +                "description": "Stat changes applied to the user of the move.",
        +                "propertyNames": {
        +                  "type": "string"
        +                },
        +                "type": "object"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "status": {
        +            "description": "Major status inflicted, e.g. \"brn\", \"par\", \"frz\".",
        +            "type": "string"
        +          },
        +          "volatileStatus": {
        +            "description": "Volatile status inflicted, e.g. \"flinch\", \"confusion\".",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "secondary": {
        +      "additionalProperties": false,
        +      "description": "Secondary effect attached to the move itself, when it has one (absent for moves with none).",
        +      "properties": {
        +        "boosts": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "Stat changes applied to the target, e.g. {\"spd\": -1} for a Special Defense drop.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "chance": {
        +          "description": "Percent chance the effect triggers; absent when it is guaranteed.",
        +          "type": "number"
        +        },
        +        "self": {
        +          "additionalProperties": false,
        +          "description": "Effect applied to the user instead of the target, e.g. a self-boost or self-drop.",
        +          "properties": {
        +            "boosts": {
        +              "additionalProperties": {
        +                "type": "number"
        +              },
        +              "description": "Stat changes applied to the user of the move.",
        +              "propertyNames": {
        +                "type": "string"
        +              },
        +              "type": "object"
        +            }
        +          },
        +          "type": "object"
        +        },
        +        "status": {
        +          "description": "Major status inflicted, e.g. \"brn\", \"par\", \"frz\".",
        +          "type": "string"
        +        },
        +        "volatileStatus": {
        +          "description": "Volatile status inflicted, e.g. \"flinch\", \"confusion\".",
        +          "type": "string"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "shortDesc": {
        +      "description": "One-line effect summary.",
        +      "type": "string"
        +    },
        +    "target": {
        +      "description": "Targeting mode, e.g. \"normal\", \"self\", \"allAdjacent\", \"allAdjacentFoes\", \"allySide\".",
        +      "type": "string"
        +    },
        +    "type": {
        +      "description": "Move type. One of \"Bug\", \"Dark\", \"Dragon\", \"Electric\", \"Fairy\", \"Fighting\", \"Fire\", \"Flying\", \"Ghost\", \"Grass\", \"Ground\", \"Ice\", \"Normal\", \"Poison\", \"Psychic\", \"Rock\", \"Steel\", \"Water\".",
        +      "type": "string"
        +    },
        +    "zMove": {
        +      "additionalProperties": false,
        +      "description": "The Z-Move this move becomes when a Z-Crystal is held; absent when it does not become one.",
        +      "properties": {
        +        "basePower": {
        +          "description": "Base power the Z-Move is fixed to.",
        +          "type": "number"
        +        },
        +        "boost": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "Stat boosts the Z-Move grants the user before attacking.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "effect": {
        +          "description": "Effect id applied by the Z-Move, e.g. \"clearnegativeboost\".",
        +          "type": "string"
        +        }
        +      },
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "num",
        +    "gen",
        +    "type",
        +    "category",
        +    "basePower",
        +    "accuracy",
        +    "pp",
        +    "priority",
        +    "target",
        +    "flags",
        +    "shortDesc",
        +    "desc",
        +    "isNonstandard"
        +  ],
        +  "type": "object"
        +}
    • Changedget_nature3 fields changed
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • addedInput schema / properties / nature / description
        Added value: +"Nature name, e.g. \"Jolly\", \"Timid\", \"Impish\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "gen": {
        +      "description": "Generation the nature system was introduced in.",
        +      "type": "number"
        +    },
        +    "minus": {
        +      "description": "Stat lowered 10%, as a stat id such as \"spa\"; absent for the five neutral natures that change nothing.",
        +      "type": "string"
        +    },
        +    "name": {
        +      "description": "Nature name, e.g. \"Jolly\".",
        +      "type": "string"
        +    },
        +    "plus": {
        +      "description": "Stat raised 10%, as a stat id such as \"spe\"; absent for the five neutral natures that change nothing.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "gen"
        +  ],
        +  "type": "object"
        +}
    • Changedget_pokemon3 fields changed
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • addedInput schema / properties / species / description
        Added value: +"Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\", \"Rotom-Wash\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "abilities": {
        +      "additionalProperties": false,
        +      "description": "Abilities keyed by Showdown slot: \"0\" primary, \"1\" secondary, \"H\" hidden, \"S\" special.",
        +      "properties": {
        +        "0": {
        +          "description": "Primary ability.",
        +          "type": "string"
        +        },
        +        "1": {
        +          "description": "Secondary ability; absent from species with only one normal ability.",
        +          "type": "string"
        +        },
        +        "H": {
        +          "description": "Hidden ability; absent from species that have none.",
        +          "type": "string"
        +        },
        +        "S": {
        +          "description": "Special slot, used by abilities that come with a forme (Battle Bond, Power Construct); absent for species that have none.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "0"
        +      ],
        +      "type": "object"
        +    },
        +    "baseForme": {
        +      "description": "Label of the species' default forme when it has formes, e.g. \"Teal\" for Ogerpon; absent otherwise.",
        +      "type": "string"
        +    },
        +    "baseSpecies": {
        +      "description": "Name of the species this entry belongs to; equal to `name` for a base forme.",
        +      "type": "string"
        +    },
        +    "baseStats": {
        +      "additionalProperties": false,
        +      "description": "All six stats keyed by stat id (\"hp\", \"atk\", \"def\", \"spa\", \"spd\", \"spe\").",
        +      "properties": {
        +        "atk": {
        +          "description": "Attack.",
        +          "type": "number"
        +        },
        +        "def": {
        +          "description": "Defense.",
        +          "type": "number"
        +        },
        +        "hp": {
        +          "description": "Hit Points.",
        +          "type": "number"
        +        },
        +        "spa": {
        +          "description": "Special Attack.",
        +          "type": "number"
        +        },
        +        "spd": {
        +          "description": "Special Defense.",
        +          "type": "number"
        +        },
        +        "spe": {
        +          "description": "Speed.",
        +          "type": "number"
        +        }
        +      },
        +      "required": [
        +        "hp",
        +        "atk",
        +        "def",
        +        "spa",
        +        "spd",
        +        "spe"
        +      ],
        +      "type": "object"
        +    },
        +    "battleOnly": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        }
        +      ],
        +      "description": "The species this entry transforms from during battle, e.g. \"Garchomp\" for Garchomp-Mega, or a list when it can come from more than one (Wishiwashi); absent for normally selectable entries."
        +    },
        +    "bst": {
        +      "description": "Base stat total — the sum of `baseStats`.",
        +      "type": "number"
        +    },
        +    "canGigantamax": {
        +      "description": "Name of the G-Max move, when this entry is a Gigantamax-capable forme; absent otherwise.",
        +      "type": "string"
        +    },
        +    "canHatch": {
        +      "description": "true when the species can hatch from an Egg.",
        +      "type": "boolean"
        +    },
        +    "cannotDynamax": {
        +      "description": "true when the species cannot Dynamax.",
        +      "type": "boolean"
        +    },
        +    "cosmeticFormes": {
        +      "anyOf": [
        +        {
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Names of cosmetic-only formes (different look, identical mechanics); null or absent when there are none."
        +    },
        +    "doublesTier": {
        +      "description": "Doubles (VGC) tier label from the bundled dataset.",
        +      "type": "string"
        +    },
        +    "eggGroups": {
        +      "description": "Egg groups, e.g. [\"Monster\", \"Dragon\"]; empty for species that cannot breed.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "evoCondition": {
        +      "description": "Free-text condition for evolutions that are not plain level, item, or move evolutions, e.g. \"Level up with 999 Coins in the bag\".",
        +      "type": "string"
        +    },
        +    "evoItem": {
        +      "description": "Item required to evolve, when the evolution is item-based.",
        +      "type": "string"
        +    },
        +    "evoLevel": {
        +      "description": "Level required to evolve, when the evolution is level-based.",
        +      "type": "number"
        +    },
        +    "evoMove": {
        +      "description": "Move the species must know to evolve, when the evolution is move-based.",
        +      "type": "string"
        +    },
        +    "evos": {
        +      "description": "Species this one evolves into; empty when it does not evolve.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "forme": {
        +      "description": "Forme label when this entry is an alternate forme, e.g. \"Mega\", \"Wash\"; absent for the base forme.",
        +      "type": "string"
        +    },
        +    "formeOrder": {
        +      "anyOf": [
        +        {
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Dataset display order of the species and its formes; absent when the species has no formes."
        +    },
        +    "gen": {
        +      "description": "Generation this entry was introduced in; 0 for entries outside the numbered generations (e.g. MissingNo.).",
        +      "type": "number"
        +    },
        +    "gender": {
        +      "description": "\"M\", \"F\", or \"N\" (genderless) for species that are not a mix of both; absent when the species has a mixed gender ratio.",
        +      "type": "string"
        +    },
        +    "genderRatio": {
        +      "additionalProperties": false,
        +      "description": "Gender odds at encounter; both 0 for genderless species.",
        +      "properties": {
        +        "F": {
        +          "description": "Fraction of encounters that are female.",
        +          "type": "number"
        +        },
        +        "M": {
        +          "description": "Fraction of encounters that are male.",
        +          "type": "number"
        +        }
        +      },
        +      "required": [
        +        "M",
        +        "F"
        +      ],
        +      "type": "object"
        +    },
        +    "isCosmeticForme": {
        +      "description": "true when this entry is a cosmetic forme rather than a mechanically distinct one.",
        +      "type": "boolean"
        +    },
        +    "isMega": {
        +      "description": "true for Mega Evolutions; absent otherwise.",
        +      "type": "boolean"
        +    },
        +    "isNonstandard": {
        +      "description": "\"Past\", \"Future\", \"Unobtainable\", or \"CAP\" when the entry is not available in the current games; null when it is standard.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "isPrimal": {
        +      "description": "true for Primal Reversions; absent otherwise.",
        +      "type": "boolean"
        +    },
        +    "name": {
        +      "description": "Display name of the entry, e.g. \"Garchomp\" or \"Ogerpon-Wellspring\".",
        +      "type": "string"
        +    },
        +    "natDexTier": {
        +      "description": "National Dex tier label; the empty string when the entry has none.",
        +      "type": "string"
        +    },
        +    "nfe": {
        +      "description": "true when the species can still evolve (not fully evolved).",
        +      "type": "boolean"
        +    },
        +    "num": {
        +      "description": "National Dex number; 0 for entries that have none.",
        +      "type": "number"
        +    },
        +    "otherFormes": {
        +      "anyOf": [
        +        {
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Names of the non-cosmetic alternate formes; null or absent when the species has none."
        +    },
        +    "prevo": {
        +      "description": "Species this one evolves from; absent for base evolutions.",
        +      "type": "string"
        +    },
        +    "requiredTeraType": {
        +      "description": "Tera type this entry is locked to (e.g. an Ogerpon mask); absent when the Tera type is freely chosen.",
        +      "type": "string"
        +    },
        +    "tags": {
        +      "description": "Dataset tags such as [\"Sub-Legendary\"] or [\"Mythical\"]; empty when the entry is untagged.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "tier": {
        +      "description": "Singles tier label from the bundled dataset, e.g. \"OU\", \"UU\", \"LC\".",
        +      "type": "string"
        +    },
        +    "types": {
        +      "description": "Typing in the requested generation, in order, e.g. [\"Dragon\", \"Ground\"]. One of \"Bug\", \"Dark\", \"Dragon\", \"Electric\", \"Fairy\", \"Fighting\", \"Fire\", \"Flying\", \"Ghost\", \"Grass\", \"Ground\", \"Ice\", \"Normal\", \"Poison\", \"Psychic\", \"Rock\", \"Steel\", \"Water\".",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "unreleasedHidden": {
        +      "description": "true when the hidden ability has not been released; absent otherwise.",
        +      "type": "boolean"
        +    },
        +    "weightkg": {
        +      "description": "Weight in kilograms, as used by weight-based moves such as Heavy Slam.",
        +      "type": "number"
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "num",
        +    "gen",
        +    "types",
        +    "baseStats",
        +    "bst",
        +    "abilities",
        +    "tier",
        +    "doublesTier",
        +    "natDexTier",
        +    "baseSpecies",
        +    "isCosmeticForme",
        +    "weightkg",
        +    "genderRatio",
        +    "eggGroups",
        +    "nfe",
        +    "canHatch",
        +    "evos",
        +    "cannotDynamax",
        +    "isNonstandard",
        +    "tags"
        +  ],
        +  "type": "object"
        +}
    • Changedget_regulation2 fields changed
      • addedInput schema / properties / regulation / description
        Added value: +"Regulation Set id or name, matched case- and punctuation-insensitively: \"M-A\", \"m-a\", \"mc\", and \"Regulation Set M-C\" all resolve to the same set."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "battleType": {
        +      "description": "Battle format this set is played in (\"Double Battles\").",
        +      "type": "string"
        +    },
        +    "bringPick": {
        +      "description": "Team preview rule (\"4 of 6\"): register six Pokémon, pick four for each match.",
        +      "type": "string"
        +    },
        +    "clauses": {
        +      "additionalProperties": false,
        +      "description": "Team-construction clauses in force for this set.",
        +      "properties": {
        +        "anyMoveAbility": {
        +          "description": "True when any move or Ability obtainable through normal gameplay is allowed, including Hidden Abilities.",
        +          "type": "boolean"
        +        },
        +        "autoLevel50": {
        +          "description": "True when Pokémon above or below level 50 are auto-levelled to 50.",
        +          "type": "boolean"
        +        },
        +        "itemClause": {
        +          "description": "True when no two team members may hold the same item.",
        +          "type": "boolean"
        +        },
        +        "speciesClause": {
        +          "description": "True when no two team members may share a National Pokédex number.",
        +          "type": "boolean"
        +        }
        +      },
        +      "required": [
        +        "speciesClause",
        +        "itemClause",
        +        "autoLevel50",
        +        "anyMoveAbility"
        +      ],
        +      "type": "object"
        +    },
        +    "eligibleCount": {
        +      "description": "How many base species are on the legal roster.",
        +      "type": "number"
        +    },
        +    "eligibleSpecies": {
        +      "description": "The full legal base-species roster (large); every form of a listed species is legal.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "end": {
        +      "description": "Last day the set is in force, ISO 8601 (inclusive).",
        +      "type": "string"
        +    },
        +    "game": {
        +      "description": "Game the set belongs to (\"Pokémon Champions\").",
        +      "type": "string"
        +    },
        +    "id": {
        +      "description": "Regulation id, e.g. \"m-a\", \"m-b\", \"m-c\".",
        +      "type": "string"
        +    },
        +    "level": {
        +      "description": "Level every Pokémon is set to (50).",
        +      "type": "number"
        +    },
        +    "megaCount": {
        +      "description": "How many base species on the roster may Mega Evolve.",
        +      "type": "number"
        +    },
        +    "megaEvolution": {
        +      "additionalProperties": false,
        +      "description": "Mega Evolution rules.",
        +      "properties": {
        +        "allowed": {
        +          "description": "Whether Mega Evolution is legal in this set.",
        +          "type": "boolean"
        +        },
        +        "perBattle": {
        +          "description": "How many times a player may Mega Evolve per battle (1).",
        +          "type": "number"
        +        },
        +        "species": {
        +          "description": "Base species allowed to Mega Evolve; every form of each is covered.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "required": [
        +        "allowed",
        +        "perBattle",
        +        "species"
        +      ],
        +      "type": "object"
        +    },
        +    "name": {
        +      "description": "Display name, e.g. \"Regulation Set M-C\".",
        +      "type": "string"
        +    },
        +    "notes": {
        +      "description": "Curator summary of the format and what it changed over the previous set.",
        +      "type": "string"
        +    },
        +    "rounds": {
        +      "description": "Tournament round structure, e.g. \"BO1/BO3 Swiss, BO3 top cut\".",
        +      "type": "string"
        +    },
        +    "source": {
        +      "description": "URL of the source the rosters were taken from.",
        +      "type": "string"
        +    },
        +    "sourceAsOf": {
        +      "description": "ISO date the rosters were last refreshed.",
        +      "type": "string"
        +    },
        +    "start": {
        +      "description": "First day the set is in force, ISO 8601 (inclusive).",
        +      "type": "string"
        +    },
        +    "status": {
        +      "description": "Status relative to today: \"past\", \"current\", or \"upcoming\".",
        +      "enum": [
        +        "past",
        +        "current",
        +        "upcoming"
        +      ],
        +      "type": "string"
        +    },
        +    "timers": {
        +      "additionalProperties": false,
        +      "description": "Match clock limits.",
        +      "properties": {
        +        "gameMinutes": {
        +          "description": "Total game clock, in minutes.",
        +          "type": "number"
        +        },
        +        "moveSeconds": {
        +          "description": "Seconds allowed per move.",
        +          "type": "number"
        +        },
        +        "playerMinutes": {
        +          "description": "Each player’s clock, in minutes.",
        +          "type": "number"
        +        },
        +        "previewSeconds": {
        +          "description": "Seconds allowed for team preview.",
        +          "type": "number"
        +        }
        +      },
        +      "required": [
        +        "gameMinutes",
        +        "playerMinutes",
        +        "moveSeconds",
        +        "previewSeconds"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "name",
        +    "game",
        +    "status",
        +    "start",
        +    "end",
        +    "eligibleCount",
        +    "megaCount",
        +    "notes",
        +    "battleType",
        +    "level",
        +    "bringPick",
        +    "timers",
        +    "rounds",
        +    "clauses",
        +    "megaEvolution",
        +    "eligibleSpecies",
        +    "source",
        +    "sourceAsOf"
        +  ],
        +  "type": "object"
        +}
    • Addedget_set
    • Changedget_type3 fields changed
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • addedInput schema / properties / type / description
        Added value: +"Type name, e.g. \"Steel\", \"Fairy\", \"Ground\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "HPivs": {
        +      "additionalProperties": false,
        +      "description": "IVs needed to make Hidden Power come out as this type, keyed by stat id; only the stats this type pins down are listed.",
        +      "properties": {
        +        "atk": {
        +          "description": "Required Attack IV (30 or 31); absent when this Hidden Power type does not constrain it.",
        +          "type": "number"
        +        },
        +        "def": {
        +          "description": "Required Defense IV (30 or 31); absent when this Hidden Power type does not constrain it.",
        +          "type": "number"
        +        },
        +        "hp": {
        +          "description": "Required HP IV (30 or 31); absent when this Hidden Power type does not constrain it.",
        +          "type": "number"
        +        },
        +        "spa": {
        +          "description": "Required Special Attack IV (30 or 31); absent when this Hidden Power type does not constrain it.",
        +          "type": "number"
        +        },
        +        "spd": {
        +          "description": "Required Special Defense IV (30 or 31); absent when this Hidden Power type does not constrain it.",
        +          "type": "number"
        +        },
        +        "spe": {
        +          "description": "Required Speed IV (30 or 31); absent when this Hidden Power type does not constrain it.",
        +          "type": "number"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "damageTaken": {
        +      "additionalProperties": {
        +        "type": "number"
        +      },
        +      "description": "Multiplier this type takes from each attacking type, keyed by attacking type name. Values: 0 (immune), 0.5 (resisted), 1 (neutral), 2 (weak). Keys are \"Bug\", \"Dark\", \"Dragon\", \"Electric\", \"Fairy\", \"Fighting\", \"Fire\", \"Flying\", \"Ghost\", \"Grass\", \"Ground\", \"Ice\", \"Normal\", \"Poison\", \"Psychic\", \"Rock\", \"Steel\", \"Water\"; e.g. {\"Fire\": 2, \"Ground\": 2, \"Water\": 0.5} for Steel.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "gen": {
        +      "description": "Always 0 in the bundled dataset — types are not stamped with the generation they were introduced in.",
        +      "type": "number"
        +    },
        +    "immunities": {
        +      "description": "Attacking types this type takes 0x from, e.g. [\"Poison\"] for Steel; empty when it has none.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "isNonstandard": {
        +      "description": "\"Future\" when the type does not exist yet in the requested generation (e.g. Dark in generation 1) and \"Past\" when it no longer exists; null for types that are standard in that generation.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "name": {
        +      "description": "Type name, e.g. \"Steel\".",
        +      "type": "string"
        +    },
        +    "resistances": {
        +      "description": "Attacking types this type takes 0.5x from; empty when it has none.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "weaknesses": {
        +      "description": "Attacking types this type takes 2x from, e.g. [\"Fire\", \"Ground\"] for Steel; empty when it has none.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "gen",
        +    "isNonstandard",
        +    "damageTaken",
        +    "weaknesses",
        +    "resistances",
        +    "immunities",
        +    "HPivs"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_archetypes2 fields changed
      • addedInput schema / properties / format / description
        Added value: +"Format to filter by: \"singles\" or \"doubles\" only, \"both\" for archetypes tagged both. Omit for every archetype."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "archetypes": {
        +      "description": "Summaries of every curated archetype matching `format`, in the order they are defined.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "counters": {
        +            "description": "How opponents beat it.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "description": "Full prose description of how the archetype wins.",
        +            "type": "string"
        +          },
        +          "format": {
        +            "description": "Format the archetype is written for; \"both\" means it applies to either.",
        +            "enum": [
        +              "singles",
        +              "doubles",
        +              "both"
        +            ],
        +            "type": "string"
        +          },
        +          "id": {
        +            "description": "Stable slug id, e.g. \"hyper-offense\"; accepted by `get_archetype`.",
        +            "type": "string"
        +          },
        +          "keyRoles": {
        +            "description": "Roles a build of this archetype must fill, e.g. \"Hazard setter\".",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "members": {
        +            "description": "Typical member species names, e.g. [\"Pelipper\", \"Barraskewda\"]; roles are not included here.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "name": {
        +            "description": "Display name, e.g. \"Hyper Offense\"; also accepted by `get_archetype`.",
        +            "type": "string"
        +          },
        +          "playstyle": {
        +            "description": "Broad playstyle family the archetype belongs to.",
        +            "enum": [
        +              "offense",
        +              "defense",
        +              "balance",
        +              "weather",
        +              "room",
        +              "gimmick"
        +            ],
        +            "type": "string"
        +          },
        +          "strengths": {
        +            "description": "What the archetype does well.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "summary": {
        +            "description": "One-sentence description of the game plan.",
        +            "type": "string"
        +          },
        +          "tips": {
        +            "description": "Teambuilding advice for running it.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "weaknesses": {
        +            "description": "Where the archetype is vulnerable.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "name",
        +          "format",
        +          "playstyle",
        +          "summary",
        +          "description",
        +          "keyRoles",
        +          "strengths",
        +          "weaknesses",
        +          "counters",
        +          "tips",
        +          "members"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "count": {
        +      "description": "Number of archetypes returned, i.e. the length of `archetypes`.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "count",
        +    "archetypes"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_forms3 fields changed
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • addedInput schema / properties / species / description
        Added value: +"Base species to expand, e.g. \"Rotom\", \"Ogerpon\", \"Gholdengo\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "baseSpecies": {
        +      "description": "Name of the base species whose forms are listed, e.g. \"Rotom\" when asked for \"Rotom-Wash\".",
        +      "type": "string"
        +    },
        +    "count": {
        +      "description": "Number of entries in `forms`, including placeholders for forms missing in this generation.",
        +      "type": "number"
        +    },
        +    "forms": {
        +      "description": "One entry per known form name of the species — base, alternate, cosmetic, and battle-only — either a full form profile or a `{name, note}` placeholder.",
        +      "items": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": false,
        +            "description": "A form that exists in the requested generation, carrying the same fields as `get_pokemon` (minus evolutions and the long tail of dataset metadata).",
        +            "properties": {
        +              "abilities": {
        +                "additionalProperties": false,
        +                "description": "Abilities keyed by Showdown slot: \"0\" primary, \"1\" secondary, \"H\" hidden, \"S\" special.",
        +                "properties": {
        +                  "0": {
        +                    "description": "Primary ability.",
        +                    "type": "string"
        +                  },
        +                  "1": {
        +                    "description": "Secondary ability; absent from species with only one normal ability.",
        +                    "type": "string"
        +                  },
        +                  "H": {
        +                    "description": "Hidden ability; absent from species that have none.",
        +                    "type": "string"
        +                  },
        +                  "S": {
        +                    "description": "Special slot, used by abilities that come with a forme (Battle Bond, Power Construct); absent for species that have none.",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "0"
        +                ],
        +                "type": "object"
        +              },
        +              "baseStats": {
        +                "additionalProperties": false,
        +                "description": "All six stats keyed by stat id (\"hp\", \"atk\", \"def\", \"spa\", \"spd\", \"spe\").",
        +                "properties": {
        +                  "atk": {
        +                    "description": "Attack.",
        +                    "type": "number"
        +                  },
        +                  "def": {
        +                    "description": "Defense.",
        +                    "type": "number"
        +                  },
        +                  "hp": {
        +                    "description": "Hit Points.",
        +                    "type": "number"
        +                  },
        +                  "spa": {
        +                    "description": "Special Attack.",
        +                    "type": "number"
        +                  },
        +                  "spd": {
        +                    "description": "Special Defense.",
        +                    "type": "number"
        +                  },
        +                  "spe": {
        +                    "description": "Speed.",
        +                    "type": "number"
        +                  }
        +                },
        +                "required": [
        +                  "hp",
        +                  "atk",
        +                  "def",
        +                  "spa",
        +                  "spd",
        +                  "spe"
        +                ],
        +                "type": "object"
        +              },
        +              "battleOnly": {
        +                "anyOf": [
        +                  {
        +                    "type": "string"
        +                  },
        +                  {
        +                    "items": {
        +                      "type": "string"
        +                    },
        +                    "type": "array"
        +                  }
        +                ],
        +                "description": "The species this form transforms from in battle; absent for normally selectable forms."
        +              },
        +              "bst": {
        +                "description": "Base stat total of the form.",
        +                "type": "number"
        +              },
        +              "doublesTier": {
        +                "description": "Doubles (VGC) tier label of the form; may be empty.",
        +                "type": "string"
        +              },
        +              "isCosmetic": {
        +                "description": "true when the form differs only cosmetically.",
        +                "type": "boolean"
        +              },
        +              "isMega": {
        +                "description": "true for Mega Evolutions; absent otherwise.",
        +                "type": "boolean"
        +              },
        +              "isPrimal": {
        +                "description": "true for Primal Reversions; absent otherwise.",
        +                "type": "boolean"
        +              },
        +              "name": {
        +                "description": "Form name, e.g. \"Rotom-Wash\".",
        +                "type": "string"
        +              },
        +              "tier": {
        +                "description": "Singles tier label of the form; may be empty for untiered forms.",
        +                "type": "string"
        +              },
        +              "types": {
        +                "description": "Typing of the form, e.g. [\"Electric\", \"Water\"]. One of \"Bug\", \"Dark\", \"Dragon\", \"Electric\", \"Fairy\", \"Fighting\", \"Fire\", \"Flying\", \"Ghost\", \"Grass\", \"Ground\", \"Ice\", \"Normal\", \"Poison\", \"Psychic\", \"Rock\", \"Steel\", \"Water\".",
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              }
        +            },
        +            "required": [
        +              "name",
        +              "types",
        +              "baseStats",
        +              "bst",
        +              "abilities",
        +              "tier",
        +              "doublesTier",
        +              "isCosmetic"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "additionalProperties": false,
        +            "description": "Placeholder for a form name the dataset knows about but that does not exist in the requested generation; distinguishes \"no such form\" from \"form missing here\".",
        +            "properties": {
        +              "name": {
        +                "description": "Form name that has no data in the requested generation.",
        +                "type": "string"
        +              },
        +              "note": {
        +                "description": "Why the entry is empty — currently always \"unavailable in this generation\".",
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "name",
        +              "note"
        +            ],
        +            "type": "object"
        +          }
        +        ]
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "baseSpecies",
        +    "count",
        +    "forms"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_regulations1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "currentSet": {
        +      "description": "Id of the one set whose status is \"current\" today, or null when no set is active.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "game": {
        +      "description": "Game every listed set belongs to (\"Pokémon Champions\").",
        +      "type": "string"
        +    },
        +    "note": {
        +      "description": "Standing note on how Regulation Sets work: the roster is seasonal and eligibility is by base species, so every form of a listed species is legal.",
        +      "type": "string"
        +    },
        +    "sets": {
        +      "description": "One summary per bundled Regulation Set, in chronological order (M-A through M-C).",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "eligibleCount": {
        +            "description": "How many base species are on the legal roster.",
        +            "type": "number"
        +          },
        +          "end": {
        +            "description": "Last day the set is in force, ISO 8601 (inclusive).",
        +            "type": "string"
        +          },
        +          "game": {
        +            "description": "Game the set belongs to (\"Pokémon Champions\").",
        +            "type": "string"
        +          },
        +          "id": {
        +            "description": "Regulation id, e.g. \"m-a\", \"m-b\", \"m-c\".",
        +            "type": "string"
        +          },
        +          "megaCount": {
        +            "description": "How many base species on the roster may Mega Evolve.",
        +            "type": "number"
        +          },
        +          "name": {
        +            "description": "Display name, e.g. \"Regulation Set M-C\".",
        +            "type": "string"
        +          },
        +          "notes": {
        +            "description": "Curator summary of the format and what it changed over the previous set.",
        +            "type": "string"
        +          },
        +          "start": {
        +            "description": "First day the set is in force, ISO 8601 (inclusive).",
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Status relative to today: \"past\", \"current\", or \"upcoming\".",
        +            "enum": [
        +              "past",
        +              "current",
        +              "upcoming"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "name",
        +          "game",
        +          "status",
        +          "start",
        +          "end",
        +          "eligibleCount",
        +          "megaCount",
        +          "notes"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "game",
        +    "currentSet",
        +    "sets",
        +    "note"
        +  ],
        +  "type": "object"
        +}
    • Addedlist_threats
    • Changedlist_tiers4 fields changed
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • addedInput schema / properties / league / description
        Added value: +"Tier list to group by: \"singles\" uses Smogon singles tiers, \"doubles\" uses VGC tiers (default \"singles\")."
      • addedInput schema / properties / tier / description
        Added value: +"Exact tier name to restrict output to, case-insensitive, e.g. \"OU\" or \"UU\". Omit for every tier."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "generation": {
        +      "description": "Generation whose data was read, after normalising `generation`.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "league": {
        +      "description": "Which tier list the grouping came from — Smogon singles or VGC doubles.",
        +      "enum": [
        +        "singles",
        +        "doubles"
        +      ],
        +      "type": "string"
        +    },
        +    "tiers": {
        +      "additionalProperties": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "count": {
        +            "description": "How many species the tier holds.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "pokemon": {
        +            "description": "Every species name in the tier, sorted alphabetically.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          }
        +        },
        +        "required": [
        +          "count",
        +          "pokemon"
        +        ],
        +        "type": "object"
        +      },
        +      "description": "Map of tier name (e.g. \"OU\", \"UU\", \"DUU\") to its roster, ordered strongest tier first. Holds every tier present in the chosen league and generation, or just the requested `tier` when one was supplied; an empty object means no tier matched.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "generation",
        +    "league",
        +    "tiers"
        +  ],
        +  "type": "object"
        +}
    • Addedoptimize_evs
    • Changedsearch5 fields changed
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • addedInput schema / properties / kind / description
        Added value: +"Table to search; one per call (default \"species\")."
      • addedInput schema / properties / limit / description
        Added value: +"Maximum results returned, 1-100 (default 20)."
      • addedInput schema / properties / query / description
        Added value: +"Substring to match against name and Showdown id, e.g. \"oger\", \"sword\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "count": {
        +      "description": "Total number of matches the query found, before truncation to `limit` — compare against `results.length` to see whether the list was cut short.",
        +      "type": "number"
        +    },
        +    "kind": {
        +      "description": "The table that was searched, echoed back from the `kind` argument.",
        +      "enum": [
        +        "species",
        +        "move",
        +        "item",
        +        "ability",
        +        "nature"
        +      ],
        +      "type": "string"
        +    },
        +    "query": {
        +      "description": "The query exactly as it was supplied (not lower-cased or trimmed).",
        +      "type": "string"
        +    },
        +    "results": {
        +      "description": "Matching entries sorted by `num` ascending and truncated to `limit`; empty when nothing matched.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "name": {
        +            "description": "Match name, usable as-is with the matching lookup tool, e.g. \"Garchomp\".",
        +            "type": "string"
        +          },
        +          "num": {
        +            "description": "National Dex (or table) number, the sort key for this list.",
        +            "type": "number"
        +          },
        +          "tier": {
        +            "description": "Competitive tier — present only when `kind` is \"species\"; absent for moves, items, abilities, and natures.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "name",
        +          "num"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "kind",
        +    "query",
        +    "count",
        +    "results"
        +  ],
        +  "type": "object"
        +}
    • Addedspeed_check
    • Changedspeed_tiers5 fields changed
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • addedInput schema / properties / level / description
        Added value: +"Level at which Speed is computed, 1-100 (default 50, the standard competitive level)."
      • addedInput schema / properties / query / description
        Added value: +"Case-insensitive substring to keep only matching species names, e.g. \"rotom\". Omit for the whole tier."
      • addedInput schema / properties / tier / description
        Added value: +"Exact singles tier name as `list_tiers` reports it, case-insensitive, e.g. \"OU\", \"UU\", \"PU\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "count": {
        +      "description": "Number of species rows returned, i.e. the length of `speedTiers`.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "generation": {
        +      "description": "Generation whose data was read, after normalising `generation`.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "level": {
        +      "description": "Level the Speed numbers were computed at, 1-100.",
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    "speedTiers": {
        +      "description": "One row per species in the tier — and matching `query` when given — sorted fastest `max` to slowest.",
        +      "items": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "baseSpe": {
        +            "description": "Base Speed stat, before nature, EVs, or level.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "max": {
        +            "description": "Speed at 252 Speed EVs, a +Spe nature (Jolly), and 31 IVs.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "neutral252": {
        +            "description": "Speed at 252 Speed EVs, a neutral nature, and 31 IVs.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "species": {
        +            "description": "Species name.",
        +            "type": "string"
        +          },
        +          "uninvested": {
        +            "description": "Speed with no Speed EVs, a neutral nature, and 31 IVs.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "species",
        +          "baseSpe",
        +          "max",
        +          "neutral252",
        +          "uninvested"
        +        ],
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "tier": {
        +      "description": "Tier name as it was requested; matches a `list_tiers` singles tier name.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "generation",
        +    "tier",
        +    "level",
        +    "count",
        +    "speedTiers"
        +  ],
        +  "type": "object"
        +}
    • Changedtype_chart4 fields changed
      • addedInput schema / properties / attacker / description
        Added value: +"Attacking type name; omit to read the chart from the defender's side or to get the full matrix."
      • addedInput schema / properties / defender / description
        Added value: +"Defending type or species name; a species contributes its current-generation types."
      • addedInput schema / properties / generation / description
        Added value: +"Generation whose data to use, 1-9 (default 9). Earlier generations omit moves, items, abilities, and forms that did not exist yet."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "$schema": "http://json-schema.org/draft-07/schema#",
        +  "additionalProperties": false,
        +  "properties": {
        +    "attacker": {
        +      "description": "The attacker as supplied, echoed back; absent when no attacker argument was given.",
        +      "type": "string"
        +    },
        +    "chart": {
        +      "additionalProperties": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "description": "Present only when neither argument was given: the full type chart as `chart[attackingType][defendingType] = multiplier`, each inner map keyed by the 18 defending type names with values 0, 0.25, 0.5, 1, 2, or 4.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "coverage": {
        +      "additionalProperties": {
        +        "additionalProperties": false,
        +        "description": "How one attacking type lands against the defender.",
        +        "properties": {
        +          "effectiveness": {
        +            "description": "Damage multiplier: 0 (immune), 0.25, 0.5 (resisted), 1 (neutral), 2 or 4 (weak).",
        +            "type": "number"
        +          },
        +          "label": {
        +            "description": "The multiplier in words: \"immune\", \"0.5x not very effective\", \"neutral\", \"2x super effective\".",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "effectiveness",
        +          "label"
        +        ],
        +        "type": "object"
        +      },
        +      "description": "Present only when an attacker was given without a defender: how that attacking type lands against each of the 18 defending types, keyed by defending type name (\"Bug\", \"Dark\", \"Dragon\", \"Electric\", \"Fairy\", \"Fighting\", \"Fire\", \"Flying\", \"Ghost\", \"Grass\", \"Ground\", \"Ice\", \"Normal\", \"Poison\", \"Psychic\", \"Rock\", \"Steel\", \"Water\").",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "damageTaken": {
        +      "additionalProperties": {
        +        "additionalProperties": false,
        +        "description": "How one attacking type lands against the defender.",
        +        "properties": {
        +          "effectiveness": {
        +            "description": "Damage multiplier: 0 (immune), 0.25, 0.5 (resisted), 1 (neutral), 2 or 4 (weak).",
        +            "type": "number"
        +          },
        +          "label": {
        +            "description": "The multiplier in words: \"immune\", \"0.5x not very effective\", \"neutral\", \"2x super effective\".",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "effectiveness",
        +          "label"
        +        ],
        +        "type": "object"
        +      },
        +      "description": "Present only when a defender was given without an attacker: everything the defender takes, keyed by attacking type name. Combined typing is folded in, so 4x and 0.25x entries appear for dual types and 0 marks immunities.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "defender": {
        +      "description": "Resolved defender name — the type or species the multipliers were computed against; present in the matchup and defender-only replies.",
        +      "type": "string"
        +    },
        +    "defenderTypes": {
        +      "description": "The defending typing the multiplier was computed from, e.g. [\"Dragon\", \"Ground\"] for Garchomp or [\"Steel\"] for a type; present in the matchup and defender-only replies.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "effectiveness": {
        +      "description": "Single multiplier for attacker against defender (0, 0.25, 0.5, 1, 2, or 4); present only when both attacker and defender were given.",
        +      "type": "number"
        +    },
        +    "label": {
        +      "description": "`effectiveness` in words, e.g. \"2x super effective\", \"neutral\", \"immune\"; present only when both attacker and defender were given.",
        +      "type": "string"
        +    },
        +    "note": {
        +      "description": "Present only alongside `chart`, spelling out how to read the full matrix (rows are attackers, columns are defenders) and the multiplier scale.",
        +      "type": "string"
        +    }
        +  },
        +  "type": "object"
        +}
  5. 20 tool updatesv0.1.0
    • First observedanalyze_team
    • First observedcalculate_damage
    • First observedcalculate_stats
    • First observedcheck_legality
    • First observedget_ability
    • First observedget_archetype
    • First observedget_item
    • First observedget_learnset
    • First observedget_move
    • First observedget_nature
    • First observedget_pokemon
    • First observedget_regulation
    • First observedget_type
    • First observedlist_archetypes
    • First observedlist_forms
    • First observedlist_regulations
    • First observedlist_tiers
    • First observedsearch
    • First observedspeed_tiers
    • First observedtype_chart

TDQS

A4.6/5.0

Scored across 21 tools

Disambiguation4/5

Every tool has a clear primary purpose and the descriptions cross-reference the right alternative for each situation, but a few closely related pairs can be confused: get_type vs get_type_matchup both cover defensive effectiveness, and calculate_damage vs calculate_matchups both perform damage rolls. The overlap is well-mitigated by explicit usage guidance, so it is mostly distinct rather than perfectly unambiguous.

Naming Consistency5/5

All 21 tools follow a predictable verb_noun snake_case pattern: get_* for lookups, list_* for enumerations, calculate_* for simulations, plus check_*, optimize_evs, search_dex, and analyze_team. The verb reliably signals the action and the noun reliably signals the resource, making the naming extremely consistent.

Tool Count4/5

21 tools is on the high side of the typical sweet spot, but the domain is genuinely broad: entity lookups, battle calculations, EV optimization, regulation data, threat lists, team analysis, and legality validation. Each tool maps to a distinct workflow with little redundancy, so the count feels justified rather than bloated.

Completeness5/5

The tool surface covers the full competitive Pokémon workflow: search to discover names, lookup entities, compute stats and damage, optimize EVs, inspect regulations, fetch usage-based sets, analyze team synergy, and validate legality. Cross-references close gaps, and unknown-name errors return near matches, so agents are unlikely to hit dead ends.

Maintenance

ActivityNo data
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI models to access comprehensive Pokémon data from PokéAPI and simulate battles between any two Pokémon with realistic mechanics including type effectiveness, stat-based damage calculations, and status effects.
    1
    -
  • F
    license
    C
    quality
    D
    maintenance
    Enables interaction with live Pokémon data through PokeAPI, providing comprehensive Pokémon information, battle calculations, moveset validation, and team analysis. Supports searching Pokémon and moves, calculating stats, checking type effectiveness, and analyzing team synergies with in-memory caching for improved performance.
    9
    -
  • A
    license
    A
    quality
    C
    maintenance
    Provides Pokemon Showdown competitive battle data to AI assistants, enabling lookup of Pokemon stats, moves, abilities, items, type matchups, and strategic information through natural language queries.
    8
    5
    MIT