A Pokemon MCP server
  • Nix 89.9%
  • Rust 10.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
cozyGalvinism 638b7ce926
feat: add build_team and install_team_skill MCP prompts
monmcp exposed only tools, so the team-building workflow lived in
whatever the client happened to remember. Two failure modes recurred:
recommending Pokemon that aren't obtainable in the user's game or
modpack, and answering before establishing any constraints at all.

Add two prompts. `build_team` carries the workflow — gate on
obtainability, ask the five constraint questions, then verify picks
with the existing tools. `install_team_skill` returns the same
workflow as a Claude Code skill document for
~/.claude/skills/pokemon-team-building/SKILL.md, so the workflow can
apply automatically instead of being invoked by hand. The server only
returns text; the client does the writing, and is told to ask first.

Both prompts render one shared TEAM_WORKFLOW const, so the prompt and
the installable skill cannot drift apart — a test asserts it.

The server instructions gain the obtainability rule too, since they
reach clients that never call a prompt.

Covered by unit tests on the prompt content and end-to-end tests that
drive the real binary over stdio JSON-RPC, including the advertised
capability and the unknown-prompt error path.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WgHd9gucxDyFn5VVtdtpZC
2026-09-06 23:46:39 +02:00
src feat: add build_team and install_team_skill MCP prompts 2026-09-06 23:46:39 +02:00
tests feat: add build_team and install_team_skill MCP prompts 2026-09-06 23:46:39 +02:00
.gitignore feat: add nix package recipe 2026-04-27 19:21:18 +02:00
Cargo.lock feat: add build_team and install_team_skill MCP prompts 2026-09-06 23:46:39 +02:00
Cargo.nix feat: add build_team and install_team_skill MCP prompts 2026-09-06 23:46:39 +02:00
Cargo.toml feat: add build_team and install_team_skill MCP prompts 2026-09-06 23:46:39 +02:00
default.nix feat: add nix package recipe 2026-04-27 19:21:18 +02:00
flake.lock feat: add flake.nix 2026-04-27 19:27:05 +02:00
flake.nix chore: remove mcp-servers-nix input 2026-04-27 19:49:34 +02:00
README.md feat: add build_team and install_team_skill MCP prompts 2026-09-06 23:46:39 +02:00

monmcp

A Pokemon MCP server. Fetches data from PokeAPI and caches it locally in SQLite so the API is only hit once per resource. Designed to run locally over stdio, making it easy to connect to Claude or any MCP-compatible client for Pokemon team-building.

Features

  • 9 MCP tools covering Pokemon, moves, abilities, items, natures, types, and team coverage
  • 2 MCP prompts — a team-building workflow, and an optional installer for it as a Claude Code skill
  • Permanent local cache — responses are stored in SQLite and never re-fetched unless invalidated
  • Cache management CLI — invalidate individual entries, entire resource kinds, or everything at once
  • No network dependency after first fetch — fully offline once data is cached

Installation

cargo install --path .

Or build directly:

cargo build --release
# Binary: ./target/release/monmcp

Usage

Start the MCP server (default)

monmcp
# or equivalently:
monmcp serve

Logs go to stderr; stdout is reserved for the JSON-RPC channel.

Cache management

Command Description
monmcp cache stats Show row counts for every cache table
monmcp cache invalidate Clear all cached data
monmcp cache invalidate --resource <KIND> Clear all entries for one resource kind
monmcp cache invalidate --resource <KIND> --key <NAME_OR_ID> Remove one specific cached entry

Resource kinds: pokemon, ability, move, type, item, nature

# Show how much is cached
monmcp cache stats

# Clear everything
monmcp cache invalidate

# Clear only move cache
monmcp cache invalidate --resource move

# Remove a single entry
monmcp cache invalidate --resource pokemon --key pikachu

MCP Tools

Tool Input Description
get_pokemon name_or_id: string Stats, types, abilities, moves, and sprite. Requires an exact PokeAPI name slug (e.g. "pikachu", "zygarde-50") or numeric dex ID — names are NOT fuzzy-matched. Use search_pokemon first to resolve the canonical slug if unsure.
get_ability name_or_id: string Effect description and list of Pokemon with this ability.
get_move name_or_id: string Power, accuracy, PP, type, damage class, and effect.
get_type_matchups type_name: string Full damage relation table (2×/0.5×/0× both ways).
search_pokemon query: string, limit?: number Search by name substring; returns canonical slugs + dex IDs. Use to resolve ambiguous names before calling get_pokemon or check_team_coverage. First call fetches and caches the full ~1300-entry index.
get_item name_or_id: string Cost, category, effect, and flavor text.
get_nature name_or_id: string Increased/decreased stat (+10%/10%) and flavor preferences.
list_pokemon_by_type type_name: string All Pokemon that have the given type.
check_team_coverage names_or_ids: string[] Defensive and offensive type coverage for a team of up to 6 Pokemon. Requires exact PokeAPI slugs or numeric IDs — use search_pokemon to resolve slugs for multi-form Pokemon.

All name_or_id / type_name inputs accept either a lowercase name ("pikachu", "fire") or a numeric ID ("25", "10").

MCP Prompts

Prompt Description
build_team The team-building workflow. Establishes which Pokemon are actually obtainable — game or modpack, legendaries, progress, generation limits — before recommending anything, then verifies picks with the tools above. PokeAPI has no availability data, so this cannot be inferred.
install_team_skill Returns the same workflow as a Claude Code skill document, for writing to ~/.claude/skills/pokemon-team-building/SKILL.md. Optional: once installed the workflow applies automatically, without invoking build_team by hand. The server only returns text — your client does the writing, and asks first.

In Claude Code these appear as /mcp__monmcp__build_team and /mcp__monmcp__install_team_skill.

Environment Variables

Variable Required Default Description
MONMCP_DB_PATH No $XDG_DATA_HOME/monmcp/cache.sqlite3 Path to the SQLite cache database. Created automatically if missing.
XDG_DATA_HOME No ~/.local/share Fallback used to compute the default DB path when MONMCP_DB_PATH is not set.
RUST_LOG No monmcp=info Log filter passed to tracing-subscriber. Example: monmcp=debug.

Nix

A flake.nix is provided. Exposes packages.x86_64-linux.default and overlays.default.

Build

nix build

NixOS / Home Manager

Add as flake input:

inputs.monmcp.url = "git+https://git.cozygalvinism.dev/cozyGalvinism/monmcp";

Apply overlay so pkgs.monmcp is available:

nixpkgs.overlays = [ inputs.monmcp.overlays.default ];

Install the binary:

home.packages = [ pkgs.monmcp ];

Integrate with mcp-servers-nix:

mcp-servers.settings.monmcp = {
  command = "${pkgs.monmcp}/bin/monmcp";
  args = [];
};

Claude Desktop / Claude Code integration

Add to your MCP config (e.g. ~/.claude/mcp.json):

{
  "mcpServers": {
    "monmcp": {
      "command": "/path/to/monmcp",
      "args": ["serve"]
    }
  }
}

Then ask Claude things like:

  • "What are Garchomp's base stats and moves?"
  • "Build me a balanced team with good type coverage."
  • "Which Pokemon learn Earthquake?"

Architecture

src/
├── main.rs          # Clap CLI (serve / cache subcommands)
├── config.rs        # Env-based configuration
├── error.rs         # AppError (thiserror)
├── db/
│   ├── mod.rs       # SQLite pool init, WAL mode
│   ├── schema.sql   # 6 cache tables + pokemon_index
│   └── cache.rs     # CacheStore — get/put/invalidate/search
├── pokeapi/
│   ├── mod.rs       # RustemonClient builder (MokaManager)
│   ├── pokemon.rs   # fetch_by_name / fetch_by_id / fetch_all_entries
│   ├── ability.rs
│   ├── move_.rs
│   ├── type_.rs
│   ├── item.rs
│   └── nature.rs
├── service/
│   ├── mod.rs       # PokeService — cache-first lookup for all resources
│   └── shape.rs     # JSON projection helpers (trim raw blobs to compact output)
└── mcp/
    ├── mod.rs       # StdioTransport + server startup
    ├── handler.rs   # ServerHandler impl
    ├── prompts.rs   # build_team + install_team_skill (one shared workflow const)
    └── tools.rs     # 9 tool structs with #[mcp_tool] + tool_box!

Cache entries are stored as raw JSON blobs keyed by both name and numeric ID, so either lookup hits the cache. The pokemon_index table is populated lazily on the first search_pokemon call.