MCP server that wraps pypokedex for PokeAPI. Exposes FastMCP tools for Pokedex lookups and analysis.
DexMCP provides 10 tools with complete input schemas and consistent descriptions. All tools follow verb_noun naming conventions (get_*, explore_*, plan_*, analyze_*, find_, suggest_). Descriptions are generally adequate (100-250 chars), exceeding the baseline minimum. However, several critical issues reduce the score: (1) parameter descriptions are generic and lack constraint details (e.g., 'Pokemon name or national dex number' with no examples of valid formats or range); (2) output schemas are inferred from type hints but not explicitly documented in descriptions; (3) error handling is absent, no guidance on what happens when a Pokemon name is invalid, a game identifier doesn't exist, or an API call fails; (4) parameters accepting free-form strings (e.g., 'game', 'language', 'side', 'variant') lack enum constraints or format specifications; (5) no tool includes retry guidance or error recovery patterns. The codebase shows clean architecture (delegation to helper functions) and proper use of Pydantic models for structured output, which supports good defaults for return types. However, the MCP tool definitions themselves do not document these return types in the descriptions, LLMs must infer them from context.
Summarize defensive type coverage for a roster. Args: names_or_dexes: Pokemon names or dex numbers to analyze. Returns: Coverage report with matchup counts and notable weaknesses.
Retrieve ability details for a Pokemon. Args: name_or_dex: Pokemon name or national dex number. Returns: Ability names and effect text details.
Find wild encounter locations for a Pokemon. Args: name_or_dex: Pokemon name or national dex number. Returns: Encounter locations grouped by version and method.
Summarize breeding details for a Pokemon. Args: name_or_dex: Pokemon name or national dex number. game: Optional game identifier for egg move filtering. Returns: Breeding info including egg groups, hatch steps, and egg moves.
Fetch localized Pokedex flavor text. Args: name_or_dex: Pokemon name or national dex number. language: Language code for flavor text. Returns: Mapping of game version to flavor text.
Free-form string parameters lack enum constraints or format specifications. 'game' accepts any string (e.g., 'scarlet-violet', 'red-blue') with no formal constraint; LLMs may hallucinate invalid game IDs. Same for 'side' (should be enum: ['front', 'back']), 'variant' (should enumerate sprite variants), and 'language' (should enumerate supported language codes). These should be declared as JSON Schema enums.
Parameter descriptions are generic and lack actionable constraint details. E.g., 'Pokemon name or national dex number' does not specify: (1) case sensitivity, (2) whether spaces are allowed, (3) valid dex number range (1-1025), (4) what happens if the identifier is ambiguous. Compare to baseline: 72 chars avg, most A+ tools include format/range. These descriptions should be 80-150 chars and include validation hints.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 64 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 43 | - | v1 |
List the learnset for a Pokemon in a specific game. Args: name_or_dex: Pokemon name or national dex number. game: PokeAPI game identifier (e.g., "scarlet-violet"). Returns: Moves the Pokemon can learn in the requested game.
Fetch a Pokemon summary for the given identifier. Args: name_or_dex: Pokemon name or national dex number. Returns: Summary stats, typing, and measurements for the Pokemon.
Resolve a sprite URL for a Pokemon. Args: name_or_dex: Pokemon name or national dex number. side: Sprite side ("front" or "back"). variant: Sprite variant (e.g., "default", "shiny"). Returns: Sprite URL with the requested side and variant.
Enumerate evolution paths that include the Pokemon. Args: name_or_dex: Pokemon name or national dex number. Returns: Evolution paths and triggers.
Recommend a moveset for a Pokemon in a game. Args: name_or_dex: Pokemon name or national dex number. game: PokeAPI game identifier to scope learnsets. limit: Maximum number of recommendations to return. include_tm: Whether to include TM moves. Returns: Ranked move recommendations based on simple heuristics.
Return types are inferred from type hints (e.g., 'PokemonSummary', 'SpriteURL') but NOT documented in tool descriptions. Baseline: 100% of A+ tools document return types. LLMs cannot reason about what fields to expect or plan downstream calls without explicit documentation. Tool descriptions should include 'Returns: <type name> with fields: [list of key fields].'
No error handling or recovery guidance. Tools do not document what happens when: (1) a Pokemon name is invalid, (2) a game ID doesn't exist in PokeAPI, (3) the API is slow or offline, (4) a language code is unsupported. Baseline: recovery-guide pattern requires 'Try X() instead' or 'Check Y list first.' Current implementation will fail silently with an exception, leaving the LLM no actionable next step.
Parameter 'game' in get_moves, get_breeding_info, suggest_moveset is required but descriptions do not explain how to discover valid game IDs. An LLM has no way to know if 'pokemon-red' or 'red-blue' or 'gen-1' is the correct PokeAPI identifier. Should reference a discovery tool or list common values.
No pagination or result-limiting mechanism. Tools like get_moves could return hundreds of moves; analyze_type_coverage with 50 Pokemon could return massive data. Baseline: paginated results cap at 20-50 items and include total_count or next_cursor. Current implementation offers no limit parameter and no guidance on result size.
Default parameter 'game' in get_breeding_info is null but description says 'Optional game identifier for egg move filtering.' Does null mean 'no filtering' (return all egg groups and moves) or 'error'? Should clarify intent and document the behavior when game is omitted.