Odel
pokeapi mcp server

pokeapi mcp server

@cyanheadsDeveloper Tools1TypeScriptApache-2.0Updated 1w ago

Look up Pokémon, moves, abilities, items, natures, and type matchups from PokéAPI v2.

Server endpointStreamable HTTP

This is the third-party server itself — Odel doesn't run it. Hitting this URL directly talks straight to the upstream server with no auth or proxying. Connect through Odel to front it with managed auth.

@cyanheads/pokeapi-mcp-server

Look up Pokémon, moves, abilities, items, natures, and type matchups from PokéAPI v2 via MCP. STDIO or Streamable HTTP.

7 Tools • 2 Resources

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

Public Hosted Server: https://pokeapi.caseyjhand.com/mcp


Tools

Seven tools covering the full PokéAPI v2 surface — a flagship consolidation tool, a computed matchup tool, single-resource lookups, and a filter tool:

ToolDescription
pokeapi_get_pokemonDenormalized Pokémon dossier in one call: base stats, types, abilities with effect text, height/weight, evolution chain, learnable moves, sprites, species flavor text, and variant list
pokeapi_get_type_matchupsComputed offensive and defensive type effectiveness — for a type name or Pokémon identifier; correctly composes dual-type matchups
pokeapi_get_moveMove details: type, damage class, power, accuracy, PP, priority, target, stat changes, status-effect chance, and full English effect text
pokeapi_get_abilityAbility details: full and short English effect text, and the Pokémon that have it (with hidden-ability flag and slot)
pokeapi_get_itemItem details: effect text, category, cost, fling power, attributes, and Pokémon that commonly hold it
pokeapi_get_natureNature details: stat boost/penalty, preferred and disliked berry flavor. Returns all 25 natures when called without an identifier
pokeapi_find_pokemonFilter Pokémon by generation, type, pokédex, or egg group; also resolves fuzzy name queries to canonical entries

pokeapi_get_pokemon

The flagship tool — fans out across the PokéAPI resource graph in parallel and returns one denormalized dossier, replacing 10–30 sub-resource GETs.

  • Fetches /pokemon, /pokemon-species, /evolution-chain, and each /ability in a two-tier parallel fan-out
  • Includes sprites (with official-artwork high-quality art URL), is_legendary, is_mythical, capture_rate, growth_rate, gender_rate
  • include_moves (default false) — set to true for a summarized learnable-move list filtered to the latest generation
  • game_version string to select flavor text by game (e.g. "sword", "red") — silently falls back to first available when no match
  • Surfaces the variant list so callers can re-call with a specific form name (regional forms, Gigantamax, Mega, etc.)

pokeapi_get_type_matchups

Computed type effectiveness — pass a type name or Pokémon identifier to get the full offensive and defensive breakdown with multiplier values.

  • For dual-type Pokémon: composes both type defensive relations correctly (immune in either type wins)
  • Returns superEffective, resistant, and immune lists for both offense and defense
  • Accepts either type (type name) or pokemon (name or dex number) — exactly one required

pokeapi_find_pokemon

Filter Pokémon by multiple criteria — returns names and dex numbers for follow-up pokeapi_get_pokemon calls.

  • Filters: generation (e.g. "generation-i"), type (e.g. "fire"), pokedex (e.g. "kanto"), egg_group (e.g. "fairy")
  • query parameter for fuzzy name search
  • Pagination via limit and offset

Resources and prompts

TypeNameDescription
Resourcepokeapi://pokemon/{identifier}Pokémon dossier by name or dex number — same payload as pokeapi_get_pokemon without moves
Resourcepokeapi://type/{typeName}Type damage relations — raw multiplier table, offensive and defensive

All resource data is also reachable via tools.


Features

Built on @cyanheads/mcp-ts-core:

  • Declarative tool and resource definitions — single file per primitive, framework handles registration and validation
  • Unified error handling — handlers throw, framework catches, classifies, and formats
  • Pluggable auth: none, jwt, oauth
  • Swappable storage backends: in-memory, filesystem, Supabase, Cloudflare KV/R2/D1
  • Structured logging with optional OpenTelemetry tracing
  • STDIO and Streamable HTTP transports

PokéAPI-specific:

  • Keyless and read-only — no API key, no auth, no configuration required to run
  • Graph-walk consolidation — pokeapi_get_pokemon fans out across /pokemon, /pokemon-species, /evolution-chain, and N /ability endpoints in two parallel tiers, returning one object
  • Aggressive caching — PokéAPI data is static game data; responses are cached in ctx.state with a configurable TTL (default 6 h) to respect PokéAPI's fair-use policy
  • Input normalization — accepts lowercase-hyphenated names or numeric IDs; strips and lowercases user input before fetching
  • English-first — effect_entries and flavor_text_entries are always filtered to language.name === 'en'; absent entries surface as null rather than a foreign-language string

Agent-friendly output:

  • Dual-type composition — pokeapi_get_type_matchups computes the effective matchup matrix from raw damage relations, so agents get a direct answer rather than raw tables to multiply
  • Variant surface — pokeapi_get_pokemon lists all form variants so agents can identify and re-call with specific forms (Alolan, Galarian, Mega, Gigantamax)
  • Sparse-safe nullable fields — upstream absent fields surface as null rather than crashing or returning a fabricated default

Getting started

Public Hosted Instance

A public instance is available at https://pokeapi.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:

{
  "mcpServers": {
    "pokeapi-mcp-server": {
      "type": "streamable-http",
      "url": "https://pokeapi.caseyjhand.com/mcp"
    }
  }
}

Self-Hosted / Local

No API key required. Add the following to your MCP client configuration file:

{
  "mcpServers": {
    "pokeapi-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/pokeapi-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Or with npx (no Bun required):

{
  "mcpServers": {
    "pokeapi-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/pokeapi-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Or with Docker:

{
  "mcpServers": {
    "pokeapi-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_TRANSPORT_TYPE=stdio",
        "ghcr.io/cyanheads/pokeapi-mcp-server:latest"
      ]
    }
  }
}

For Streamable HTTP, set the transport and start the server:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp

Prerequisites

  • Bun v1.3.0 or higher (or Node.js v24+).
  • No API key required — PokéAPI is fully public.

Installation

  1. Clone the repository:
git clone https://github.com/cyanheads/pokeapi-mcp-server.git
  1. Navigate into the directory:
cd pokeapi-mcp-server
  1. Install dependencies:
bun install
  1. Configure environment (optional):
cp .env.example .env
# All vars are optional — the server works with defaults

Configuration

VariableDescriptionDefault
POKEAPI_BASE_URLPokéAPI base URL — override for local mirrors or proxies.https://pokeapi.co/api/v2
POKEAPI_CACHE_TTL_SECONDSHow long to cache PokéAPI responses (seconds).21600 (6 h)
POKEAPI_REQUEST_TIMEOUT_MSPer-request timeout in milliseconds.10000
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTPort for HTTP server.3010
MCP_AUTH_MODEAuth mode: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (RFC 5424).info
LOGS_DIRDirectory for log files (Node.js only).<project-root>/logs
OTEL_ENABLEDEnable OpenTelemetry instrumentation.false

See .env.example for the full list of optional overrides.

Self-hosting for high-volume use

PokéAPI's Fair Use Policy asks consumers to cache aggressively and points high-volume deployments toward running a local instance. This server already caches responses for 6 hours by default (POKEAPI_CACHE_TTL_SECONDS), which covers most workloads. For hosted or batch-heavy deployments, run the official PokéAPI Docker image locally and point POKEAPI_BASE_URL at it — the server switches transparently.


Running the server

Local development

  • Build and run:

    bun run rebuild
    
    bun run start:stdio
    # or
    bun run start:http
    
  • Run checks and tests:

    bun run devcheck   # Lint, format, typecheck, security
    bun run test       # Vitest test suite
    bun run lint:mcp   # Validate MCP definitions against spec
    

Docker

docker build -t pokeapi-mcp-server .
docker run --rm -p 3010:3010 pokeapi-mcp-server

The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/pokeapi-mcp-server. Build with --build-arg OTEL_ENABLED=false to omit OpenTelemetry peer dependencies.


Project structure

PathPurpose
src/index.tscreateApp() entry point — registers tools, resources, and inits services.
src/config/Server-specific env var parsing with Zod (server-config.ts).
src/mcp-server/tools/Tool definitions (*.tool.ts).
src/mcp-server/resources/Resource definitions (*.resource.ts).
src/services/pokeapi/PokeApiService — typed fetch methods, caching, retry, timeout.
tests/Vitest test suite mirroring src/.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging, ctx.state for tenant-scoped storage (and caching)
  • Register new tools and resources via the barrels in src/mcp-server/*/definitions/index.ts
  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Contributing

Issues and pull requests are welcome. Run checks and tests before submitting:

bun run devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.