Metadata-Version: 2.4
Name: tcg-mcp
Version: 0.4.0
Summary: MCP server for Pokemon TCG: PSA grading lookups, local collection management, and multi-provider pricing (Pokemon TCG API + PriceCharting).
Project-URL: Homepage, https://github.com/seanlok/tcg-mcp
Project-URL: Documentation, https://github.com/seanlok/tcg-mcp#readme
Project-URL: Repository, https://github.com/seanlok/tcg-mcp.git
Project-URL: Issues, https://github.com/seanlok/tcg-mcp/issues
Project-URL: Changelog, https://github.com/seanlok/tcg-mcp/releases
Author: Sean Lok
License: MIT
License-File: LICENSE
Keywords: claude,grading,mcp,model-context-protocol,pokemon,pricecharting,psa,tcgplayer,trading-cards
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp>=1.2.0
Requires-Dist: pydantic-settings>=2.3.0
Requires-Dist: pydantic>=2.7.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# tcg-mcp

<!-- mcp-name: io.github.seanlok/tcg-mcp -->

> A Pokemon TCG MCP server. Looks up graded cards (PSA today, CGC/BGS
> stubbed), manages your owned collection in a local SQLite DB, queries
> pricing providers (Pokemon TCG API + PriceCharting), tracks a watchlist
> with target prices, and snapshots PSA pop counts so you can see trends
> over time.

[![PyPI](https://img.shields.io/pypi/v/tcg-mcp.svg)](https://pypi.org/project/tcg-mcp/)
[![Python](https://img.shields.io/pypi/pyversions/tcg-mcp.svg)](https://pypi.org/project/tcg-mcp/)
[![Downloads](https://img.shields.io/pypi/dm/tcg-mcp.svg)](https://pypistats.org/packages/tcg-mcp)
[![CI](https://github.com/seanlok/tcg-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/seanlok/tcg-mcp/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

`tcg-mcp` is a [Model Context Protocol](https://modelcontextprotocol.io)
server. Install it once, wire it into Claude Desktop / Claude Code / Cursor /
any MCP client, and your assistant gains 25 tools for working with PSA cert
data, your personal collection, and live market prices.

---

## What it does — 25 tools, namespaced

**PSA grading (`tcg_psa_*`)** — cert lookup, front/back images, snapshot pop
data over time, plus a workflow tool that looks up a cert and records it as
owned in one call.

**CGC / BGS (`tcg_cgc_*`, `tcg_bgs_*`)** — stubs in v0.2; no public API exists
for either grader. Listed for routing parity; will route cleanly if either
grader publishes an API.

**Collection (`tcg_collection_*`)** — add raw or graded cards (or sealed
products: ETBs, booster boxes, UPCs, tins), list with filters, update cost
basis, soft-delete (mark sold) or hard-delete, attach a card to a pricing
listing, get a cost-basis summary or a live market valuation that joins
against the most recent pricing snapshots.

**Pricing (`tcg_pricing_*`)** — search a provider, get a full price quote
(top-level market/low/high plus per-variant breakdown for Pokemon TCG API,
plus per-grade levels for PriceCharting), persist snapshots into the local
DB, **bulk-snapshot every attached card in one call** with per-provider
rate-limit awareness, and **query historical snapshots** as a time series
for trend analysis.

**Watchlist (`tcg_watchlist_*`)** — add target buy prices with thesis text,
list by horizon (flip / hold / sealed), update, and close with a reason
(bought / thesis_invalidated / manual).

**Meta (`tcg_list_providers`)** — discovery tool that shows which grading +
pricing providers are enabled, what env var each needs, and what tools are
in the namespace.

For the full tool list run `tcg_list_providers` after install or read the
[architecture doc](docs/architecture.md).

---

## Prerequisites

1. **Python 3.10 or newer** (3.13 recommended).
2. **An MCP client** — Claude Desktop, Claude Code, Cursor, Continue, etc.
3. *(Optional, for PSA tools only)* **A PSA Public API token** — free, sign
   up at [psacard.com/publicapi](https://www.psacard.com/publicapi).

The server works without any tokens — Pokemon TCG API queries, collection,
and watchlist tools all function on a fresh install with zero credentials.

---

## Install

### Option A — `uvx` (recommended, zero install)

```bash
# install uv if you don't have it
curl -LsSf https://astral.sh/uv/install.sh | sh

# run the server (auto-installs the package on first use)
uvx tcg-mcp --help
```

### Option B — `pipx`

```bash
pipx install tcg-mcp
tcg-mcp --help
```

### Option C — `pip`

```bash
python3 -m pip install tcg-mcp
```

### Option D — from source (for contributors)

```bash
git clone https://github.com/seanlok/tcg-mcp.git
cd tcg-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest        # run the test suite
```

---

## Configure

Copy `.env.example` to `.env` and fill in any tokens you have:

```bash
cp .env.example .env
$EDITOR .env
```

Or set the env vars however your client supports it (most clients let you
specify `env` per MCP server in the config).

| Env var | Required for | Notes |
|---|---|---|
| `PSA_API_TOKEN` | PSA tools | [Get one](https://www.psacard.com/publicapi) — free |
| `POKEMONTCG_API_KEY` | Higher Pokemon TCG API rate limit (optional) | [Get one](https://dev.pokemontcg.io/) — free |
| `PRICECHARTING_TOKEN` | PriceCharting tools | Paid subscription required |
| `TCG_DB_PATH` | Local DB location | Default `~/.tcg-mcp/tcg.db` |

---

## Wire it into your MCP client

### Claude Desktop

Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS),
`%APPDATA%\Claude\claude_desktop_config.json` (Windows), or
`~/.config/Claude/claude_desktop_config.json` (Linux):

```json
{
  "mcpServers": {
    "tcg-mcp": {
      "command": "uvx",
      "args": ["tcg-mcp"],
      "env": {
        "PSA_API_TOKEN": "your-token-here",
        "TCG_DB_PATH": "~/Documents/tcg-mcp.db"
      }
    }
  }
}
```

Quit Claude Desktop fully (⌘Q on macOS — closing the window isn't enough)
and relaunch.

### Claude Code

```bash
claude mcp add tcg-mcp -- uvx tcg-mcp
```

Then export the tokens you have in the shell that runs `claude`.

### Cursor / Continue / etc.

Same shape — point the client at:

```
command: uvx
args:    ["tcg-mcp"]
env:     PSA_API_TOKEN=...    # optional
```

---

## Smoke-test it

After wiring up the client, ask it:

> "Use tcg-mcp to list providers."

You should see `pokemontcg` enabled, plus `psa` enabled if your token is
set, and stubs for the others.

Then try a real lookup:

> "Search Pokemon TCG API for Charizard ex from Obsidian Flames."

> "Add a 1999 Pokemon Base Set Charizard #4 (raw) to my collection — paid $250 on 2026-04-15."

> "Add Charizard ex Surging Sparks to my watchlist with a target buy price of $180."

> "What's my collection cost basis?"

---

## Architecture, briefly

```
+----------------------+
|     MCP client       |  Claude Desktop, Cursor, etc.
+----------+-----------+
           | stdio (JSON-RPC)
+----------v-----------+
|     server.py        |  FastMCP — tool registration, validation
+----------+-----------+
           |
   +-------+-------+----------------+
   |               |                |
+--v--+         +--v--+        +----v----+
| psa |  ...    |pricing|      | storage |  SQLite — collection,
+--+--+         +--+----+      +----+----+  watchlist, pop trends,
   | httpx         | httpx          |       pricing snapshots
+--v---------------v----+      +----v----+
|  PSA / Pokemon TCG    |      | tcg.db  |
|  API / PriceCharting  |      +---------+
+-----------------------+
```

Provider abstractions ([`providers/base.py`](src/tcg_mcp/providers/base.py),
[`pricing/base.py`](src/tcg_mcp/pricing/base.py)) make adding a new grader
or pricing source a single-file change. See
[`docs/adding-a-provider.md`](docs/adding-a-provider.md).

---

## Local SQLite database

All your personal data — collection, watchlist, pricing snapshots, pop
snapshots — lives in a single SQLite file. Default location is
`~/.tcg-mcp/tcg.db`. Point `TCG_DB_PATH` at any path you prefer.

The file format is plain SQLite, so you can inspect or back up the data
directly:

```bash
sqlite3 ~/.tcg-mcp/tcg.db
.tables
SELECT subject, grade, acquisition_price FROM owned_cards WHERE status='owned';
```

Schema is in [`src/tcg_mcp/storage/schema.sql`](src/tcg_mcp/storage/schema.sql).
Migrations are forward-only and idempotent (safe to run on every startup).

---

## Known limits

- **PSA images** only exist for cards graded after **October 2021**. Older
  slabs return an empty image list — that's the upstream API, not a bug.
- **PSA's `Brand` field** is the closest thing to a clean "set name" in
  their schema. We surface it as `set_name`; for finer-grained set parsing,
  reach into the raw payload.
- **CGC / BGS** providers are stubs in v0.2. They're listed for discovery
  but raise `NotSupportedError` if called. Implementation depends on either
  grader publishing a public API or an explicit decision to support polite
  scraping.
- **Rate limits** on the PSA free tier aren't publicly documented. If you
  see "PSA API rate limit exceeded", wait or upgrade your plan.
- **PriceCharting** is paid-only. Without a `PRICECHARTING_TOKEN` the
  provider is registered as `disabled` and graded-card prices aren't
  available — but Pokemon TCG API still gives you raw market prices.

---

## Roadmap

> **Standing constraint:** every milestone below has a **free path** as the
> default. Paid providers (GemRate, eBay Marketplace Insights, etc.) stay
> optional add-ons that activate only when their key is configured.

- ✅ **v0.3 — shipped:** `tcg_pricing_snapshot_collection`,
  `tcg_pricing_get_history`, rounded per-item valuation, clearer PSA 429
  error message, `CHANGELOG.md`.
- ✅ **v0.4 — shipped:** Catalog tools (`tcg_catalog_*`) backed by Pokemon
  TCG API, `tcg_collection_set_completion` with watchlist intersection,
  richer `tcg_collection_search`, smart-routed `tcg_pricing_get_card`.
- v0.5 — CGC support (free path: polite scraping; optional paid GemRate).
- v0.6 — BGS support (free path: polite scraping; optional paid GemRate).
- v0.7 — eBay sold comps (free path: eBay Browse API + scraping; optional
  paid Marketplace Insights API).

See [`CHANGELOG.md`](CHANGELOG.md) for the full version history.

---

## Contributing

Contributions welcome. To add a new grading or pricing provider, see
[`docs/adding-a-provider.md`](docs/adding-a-provider.md). The contract is
intentionally small: implement a Protocol method, register it conditionally
based on credentials, write a mock-httpx test.

```bash
# Run tests + lint locally
pytest
ruff check .
```

---

## Disclaimers

This project is **independent**. It is not affiliated with PSA, CGC,
Beckett, The Pokemon Company, Nintendo, TCGPlayer, Cardmarket,
PriceCharting, or any other organization. Each external API call is
subject to that provider's Terms of Service.

---

## License

MIT — see [`LICENSE`](LICENSE).

---

## Sources / further reading

- [Model Context Protocol](https://modelcontextprotocol.io) — official site
- [MCP Registry](https://modelcontextprotocol.io/registry) — discovery
- [Pokemon TCG API](https://docs.pokemontcg.io/) — pricing + catalog
- [PSA Public API](https://www.psacard.com/publicapi/documentation)
- [PriceCharting API](https://www.pricecharting.com/api-documentation)
