PokéWallet MCP
Vision-guided Pokémon TCG card identification server that matches exact printings using visual evidence and marketplace data.
README
<div align="center">

PokéWallet MCP
Point your vision model at a card. Get the exact printing—not a confident guess.
Vision-guided Pokémon TCG identification, exact-variant price matching, set research, and local collection tools for standards-compliant MCP clients.
</div>
PokéWallet MCP fixes the dangerous gap between “that looks like a Charizard” and “this is the 1st Edition Shadowless holo printing.” It combines a vision-capable OpenAI-compatible model with PokéWallet catalog data, ranks candidate printings, validates visible edition and foil evidence, and returns only marketplace variants supported by the photo.
Why collectors need exact-variant matching
Cards sharing the same name and collector number can have radically different values. Edition stamps, foil coverage, holo patterns, regional printings, distribution stamps, and known error markers all matter. A normal name search cannot safely resolve those differences.
PokéWallet MCP uses a staged pipeline:
local photo
→ safe decode + orientation contact sheets
→ structured visual evidence
→ PokéWallet catalog candidates
→ metadata ranking + reference-image verification
→ strict marketplace-variant selection
→ confidence, uncertainty, and data-quality warnings
It does not authenticate cards, assign a condition or grade, or promise a sale value. It identifies visible printing evidence and keeps uncertainty visible.
Built for the details that change the price
| Evidence family | Recognized examples |
|---|---|
| Edition and print run | 1st Edition, Unlimited, Shadowless, no-edition mark, 1999–2000 copyright line |
| Core finishes | normal, holofoil, reverse holofoil |
| Foil coverage | artwork-only, card-body, full-card, selective |
| Reverse patterns | Poké Ball, Master Ball, Legendary Collection fireworks, Energy symbol, type symbol, set-logo, gold-border |
| Holo patterns | standard/plain, Cosmos, Galaxy Star, Galaxy, Cracked Ice, Line, Confetti, Etched, Textured, Rainbow |
| Distribution variants | Black Star Promo, Prerelease, STAFF, Pokémon Center, retailer exclusive, League, Winner, World Championships, theme-deck, blister, gift-with-purchase, stamped promo |
| Cautious error markers | gray/ghost stamp, no-symbol, Black Dot, No Damage, evolution/text errors |
Specific evidence is strict. If the image shows a Master Ball reverse pattern, a generic Reverse Holo price is not silently substituted. If it shows Cracked Ice, a generic Holofoil row is not treated as equivalent. Possible error-card markers improve candidate ranking but remain explicitly tentative until independently authenticated.
Dynamic photos, not scanner-perfect inputs
The image pipeline accepts local paths or base64 data and builds multiple evidence views:
- EXIF-aware orientation correction
- multi-scale, card-aspect region proposals that magnify cards embedded in screenshots or wide scenes
- 0°, 90°, 180°, and 270° views
- high-resolution full-card views plus focused detail crops
- skew/perspective reporting and robust contact sheets
- bounded pixel count, byte size, and image edge length
- optional allowed-root enforcement for local image paths
Acceptance testing includes upright, sideways, upside-down, and crooked card photos. No OpenCV or GPU-heavy detector is required for preprocessing; Pillow prepares the views and your configured vision model performs the visual analysis.
Real Hermes result
This abridged screenshot was rendered from the live Hermes acceptance test using the photographed Base Set Charizard. Hermes loaded the portable skill, discovered and called mcp__pokewallet__analyze_pokemon_card, detected the circular 1st Edition stamp at 100% focused-pass confidence, selected 1st Edition Holofoil, rejected the Unlimited row, and surfaced inconsistent marketplace fields instead of presenting a misleading number.

Natural-language valuation in action
Ask a plain-language question with a card image and the agent can resolve the printing, query PokéWallet marketplace data, keep USD and EUR sources separate, and explain the result in collector-friendly language.

Marketplace figures are point-in-time source data, not an appraisal. Condition, authenticity, and grade still require independent evaluation.
The structured response includes the evidence—not just the answer:
{
"status": "likely",
"identified_card": {
"name": "Charizard",
"collector_number": "004/102",
"set": {"name": "Base Set (Shadowless)"}
},
"detected": {
"edition_guess": "first_edition",
"finish_guess": "holofoil",
"foil_pattern_guess": "standard_holofoil",
"visible_stamps": ["EDITION 1"],
"field_confidence": {"edition_guess": 1.0}
},
"edition_evidence": {
"edition_guess": "first_edition",
"visible_stamp_text": ["EDITION 1"],
"confidence": 1.0
},
"matched_price_variants": [{
"source": "tcgplayer",
"currency": "USD",
"variant": {"name": "1st Edition Holofoil"},
"data_quality_warnings": [
"Marketplace fields are internally inconsistent; verify recent sold listings."
]
}]
}
Feature set
- 40 MCP tools for cards, sets, prices, analytics, local collections, watchlists, status, and image identification
- 8 resources for cards, localized card images, sets, set logos, collection, and watchlist data
- 4 prompts for image identification, card research, printing comparison, and set browsing
- A standards-based Agent Skill with trigger-rich natural-language routing instructions
- MCP initialization instructions and a single high-level
analyze_pokemon_cardentry point that are independent of client-specific tool prefixes - Exact collector-number parsing for standard, alphanumeric, fraction, promo, and leading-zero formats
- Candidate scoring from title, collector number, set code, HP, stage, visible stamps, variant markers, and possible errors
- Reference-image verification when metadata alone cannot separate nearby printings
- Per-source price variants with TCGPlayer USD and Cardmarket EUR kept separate
- A machine-readable
answer_policythat forbids harnesses from adding outside auction, grading, sold-listing, or memory-based prices - Explicit ambiguity states:
confirmed,likely,ambiguous, andnot_found - Batch image identification, bounded concurrency, caching, retry/backoff, and structured errors
- Local SQLite collection/watchlist storage with JSON and CSV export
- stdio and Streamable HTTP transports
- Non-root Docker image and loopback-only Compose port binding
Quick start
Requirements:
- Python 3.11 or newer
- uv
- A PokéWallet API key
- For image identification, an OpenAI-compatible vision endpoint and a vision-capable model
git clone <your-repository-url>
cd poke-mcp
uv sync --extra dev
cp .env.example .env
On PowerShell, use Copy-Item .env.example .env for the final command. Then edit .env:
POKEWALLET_API_KEY=your_key_here
VISION_API_BASE=http://127.0.0.1:1234/v1
VISION_API_KEY=your_local_provider_key_if_required
VISION_MODEL=your_vision_model_alias
VISION_TIMEOUT_SECONDS=600
VISION_MAX_TOKENS=3000
VISION_DISABLE_THINKING=true
Use the model alias exposed by the local provider, not a raw model filename. Some runtimes attach the vision projector only through that alias; selecting the GGUF directly can leave the GPU idle and make image requests behave like text-only calls.
API keys and secrets
- Copy
.env.exampleto.env; never rename or edit.env.examplewith real credentials. - Set
POKEWALLET_API_KEY. This is the only required API credential for text/catalog operations. - Set
VISION_MODELfor image identification, plusVISION_API_BASEwhen the provider is not on the default local URL. - Set
VISION_API_KEYonly when the vision provider requires authentication. Local servers commonly accept an empty value; hosted providers usually do not. - Keep client configuration examples on
${POKEWALLET_API_KEY}and${VISION_API_KEY}placeholders. Do not paste real keys into committed JSON, YAML, screenshots, or shell scripts.
The included .gitignore excludes .env, .env.*, caches, databases, exports, logs, and local virtual environments while explicitly allowing the safe .env.example template. --check-config reports only whether keys are configured; it does not print them.
Validate before connecting a client:
uv run pokewallet-mcp --check-config
uv run pokewallet-mcp --health-check
Universal natural-language routing
PokéWallet's portable routing layer lives in the MCP server, not in a Pi, Hermes, Discord, or other frontend adapter:
- During the standard MCP initialization handshake, the server sends a routing contract telling the client to call
analyze_pokemon_cardfor card-photo identification or value questions. analyze_pokemon_cardis an explicitly titled, read-only, idempotent high-level tool. Its description contains the complete selection rule and works even when a client adds its own prefix to tool names.skills/pokewallet-card-analysis/SKILL.mdpackages the same workflow in the open Agent Skills format. Any Agent Skills-compatible harness can load that one unchanged skill; only the harness's discovery/install location varies.
No client-specific routing adapter is required for this portable path. Connect the MCP server and, if the harness supports Agent Skills, copy or link skills/pokewallet-card-analysis into that harness's normal skills directory. Configure the harness to preload or auto-activate that skill for card-image conversations when its skill implementation requires it. The skill name, content, and MCP tool-selection logic stay unchanged across harnesses; only installation/discovery/activation is harness-owned.
There is one unavoidable protocol boundary: MCP servers do not receive raw chat turns or attachments until the client calls a tool. The MCP specification permits clients to use server initialization instructions, but cannot force them to do so. The client must also expose the attachment as a real path or base64 payload. A client that discards MCP instructions, never selects tools, or hides attachment bytes cannot be made automatic by server code or a skill; that client needs its own routing fix.
Install on Hermes
The included installer is idempotent and production-safe: it finds the project virtual environment, adds or updates only the pokewallet MCP entry, installs the unchanged portable Agent Skill into Hermes's standard skills directory, mirrors non-secret project settings, backs up Hermes configuration and any previous skill copy, copies secrets into Hermes's private .env, and leaves ${...} placeholders in YAML. It never prints API keys.
Windows PowerShell
Copy-Item .env.example .env
# Configure .env first, then:
uv run python scripts/install_hermes.py `
--project . `
--hermes-home "$env:LOCALAPPDATA\hermes"
hermes gateway restart
macOS or Linux
cp .env.example .env
# Configure .env first, then:
uv run python scripts/install_hermes.py --project . --hermes-home "$HOME/.hermes"
hermes gateway restart
Hermes advertises installed skill metadata to the model, but some local models may start generic vision in parallel with skill_view before reading the skill body. Preload the standard skill so its instructions are active before first-turn tool selection:
hermes chat --skills pokewallet-card-analysis
You can also use -s pokewallet-card-analysis with a one-shot hermes chat -q ... invocation. For a Discord or Slack gateway channel, use Hermes's built-in channel_skill_bindings with that channel's ID:
discord:
channel_skill_bindings:
- id: "YOUR_CHANNEL_ID"
skills: ["pokewallet-card-analysis"]
Once preloaded through Hermes's standard Agent Skill activation mechanisms, natural-language requests such as “what is this Pokémon card worth?” discover deferred MCP tools when necessary and call the high-level analyzer without generic vision or web valuation.
Verify from the Hermes environment:
python scripts/verify_hermes.py
Hermes should report registered pokewallet entries and hermes skills list should show pokewallet-card-analysis as enabled. Then launch Hermes itself with the skill preloaded, give it a local card image, and ask it to identify the exact printing and matched marketplace variant. Discord is only a frontend if your Discord bot routes to that Hermes instance; use a standard channel skill binding when you want the same preload there.
Install in other MCP clients
Any client that supports stdio MCP servers can launch the package directly. Use absolute paths because desktop clients often start outside the repository.
Generic mcpServers configuration
{
"mcpServers": {
"pokewallet": {
"command": "/absolute/path/to/poke-mcp/.venv/bin/python",
"args": ["-m", "pokewallet_mcp", "--transport", "stdio"],
"env": {
"POKEWALLET_API_KEY": "${POKEWALLET_API_KEY}",
"VISION_API_BASE": "http://127.0.0.1:1234/v1",
"VISION_API_KEY": "${VISION_API_KEY}",
"VISION_MODEL": "your_vision_model_alias",
"VISION_TIMEOUT_SECONDS": "600",
"VISION_MAX_TOKENS": "3000",
"VISION_DISABLE_THINKING": "true"
}
}
}
}
On Windows, command will usually end in .venv\\Scripts\\python.exe. The same shape works with clients such as Claude Desktop, Cursor, Windsurf, and VS Code MCP integrations; use the configuration location and environment-variable syntax required by that client. Avoid pasting real keys into a committed JSON file.
For any harness that implements Agent Skills, also copy or link this repository's skills/pokewallet-card-analysis directory into its documented skill search path and use that harness's normal auto-activation or preload setting. Harnesses that automatically expand a matching skill need no extra rule; harnesses that expose only metadata until the model calls skill_view should preload it to prevent a first-turn generic-vision race. Harnesses that do not implement Agent Skills can still use the MCP initialization instructions and high-level tool. No Pi adapter, Discord adapter, or client-specific Python router is part of this project.
Streamable HTTP
uv run pokewallet-mcp --transport streamable-http
The default endpoint binds to 127.0.0.1:8765. For a containerized local deployment:
docker compose up --build -d
Configuration
All settings are environment variables. .env.example is safe to commit; .env and .env.* are ignored, with an explicit exception for .env.example.
| Variable | Default | Purpose |
|---|---|---|
POKEWALLET_API_KEY |
empty | Required PokéWallet credential |
POKEWALLET_BASE_URL |
https://api.pokewallet.io |
API origin |
POKEWALLET_TIMEOUT_SECONDS |
30 |
API timeout, maximum 300 seconds |
POKEWALLET_ENABLE_PRO |
false |
Enables Pro-only endpoints |
VISION_API_BASE |
http://127.0.0.1:1234/v1 |
OpenAI-compatible vision API |
VISION_API_KEY |
empty | Vision-provider credential, if required |
VISION_MODEL |
empty | Provider's vision-capable model alias |
VISION_TIMEOUT_SECONDS |
600 in example |
Vision request timeout, maximum 600 seconds |
VISION_MAX_TOKENS |
3000 in example |
Structured extraction response budget |
VISION_TEMPERATURE |
0.0 |
Deterministic extraction temperature |
VISION_DISABLE_THINKING |
true in example |
Requests direct JSON from compatible local models |
CARD_IMAGE_MAX_MB |
15 |
Input byte limit |
CARD_IMAGE_MAX_PIXELS |
40000000 |
Decompression-bomb guard |
CARD_IMAGE_MAX_EDGE |
1600 |
Prepared-image edge limit |
ALLOWED_IMAGE_ROOTS |
empty | Comma-separated local path allowlist |
MCP_TRANSPORT |
stdio |
stdio or streamable-http |
MCP_HOST / MCP_PORT |
127.0.0.1 / 8765 |
HTTP bind address |
CACHE_ENABLED |
true |
In-memory and image caching |
COLLECTION_ENABLED |
true |
Local collection/watchlist tools |
COLLECTION_DATABASE_PATH |
platform data dir | SQLite database location |
COLLECTION_EXPORT_DIRECTORY |
platform data dir | JSON/CSV export destination |
Tool map
| Area | Tools |
|---|---|
| Identification | analyze_pokemon_card, identify_card_from_image, identify_cards_from_images, resolve_card |
| Card discovery | search_cards, search_card_by_name, find_card_by_number, batch_search_cards, get_card |
| Prices and comparisons | get_card_prices, summarize_card_value, compare_card_prices, compare_printings, compare_cards |
| Images | get_card_image plus image resources |
| Sets | list_sets, search_sets, get_set, get_set_cards, get_complete_set_cards, get_set_image |
| Analytics | set statistics, trending sets, completion value, set prices, price history, top cards |
| Collection | add/update/remove/list/value/export/summary |
| Watchlist | add/remove/list/check |
| Operations | pokewallet_health, pokewallet_api_info |
How exact identification works
- The server rejects remote URLs and safely decodes a local path or base64 image.
- It proposes colorful, detailed card-shaped regions at multiple scales, allowing a card to be recovered from a screenshot or wide scene without a heavyweight CV dependency.
- It normalizes EXIF orientation, generates rotated full-card views, and creates targeted crops for fine print, stamps, set symbols, and foil evidence.
- The vision model returns a strict schema with confidence per field, visible markers, and uncertainties.
- PokéWallet candidates are ranked by stable metadata and visible variant evidence.
- Close candidates can be compared against reference card images.
- A targeted variant pass inspects edition, finish, foil pattern/coverage, distribution stamps, and possible error markers.
- Early Wizards cards receive an isolated upright edition close-up so a visible circular
EDITION 1stamp can override an incorrect Unlimited guess without confusing rarity or energy symbols. - Marketplace variants that conflict with observed evidence are removed. The response carries only supported rows, preserved currencies, ambiguity flags, and source-data warnings.
Security posture
- No API key is hard-coded in application code, examples, screenshots, Docker files, or Hermes YAML.
.env,.env.*, databases, caches, logs, exports, test environments, IDE metadata, and OS junk are ignored.- The Hermes installer reads secrets from the project
.env, writes them only to the private Hermes.env, installs the portable skill, and creates timestamped backups. - Configuration/status output reports only booleans such as
api_key_configured; it never returns secret values. - Image tools reject remote URLs, enforce decoded-image limits, and can restrict access to explicit filesystem roots.
- HTTP transport binds to loopback by default; the Docker Compose port is also loopback-only.
- Collection exports are constrained to the configured export directory.
Before publishing a fork, run a secret scan appropriate for your organization. A useful local baseline is:
git grep -nEi '(api[_-]?key|token|secret|password).{0,30}[=:].{0,5}[A-Za-z0-9_-]{16,}' -- ':!README.md' ':!.env.example'
Tests
uv run ruff check .
uv run ruff format --check .
uv run pytest -q
Live tests are opt-in because they call external services:
POKEWALLET_RUN_LIVE_TESTS=1 uv run pytest -m integration -q
Utility scripts under scripts/ cover transport smoke tests, live identification, focused edition detection, prepared-sheet inspection, orientation fixtures, vision diagnostics, Hermes installation, and Hermes MCP registration.
Research and design references
The implementation uses original code, but the photo strategy and variant taxonomy were checked against existing open-source scanners and collector references:
- MCP lifecycle specification defines portable server
instructionsin the initialization response. - Agent Skills specification defines the portable
SKILL.mdpackage included in this repository. - 1vcian/Pokemon-TCGP-Card-Scanner demonstrates contour/aspect-ratio scanning, perceptual matching, oriented bounding boxes, and synthetic rotation/perspective augmentation. PokéWallet MCP adopts the resilience goals without adding its YOLO/OpenCV runtime.
- hugopeixoto/ptcg-detection explores perceptual hashes and set-symbol templates; this server instead combines structured vision with catalog candidates so it is not locked to a single camera resolution or template library.
- OpenCV card-scanner example informed the perspective/skew threat model.
- TCGplayer's rarity guide documents collector numbers, promo stars, and holo versus reverse-holo distinctions.
- CGC's Pokémon variant guide documents gray/ghost stamps, Cosmos Machamp, No Damage Ninetales, Black Dot Charizard, evolution errors, and the
1999–2000print run. - CGC's Jungle No Symbol guide covers the missing-set-symbol variant.
- Bulbapedia's holofoil guide catalogs Cosmos, Cracked Ice, set-logo, symbol, gold-border, and other historical patterns.
- Pokémon Card 151 documents the distinct Poké Ball and rarer Master Ball mirror-holo patterns in supported Asian-language releases.
- Prerelease Cards covers
PRERELEASE, expansion-logo, andSTAFFstamps.
These are visual-identification references, not price sources. Price responses come from the configured PokéWallet API and retain its marketplace/source metadata.
Limitations
- A single photo often cannot prove authenticity, card stock, surface condition, or exact grade.
- Sleeve glare, compression, shadows, and a missing back photo can hide foil or counterfeit indicators.
- Foil-pattern classification is only as reliable as the image and the configured vision model.
- Error-card markers are reported as possible variants, never certified errors.
- Marketplace data may be stale or internally inconsistent; warnings must be preserved and recent sold listings should be independently verified for consequential decisions.
- Natural-language auto-routing depends on the MCP client honoring server instructions and making attachments available to tool arguments; MCP cannot intercept the client's raw chat input.
License and trademarks
MIT. The generated project artwork is original and intentionally avoids official character art, card backs, logos, and trademarked ball symbols.
Pokémon and related names are trademarks of their respective owners. PokéWallet MCP is an independent integration and is not affiliated with, endorsed by, or sponsored by Nintendo, Creatures, GAME FREAK, The Pokémon Company, TCGplayer, Cardmarket, or PokéWallet.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.