Skip to main content
Glama

Pokédex MCP Server

by hollanddd
formatters.ts5.48 kB
/** * Response formatters for MCP tools */ import type { Pokemon, Type, LocationAreaEncounter } from "./client.js"; export interface MCPTextContent { [x: string]: unknown; type: "text"; text: string; _meta?: { [x: string]: unknown } | undefined; } export interface MCPResponse { [x: string]: unknown; content: MCPTextContent[]; _meta?: { [x: string]: unknown } | undefined; structuredContent?: { [x: string]: unknown } | undefined; isError?: boolean | undefined; } /** * Format a Pokemon object into a readable text response */ export function formatPokemon(pokemon: Pokemon): MCPResponse { const stats = pokemon.stats .map((s) => `${s.stat.name}: ${s.base_stat}`) .join(", "); const types = pokemon.types.map((t) => t.type.name).join(", "); const abilities = pokemon.abilities .map((a) => a.is_hidden ? `${a.ability.name} (hidden)` : a.ability.name, ) .join(", "); const artworkUrl = pokemon.sprites.other?.["official-artwork"]?.front_default; return { content: [ { type: "text", text: `**${pokemon.name}** (ID: ${pokemon.id}) Height: ${pokemon.height} decimetres (${(pokemon.height / 10).toFixed(1)}m) Weight: ${pokemon.weight} hectograms (${(pokemon.weight / 10).toFixed(1)}kg) Base Experience: ${pokemon.base_experience || "N/A"} Order: ${pokemon.order || "N/A"} **Types:** ${types} **Abilities:** ${abilities} **Base Stats:** ${stats} **Sprites:** - Default: ${pokemon.sprites.front_default || "N/A"} - Shiny: ${pokemon.sprites.front_shiny || "N/A"} ${artworkUrl ? `- Artwork: ${artworkUrl}` : ""}`, }, ], }; } /** * Format type effectiveness information into a readable text response */ export function formatTypeEffectiveness(effectiveness: { type: Type; strongAgainst: string[]; weakAgainst: string[]; immuneTo: string[]; resistantTo: string[]; vulnerableTo: string[]; }): MCPResponse { const formatList = (list: string[]) => list.length > 0 ? list.join(", ") : "None"; const pokemonList = effectiveness.type.pokemon .slice(0, 10) .map((p) => p.pokemon.name) .join(", "); const moreCount = effectiveness.type.pokemon.length > 10 ? ` and ${effectiveness.type.pokemon.length - 10} more...` : ""; return { content: [ { type: "text", text: `**${effectiveness.type.name.toUpperCase()} Type Effectiveness** **Strong Against (2x damage to):** ${formatList(effectiveness.strongAgainst)} **Weak Against (0.5x damage to):** ${formatList(effectiveness.weakAgainst)} **No Effect Against (0x damage to):** ${formatList(effectiveness.immuneTo)} **Resistant To (0.5x damage from):** ${formatList(effectiveness.resistantTo)} **Vulnerable To (2x damage from):** ${formatList(effectiveness.vulnerableTo)} **Pokémon with this type:** ${pokemonList}${moreCount}`, }, ], }; } /** * Format Pokemon encounters into a readable text response */ export function formatPokemonEncounters( pokemon: Pokemon, encounters: LocationAreaEncounter[] ): MCPResponse { if (encounters.length === 0) { return { content: [ { type: "text", text: `**${pokemon.name}** has no recorded wild encounters. This Pokémon might be: - A starter Pokémon - Obtained through evolution - A legendary/mythical Pokémon - Only available through special events`, }, ], }; } const locationInfo = encounters .map((encounter) => { const locationName = encounter.location_area.name.replace("-", " "); const versions = encounter.version_details .map((vd) => { const encounterMethods = vd.encounter_details .map( (ed) => `${ed.method.name} (Lv.${ed.min_level}-${ed.max_level}, ${ed.chance}% chance)`, ) .join(", "); return `${vd.version.name}: ${encounterMethods}`; }) .join("\n "); return `**${locationName}:**\n ${versions}`; }) .join("\n\n"); return { content: [ { type: "text", text: `**${pokemon.name} Encounter Locations:**\n\n${locationInfo}`, }, ], }; } /** * Format Pokemon search results into a readable text response */ export function formatPokemonSearchResults( query: string, matches: Array<{ name: string; url: string }> ): MCPResponse { if (matches.length === 0) { return { content: [ { type: "text", text: `No Pokémon found matching "${query}". Try a different search term.`, }, ], }; } const resultText = matches .map((p, index) => { const id = p.url.split("/").filter(Boolean).pop(); return `${index + 1}. ${p.name} (ID: ${id})`; }) .join("\n"); return { content: [ { type: "text", text: `**Search results for "${query}":**\n\n${resultText}\n\n*Use fetch_pokemon with any of these names to get detailed information.*`, }, ], }; } /** * Format error messages into MCP response format */ export function formatError(message: string): MCPResponse { return { content: [ { type: "text", text: message, }, ], }; } /** * Format generic error from caught exception */ export function formatCaughtError(error: unknown, context: string): MCPResponse { const message = error instanceof Error ? error.message : String(error); return formatError(`Error ${context}: ${message}`); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hollanddd/pokedex-mcp'

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