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 — and carries nothing from the games that came before it: the Smogon-tier and archetype surface that used to sit alongside it is gone, and no entry reports the generation it came from or whether it is still obtainable in some other game.

What it provides

  • The server introduces itself. initialize returns a titled, described serverInfo and model-facing instructions, and every tool description names the game — so a client knows before its first tool call that this server is exclusively Pokémon Champions

  • 9 compound tools: lookup, calculate, analyze_team, optimize_team, prepare_matchup, analyze_battle, analyze_meta, team_io, and record_set — intent-level entrypoints that dispatch on a mode, so the model picks an intent and the server does the orchestration. Eight are pure reads over the measured meta; record_set is the one writer, filing a set the reasoning generated into a local, per-user record

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

  • An MCP App workspace — one portable, sandboxed UI (ui://getcompetitive/workspace) with three Views over the same deterministic engine: Team Doctor (synergy/diagnose), Team Builder (slot optimization) and Matchup Board (pre-game dossier). It renders inside any Apps-capable host; the compact text output is unchanged for hosts without Apps support

  • 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

Eight compound tools; each dispatches on a mode field where the name alone is ambiguous, and each accepts detail: "compact" | "evidence" | "debug" — compact by default, so responses carry conclusions and the numbers needed to reason, and you ask for ranges, benchmarks and provenance only when the reasoning needs them.

Tool

Purpose

Modes

lookup

One data lookup

species, forms, search, move, item, ability, nature, learnset, type, matchup, sprites

calculate

One battle calc

stats, damage, matchups, speed, optimize_evs

analyze_team

Team analysis

synergy, diagnose

optimize_team

Fill open team slots against constraints

—

prepare_matchup

Pre-game dossier: likely sets, speed races, damage rolls, exhaustive bring-four with alternates, scored leads, win/loss conditions

—

analyze_battle

Post-game and scouting

replay, infer

analyze_meta

The meta, measured

threats, compare, set

team_io

Team import/export and validation

parse, format, legality, regulation, regulations

record_set

File a generated set into the local per-user record

—

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 makes no outbound request and needs no credential — every tool is an offline read, except record_set, which appends to a local file (see Recorded sets). Browsing http://<host>:<port>/ serves the evidence app — the model converses, the page displays the proof (bring-four, threat matrix, key rolls).

Hosted MCP

dist/worker.js is a serverless fetch handler over the same surface — deploy it and clients need nothing but a URL:

npx wrangler deploy            # with wrangler.toml
# connect clients to https://<your-worker>.workers.dev/mcp

The worker is stateless per request, so it scales without session storage; TLS and rate limiting come from the platform.

MCP App

The server also ships a portable MCP App — one self-contained HTML resource registered at ui://getcompetitive/workspace and linked from analyze_team, optimize_team and prepare_matchup. In an Apps-capable host (the official MCP Apps example host, or a Bud-style client) calling one of those tools renders a sandboxed iframe with the matching View:

  • Team Doctor — the six sets, a labelled heuristic score, stacked weaknesses, coverage, speed placement and top fixes; expand a panel to pull the per-type breakdown via detail: "evidence"

  • Team Builder — the constraint set and scored recommendations; add a proposed member (legality-checked), then re-optimize or read the finished team, and export the paste through team_io

  • Matchup Board — usage-derived opponent sets (labelled separately from base-stat estimates), the bring-four, speed races, calculated damage rolls (labelled separately from heuristic leads), and the assumptions behind each

The three App tools wrap their analytics in a small versioned envelope in structuredContent ({ schemaVersion, view, tool, mode, regulation, data }); the model-facing text is unchanged. Every View number comes from that envelope, never from the model's text, and a View that sees an unknown schemaVersion renders an unsupported-schema state instead of guessing. The bundle is built by scripts/build-app.mjs (esbuild, no external CDN, fonts or scripts) and embedded in the compiled server JS, so the stdio, HTTP and Worker entrypoints serve byte-identical markup.

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_team → diagnose_team → format_team ("fix my team")

/matchup-prep

parse_team → prepare_matchup ("here is my opponent")

/build-around

get_set → analyze_team → diagnose_team → check_legality → format_team

/tournament-prep

get_regulation → list_threats → get_set (a pre-event briefing)

/learn-my-team

parse_team → analyze_team → diagnose_team → get_set (a team guide)

/meta-report

list_threats → get_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

  • lookup { "mode": "species", "species": "Ogerpon-Wellspring" }

  • lookup { "mode": "matchup", "attacker": "Ice", "defender": "Garchomp" } → 4x super effective

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

  • calculate { "mode": "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" }

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

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

  • analyze_team { "mode": "synergy", "team": [...], "regulation": "m-c", "detail": "evidence" } → adds the per-type tables; "debug" adds the engine provenance block

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

  • analyze_team { "mode": "diagnose", "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"] }

  • analyze_meta { "mode": "set", "species": "Annihilape", "includeRecorded": true } → the usage-derived set when one exists, plus every set you filed for it under recorded

  • record_set { "set": { "species": "Annihilape", "item": "Leftovers", "ability": "Defiant", "nature": "Adamant", "championsPoints": { "hp": 32, "atk": 32, "spd": 2 }, "moves": ["Rage Fist", "Drain Punch", "Protect", "Bulk Up"] }, "basis": "proposed", "tool": "diagnose_team", "regulation": "m-c" }

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). The Champions game model is the single getChampionsDex() layer: node scripts/verify-champions.mjs diffs base stats, types and abilities for every Champions-exclusive form, the whole roster, and every threat species against official data and refreshes the committed facts table, which test/champions.mjs pins as golden regression tests. All generated data files are committed, so the tools stay offline at runtime. See CONTRIBUTING.

Recorded sets

The usage-derived meta has exactly one home: src/threats.data.ts, regenerated from tournament data by scripts/build-threats.mjs. A set the reasoning generated — solved from battle observations, or proposed for a team — has no sample and no rank, so it is filed separately by record_set into a local, per-user record: $GETCOMPETITIVE_STORE, or ~/.getcompetitive/sets.jsonl by default. The file is append-only JSON Lines, created on first write and keyed by a hash of the set itself, so re-recording an identical set is a no-op while a changed spread, item or move set becomes a new record — the file is the timeline of what was generated.

Records are per user and never leave the machine. analyze_meta with mode: "set" returns them only when asked with includeRecorded, under recorded, separately from the usage-derived fields: no usage share, no rank, no sample, only how each one was arrived at (inferred or proposed). No other tool writes, and on a runtime with no writable filesystem (the hosted worker) record_set returns an isError naming the path it could not write.

Contributing

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

License

MIT. Data is sourced from the official Pokémon Champions event pages, 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

9 tools
analyze_battleAnalyze BattleA
Read-onlyIdempotent

Pokémon Champions battle analysis, dispatching on mode: "replay" turns a Showdown-format battle log into a deterministic post-match read (teams, KOs, observed Speed order, damage percentages, type read), "infer" runs reverse constraint solving on battle observations to narrow an opponent’s set. Each mode carries the same documented fields the dedicated tools had. Read-only and offline.

ParametersJSON Schema
NameRequiredDescriptionDefault
logNo
modeYesWhich operation to run: "replay", "infer", "scout".
teamNoYour team with its real sets — the Speed reference and the attackers’ damage math need them.
detailNoHow much detail to return: "compact" (default) gives conclusions and the numbers needed to reason; "evidence" adds ranges, benchmarks and per-row detail; "debug" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.
speciesNo
regulationNo
observationsNoWhat the player saw, applied in order; later observations narrow earlier results.

TDQS

A3.6/5.0
Behavior4/5

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

The annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, and the description adds 'offline' and 'deterministic', which are behavioral traits not present in the annotations. It accurately describes the read-only nature of the operation and does not contradict any annotation. The claim that each mode carries the same documented fields as dedicated tools is vague, but the safety profile is well disclosed.

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 compact two-sentence summary that front-loads the tool's purpose and dispatch pattern. The phrase 'Each mode carries the same documented fields the dedicated tools had' is vague and arguably does not earn its place, but the overall text is appropriately sized and scannable.

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

Completeness3/5

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

For a tool with seven parameters and no output schema, the description covers the replay and infer modes with output summaries, but it entirely omits the `scout` mode found in the schema enum. The rich schema descriptions and annotations compensate for parameter-level detail, but the missing mode and the opaque reference to 'dedicated tools' leave the description with clear gaps.

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?

The description enriches the meaning of the `mode` parameter by explaining what replay and infer do, which goes beyond the schema enum. However, it does not discuss `scout`, nor does it describe parameters like `log`, `team`, `observations`, `detail`, `species`, or `regulation`; the schema already provides descriptions for those, so the description adds only modest value. The omission of the `scout` value is a notable gap given it is part of the enum.

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

Purpose4/5

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

The description clearly identifies the tool as battle analysis and explains two dispatch modes with concrete outputs: replay produces a post-match read and infer narrows an opponent's set via constraint solving. However, it omits the `scout` mode that appears in the schema enum, and it does not differentiate the tool from siblings like analyze_team or analyze_meta. It is clear on the main modes but incomplete on the full mode surface.

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

Usage Guidelines3/5

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

The description provides conditional guidance: use `replay` when you have a Showdown-format battle log, and use `infer` when you have battle observations to constrain an opponent's set. It does not say when to prefer this tool over the sibling tools, and its reference to 'the dedicated tools' is vague. Usage guidance is implied rather than comparative.

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

analyze_metaAnalyze MetaA
Read-onlyIdempotent

Pokémon Champions meta intelligence, dispatching on mode: "threats" for the usage-ranked threat list, "compare" for the two-window usage deltas and emerging cores, "set" for one species’ most-played standard set (batched). Each mode carries the same documented fields the dedicated tools had. Read-only and offline; usage-derived from measured tournament data.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeYesWhich operation to run: "threats", "compare", "set".
detailNoHow much detail to return: "compact" (default) gives conclusions and the numbers needed to reason; "evidence" adds ranges, benchmarks and per-row detail; "debug" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.
speciesNoBase 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.
regulationNo
includeRecordedNoAlso read the local, per-user record of sets the reasoning generated (`record_set`) and return the ones filed under the requested species as `recorded`. They carry no rank, usage share or sample, so they are never merged into the usage-derived fields; a record that named no regulation matches any `regulation` scope. Absent or false, the answer is the measured meta only.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already carry readOnlyHint and idempotentHint, and the description reinforces this with 'Read-only and offline' and 'usage-derived from measured tournament data', adding a useful data-source and side-effect guarantee. It also notes batched set retrieval. 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 with no filler: core purpose is front-loaded, the mode breakdown is compact, and the read-only/offline caveat is placed at the end. Every sentence contributes either selection guidance or behavioral context.

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

Completeness4/5

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

The schema covers the mechanical details of all five parameters, and the description covers the conceptual operation switching, so an agent can select and invoke the main modes correctly. The main gap is the reference to 'the same documented fields the dedicated tools had' without naming or describing those fields, which may leave return-value expectations underspecified.

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 description adds real meaning to the `mode` parameter beyond the schema enum by explaining what each mode returns: threat lists, usage deltas/emerging cores, and standard sets. The remaining parameters are already well documented in the schema, so the 80% coverage baseline is comfortably met.

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 a specific resource (Pokémon Champions meta intelligence) and a concrete dispatch mechanism on `mode`, with each mode given a distinct outcome: usage-ranked threat list, two-window usage deltas/cores, and most-played standard set. The meta-focused wording separates it from sibling team/battle tools, even without naming them explicitly.

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

Usage Guidelines3/5

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

The mode descriptions imply when each operation is useful, and the phrase 'dedicated tools' hints at consolidation, but there is no explicit when-to-use versus alternatives such as analyze_team or analyze_battle, nor any stated exclusions. The agent has to infer the routing based on the word 'meta' and mode names.

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

analyze_teamAnalyze TeamA
Read-onlyIdempotent

Pokémon Champions team analysis, dispatching on mode: "synergy" for the type-synergy read (stacked weaknesses, coverage gaps, speed placement, heuristic score, and battle-math answerClass verdicts against the meta when a regulation and moves are supplied), "diagnose" for the coaching read ("fix my team": problems with evidence, then concrete spread/move/item/member changes). Each mode carries the same documented fields the dedicated tools had. Read-only and offline.

ParametersJSON Schema
NameRequiredDescriptionDefault
goalNoWhat the caller is trying to achieve, e.g. "improve against the current meta"; carried into the result verbatim, the analysis itself is always meta-coverage-first.
modeYesWhich operation to run: "synergy", "diagnose".
teamNo
detailNoHow much detail to return: "compact" (default) gives conclusions and the numbers needed to reason; "evidence" adds ranges, benchmarks and per-row detail; "debug" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.
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.
regulationNo
lockedMembersNoSpecies to keep as-is; they are excluded from member-swap suggestions (spread, move and item changes still apply to them).

TDQS

A4.1/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 value by noting 'Read-only and offline,' clarifying error behavior ('Unknown names are reported, not fatal' for moves; 'Unknown names return an isError' for opponent and regulation), and advising on the `detail` parameter ('model context is the expensive resource'). These go beyond what annotations provide.

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 well-structured, starting with the dispatch mechanism, then describing each mode, and ending with a note on parity with dedicated tools and the read-only/offline nature. It is somewhat long (about 200 words) but each sentence adds useful information. It could be tightened, but the organization is logical and front-loaded.

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

Completeness4/5

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

Given the tool's complexity (two modes, seven parameters, no output schema), the description covers the main aspects: what each mode does, error handling, offline/read-only behavior, and the `detail` levels. It does not explicitly describe the return format, but it references parity with dedicated tools, which implies known output shapes. This is adequate for an agent to understand and invoke 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 71%, and the schema already includes descriptions for most parameters, including the meaning of `mode`, `detail`, and the team structure. The description adds some extra context (e.g., `goal` is carried into the result verbatim, analysis is meta-coverage-first, and the `detail` hint), but it does not substantially clarify parameters beyond what the schema already documents. This matches the baseline for high 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 clearly states the tool performs team analysis, dispatches on `mode`, and explicitly names the two modes ('synergy' and 'diagnose') with their distinct outputs. It also mentions that each mode carries the same fields as the dedicated tools, which helps distinguish it from siblings like analyze_battle and analyze_meta.

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

Usage Guidelines4/5

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

The description explains the purpose of each mode and the conditions under which each is appropriate ('synergy' for type-synergy read, 'diagnose' for coaching). However, it does not explicitly contrast analyze_team with sibling tools like analyze_battle or analyze_meta, leaving some ambiguity about when to prefer this combined tool over the dedicated ones.

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

calculateCalculateA
Read-onlyIdempotent

Pokémon Champions battle calculation, dispatching on mode: "stats" for a final stat table, "damage" for a full single-attack simulation, "matchups" to test one attacker against many defenders, "speed" to place a Speed stat against a regulation roster, and "optimize_evs" to derive a minimal spread from goals (survive, outspeed, KO). Each mode carries the same documented fields the dedicated calc tools had. Read-only and offline; deterministic. Give one spread scale per member: evs (0-252 each, 510 total) or championsPoints (the Champions CP economy: 8 EVs = 1 CP, each stat 0-32, 66 CP total, e.g. 252 HP / 252 Atk / 4 SpD = 32 / 32 / 1 CP); giving both is rejected.

ParametersJSON Schema
NameRequiredDescriptionDefault
evsNo
ivsNo
itemNo
killNoAdd a KO goal: minimizes Atk or SpA so that even the lowest damage roll reaches the per-hit HP threshold.
modeYesWhich operation to run: "stats", "damage", "matchups", "speed", "optimize_evs".
moveNo
fieldNo
levelNo
boostsNoStat stages; only `spe` (-6..+6) is applied, e.g. { spe: 1 } for a +1 Speed stage.
detailNoHow much detail to return: "compact" (default) gives conclusions and the numbers needed to reason; "evidence" adds ranges, benchmarks and per-row detail; "debug" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.
natureNo
abilityNoAbility assumed active while solving, e.g. "Intimidate", "Protosynthesis".
speciesNo
surviveNoAdd a "always live this hit" goal: the search minimizes HP plus the relevant Defense EVs that keep the worst roll below max HP.
attackerNo
defenderNoThe defending Pokémon, same fields as `attacker`; its Defense/SpD, HP, typing, and ability drive the result.
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).
defendersNo1-30 defender sets, each with the same fields as `attacker`; every entry is scored against the same attacker, move set, and field.
regulationNoRegulation Set name or id from `list_regulations` to compare against, e.g. "Regulation Set G"; omit to get the raw Speed only.
championsPointsNo

TDQS

A4.4/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 useful behavior beyond annotations: the tool is offline and deterministic, and supplying both evs and championsPoints is rejected. This is meaningful context, though it does not describe full output behavior.

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 dense, front-loaded sentences. The mode list and the EV/CP exclusion rule are the most decision-relevant facts and appear first. Every sentence earns its place with no filler or repetition of annotation content.

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

Completeness4/5

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

For a complex 21-parameter tool with nested objects and no output schema, the description covers mode selection, the spread-scale constraint, and the read-only/offline/deterministic nature. The schema carries per-field details. A minor gap is the lack of explicit return-value shape per mode, but each mode's purpose is described well enough to invoke 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 description coverage is only 52%, so the description carries some parameter-semantics burden. It compensates by explaining the critical `mode` parameter's five values and the mutually exclusive evs/championsPoints spread scales with a concrete CP conversion example. The schema's own individual property descriptions handle the remaining fields in detail.

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 a specific verb+resource ('battle calculation' on 'Pokémon Champions') and explicitly enumerates the five dispatch modes with their outputs (stats table, damage simulation, matchups, speed placement, EV optimization). This clearly differentiates it from sibling tools like analyze_team or optimize_team, which address different concerns.

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

Usage Guidelines4/5

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

The mode list gives clear context for when to call this tool: if you need stats, damage, matchups, speed, or optimized EV spreads. 'Read-only and offline; deterministic' sets expectations for safety and repeatability. However, it does not explicitly state when not to use it or name alternatives such as the 'dedicated calc tools' it references.

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

lookupLookupA
Read-onlyIdempotent

Pokémon Champions data lookup, dispatching on mode: "species" for one Pokémon’s profile, "forms" for its forms, "search" for a fuzzy name search across the dataset, "move"/"item"/"ability"/"nature"/"learnset" for those records, "type" for a type’s defensive profile, "matchup" for one type multiplier, and "sprites" for a whole team’s sprite URLs in one call. Each mode carries the same documented fields the dedicated lookup tools had; pick the mode that names the thing being looked up and pass its arguments. Read-only and offline over the bundled dataset.

ParametersJSON Schema
NameRequiredDescriptionDefault
itemNoItem name, e.g. "Choice Band", "Assault Vest", "Leftovers".
kindNoTable to search; one per call (default "species").species
modeYesWhich operation to run: "species", "forms", "search", "move", "item", "ability", "nature", "learnset", "type", "matchup", "sprites".
moveNoMove name, e.g. "Earthquake", "Make It Rain", "Dragon Claw".
sizeNoWhich image the URLs point at: "artwork" (default) is the 475×475 transparent official art, "icon" is the 96×96 game sprite for a compact row.
typeNoType name, e.g. "Steel", "Fairy", "Ground".
limitNoMaximum results returned, 1-100 (default 20).
queryNoSubstring to match against name and Showdown id, e.g. "oger", "sword".
detailNoHow much detail to return: "compact" (default) gives conclusions and the numbers needed to reason; "evidence" adds ranges, benchmarks and per-row detail; "debug" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.
natureNoNature name, e.g. "Jolly", "Timid", "Impish".
abilityNoAbility name, e.g. "Intimidate", "Protosynthesis".
speciesNo
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 types.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds the non-obvious dispatch behavior across 11 modes and the offline-dataset context. It does not describe return shapes, but the schema's 'detail' parameter partially covers output granularity, and 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.

Conciseness4/5

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

The description is dense and front-loaded, with the full mode list in the first sentence and the read-only/offline note at the end. Every sentence earns its place, though the long first sentence and the vague 'same documented fields' phrase are slightly less crisp than ideal.

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

Completeness3/5

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

For a 14-parameter, 11-mode tool, the description handles dispatch and mode selection well. However, it relies on 'the same documented fields the dedicated lookup tools had' instead of stating what each mode returns, and with no output schema that is a meaningful gap for agents unfamiliar with those prior tools.

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 93%, so parameters are already well documented individually. The description adds a crucial cross-cutting mapping: each mode selects which arguments to pass ('pass its arguments'), which the schema's flat parameter list does not make explicit. It could go further by naming the exact arguments per mode.

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 'Pokémon Champions data lookup' and enumerates every mode ('species', 'forms', 'search', 'move', etc.), making the verb, resource, and scope explicit. This clearly distinguishes the tool from sibling analysis/optimization tools.

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

Usage Guidelines4/5

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

It gives direct selection guidance: 'pick the mode that names the thing being looked up and pass its arguments.' It also notes the tool is read-only and offline, implying use for offline data lookups, but it does not explicitly name sibling alternatives like analyze_team or optimize_team.

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

optimize_teamOptimize team slotsA
Read-onlyIdempotent

Pokémon Champions team building: fill open slots against constraints: "cover these types" and "answer these threats." The engine scores every legal species in the regulation against the constraint set — the types the current team never hits super-effectively (computed automatically, or supplied), and the threats named or defaulted to the meta’s top five by usage — by what its typing covers, resists and hits, with a small preference for species the meta actually plays. With two open slots it scores pairs on their combined coverage, not just the sum. Every recommendation carries the reasons, so the tradeoff is visible; unranked species are scored on typing alone because their movesets are unknown. The fills respect Species Clause and stay inside the roster, so the result passes check_legality — verify with it once the team is assembled. Read-only and offline.

ParametersJSON Schema
NameRequiredDescriptionDefault
teamYesThe team so far, in the canonical shape `parse_team` returns; the open slots are what this tool fills.
slotsYesHow many members to recommend: one species, or a pair whose combined coverage is scored together.
detailNoHow much detail to return: "compact" (default) gives conclusions and the numbers needed to reason; "evidence" adds ranges, benchmarks and per-row detail; "debug" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.
playstyleNoShorthand for the objective: "tailwind" or "trick-room" map to the corresponding required role; any other value is carried into the note verbatim.
coverTypesNoTypes the finished team must hit super-effectively, e.g. ["Water", "Steel"]; omitted, the engine computes the types the current team cannot hit at all.
regulationNoRegulation id, e.g. "m-c"; omitted, the current set is used and its roster bounds the candidates.
answerThreatsNoSpecies the finished team must answer, e.g. ["Sneasler", "Gholdengo"]; omitted, the regulation’s five most-used threats are used.
requiredRolesNoCompetitive roles the filled slots must collectively provide, e.g. ["tailwind", "fake_out"]; candidates earn score for roles the team still lacks.
excludedSpeciesNoSpecies to exclude from the search, e.g. ["Milotic"]; case- and punctuation-insensitive.

TDQS

A4.5/5.0
Behavior5/5

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

The description goes well beyond the readOnly/idempotent/destructive annotations by explaining the scoring algorithm, default to the meta's top five threats, pair-based scoring for two slots, the unranked-species limitation, and the Species Clause/roster constraints. It also explicitly says "Read-only and offline," adding context consistent with 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 first sentence front-loads the purpose, and every following sentence carries useful behavioral detail. It is longer than strictly necessary, but for a complex optimization tool the density is justified and there is no filler.

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

Completeness4/5

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

Given the tool's complexity, nine parameters, no output schema, and rich annotations, the description covers the core behavior, defaults, constraints, and even output detail levels through the detail parameter. It could be more complete by explicitly mentioning how requiredRoles and excludedSpecies influence the search in prose, but the schema covers those and the description provides enough 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?

Schema coverage is 100%, so the baseline is 3, but the description adds real semantic value by explaining how coverTypes and answerThreats interact with scoring, what happens when they are omitted, and how two slots are evaluated jointly. It does not discuss every optional parameter such as playstyle or requiredRoles, but those are already well-described 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 and resource: "fill open slots" in a Pokémon Champions team, scoring legal species against coverage and threat constraints. It clearly distinguishes this from analyzer/calculator siblings by describing a search-and-recommend engine rather than a generic analysis. The scope is immediately apparent.

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

Usage Guidelines4/5

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

"Pokémon Champions team building: fill open slots" gives clear context for when the tool is appropriate, and the closing instruction to verify with check_legality implies the downstream workflow. It does not name alternative sibling tools or explicitly state when not to use it, so it stops short of full routing guidance.

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

prepare_matchupPrepare a matchupA
Read-onlyIdempotent

Prepare a Pokémon Champions match against a known opponent: "here is their team — what do I bring, and what should I watch for?" A deterministic pre-game dossier composed from the rest of the surface. likelySets orders the opponent most-used first, carrying each species’ actual usage-derived set (item, ability, nature, EVs, four moves, usage share) where one exists. speedTiers compares real level-50 Speed with the margins spelled out. relevantDamageCalcs runs real damage rolls for the key matchups — the team’s hardest hit into their top threats and the threat’s hardest hit back at the member that answers it. recommendedBringFour is the same type-scored pick analyze_team makes. Leads, win conditions, loss conditions, and the members to preserve are heuristics from movesets, Speed and typing, each labelled with what it can see. Speeds and moves for uncurated opponent species are base-stat or STAB estimates and say so. The caller narrates; every number here is a real calculation or a real usage figure.

ParametersJSON Schema
NameRequiredDescriptionDefault
teamYesYour team, in the canonical shape `parse_team` returns: species with optional moves, ability, nature, evs or championsPoints, and item.
detailNoHow much detail to return: "compact" (default) gives conclusions and the numbers needed to reason; "evidence" adds ranges, benchmarks and per-row detail; "debug" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.
opponentYesThe opponent’s team: species names for what preview shows, or full sets when more is known — full sets widen the damage calculations and speed math.
regulationNoRegulation id the match is under, e.g. "m-c"; omitted, the current set is used.

TDQS

A4.7/5.0
Behavior5/5

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

The description is exceptionally transparent, going beyond the annotations (readOnlyHint=true, idempotentHint=true, destructiveHint=false) to disclose that the tool is deterministic, that all numbers are 'real calculations or real usage figures', that estimates for uncurated opponent species are labeled, and that heuristics are 'each labelled with what it can see'. This thoroughly informs the agent of what to trust and what is approximate, with 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 a substantial paragraph, but it is well-structured and front-loaded with the purpose before enumerating output components. Every sentence adds information about what the tool computes or how it behaves; there is no filler. It could be slightly more compact, but the density is justified given the tool's complexity, so it earns a 4 rather than a 5.

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 and the absence of an output schema, the description is thorough enough for an agent to use it correctly. It covers inputs (team, opponent, detail, regulation), explains each output field, discloses data sources (usage-derived sets, real damage rolls, heuristics), flags limitations (estimates for uncurated species), and ties return values to the overall purpose. Nothing critical 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?

Even though schema coverage is 100%, the description adds meaningful semantics beyond the JSON schema. It explains that team should be 'the canonical shape parse_team returns', clarifies that opponent accepts species names or full sets with the trade-off ('full sets widen the damage calculations and speed math'), and gives guidance on detail levels (compact/evidence/debug) with a cost recommendation. These details materially help an agent choose parameter values correctly.

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 ('Prepare'), a clear resource ('a match against a known opponent'), and delineates exactly what it produces (likelySets, speedTiers, relevantDamageCalcs, recommendedBringFour, etc.). It also distinguishes itself from the sibling analyze_team by noting that recommendedBringFour is 'the same type-scored pick analyze_team makes', which clarifies its unique role without ambiguity.

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

Usage Guidelines4/5

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

The description opens with a clear use case ('their team — what do I bring, and what should I watch for?') and explains when to request more detail via the detail parameter, including the cost trade-off ('model context is the expensive resource'). It does not explicitly enumerate when not to use this tool versus every sibling, but it references analyze_team and implies this tool is the pre-game dossier counterpart. This is strong guidance, though it falls short of explicitly naming alternatives for each scenario.

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

record_setRecord a generated setA
Idempotent

File a Pokémon Champions set the reasoning produced into the local, per-user record, so a set generated once can be read back later — get_set returns it under recorded when asked with includeRecorded. The usage-derived meta (list_threats, get_set) stays the only home of measured usage: a record carries no rank, no usage share and no sample, and is labelled with how it was arrived at — "inferred" (solved from battle observations) or "proposed" (generated for a team). The store is one JSON-Lines file per user, $GETCOMPETITIVE_STORE or ~/.getcompetitive/sets.jsonl, created on first write; re-recording an identical set is a no-op (created: false) and a changed spread, item or move set is filed as a new record, so the file is the timeline of what was generated. The set is resolved against the dataset with the same rules the rest of the server uses, so an unknown species, item, nature or an illegal spread is rejected rather than filed, while unknown moves come back as warnings and the set is filed as given. This is the only tool on the server that writes anything; where there is no writable filesystem (the hosted endpoint) it returns an isError naming the path it could not write.

ParametersJSON Schema
NameRequiredDescriptionDefault
setYesThe set to file, in the canonical shape `parse_team`, `diagnose_team`, `infer_set` and the analysis tools all consume.
noteNoWhy this set exists — the question it answers or the evidence behind it; carried verbatim into the record’s `origin`.
toolYesWhich part of the reasoning produced it, e.g. "infer_set", "diagnose_team", "optimize_team"; carried verbatim into the record’s `origin`.
basisYesHow the set was arrived at: "inferred" when it was solved from battle observations, "proposed" when the reasoning generated it for a team. Neither is measured usage.
detailNoHow much detail to return: "compact" (default) gives conclusions and the numbers needed to reason; "evidence" adds ranges, benchmarks and per-row detail; "debug" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.
regulationNoRegulation the set was generated for, e.g. "m-c"; when given it must resolve, and it becomes part of the record’s identity.

TDQS

A4.7/5.0
Behavior5/5

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

The description goes far beyond the annotations: it discloses the JSON-Lines store path, creation-on-first-write, the no-op behavior for identical records, new-record behavior for changed content, dataset validation with rejection versus warnings, and the error path on non-writable filesystems. These details match and enrich the idempotentHint annotation without contradicting it.

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 dense, and the core purpose is front-loaded. Each later block earns its place by covering a distinct concern: provenance, storage, idempotency, validation, and deployment failure. A few parentheticals, such as the usage-derived meta note, are somewhat knotted, but there is no real padding.

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

Completeness4/5

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

For a write tool with no output schema, the description covers the essential runtime context: file location, append semantics, record identity, validation behavior, failure mode, and idempotency. The one notable gap is the full success response shape — only `created: false` is mentioned — so an agent is left to infer the rest of the return structure.

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 already strong. The description adds meaningful parameter context: basis labels are tied to inferred versus proposed, the set is resolved with server-wide rules, illegal spreads are rejected while unknown moves become warnings, and regulation becomes part of the record's identity. This supplements the schema rather than merely repeating it.

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 concrete action and resource: file a Pokémon Champions set into the local per-user record for later read-back via get_set. It clearly separates this write tool from the get_set read path and from analysis siblings, and it names itself as the only writing tool on the server, removing ambiguity about its role.

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 when to use the tool — when reasoning produced a set that should be persisted — and where to read it back: get_set with includeRecorded. It also states the hosted endpoint has no writable filesystem and will fail, which is a practical exclusion. This gives an agent a clear decision rule.

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

team_ioTeam IoA
Read-onlyIdempotent

Pokémon Champions team import/export and validation, dispatching on mode: "parse" turns pasted text into the canonical team shape, "format" renders a canonical team back into paste text, "legality" checks a team against a regulation’s rules, "regulation" reads one regulation’s rules (rosters optional), "regulations" lists them all. Each mode carries the same documented fields the dedicated tools had. Read-only and offline.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeYesWhich operation to run: "parse", "format", "legality", "regulation", "regulations".
teamNo
textNoThe team text: one Showdown-format block per Pokémon, separated by blank lines, or one shorthand line per Pokémon with pipe-separated fields.
detailNoHow much detail to return: "compact" (default) gives conclusions and the numbers needed to reason; "evidence" adds ranges, benchmarks and per-row detail; "debug" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.
regulationNo
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.

TDQS

A4.3/5.0
Behavior4/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 adds 'Read-only and offline', which is consistent and adds the offline qualifier not in annotations. It also clarifies that behavior varies by mode via 'dispatching on mode', which is useful. No contradictions; the description complements the annotations without repeating them.

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 about 200 words, which is justified for a tool with five modes and six parameters. It front-loads the overall purpose and then enumerates modes in a compact list, followed by field clarifications. While a bit dense, every sentence contributes to clarifying behavior or usage; no fluff. Could be slightly more concise by trimming redundant phrasing, but it's well-structured.

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

Completeness4/5

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

For a complex dispatcher with five modes and six parameters, the description covers all modes and all parameters with enough detail to call the tool correctly. It lacks explicit return-format expectations, but since there is no output schema, the description could be expected to hint at that; the phrase 'each mode carries the same documented fields the dedicated tools had' is a partial hint but vague. Given the annotations cover safety, the description is largely complete for an agent to invoke it properly.

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 descriptions already cover most parameters (mode enum, team shape, text format, detail levels, regulation matching, includeRoster). The description adds value by explaining the dispatch semantics for mode, clarifying that detail levels should be requested judiciously ('model context is the expensive resource'), and giving examples of regulation resolution ('M-A', 'm-a', 'mc' all match). It also notes the team shape matches what parse_team and analysis tools use, aiding cross-tool understanding.

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 purpose: 'Pokémon Champions team import/export and validation', and then enumerates each mode (parse, format, legality, regulation, regulations) with a one-line explanation of what each does. It distinguishes itself from the sibling analysis tools (analyze_team, analyze_battle, etc.) by focusing on import/export and validation rather than analysis, so an agent can tell when to use this instead of those.

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

Usage Guidelines4/5

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

The description explains the dispatch mechanism by listing each mode and its operation, giving clear context for when to use each. It doesn't explicitly state when NOT to use this tool or name alternatives, but the mode descriptions are self-explanatory and the sibling tools are obviously different. A small gap is the lack of explicit 'use this instead of X when...' guidance, but the mode-specific detail largely covers it.

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. 1 tool updatev8.0.4
    • Changedcalculate13 fields changed
      • changedInput schema / properties / attacker / anyOf
        Previous value: -[
        -  {
        -    "description": "The attacking Pokémon: species plus optional level, nature, IVs, EVs, item, ability, boosts, status, and current HP.",
        -    "properties": {
        -      "ability": {
        -        "description": "Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability.",
        -        "type": "string"
        -      },
        -      "abilityOn": {
        -        "description": "Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc.",
        -        "type": "boolean"
        -      },
        -      "boosts": {
        -        "additionalProperties": {
        -          "type": "number"
        -        },
        -        "description": "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).",
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "championsPoints": {
        -        "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"
        -      },
        -      "curHP": {
        -        "description": "Current HP when entering damaged, e.g. 120; defaults to full HP.",
        -        "type": "number"
        -      },
        -      "evs": {
        -        "additionalProperties": {
        -          "type": "number"
        -        },
        -        "description": "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.",
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "item": {
        -        "description": "Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect.",
        -        "type": "string"
        -      },
        -      "ivs": {
        -        "additionalProperties": {
        -          "type": "number"
        -        },
        -        "description": "IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.",
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "level": {
        -        "description": "Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools.",
        -        "maximum": 100,
        -        "minimum": 1,
        -        "type": "integer"
        -      },
        -      "moves": {
        -        "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender.",
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      },
        -      "nature": {
        -        "description": "Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted.",
        -        "type": "string"
        -      },
        -      "species": {
        -        "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        -        "type": "string"
        -      },
        -      "status": {
        -        "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed.",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "species"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "description": "The single attacking Pokémon; set `moves` to let the tool choose the best move against each defender.",
        -    "properties": {
        -      "ability": {
        -        "description": "Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability.",
        -        "type": "string"
        -      },
        -      "abilityOn": {
        -        "description": "Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc.",
        -        "type": "boolean"
        -      },
        -      "boosts": {
        -        "additionalProperties": {
        -          "type": "number"
        -        },
        -        "description": "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).",
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "championsPoints": {
        -        "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"
        -      },
        -      "curHP": {
        -        "description": "Current HP when entering damaged, e.g. 120; defaults to full HP.",
        -        "type": "number"
        -      },
        -      "evs": {
        -        "additionalProperties": {
        -          "type": "number"
        -        },
        -        "description": "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.",
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "item": {
        -        "description": "Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect.",
        -        "type": "string"
        -      },
        -      "ivs": {
        -        "additionalProperties": {
        -          "type": "number"
        -        },
        -        "description": "IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.",
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "level": {
        -        "description": "Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools.",
        -        "maximum": 100,
        -        "minimum": 1,
        -        "type": "integer"
        -      },
        -      "moves": {
        -        "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender.",
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      },
        -      "nature": {
        -        "description": "Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted.",
        -        "type": "string"
        -      },
        -      "species": {
        -        "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        -        "type": "string"
        -      },
        -      "status": {
        -        "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed.",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "species"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "description": "The attacking Pokémon: species plus optional level, nature, IVs, EVs, item, ability, boosts, status, and current HP.",
        +    "properties": {
        +      "ability": {
        +        "description": "Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability.",
        +        "type": "string"
        +      },
        +      "abilityOn": {
        +        "description": "Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc.",
        +        "type": "boolean"
        +      },
        +      "boosts": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "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).",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "championsPoints": {
        +        "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. The CP economy is 8 EVs = 1 CP, so a 252 HP / 252 Atk / 4 SpD spread is 32 / 32 / 1 CP (65 of 66); a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "curHP": {
        +        "description": "Current HP when entering damaged, e.g. 120; defaults to full HP.",
        +        "type": "number"
        +      },
        +      "evs": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "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. Give this or `championsPoints` (the Champions 0-32 scale, 8 EVs = 1 CP, 66 total), never both.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "item": {
        +        "description": "Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect.",
        +        "type": "string"
        +      },
        +      "ivs": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "level": {
        +        "description": "Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools.",
        +        "maximum": 100,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "moves": {
        +        "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "nature": {
        +        "description": "Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted.",
        +        "type": "string"
        +      },
        +      "species": {
        +        "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "species"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "description": "The single attacking Pokémon; set `moves` to let the tool choose the best move against each defender.",
        +    "properties": {
        +      "ability": {
        +        "description": "Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability.",
        +        "type": "string"
        +      },
        +      "abilityOn": {
        +        "description": "Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc.",
        +        "type": "boolean"
        +      },
        +      "boosts": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "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).",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "championsPoints": {
        +        "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. The CP economy is 8 EVs = 1 CP, so a 252 HP / 252 Atk / 4 SpD spread is 32 / 32 / 1 CP (65 of 66); a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "curHP": {
        +        "description": "Current HP when entering damaged, e.g. 120; defaults to full HP.",
        +        "type": "number"
        +      },
        +      "evs": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "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. Give this or `championsPoints` (the Champions 0-32 scale, 8 EVs = 1 CP, 66 total), never both.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "item": {
        +        "description": "Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect.",
        +        "type": "string"
        +      },
        +      "ivs": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "level": {
        +        "description": "Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools.",
        +        "maximum": 100,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "moves": {
        +        "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "nature": {
        +        "description": "Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted.",
        +        "type": "string"
        +      },
        +      "species": {
        +        "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "species"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedInput schema / properties / championsPoints / anyOf
        Previous 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"
        -  },
        -  {
        -    "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"
        -  }
        -]New 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. The CP economy is 8 EVs = 1 CP, so a 252 HP / 252 Atk / 4 SpD spread is 32 / 32 / 1 CP (65 of 66); a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces.",
        +    "propertyNames": {
        +      "type": "string"
        +    },
        +    "type": "object"
        +  },
        +  {
        +    "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`, never both; 8 EVs = 1 CP.",
        +    "propertyNames": {
        +      "type": "string"
        +    },
        +    "type": "object"
        +  }
        +]
      • changedInput schema / properties / defender / properties / championsPoints / description
        Previous value: -"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."New value: +"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. The CP economy is 8 EVs = 1 CP, so a 252 HP / 252 Atk / 4 SpD spread is 32 / 32 / 1 CP (65 of 66); a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces."
      • changedInput schema / properties / defender / properties / evs / description
        Previous 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."New 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. Give this or `championsPoints` (the Champions 0-32 scale, 8 EVs = 1 CP, 66 total), never both."
      • changedInput schema / properties / defenders / items / properties / championsPoints / description
        Previous value: -"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."New value: +"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. The CP economy is 8 EVs = 1 CP, so a 252 HP / 252 Atk / 4 SpD spread is 32 / 32 / 1 CP (65 of 66); a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces."
      • changedInput schema / properties / defenders / items / properties / evs / description
        Previous 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."New 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. Give this or `championsPoints` (the Champions 0-32 scale, 8 EVs = 1 CP, 66 total), never both."
      • changedInput schema / properties / evs / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": {
        -      "type": "number"
        -    },
        -    "description": "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.",
        -    "propertyNames": {
        -      "type": "string"
        -    },
        -    "type": "object"
        -  },
        -  {
        -    "additionalProperties": {
        -      "type": "number"
        -    },
        -    "description": "EVs keyed by stat id; only `spe` (0-252) changes the result, e.g. { spe: 252 }.",
        -    "propertyNames": {
        -      "type": "string"
        -    },
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": {
        +      "type": "number"
        +    },
        +    "description": "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. Give this or `championsPoints` (the Champions 0-32 scale, 8 EVs = 1 CP, 66 total), never both.",
        +    "propertyNames": {
        +      "type": "string"
        +    },
        +    "type": "object"
        +  },
        +  {
        +    "additionalProperties": {
        +      "type": "number"
        +    },
        +    "description": "EVs keyed by stat id; only `spe` (0-252) changes the result, e.g. { spe: 252 }.",
        +    "propertyNames": {
        +      "type": "string"
        +    },
        +    "type": "object"
        +  }
        +]
      • changedInput schema / properties / kill / properties / target / properties / championsPoints / description
        Previous value: -"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."New value: +"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. The CP economy is 8 EVs = 1 CP, so a 252 HP / 252 Atk / 4 SpD spread is 32 / 32 / 1 CP (65 of 66); a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces."
      • changedInput schema / properties / kill / properties / target / properties / evs / description
        Previous 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."New 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. Give this or `championsPoints` (the Champions 0-32 scale, 8 EVs = 1 CP, 66 total), never both."
      • changedInput schema / properties / outspeed / properties / target / properties / championsPoints / description
        Previous value: -"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."New value: +"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. The CP economy is 8 EVs = 1 CP, so a 252 HP / 252 Atk / 4 SpD spread is 32 / 32 / 1 CP (65 of 66); a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces."
      • changedInput schema / properties / outspeed / properties / target / properties / evs / description
        Previous 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."New 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. Give this or `championsPoints` (the Champions 0-32 scale, 8 EVs = 1 CP, 66 total), never both."
      • changedInput schema / properties / survive / properties / attacker / properties / championsPoints / description
        Previous value: -"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."New value: +"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. The CP economy is 8 EVs = 1 CP, so a 252 HP / 252 Atk / 4 SpD spread is 32 / 32 / 1 CP (65 of 66); a converted spread is trimmed from its largest stats to fit the 510 EV cap the calculator enforces."
      • changedInput schema / properties / survive / properties / attacker / properties / evs / description
        Previous 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."New 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. Give this or `championsPoints` (the Champions 0-32 scale, 8 EVs = 1 CP, 66 total), never both."
  2. 9 tool updatesv8.0.2
    • Changedanalyze_battle9 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / properties / detail
        Added value: +{
        +  "description": "How much detail to return: \"compact\" (default) gives conclusions and the numbers needed to reason; \"evidence\" adds ranges, benchmarks and per-row detail; \"debug\" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.",
        +  "enum": [
        +    "compact",
        +    "evidence",
        +    "debug"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / log
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The battle log text, exactly as exported (lines beginning with |), e.g. from Showdown or a Champions client export.",
        +      "type": "string"
        +    },
        +    {
        +      "description": "The battle log text, exactly as exported (lines beginning with |).",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedInput schema / properties / mode
        Added value: +{
        +  "description": "Which operation to run: \"replay\", \"infer\", \"scout\".",
        +  "enum": [
        +    "replay",
        +    "infer",
        +    "scout"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / observations
        Added value: +{
        +  "description": "What the player saw, applied in order; later observations narrow earlier results.",
        +  "items": {
        +    "anyOf": [
        +      {
        +        "properties": {
        +          "kind": {
        +            "const": "speed",
        +            "type": "string"
        +          },
        +          "referenceSpeed": {
        +            "description": "The Speed of the member it raced against.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "relation": {
        +            "description": "\"outsped\" means it moved first; \"outspeeds\" means your member moved first.",
        +            "enum": [
        +              "outsped",
        +              "outspeeds"
        +            ],
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "kind",
        +          "referenceSpeed",
        +          "relation"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "properties": {
        +          "kind": {
        +            "const": "damageDealt",
        +            "type": "string"
        +          },
        +          "move": {
        +            "description": "The move it used.",
        +            "type": "string"
        +          },
        +          "percent": {
        +            "description": "Damage as a percentage of the target’s HP.",
        +            "type": "number"
        +          },
        +          "target": {
        +            "properties": {
        +              "ability": {
        +                "type": "string"
        +              },
        +              "championsPoints": {
        +                "additionalProperties": {
        +                  "type": "number"
        +                },
        +                "propertyNames": {
        +                  "type": "string"
        +                },
        +                "type": "object"
        +              },
        +              "evs": {
        +                "additionalProperties": {
        +                  "type": "number"
        +                },
        +                "propertyNames": {
        +                  "type": "string"
        +                },
        +                "type": "object"
        +              },
        +              "item": {
        +                "type": "string"
        +              },
        +              "level": {
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "nature": {
        +                "type": "string"
        +              },
        +              "species": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "species"
        +            ],
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "kind",
        +          "move",
        +          "target",
        +          "percent"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "properties": {
        +          "attacker": {
        +            "properties": {
        +              "ability": {
        +                "type": "string"
        +              },
        +              "championsPoints": {
        +                "additionalProperties": {
        +                  "type": "number"
        +                },
        +                "propertyNames": {
        +                  "type": "string"
        +                },
        +                "type": "object"
        +              },
        +              "evs": {
        +                "additionalProperties": {
        +                  "type": "number"
        +                },
        +                "propertyNames": {
        +                  "type": "string"
        +                },
        +                "type": "object"
        +              },
        +              "item": {
        +                "type": "string"
        +              },
        +              "level": {
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "nature": {
        +                "type": "string"
        +              },
        +              "species": {
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "species"
        +            ],
        +            "type": "object"
        +          },
        +          "kind": {
        +            "const": "damageTaken",
        +            "type": "string"
        +          },
        +          "move": {
        +            "description": "The move that hit it.",
        +            "type": "string"
        +          },
        +          "percentTaken": {
        +            "description": "Damage it took, as a percentage of its own HP.",
        +            "type": "number"
        +          }
        +        },
        +        "required": [
        +          "kind",
        +          "move",
        +          "attacker",
        +          "percentTaken"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "properties": {
        +          "ability": {
        +            "description": "An ability it is known to have.",
        +            "type": "string"
        +          },
        +          "kind": {
        +            "const": "ability",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "kind",
        +          "ability"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "properties": {
        +          "item": {
        +            "description": "An item it is known to hold.",
        +            "type": "string"
        +          },
        +          "kind": {
        +            "const": "item",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "kind",
        +          "item"
        +        ],
        +        "type": "object"
        +      }
        +    ]
        +  },
        +  "maxItems": 8,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • addedInput schema / properties / regulation
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Regulation id, e.g. \"m-c\"; scopes which curated meta set anchors the prior.",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Regulation id, e.g. \"m-c\"; scopes the meta prior for the inference.",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedInput schema / properties / species
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The opponent’s species as observed, e.g. \"Sneasler\", \"Salamence-Mega\"; resolves case- and punctuation-insensitively.",
        +      "type": "string"
        +    },
        +    {
        +      "description": "The opponent species to scout, e.g. \"Sneasler\"; must appear on the opposing side of the log.",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedInput schema / properties / team
        Added value: +{
        +  "description": "Your team with its real sets — the Speed reference and the attackers’ damage math need them.",
        +  "items": {
        +    "properties": {
        +      "ability": {
        +        "description": "Ability, canonical spelling when known.",
        +        "type": "string"
        +      },
        +      "championsPoints": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "Pokémon Champions stat points keyed by stat id, 0-32 each, 66 total; present when the spread was parsed as point-scale — values that all fit 0-32 and total at most 66, or an explicit SP line.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "evs": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "EVs keyed by stat id, 0-252; present when the spread was parsed as EV-scale.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "item": {
        +        "description": "Held item, canonical spelling when known.",
        +        "type": "string"
        +      },
        +      "ivs": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "IVs from an IVs line, keyed by stat id.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "level": {
        +        "description": "Level when the paste stated one; Champions always plays at 50.",
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "moves": {
        +        "description": "Moves in paste order, canonical spelling when known.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "nature": {
        +        "description": "Nature as supplied.",
        +        "type": "string"
        +      },
        +      "species": {
        +        "description": "Species as the dataset resolves it, e.g. \"Rotom-Wash\", \"Salamence-Mega\"; the spelling supplied is kept when the species is unknown.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "species"
        +    ],
        +    "type": "object"
        +  },
        +  "maxItems": 6,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • addedInput schema / required
        Added value: +[
        +  "mode"
        +]
    • Changedanalyze_meta7 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / properties / detail
        Added value: +{
        +  "description": "How much detail to return: \"compact\" (default) gives conclusions and the numbers needed to reason; \"evidence\" adds ranges, benchmarks and per-row detail; \"debug\" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.",
        +  "enum": [
        +    "compact",
        +    "evidence",
        +    "debug"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / includeRecorded
        Added value: +{
        +  "description": "Also read the local, per-user record of sets the reasoning generated (`record_set`) and return the ones filed under the requested species as `recorded`. They carry no rank, usage share or sample, so they are never merged into the usage-derived fields; a record that named no regulation matches any `regulation` scope. Absent or false, the answer is the measured meta only.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / mode
        Added value: +{
        +  "description": "Which operation to run: \"threats\", \"compare\", \"set\".",
        +  "enum": [
        +    "threats",
        +    "compare",
        +    "set"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / regulation
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Optional regulation set id, e.g. \"m-c\" (matched case- and punctuation-insensitively); omit to list every regulation with its threat count.",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Regulation id, e.g. \"m-c\" (case- and punctuation-insensitive); omitted, the single regulation with history is used.",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Optional regulation set id, e.g. \"m-c\"; omit to search every list.",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedInput schema / properties / species
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "maxItems": 24,
        +      "minItems": 1,
        +      "type": "array"
        +    }
        +  ],
        +  "description": "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."
        +}
      • addedInput schema / required
        Added value: +[
        +  "mode"
        +]
    • Changedanalyze_team9 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / properties / detail
        Added value: +{
        +  "description": "How much detail to return: \"compact\" (default) gives conclusions and the numbers needed to reason; \"evidence\" adds ranges, benchmarks and per-row detail; \"debug\" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.",
        +  "enum": [
        +    "compact",
        +    "evidence",
        +    "debug"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / goal
        Added value: +{
        +  "description": "What the caller is trying to achieve, e.g. \"improve against the current meta\"; carried into the result verbatim, the analysis itself is always meta-coverage-first.",
        +  "type": "string"
        +}
      • addedInput schema / properties / lockedMembers
        Added value: +{
        +  "description": "Species to keep as-is; they are excluded from member-swap suggestions (spread, move and item changes still apply to them).",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / mode
        Added value: +{
        +  "description": "Which operation to run: \"synergy\", \"diagnose\".",
        +  "enum": [
        +    "synergy",
        +    "diagnose"
        +  ],
        +  "type": "string"
        +}
      • 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"
        +}
      • addedInput schema / properties / regulation
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "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.",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Regulation id to diagnose against, e.g. \"m-c\"; omitted, the current set is used.",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedInput schema / properties / team
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Team of up to 6 members, each a species with optional moves and a set.",
        +      "items": {
        +        "properties": {
        +          "championsPoints": {
        +            "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"
        +          },
        +          "evs": {
        +            "additionalProperties": {
        +              "type": "number"
        +            },
        +            "description": "Optional spread in the 0-252 scale; only Speed affects this analysis.",
        +            "propertyNames": {
        +              "type": "string"
        +            },
        +            "type": "object"
        +          },
        +          "item": {
        +            "description": "Optional held item, e.g. \"Choice Scarf\"; Choice Scarf multiplies the member’s Speed by 1.5 in the threat coverage.",
        +            "type": "string"
        +          },
        +          "moves": {
        +            "description": "Optional move names, e.g. [\"Knock Off\"]; their types widen offensive coverage. Unknown names are reported, not fatal.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "nature": {
        +            "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"
        +          },
        +          "species": {
        +            "description": "Species name as it appears in Showdown, e.g. \"Incineroar\", \"Garchomp\".",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "species"
        +        ],
        +        "type": "object"
        +      },
        +      "maxItems": 6,
        +      "minItems": 1,
        +      "type": "array"
        +    },
        +    {
        +      "description": "The team to diagnose, in the canonical shape `parse_team` returns: species with optional moves, ability, nature, evs or championsPoints, and item.",
        +      "items": {
        +        "properties": {
        +          "ability": {
        +            "description": "Ability, canonical spelling when known.",
        +            "type": "string"
        +          },
        +          "championsPoints": {
        +            "additionalProperties": {
        +              "type": "number"
        +            },
        +            "description": "Pokémon Champions stat points keyed by stat id, 0-32 each, 66 total; present when the spread was parsed as point-scale — values that all fit 0-32 and total at most 66, or an explicit SP line.",
        +            "propertyNames": {
        +              "type": "string"
        +            },
        +            "type": "object"
        +          },
        +          "evs": {
        +            "additionalProperties": {
        +              "type": "number"
        +            },
        +            "description": "EVs keyed by stat id, 0-252; present when the spread was parsed as EV-scale.",
        +            "propertyNames": {
        +              "type": "string"
        +            },
        +            "type": "object"
        +          },
        +          "item": {
        +            "description": "Held item, canonical spelling when known.",
        +            "type": "string"
        +          },
        +          "ivs": {
        +            "additionalProperties": {
        +              "type": "number"
        +            },
        +            "description": "IVs from an IVs line, keyed by stat id.",
        +            "propertyNames": {
        +              "type": "string"
        +            },
        +            "type": "object"
        +          },
        +          "level": {
        +            "description": "Level when the paste stated one; Champions always plays at 50.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "moves": {
        +            "description": "Moves in paste order, canonical spelling when known.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "nature": {
        +            "description": "Nature as supplied.",
        +            "type": "string"
        +          },
        +          "species": {
        +            "description": "Species as the dataset resolves it, e.g. \"Rotom-Wash\", \"Salamence-Mega\"; the spelling supplied is kept when the species is unknown.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "species"
        +        ],
        +        "type": "object"
        +      },
        +      "maxItems": 6,
        +      "minItems": 1,
        +      "type": "array"
        +    }
        +  ]
        +}
      • addedInput schema / required
        Added value: +[
        +  "mode"
        +]
    • Changedcalculate23 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / properties / ability
        Added value: +{
        +  "description": "Ability assumed active while solving, e.g. \"Intimidate\", \"Protosynthesis\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / attacker
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The attacking Pokémon: species plus optional level, nature, IVs, EVs, item, ability, boosts, status, and current HP.",
        +      "properties": {
        +        "ability": {
        +          "description": "Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability.",
        +          "type": "string"
        +        },
        +        "abilityOn": {
        +          "description": "Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc.",
        +          "type": "boolean"
        +        },
        +        "boosts": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "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).",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "championsPoints": {
        +          "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"
        +        },
        +        "curHP": {
        +          "description": "Current HP when entering damaged, e.g. 120; defaults to full HP.",
        +          "type": "number"
        +        },
        +        "evs": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "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.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "item": {
        +          "description": "Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect.",
        +          "type": "string"
        +        },
        +        "ivs": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "level": {
        +          "description": "Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools.",
        +          "maximum": 100,
        +          "minimum": 1,
        +          "type": "integer"
        +        },
        +        "moves": {
        +          "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "nature": {
        +          "description": "Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted.",
        +          "type": "string"
        +        },
        +        "species": {
        +          "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        +          "type": "string"
        +        },
        +        "status": {
        +          "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "species"
        +      ],
        +      "type": "object"
        +    },
        +    {
        +      "description": "The single attacking Pokémon; set `moves` to let the tool choose the best move against each defender.",
        +      "properties": {
        +        "ability": {
        +          "description": "Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability.",
        +          "type": "string"
        +        },
        +        "abilityOn": {
        +          "description": "Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc.",
        +          "type": "boolean"
        +        },
        +        "boosts": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "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).",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "championsPoints": {
        +          "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"
        +        },
        +        "curHP": {
        +          "description": "Current HP when entering damaged, e.g. 120; defaults to full HP.",
        +          "type": "number"
        +        },
        +        "evs": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "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.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "item": {
        +          "description": "Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect.",
        +          "type": "string"
        +        },
        +        "ivs": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "level": {
        +          "description": "Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools.",
        +          "maximum": 100,
        +          "minimum": 1,
        +          "type": "integer"
        +        },
        +        "moves": {
        +          "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "nature": {
        +          "description": "Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted.",
        +          "type": "string"
        +        },
        +        "species": {
        +          "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        +          "type": "string"
        +        },
        +        "status": {
        +          "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "species"
        +      ],
        +      "type": "object"
        +    }
        +  ]
        +}
      • addedInput schema / properties / boosts
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "Stat stages; only `spe` (-6..+6) is applied, e.g. { spe: 1 } for a +1 Speed stage.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / championsPoints
        Added value: +{
        +  "anyOf": [
        +    {
        +      "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"
        +    },
        +    {
        +      "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"
        +    }
        +  ]
        +}
      • addedInput schema / properties / defender
        Added value: +{
        +  "description": "The defending Pokémon, same fields as `attacker`; its Defense/SpD, HP, typing, and ability drive the result.",
        +  "properties": {
        +    "ability": {
        +      "description": "Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability.",
        +      "type": "string"
        +    },
        +    "abilityOn": {
        +      "description": "Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc.",
        +      "type": "boolean"
        +    },
        +    "boosts": {
        +      "additionalProperties": {
        +        "type": "number"
        +      },
        +      "description": "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).",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "championsPoints": {
        +      "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"
        +    },
        +    "curHP": {
        +      "description": "Current HP when entering damaged, e.g. 120; defaults to full HP.",
        +      "type": "number"
        +    },
        +    "evs": {
        +      "additionalProperties": {
        +        "type": "number"
        +      },
        +      "description": "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.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "item": {
        +      "description": "Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect.",
        +      "type": "string"
        +    },
        +    "ivs": {
        +      "additionalProperties": {
        +        "type": "number"
        +      },
        +      "description": "IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "level": {
        +      "description": "Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools.",
        +      "maximum": 100,
        +      "minimum": 1,
        +      "type": "integer"
        +    },
        +    "moves": {
        +      "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "nature": {
        +      "description": "Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted.",
        +      "type": "string"
        +    },
        +    "species": {
        +      "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        +      "type": "string"
        +    },
        +    "status": {
        +      "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "species"
        +  ],
        +  "type": "object"
        +}
      • addedInput schema / properties / defenders
        Added value: +{
        +  "description": "1-30 defender sets, each with the same fields as `attacker`; every entry is scored against the same attacker, move set, and field.",
        +  "items": {
        +    "properties": {
        +      "ability": {
        +        "description": "Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability.",
        +        "type": "string"
        +      },
        +      "abilityOn": {
        +        "description": "Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc.",
        +        "type": "boolean"
        +      },
        +      "boosts": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "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).",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "championsPoints": {
        +        "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"
        +      },
        +      "curHP": {
        +        "description": "Current HP when entering damaged, e.g. 120; defaults to full HP.",
        +        "type": "number"
        +      },
        +      "evs": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "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.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "item": {
        +        "description": "Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect.",
        +        "type": "string"
        +      },
        +      "ivs": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "level": {
        +        "description": "Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools.",
        +        "maximum": 100,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "moves": {
        +        "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "nature": {
        +        "description": "Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted.",
        +        "type": "string"
        +      },
        +      "species": {
        +        "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "species"
        +    ],
        +    "type": "object"
        +  },
        +  "maxItems": 30,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • addedInput schema / properties / detail
        Added value: +{
        +  "description": "How much detail to return: \"compact\" (default) gives conclusions and the numbers needed to reason; \"evidence\" adds ranges, benchmarks and per-row detail; \"debug\" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.",
        +  "enum": [
        +    "compact",
        +    "evidence",
        +    "debug"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / evs
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": {
        +        "type": "number"
        +      },
        +      "description": "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.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    {
        +      "additionalProperties": {
        +        "type": "number"
        +      },
        +      "description": "EVs keyed by stat id; only `spe` (0-252) changes the result, e.g. { spe: 252 }.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    }
        +  ]
        +}
      • addedInput schema / properties / field
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Battlefield conditions applied to the calc; omit it for a neutral Singles field with no weather, terrain, or hazards.",
        +      "properties": {
        +        "attackerSide": {
        +          "additionalProperties": {},
        +          "description": "Attacker-side flags, e.g. { isHelpingHand: true, isTailwind: true, spikes: 2 }.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "defenderSide": {
        +          "additionalProperties": {},
        +          "description": "Defender-side flags, e.g. { isReflect: true, isLightScreen: true, isAuroraVeil: true, isSR: true }.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "gameType": {
        +          "description": "Doubles spreads damage across targets; default Singles.",
        +          "enum": [
        +            "Singles",
        +            "Doubles"
        +          ],
        +          "type": "string"
        +        },
        +        "terrain": {
        +          "description": "Terrain: \"Electric\", \"Grassy\", \"Psychic\", or \"Misty\"; default none.",
        +          "type": "string"
        +        },
        +        "weather": {
        +          "description": "Weather: \"Sand\", \"Sun\", \"Rain\", \"Hail\", \"Snow\", \"Harsh Sunshine\", \"Heavy Rain\", or \"Strong Winds\"; default none.",
        +          "type": "string"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    {
        +      "description": "Shared battlefield conditions for every matchup; omit for a neutral Singles field. Side hazards and screens are only available on `calculate_damage`.",
        +      "properties": {
        +        "gameType": {
        +          "description": "Doubles spreads damage across targets; default Singles.",
        +          "enum": [
        +            "Singles",
        +            "Doubles"
        +          ],
        +          "type": "string"
        +        },
        +        "terrain": {
        +          "description": "Terrain: \"Electric\", \"Grassy\", \"Psychic\", or \"Misty\"; default none.",
        +          "type": "string"
        +        },
        +        "weather": {
        +          "description": "Weather: \"Sand\", \"Sun\", \"Rain\", \"Hail\", \"Snow\", \"Harsh Sunshine\", \"Heavy Rain\", or \"Strong Winds\"; default none.",
        +          "type": "string"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    {
        +      "description": "Battlefield conditions applied while testing the survive and kill goals; omit for a neutral Singles field.",
        +      "properties": {
        +        "gameType": {
        +          "description": "Doubles spreads damage across targets; default Singles.",
        +          "enum": [
        +            "Singles",
        +            "Doubles"
        +          ],
        +          "type": "string"
        +        },
        +        "terrain": {
        +          "description": "Terrain for the survive/kill calcs: \"Electric\", \"Grassy\", \"Psychic\", or \"Misty\"; default none.",
        +          "type": "string"
        +        },
        +        "weather": {
        +          "description": "Weather for the survive/kill calcs, e.g. \"Sun\", \"Rain\", \"Sand\"; default none.",
        +          "type": "string"
        +        }
        +      },
        +      "type": "object"
        +    }
        +  ]
        +}
      • addedInput schema / properties / item
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Held item, e.g. \"Choice Scarf\"; only Choice Scarf multiplies Speed (×1.5), other items are listed as speed-neutral.",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Item held while solving, e.g. \"Assault Vest\"; it changes the bulk or Speed the goals are tested against.",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedInput schema / properties / ivs
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": {
        +        "type": "number"
        +      },
        +      "description": "IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    {
        +      "additionalProperties": {
        +        "type": "number"
        +      },
        +      "description": "IVs keyed by stat id; only `spe` (0-31) changes the result, and it defaults to 31.",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    {
        +      "additionalProperties": {
        +        "type": "number"
        +      },
        +      "description": "IVs to hold fixed while searching, keyed by stat id; omitted stats default to 31 (use 0 for a Trick Room Speed IV).",
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    }
        +  ]
        +}
      • addedInput schema / properties / kill
        Added value: +{
        +  "description": "Add a KO goal: minimizes Atk or SpA so that even the lowest damage roll reaches the per-hit HP threshold.",
        +  "properties": {
        +    "hits": {
        +      "default": 1,
        +      "description": "Number of hits the move must KO in, 1-4 (default 1); each hit must reach target max HP / hits.",
        +      "maximum": 4,
        +      "minimum": 1,
        +      "type": "integer"
        +    },
        +    "move": {
        +      "description": "Move used for the KO, e.g. \"Knock Off\"; its category decides whether Atk or SpA EVs are minimized.",
        +      "type": "string"
        +    },
        +    "target": {
        +      "description": "The defender that must be KOed, including its bulk EVs, item, and ability; give it the same `level` as the optimized Pokémon, since a nested set defaults to level 100.",
        +      "properties": {
        +        "ability": {
        +          "description": "Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability.",
        +          "type": "string"
        +        },
        +        "abilityOn": {
        +          "description": "Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc.",
        +          "type": "boolean"
        +        },
        +        "boosts": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "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).",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "championsPoints": {
        +          "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"
        +        },
        +        "curHP": {
        +          "description": "Current HP when entering damaged, e.g. 120; defaults to full HP.",
        +          "type": "number"
        +        },
        +        "evs": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "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.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "item": {
        +          "description": "Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect.",
        +          "type": "string"
        +        },
        +        "ivs": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "level": {
        +          "description": "Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools.",
        +          "maximum": 100,
        +          "minimum": 1,
        +          "type": "integer"
        +        },
        +        "moves": {
        +          "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "nature": {
        +          "description": "Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted.",
        +          "type": "string"
        +        },
        +        "species": {
        +          "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        +          "type": "string"
        +        },
        +        "status": {
        +          "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "species"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "target",
        +    "move"
        +  ],
        +  "type": "object"
        +}
      • addedInput schema / properties / level
        Added value: +{
        +  "anyOf": [
        +    {
        +      "default": 50,
        +      "description": "Level 1-100; default 50.",
        +      "maximum": 100,
        +      "minimum": 1,
        +      "type": "integer"
        +    },
        +    {
        +      "default": 50,
        +      "description": "Level 1-100; default 50, matching VGC play.",
        +      "maximum": 100,
        +      "minimum": 1,
        +      "type": "integer"
        +    },
        +    {
        +      "default": 50,
        +      "description": "Level 1-100; default 50 (VGC), where bulk and Speed benchmarks are tightest.",
        +      "maximum": 100,
        +      "minimum": 1,
        +      "type": "integer"
        +    }
        +  ]
        +}
      • addedInput schema / properties / maximize
        Added value: +{
        +  "default": "spe",
        +  "description": "Stat that receives leftover EVs after the goals are met, capped at 252 (default spe); EVs are added in steps of 4.",
        +  "enum": [
        +    "atk",
        +    "spa",
        +    "spe",
        +    "hp",
        +    "def",
        +    "spd"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / mode
        Added value: +{
        +  "description": "Which operation to run: \"stats\", \"damage\", \"matchups\", \"speed\", \"optimize_evs\".",
        +  "enum": [
        +    "stats",
        +    "damage",
        +    "matchups",
        +    "speed",
        +    "optimize_evs"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / move
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Move used by the attacker, e.g. \"Earthquake\", \"Make It Rain\"; must be a real move name.",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Pin the matchup to this one move, e.g. \"Close Combat\"; when omitted, `attacker.moves` is searched instead.",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedInput schema / properties / nature
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Nature name, e.g. \"Jolly\", \"Modest\"; default Serious (raises and lowers nothing).",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Nature name, e.g. \"Jolly\", \"Timid\"; default Serious (neutral Speed).",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Nature used for every stat calculation, e.g. \"Adamant\", \"Calm\"; default Serious. Change it to trade one stat for another.",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedInput schema / properties / outspeed
        Added value: +{
        +  "description": "Add an outspeed goal: supply `target` or `speed` (one is required here, otherwise that goal errors).",
        +  "properties": {
        +    "speed": {
        +      "description": "Raw Speed number to beat when there is no full target set, e.g. 189.",
        +      "maximum": 9007199254740991,
        +      "minimum": 1,
        +      "type": "integer"
        +    },
        +    "target": {
        +      "description": "Set to outspeed, e.g. {\"species\": \"Dragapult\", \"nature\": \"Jolly\", \"evs\": {\"spe\": 252}}; its computed Speed becomes the benchmark. Give it the same `level` as the optimized Pokémon, since a nested set defaults to level 100.",
        +      "properties": {
        +        "ability": {
        +          "description": "Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability.",
        +          "type": "string"
        +        },
        +        "abilityOn": {
        +          "description": "Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc.",
        +          "type": "boolean"
        +        },
        +        "boosts": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "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).",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "championsPoints": {
        +          "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"
        +        },
        +        "curHP": {
        +          "description": "Current HP when entering damaged, e.g. 120; defaults to full HP.",
        +          "type": "number"
        +        },
        +        "evs": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "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.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "item": {
        +          "description": "Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect.",
        +          "type": "string"
        +        },
        +        "ivs": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "level": {
        +          "description": "Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools.",
        +          "maximum": 100,
        +          "minimum": 1,
        +          "type": "integer"
        +        },
        +        "moves": {
        +          "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "nature": {
        +          "description": "Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted.",
        +          "type": "string"
        +        },
        +        "species": {
        +          "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        +          "type": "string"
        +        },
        +        "status": {
        +          "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "species"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / regulation
        Added value: +{
        +  "description": "Regulation Set name or id from `list_regulations` to compare against, e.g. \"Regulation Set G\"; omit to get the raw Speed only.",
        +  "type": "string"
        +}
      • addedInput schema / properties / species
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Species or form name, e.g. \"Dragapult\", \"Ogerpon-Wellspring\".",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Species or form name to optimize, e.g. \"Garchomp\", \"Incineroar\".",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedInput schema / properties / survive
        Added value: +{
        +  "description": "Add a \"always live this hit\" goal: the search minimizes HP plus the relevant Defense EVs that keep the worst roll below max HP.",
        +  "properties": {
        +    "attacker": {
        +      "description": "The attacker whose move must be survived; the calc picks Defense or SpD from the move’s category. Set its `level` to match the optimized Pokémon’s, since a nested set defaults to level 100.",
        +      "properties": {
        +        "ability": {
        +          "description": "Ability name, e.g. \"Intimidate\", \"Protosynthesis\"; defaults to the species’ default ability.",
        +          "type": "string"
        +        },
        +        "abilityOn": {
        +          "description": "Force the ability on (true) or off (false), e.g. to compare Protosynthesis active vs not; omitted leaves it to the calc.",
        +          "type": "boolean"
        +        },
        +        "boosts": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "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).",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "championsPoints": {
        +          "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"
        +        },
        +        "curHP": {
        +          "description": "Current HP when entering damaged, e.g. 120; defaults to full HP.",
        +          "type": "number"
        +        },
        +        "evs": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "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.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "item": {
        +          "description": "Held item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\"; the calc applies its damage, Speed, or bulk effect.",
        +          "type": "string"
        +        },
        +        "ivs": {
        +          "additionalProperties": {
        +            "type": "number"
        +          },
        +          "description": "IVs keyed by stat id (hp, atk, def, spa, spd, spe), each 0-31; omitted stats default to 31.",
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "level": {
        +          "description": "Level 1-100; defaults to 100 in the damage tools and 50 in the stat/speed tools.",
        +          "maximum": 100,
        +          "minimum": 1,
        +          "type": "integer"
        +        },
        +        "moves": {
        +          "description": "Moveset names, e.g. [\"Earthquake\", \"Dragon Claw\"]; used by `calculate_matchups` to pick the hardest-hitting move per defender.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "nature": {
        +          "description": "Nature name, e.g. \"Jolly\", \"Modest\", \"Adamant\"; defaults to Serious (neutral) when omitted.",
        +          "type": "string"
        +        },
        +        "species": {
        +          "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        +          "type": "string"
        +        },
        +        "status": {
        +          "description": "Pre-existing status such as \"brn\", \"par\", or \"tox\"; burn halves physical damage, paralysis cuts Speed.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "species"
        +      ],
        +      "type": "object"
        +    },
        +    "move": {
        +      "description": "Move being survived, e.g. \"Close Combat\"; a valid move name is required.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "attacker",
        +    "move"
        +  ],
        +  "type": "object"
        +}
      • addedInput schema / required
        Added value: +[
        +  "mode"
        +]
    • Changedlookup16 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / properties / ability
        Added value: +{
        +  "description": "Ability name, e.g. \"Intimidate\", \"Protosynthesis\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / attacker
        Added value: +{
        +  "description": "Attacking type name; omit to read the chart from the defender's side or to get the full matrix.",
        +  "type": "string"
        +}
      • addedInput schema / properties / defender
        Added value: +{
        +  "description": "Defending type or species name; a species contributes its types.",
        +  "type": "string"
        +}
      • addedInput schema / properties / detail
        Added value: +{
        +  "description": "How much detail to return: \"compact\" (default) gives conclusions and the numbers needed to reason; \"evidence\" adds ranges, benchmarks and per-row detail; \"debug\" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.",
        +  "enum": [
        +    "compact",
        +    "evidence",
        +    "debug"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / item
        Added value: +{
        +  "description": "Item name, e.g. \"Choice Band\", \"Assault Vest\", \"Leftovers\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / kind
        Added value: +{
        +  "default": "species",
        +  "description": "Table to search; one per call (default \"species\").",
        +  "enum": [
        +    "species",
        +    "move",
        +    "item",
        +    "ability",
        +    "nature"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "default": 20,
        +  "description": "Maximum results returned, 1-100 (default 20).",
        +  "maximum": 100,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / mode
        Added value: +{
        +  "description": "Which operation to run: \"species\", \"forms\", \"search\", \"move\", \"item\", \"ability\", \"nature\", \"learnset\", \"type\", \"matchup\", \"sprites\".",
        +  "enum": [
        +    "species",
        +    "forms",
        +    "search",
        +    "move",
        +    "item",
        +    "ability",
        +    "nature",
        +    "learnset",
        +    "type",
        +    "matchup",
        +    "sprites"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / move
        Added value: +{
        +  "description": "Move name, e.g. \"Earthquake\", \"Make It Rain\", \"Dragon Claw\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / nature
        Added value: +{
        +  "description": "Nature name, e.g. \"Jolly\", \"Timid\", \"Impish\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / query
        Added value: +{
        +  "description": "Substring to match against name and Showdown id, e.g. \"oger\", \"sword\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / size
        Added value: +{
        +  "description": "Which image the URLs point at: \"artwork\" (default) is the 475×475 transparent official art, \"icon\" is the 96×96 game sprite for a compact row.",
        +  "enum": [
        +    "artwork",
        +    "icon"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / species
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\", \"Rotom-Wash\".",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Base species to expand, e.g. \"Rotom\", \"Ogerpon\", \"Gholdengo\".",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Species or form name, e.g. \"Garchomp\", \"Ogerpon-Wellspring\".",
        +      "type": "string"
        +    },
        +    {
        +      "description": "Species names, e.g. [\"Garchomp\", \"Rotom-Wash\", \"Salamence-Mega\"], in any order; a whole team is the expected payload.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "maxItems": 30,
        +      "minItems": 1,
        +      "type": "array"
        +    }
        +  ]
        +}
      • addedInput schema / properties / type
        Added value: +{
        +  "description": "Type name, e.g. \"Steel\", \"Fairy\", \"Ground\".",
        +  "type": "string"
        +}
      • addedInput schema / required
        Added value: +[
        +  "mode"
        +]
    • Changedoptimize_team1 field changed
      • removedInput schema / properties / team / items / properties / teraType
        Removed value: -{
        -  "description": "Tera Type carried verbatim from a Showdown paste; Champions math ignores it.",
        -  "type": "string"
        -}
    • Changedprepare_matchup2 fields changed
      • changedInput schema / properties / opponent / items / anyOf
        Previous value: -[
        -  {
        -    "description": "A species name, e.g. \"Sneasler\", \"Salamence-Mega\".",
        -    "type": "string"
        -  },
        -  {
        -    "properties": {
        -      "ability": {
        -        "description": "Ability, canonical spelling when known.",
        -        "type": "string"
        -      },
        -      "championsPoints": {
        -        "additionalProperties": {
        -          "type": "number"
        -        },
        -        "description": "Pokémon Champions stat points keyed by stat id, 0-32 each, 66 total; present when the spread was parsed as point-scale — values that all fit 0-32 and total at most 66, or an explicit SP line.",
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "evs": {
        -        "additionalProperties": {
        -          "type": "number"
        -        },
        -        "description": "EVs keyed by stat id, 0-252; present when the spread was parsed as EV-scale.",
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "item": {
        -        "description": "Held item, canonical spelling when known.",
        -        "type": "string"
        -      },
        -      "ivs": {
        -        "additionalProperties": {
        -          "type": "number"
        -        },
        -        "description": "IVs from an IVs line, keyed by stat id.",
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "level": {
        -        "description": "Level when the paste stated one; Champions always plays at 50.",
        -        "maximum": 9007199254740991,
        -        "minimum": -9007199254740991,
        -        "type": "integer"
        -      },
        -      "moves": {
        -        "description": "Moves in paste order, canonical spelling when known.",
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      },
        -      "nature": {
        -        "description": "Nature as supplied.",
        -        "type": "string"
        -      },
        -      "species": {
        -        "description": "Species as the dataset resolves it, e.g. \"Rotom-Wash\", \"Salamence-Mega\"; the spelling supplied is kept when the species is unknown.",
        -        "type": "string"
        -      },
        -      "teraType": {
        -        "description": "Tera Type carried verbatim from a Showdown paste; Champions math ignores it.",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "species"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "description": "A species name, e.g. \"Sneasler\", \"Salamence-Mega\".",
        +    "type": "string"
        +  },
        +  {
        +    "properties": {
        +      "ability": {
        +        "description": "Ability, canonical spelling when known.",
        +        "type": "string"
        +      },
        +      "championsPoints": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "Pokémon Champions stat points keyed by stat id, 0-32 each, 66 total; present when the spread was parsed as point-scale — values that all fit 0-32 and total at most 66, or an explicit SP line.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "evs": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "EVs keyed by stat id, 0-252; present when the spread was parsed as EV-scale.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "item": {
        +        "description": "Held item, canonical spelling when known.",
        +        "type": "string"
        +      },
        +      "ivs": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "description": "IVs from an IVs line, keyed by stat id.",
        +        "propertyNames": {
        +          "type": "string"
        +        },
        +        "type": "object"
        +      },
        +      "level": {
        +        "description": "Level when the paste stated one; Champions always plays at 50.",
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "moves": {
        +        "description": "Moves in paste order, canonical spelling when known.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "nature": {
        +        "description": "Nature as supplied.",
        +        "type": "string"
        +      },
        +      "species": {
        +        "description": "Species as the dataset resolves it, e.g. \"Rotom-Wash\", \"Salamence-Mega\"; the spelling supplied is kept when the species is unknown.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "species"
        +    ],
        +    "type": "object"
        +  }
        +]
      • removedInput schema / properties / team / items / properties / teraType
        Removed value: -{
        -  "description": "Tera Type carried verbatim from a Showdown paste; Champions math ignores it.",
        -  "type": "string"
        -}
    • Addedrecord_set
    • Changedteam_io8 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / properties / detail
        Added value: +{
        +  "description": "How much detail to return: \"compact\" (default) gives conclusions and the numbers needed to reason; \"evidence\" adds ranges, benchmarks and per-row detail; \"debug\" adds provenance and every intermediate. Ask for more only when the reasoning actually needs it — model context is the expensive resource.",
        +  "enum": [
        +    "compact",
        +    "evidence",
        +    "debug"
        +  ],
        +  "type": "string"
        +}
      • 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"
        +}
      • addedInput schema / properties / mode
        Added value: +{
        +  "description": "Which operation to run: \"parse\", \"format\", \"legality\", \"regulation\", \"regulations\".",
        +  "enum": [
        +    "parse",
        +    "format",
        +    "legality",
        +    "regulation",
        +    "regulations"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / regulation
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "Optional regulation id (e.g. \"m-c\") to check species legality against; illegal species become warnings, the team is still returned.",
        +      "type": "string"
        +    },
        +    {
        +      "description": "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.",
        +      "type": "string"
        +    },
        +    {
        +      "description": "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.",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedInput schema / properties / team
        Added value: +{
        +  "anyOf": [
        +    {
        +      "description": "The team to render, in the canonical shape `parse_team` and the analysis tools use: species with optional item, ability, nature, level, ivs, evs or championsPoints, and moves.",
        +      "items": {
        +        "properties": {
        +          "ability": {
        +            "description": "Ability, canonical spelling when known.",
        +            "type": "string"
        +          },
        +          "championsPoints": {
        +            "additionalProperties": {
        +              "type": "number"
        +            },
        +            "description": "Pokémon Champions stat points keyed by stat id, 0-32 each, 66 total; present when the spread was parsed as point-scale — values that all fit 0-32 and total at most 66, or an explicit SP line.",
        +            "propertyNames": {
        +              "type": "string"
        +            },
        +            "type": "object"
        +          },
        +          "evs": {
        +            "additionalProperties": {
        +              "type": "number"
        +            },
        +            "description": "EVs keyed by stat id, 0-252; present when the spread was parsed as EV-scale.",
        +            "propertyNames": {
        +              "type": "string"
        +            },
        +            "type": "object"
        +          },
        +          "item": {
        +            "description": "Held item, canonical spelling when known.",
        +            "type": "string"
        +          },
        +          "ivs": {
        +            "additionalProperties": {
        +              "type": "number"
        +            },
        +            "description": "IVs from an IVs line, keyed by stat id.",
        +            "propertyNames": {
        +              "type": "string"
        +            },
        +            "type": "object"
        +          },
        +          "level": {
        +            "description": "Level when the paste stated one; Champions always plays at 50.",
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          "moves": {
        +            "description": "Moves in paste order, canonical spelling when known.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "nature": {
        +            "description": "Nature as supplied.",
        +            "type": "string"
        +          },
        +          "species": {
        +            "description": "Species as the dataset resolves it, e.g. \"Rotom-Wash\", \"Salamence-Mega\"; the spelling supplied is kept when the species is unknown.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "species"
        +        ],
        +        "type": "object"
        +      },
        +      "maxItems": 6,
        +      "minItems": 1,
        +      "type": "array"
        +    },
        +    {
        +      "description": "Team members, 1-6 of them; a VGC Battle Team must be exactly 6, so any other length adds a team-size violation.",
        +      "items": {
        +        "properties": {
        +          "item": {
        +            "description": "Held item; a duplicate across the team is an Item Clause violation and an unknown item is reported as a violation.",
        +            "type": "string"
        +          },
        +          "moves": {
        +            "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"
        +          },
        +          "species": {
        +            "description": "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.",
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "species"
        +        ],
        +        "type": "object"
        +      },
        +      "maxItems": 6,
        +      "minItems": 1,
        +      "type": "array"
        +    }
        +  ]
        +}
      • addedInput schema / properties / text
        Added value: +{
        +  "description": "The team text: one Showdown-format block per Pokémon, separated by blank lines, or one shorthand line per Pokémon with pipe-separated fields.",
        +  "type": "string"
        +}
      • addedInput schema / required
        Added value: +[
        +  "mode"
        +]
  3. 28 tool updatesv6.2.2
    • Addedanalyze_battle
    • Addedanalyze_meta
    • Changedanalyze_team6 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / properties / opponent
        Removed 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"
        -}
      • removedInput schema / properties / regulation
        Removed value: -{
        -  "description": "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.",
        -  "type": "string"
        -}
      • removedInput schema / properties / team
        Removed value: -{
        -  "description": "Team of up to 6 members, each a species with optional moves and a set.",
        -  "items": {
        -    "properties": {
        -      "championsPoints": {
        -        "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"
        -      },
        -      "evs": {
        -        "additionalProperties": {
        -          "type": "number"
        -        },
        -        "description": "Optional spread in the 0-252 scale; only Speed affects this analysis.",
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "item": {
        -        "description": "Optional held item, e.g. \"Choice Scarf\"; Choice Scarf multiplies the member’s Speed by 1.5 in the threat coverage.",
        -        "type": "string"
        -      },
        -      "moves": {
        -        "description": "Optional move names, e.g. [\"Knock Off\"]; their types widen offensive coverage. Unknown names are reported, not fatal.",
        -        "items": {
        -          "type": "string"
        -        },
        -        "type": "array"
        -      },
        -      "nature": {
        -        "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"
        -      },
        -      "species": {
        -        "description": "Species name as it appears in Showdown, e.g. \"Incineroar\", \"Garchomp\".",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "species"
        -    ],
        -    "type": "object"
        -  },
        -  "maxItems": 6,
        -  "minItems": 1,
        -  "type": "array"
        -}
      • removedInput schema / required
        Removed value: -[
        -  "team"
        -]
      • changedOutput schema / (root)
        Previous 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"
        -    },
        -    "bringFour": {
        -      "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"
        -    },
        -    "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.",
        -      "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 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 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.",
        -          "maximum": 9007199254740991,
        -          "minimum": -9007199254740991,
        -          "type": "integer"
        -        },
        -        "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"
        -        },
        -        "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"
        -          },
        -          "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"
        -    },
        -    "threatCoverage": {
        -      "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": {
        -        "fastestSpeed": {
        -          "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"
        -        },
        -        "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"
        -              },
        -              "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 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",
        -              "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",
        -        "fastestSpeed",
        -        "threats",
        -        "unanswered",
        -        "unansweredCount",
        -        "note"
        -      ],
        -      "type": "object"
        -    },
        -    "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"
        -}New value: +null
    • Addedcalculate
    • Removedcalculate_damage
    • Removedcalculate_matchups
    • Removedcalculate_stats
    • Removedcheck_legality
    • Removedcheck_speed
    • Removedget_ability
    • Removedget_item
    • Removedget_learnset
    • Removedget_move
    • Removedget_nature
    • Removedget_pokemon
    • Removedget_regulation
    • Removedget_set
    • Removedget_type
    • Removedget_type_matchup
    • Removedlist_forms
    • Removedlist_regulations
    • Removedlist_threats
    • Addedlookup
    • Removedoptimize_evs
    • Addedoptimize_team
    • Addedprepare_matchup
    • Removedsearch_dex
    • Addedteam_io
  4. 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"
        -}
  5. 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"
        +]
  6. 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
  7. 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"
        +}
  8. 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.1/5.0

Scored across 9 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: lookup for data, calculate for damage/stat calcs, analyze_* for different analysis domains (team, battle, meta), team_io for import/export, optimize_team for building, prepare_matchup for pre-game prep, and record_set for persistence. The mode-based dispatch within each tool keeps sub-functions organized without overlapping across tools.

Naming Consistency4/5

Tool names are consistently lowercase with underscores, mostly verb_noun (analyze_team, optimize_team, prepare_matchup, record_set) but a few are single verbs (lookup, calculate) and one is a noun phrase (team_io). The pattern is predictable and readable, though not perfectly uniform.

Tool Count5/5

9 tools is well within the ideal 3-15 range and each covers a distinct functional area. The scope is well-proportioned for a competitive Pokémon analysis server, with no redundant or trivial tools.

Completeness3/5

The surface covers data lookup, calculations, team/battle/meta analysis, import/export, optimization, matchup prep, and recording sets. However, the description mentions a `get_set` function to read recorded sets, but that tool is not present, leaving a gap in the read path for persisted data. Other minor gaps include no explicit delete or update for recorded sets, but these are less critical.

Maintenance

ActivityMaintained
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
    D
    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