Skip to main content
Glama
jpbullalayao

Pokémon VGC Damage Calculator MCP Server

calculator.ts4.36 kB
import { calculate, Pokemon as SmogonPokemon, Move as SmogonMove, Field as SmogonField, Side as SmogonSide, Generations } from '@smogon/calc'; import type { CalculateDamageRequest, CalculateDamageResponse, Pokemon, Move, Field, Side } from './types.js'; const gen = Generations.get(9); function createSmogonPokemon(pokemon: Pokemon): SmogonPokemon { const options: any = { species: pokemon.species, level: pokemon.level ?? 50, }; if (pokemon.ability) options.ability = pokemon.ability; if (pokemon.item) options.item = pokemon.item; if (pokemon.nature) options.nature = pokemon.nature; if (pokemon.status) options.status = pokemon.status; if (pokemon.evs) { options.evs = { hp: pokemon.evs.hp ?? 0, atk: pokemon.evs.atk ?? 0, def: pokemon.evs.def ?? 0, spa: pokemon.evs.spa ?? 0, spd: pokemon.evs.spd ?? 0, spe: pokemon.evs.spe ?? 0, }; } if (pokemon.ivs) { options.ivs = { hp: pokemon.ivs.hp ?? 31, atk: pokemon.ivs.atk ?? 31, def: pokemon.ivs.def ?? 31, spa: pokemon.ivs.spa ?? 31, spd: pokemon.ivs.spd ?? 31, spe: pokemon.ivs.spe ?? 31, }; } if (pokemon.boosts) { options.boosts = { atk: pokemon.boosts.atk ?? 0, def: pokemon.boosts.def ?? 0, spa: pokemon.boosts.spa ?? 0, spd: pokemon.boosts.spd ?? 0, spe: pokemon.boosts.spe ?? 0, }; } try { return new SmogonPokemon(gen, pokemon.species, options); } catch (error) { throw new Error(`Invalid Pokémon: ${pokemon.species}. ${error instanceof Error ? error.message : String(error)}`); } } function createSmogonMove(move: Move): SmogonMove { const options: any = {}; if (move.isCrit) options.isCrit = true; try { return new SmogonMove(gen, move.name, options); } catch (error) { throw new Error(`Invalid move: ${move.name}. ${error instanceof Error ? error.message : String(error)}`); } } function createSmogonSide(side?: Side): SmogonSide { const options: any = {}; if (side) { if (side.isSR) options.isSR = true; if (side.spikes && side.spikes > 0) options.spikes = side.spikes; if (side.isLightScreen) options.isLightScreen = true; if (side.isReflect) options.isReflect = true; } return new SmogonSide(options); } function createSmogonField(field: Field): SmogonField { const options: any = {}; if (field.gameType) options.gameType = field.gameType; if (field.weather) options.weather = field.weather; if (field.terrain) options.terrain = field.terrain; if (field.isBeadsOfRuin) options.isBeadsOfRuin = true; if (field.isTabletsOfRuin) options.isTabletsOfRuin = true; if (field.isSwordOfRuin) options.isSwordOfRuin = true; if (field.isVesselOfRuin) options.isVesselOfRuin = true; options.attackerSide = createSmogonSide(field.attackerSide); options.defenderSide = createSmogonSide(field.defenderSide); return new SmogonField(options); } export function calculateDamage(request: CalculateDamageRequest): CalculateDamageResponse { try { // Validate required fields if (!request.attacker?.species) { throw new Error("Attacker species is required"); } if (!request.defender?.species) { throw new Error("Defender species is required"); } if (!request.move?.name) { throw new Error("Move name is required"); } const attacker = createSmogonPokemon(request.attacker); const defender = createSmogonPokemon(request.defender); const move = createSmogonMove(request.move); const field = createSmogonField(request.field); const result = calculate(gen, attacker, defender, move, field); let damageRange: [number, number]; if (result.damage) { if (Array.isArray(result.damage)) { const damageArray = result.damage as number[]; damageRange = [damageArray[0], damageArray[damageArray.length - 1]]; } else { const singleDamage = result.damage as number; damageRange = [singleDamage, singleDamage]; } } else { damageRange = [0, 0]; } return { description: result.fullDesc(), damage: damageRange, koChance: result.kochance().text, fullResult: result }; } catch (error) { throw new Error(`Calculation failed: ${error instanceof Error ? error.message : String(error)}`); } }

Implementation Reference

Latest Blog Posts

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/jpbullalayao/pokemon-vgc-calc-mcp'

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