poke-mcp docs

MCP server que expoe a PokeAPI v2 como ferramentas para agentes de IA. 10 tools, 4 IDEs, 1 executavel.

01. Visao Geral

O poke-mcp e um servidor que implementa o Model Context Protocol (MCP) — protocolo aberto criado pela Anthropic que padroniza a comunicacao entre aplicacoes de IA e fontes de dados externas.

O servidor expoe 10 ferramentas que permitem a agentes de IA consultar dados de Pokemon diretamente da PokeAPI v2 — stats, tipos, moves, abilities, itens, berries, locais de encontro e cadeias de evolucao.

10 Tools

Cobertura completa da PokeAPI: Pokemon, batalha, itens e evolucoes

💻 4 IDEs

Claude Desktop, Cursor, Windsurf e Claude Code CLI

📦 Standalone

Distribuicao .exe sem dependencias via PyInstaller

02. Arquitetura

Claude Desktop
Cursor
Windsurf
Claude Code
↓ stdio (JSON-RPC 2.0) ↓
poke-mcp (FastMCP)
↓ httpx (async) ↓
PokeAPI v2

Transporte: stdio

O servidor usa transporte stdio com JSON-RPC 2.0. A IDE lanca o processo e se comunica via stdin/stdout. Logging vai exclusivamente para stderr — stdout e reservado para o protocolo.

Camadas do Sistema

CamadaArquivoResponsabilidade
Entry Point__main__.pyBootstrap do servidor
Serverserver.pyFastMCP instance, lifespan, httpx client, fetch()
Toolstools.py10 ferramentas MCP via @mcp.tool()
Installerinstall.pyInstalador multi-IDE com UI visual
Buildbuild.pyEmpacotamento PyInstaller
Teststest_tools.pyTestes unitarios com mock HTTP

Estrutura de Diretorio

poke-mcp/
├── src/poke_mcp/
│   ├── __init__.py        # Versao do pacote
│   ├── __main__.py        # python -m poke_mcp
│   ├── server.py          # FastMCP + httpx client
│   └── tools.py           # 10 tools registradas
├── tests/
│   └── test_tools.py      # Testes com mock
├── docs/
│   └── index.html         # Esta pagina
├── build.py               # PyInstaller build
├── install.py             # Instalador multi-IDE
└── pyproject.toml         # Config do projeto

03. Padroes de Design

Singleton via Lifespan

HTTP Client Compartilhado

Um unico httpx.AsyncClient e criado no lifespan do FastMCP e compartilhado entre todas as tools. Connection pooling automatico com ate 20 conexoes simultaneas e 5 keep-alive.

@asynccontextmanager
async def lifespan(server: FastMCP):
    global api_client
    api_client = httpx.AsyncClient(
        base_url=BASE_URL,
        timeout=30.0,
        limits=httpx.Limits(max_connections=20, max_keepalive_connections=5),
    )
    try:
        yield
    finally:
        await api_client.aclose()
Gateway Pattern

Funcao fetch() Centralizada

Todas as tools passam por uma unica funcao fetch() que encapsula montagem de URL, tratamento de erros (timeout, 404, HTTP errors, conexao) e retorna None em qualquer falha. Nenhuma tool precisa fazer try/except.

async def fetch(endpoint: str) -> dict[str, Any] | None:
    """GET a PokeAPI endpoint. Returns None on any error."""
    url = f"/{endpoint}"
    resp = await api_client.get(url)
    resp.raise_for_status()
    return resp.json()
Registry Pattern

IDE Targets no Instalador

Cada IDE suportada e uma entrada num array de IDETarget dataclass. Adicionar uma nova IDE = adicionar 1 objeto. A logica de configure/unconfigure e generica.

@dataclass
class IDETarget:
    name: str
    config_path_fn: Callable[[], Path]
    detect_fn: Callable[[], bool]

IDE_TARGETS = [
    IDETarget("Claude Desktop", _claude_desktop_config, _claude_desktop_detected),
    IDETarget("Cursor", _cursor_config, _cursor_detected),
    ...
]
Decorator Registration

Tools via @mcp.tool()

Cada tool e registrada com o decorator @mcp.tool(). O docstring vira a descricao que o LLM ve. Os type hints geram o JSON Schema dos parametros automaticamente.

@mcp.tool()
async def get_pokemon(name_or_id: str) -> str:
    """Get Pokemon details including stats, types, abilities, and sprites."""
    data = await fetch(f"pokemon/{name_or_id}")
    if not data:
        return f"Pokemon '{name_or_id}' not found."

04. Ferramentas MCP

Pokemon

ToolEndpointDados
get_pokemon/pokemon/{id}Stats, tipos, abilities, sprites, peso, altura
get_pokemon_species/pokemon-species/{id}Flavor text, habitat, egg groups, evolution chain
list_pokemon/pokemon?limit&offsetListagem paginada (1-100)
get_pokemon_encounters/pokemon/{id}/encountersLocais, versao, metodo, chance, nivel

Batalha

ToolEndpointDados
get_type/type/{id}Relacoes de dano (2x, 0.5x, 0x)
get_move/move/{id}Poder, precisao, PP, efeito, meta
get_ability/ability/{id}Descricao, lista de Pokemon

Itens, Berries e Evolucao

ToolEndpointDados
get_item/item/{id}Custo, categoria, efeitos, atributos
get_berry/berry/{id}Crescimento, sabores, Natural Gift
get_evolution_chain/evolution-chain/{id}Arvore completa com triggers

05. Instalador Multi-IDE

O instalador detecta automaticamente quais IDEs estao instaladas e apresenta um menu interativo com checkboxes para selecao.

C
Claude Desktop
%APPDATA%/Claude/claude_desktop_config.json
Cu
Cursor
%APPDATA%/Cursor/.../mcp.json
W
Windsurf
%APPDATA%/Codeium/windsurf/mcp_config.json
>
Claude Code CLI
%USERPROFILE%/.claude.json

Fluxo do Instalador

====================================================
     PokeAPI MCP Server — Installer v2.0
====================================================
  MCP server for AI IDEs | pokeapi.co/api/v2

  Status: Not installed

  [I] Install / Reinstall
  [U] Uninstall
  [Q] Exit

  >>> Choose an option (I/U/Q): I

  Select IDEs to configure:

  [1] [x] Claude Desktop     (Detected)
  [2] [x] Cursor              (Detected)
  [3] [ ] Windsurf            (Not found)
  [4] [ ] Claude Code CLI     (Not found)

  Toggle: type numbers (e.g. 1,3) | Enter: confirm | 0: cancelTerminal Output

06. Testes

Estrategia

Mock no nivel do httpx.AsyncClient — o client real nunca e chamado nos testes. Uma fixture autouse injeta o mock em server.api_client antes de cada teste. O helper _mock_response() cria respostas HTTP mockadas com status configuravel.

Cobertura por Tool

ToolCenarios
get_pokemonSucesso (Pikachu), Not Found (404)
get_typeSucesso (Electric com damage relations)
list_pokemonSucesso (paginacao), Clamp de limite (999 → 100)
get_evolution_chainArvore completa (Pichu → Pikachu → Raichu)
get_moveThunderbolt com efeito e meta
get_itemMaster Ball com atributos
get_berryCheri Berry com sabores
get_pokemon_speciesPikachu com flavor text e evolution chain
$ pytest -v
tests/test_tools.py::test_get_pokemon_success       PASSED
tests/test_tools.py::test_get_pokemon_not_found      PASSED
tests/test_tools.py::test_get_type_success           PASSED
tests/test_tools.py::test_list_pokemon_success       PASSED
tests/test_tools.py::test_list_pokemon_clamps_limit  PASSED
tests/test_tools.py::test_get_evolution_chain        PASSED
tests/test_tools.py::test_get_move                   PASSED
tests/test_tools.py::test_get_item                   PASSED
tests/test_tools.py::test_get_berry                  PASSED
tests/test_tools.py::test_get_pokemon_species        PASSED

10 passed in 0.42spytest output

07. Stack Tecnica

Python 3.11+ Runtime
MCP SDK >=1.2.0 Protocolo
httpx >=0.27.0 HTTP Async
PyInstaller >=6.0 Build .exe
pytest >=8.0 Testes
pytest-asyncio Async Tests
ruff >=0.6.0 Lint + Format
hatchling Build Backend

Competencias Demonstradas

MCP Protocol Python Async/Await Connection Pooling Design Patterns PyInstaller Packaging Unit Testing (Mock) Terminal UI (ANSI) GitHub Releases Multi-IDE Support JSON-RPC 2.0 REST API Integration GitHub Pages

08. Build e Deploy

Pipeline de Build

O build.py gera dois executaveis via PyInstaller:

poke-mcp.exe

Servidor MCP standalone. --onefile com todas as dependencias. Hidden imports para httpx, anyio, pydantic, uvicorn.

install.exe

Instalador self-contained. Embute o poke-mcp.exe via --add-data. O usuario so precisa baixar e executar.

Comandos

# Setup
python -m venv .venv && .venv/Scripts/activate
pip install -e ".[dev]"

# Dev
python -m poke_mcp          # Run server
pytest                       # Run tests
ruff check src/ tests/       # Lint
ruff format src/ tests/      # Format

# Build & Release
python build.py              # Generate .exe files
gh release create v2.0.0     # Create GitHub Release
gh release upload v2.0.0 dist/*.exebash