uk.co.leewinder/tcgdex
NPM · @LEEWINDER/MCP-TCGDEX
MCP server exposing the TCGdex Pokémon TCG API to LLM tools
Available components
Last scanned (8 hours ago)
Scores higher than 72% of npm servers
Category Entertainment and Games
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security100
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- No install/post-install scripts declared.Pass
- 0 of 8 dependencies flagged as unhealthy. View diagnostics → Pass
Provenance & Transparency45
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
- Clear OSI-approved license (MIT).Pass
- Actively maintained (last published 31 days ago).Pass
- Security-disclosure policy not yet verified: we couldn't inspect the source repository.Unverified
Schema Quality & AI Usability62
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 3258 tokens (~465/item across 7 items; 7 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management100
- No destabilizing schema changes in the last 30 days.Pass
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
- Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- We read all 7 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
- An AI judge read all 8 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 4 Nov 26 0
- Stability: 0.97 → pass security
- 3 Nov 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 93 to 97. That category is still filling its 30-day observation window: 28 days of observed history at the previous scan, 29 at this one. The score rises as the window fills, whether or not the server changes.
- 1 Nov 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 87 to 90. That category is still filling its 30-day observation window: 26 days of observed history at the previous scan, 27 at this one. The score rises as the window fills, whether or not the server changes.
- 30 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 80 to 83. That category is still filling its 30-day observation window: 24 days of observed history at the previous scan, 25 at this one. The score rises as the window fills, whether or not the server changes.
- 28 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 73 to 77. That category is still filling its 30-day observation window: 22 days of observed history at the previous scan, 23 at this one. The score rises as the window fills, whether or not the server changes.
- 25 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 63 to 67. That category is still filling its 30-day observation window: 19 days of observed history at the previous scan, 20 at this one. The score rises as the window fills, whether or not the server changes.
- 23 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 57 to 60. That category is still filling its 30-day observation window: 17 days of observed history at the previous scan, 18 at this one. The score rises as the window fills, whether or not the server changes.
- 21 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 50 to 53. That category is still filling its 30-day observation window: 15 days of observed history at the previous scan, 16 at this one. The score rises as the window fills, whether or not the server changes.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 5 Nov 2026 · Analysed npm/@leewinder/mcp-tcgdex@1.0.0
Provenance No attestation
The registry publishes no build provenance for this version, so there is nothing to verify.
| Result | No attestation |
|---|---|
| Ecosystem | npm |
Background: How many MCP packages publish verified provenance →
Dependencies 8 packages
| Packages resolved | 8 |
|---|---|
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
get_card ~263
Read one whole card by its `id`, or by its `set` and the number printed on it, `localId` — not both. The set may be an id or a printed name, ignoring case, and leading zeros in the number are optional. Returns the shape search_cards gives at `detail` 'full'. A card that does not exist is an error saying whether the set or the number was wrong.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | – | Global card id, e.g. 'swsh3-136'. Give it alone; take it from a search_cards or get_set result rather than composing one. |
| language | string | – | Catalogue language. Names, values and set lists are localised (the Asian catalogues have their own set ids), so look values up in it; prices are the same in every language. |
| localId | string | – | The number printed on the card, e.g. '105'; leading zeros are optional. Give it with `set`, not with `id`. |
| set | string | – | The card's set, given with `localId`: id ('sv04.5') or printed name ('Paldean Fates'), ignoring case; a name several sets share covers them all. list_sets lists both. |
| Name | Type | Req | Description |
|---|---|---|---|
| card | object | yes | The whole card, in the requested language: every field you can search on, its rules text (attacks, abilities and effect), its weaknesses and resistances, its tournament legality and its image URLs. M… |
| language | string | yes | The catalogue language this response was read in. |
No examples provided.
get_card_pricing ~493
Price up to 50 cards in EUR, USD or GBP, from Cardmarket (EUR) and TCGplayer (USD) side by side, with one total per market — never blended, since one is a trend and the other a market price. Name each card by `id`, or by `set` and `localId`, with an optional `variant` and `quantity`. Each line's `status` is `priced`; `unpriced`; `ambiguous`, when no `variant` was named and the copy held is unclear — name one of its `variants`; or `unavailable`, when the card could not be read or the line is malformed, which never fails the call. A missing price gives a `reason`: `no_listing`, `variant_unpriced`, `variant_not_printed`, `separate_product` (sold as a product of its own and unpriced here, like Base Set's 1st Edition or a Poké Ball reverse), `window_unavailable`, `platform_unpriced`, `unavailable` or `unrecognised_shape`. `approximateVariant` marks a price that may cover more than the printing named, and `separatelyListedPrintings` counts printings sold separately. Each price has its native `amount` and a `convertedAmount` at the ECB rate in `exchangeRates.rates`. A total is `complete` only when every line is priced. `warnings` flag markets more than 10× apart for a printing, and stale rates. Prices are for one copy in unspecified condition, before fees, and the same in every language.
| Name | Type | Req | Description |
|---|---|---|---|
| basis | string | – | Which figure to read. 'market' is TCGplayer's market price and Cardmarket's trend; 'low' the lowest listing; the day averages are Cardmarket's alone. TCGplayer gives `window_unavailable` for an avera… |
| cards | array | yes | One line per card, named the way get_card names one. A bad line is reported as unavailable; it never fails the call. |
| currency | string | yes | The currency to convert to. Each price is also given in its market's own currency. |
| language | string | – | Catalogue language. Names, values and set lists are localised (the Asian catalogues have their own set ids), so look values up in it; prices are the same in every language. |
| Name | Type | Req | Description |
|---|---|---|---|
| basis | string | yes | The figure read, whether requested or defaulted to. |
| currency | string | yes | The requested currency, echoed. |
| exchangeRates | – | yes | The exchange rates every converted amount here used. Null when nothing needed converting, or when no rates could be fetched. |
| language | string | yes | The catalogue language this response was read in. |
| lines | array | yes | One entry per requested line, in the order asked. |
| totals | object | yes | One total per market, never blended into one: the two markets measure prices differently, and a line priced in one market may be unpriced in the other. |
| warnings | array | yes | Anything that limits how far these numbers can be relied on, such as exchange rates that are stale or unavailable, or prices the two markets put more than 10× apart. Empty when nothing does. |
No examples provided.
get_set ~224
Read one set by id or printed name: its series, release date, platform and card counts, with a page of its cards in printed order as checklist lines of `id`, `localId`, `name` and `rarity`. Call get_card for a card that matters. Legality is per card, from get_card: upstream's set-level flag is wrong for every current set.
| Name | Type | Req | Description |
|---|---|---|---|
| language | string | – | Catalogue language. Names, values and set lists are localised (the Asian catalogues have their own set ids), so look values up in it; prices are the same in every language. |
| page | integer | – | Zero-indexed page. A page past the end is an empty success with `hasMore` false. |
| set | string | yes | The set to read, as id ('sv04.5') or printed name ('Paldean Fates'), ignoring case; a name several sets share covers them all. list_sets lists both. |
| size | integer | – | Results per page; only `hasMore` says whether more exist. |
| Name | Type | Req | Description |
|---|---|---|---|
| cards | array | yes | One page of the set's cards, in printed order, in the requested language. Four sets in the English catalogue hold no cards at all, so an empty list here is an honest answer rather than a failure. Eac… |
| hasMore | boolean | yes | True when at least one further page of results exists after this one. Request every result by incrementing 'page' until this is false. There is deliberately no total count: the length of the returned… |
| language | string | yes | The catalogue language this response was read in. |
| page | integer | yes | The zero-indexed page of results this response holds, whether it was requested or defaulted to. |
| set | object | yes | What the set is: its identity, its series, when it was released and how large it is. Tournament legality is not given for a set, because it belongs to each card — one set can mix regulation marks, an… |
| size | integer | yes | The page size this response was built with, whether it was requested or defaulted to. It is the maximum number of results this page can hold, not the number it does hold — the last page holds fewer. |
No examples provided.
list_card_field_values ~279
List the values a card `field` accepts in a language, which search_cards' filters take. `contains` filters them case-insensitively before paging; read further pages while `hasMore` is true. Values come from upstream as they are, so near-identical spellings of one artist can both appear.
| Name | Type | Req | Description |
|---|---|---|---|
| contains | string | – | Case-insensitive substring, applied to the whole field before paging, e.g. 'arita' finds 'Mitsuhiro Arita'. |
| field | string | yes | The card field to list values for. 'type' is a Pokémon card's type (Fire, Water, …); 'energy' is an Energy card's class (Normal or Special); 'category' is the kind of card (Pokemon, Trainer or Energy… |
| language | string | – | Catalogue language. Names, values and set lists are localised (the Asian catalogues have their own set ids), so look values up in it; prices are the same in every language. |
| page | integer | – | Zero-indexed page. A page past the end is an empty success with `hasMore` false. |
| size | integer | – | Results per page; only `hasMore` says whether more exist. |
| Name | Type | Req | Description |
|---|---|---|---|
| hasMore | boolean | yes | True when at least one further page of results exists after this one. Request every result by incrementing 'page' until this is false. There is deliberately no total count: the length of the returned… |
| language | string | yes | The catalogue language this response was read in. |
| page | integer | yes | The zero-indexed page of results this response holds, whether it was requested or defaulted to. |
| size | integer | yes | The page size this response was built with, whether it was requested or defaulted to. It is the maximum number of results this page can hold, not the number it does hold — the last page holds fewer. |
| values | array | yes | One page of the field's accepted values, in the requested language, after any 'contains' filter. Pass a value back as listed when filtering a card search. Values come from the upstream data as-is and… |
No examples provided.
list_sets ~278
List a language's sets, each with its `id`, `name`, `platform`, `releaseDate`, `serie` and card counts — the values a `set` filter takes. Oldest first unless `sort` or `order` say otherwise: `order` 'desc' lists the newest first. `contains` and `platform` filter the whole catalogue before paging.
| Name | Type | Req | Description |
|---|---|---|---|
| contains | string | – | Case-insensitive substring of the id or name, applied before paging. |
| language | string | – | Catalogue language. Names, values and set lists are localised (the Asian catalogues have their own set ids), so look values up in it; prices are the same in every language. |
| order | string | – | Whether the order runs ascending or descending — 'desc' on `releaseDate` puts the newest set first. |
| page | integer | – | Zero-indexed page. A page past the end is an empty success with `hasMore` false. |
| platform | string | – | 'TCG' for printed sets, 'TCG Pocket' for digital ones; applied before paging. Some catalogues hold only one. |
| size | integer | – | Results per page; only `hasMore` says whether more exist. |
| sort | string | – | `releaseDate` (default), `name` or `id`. |
| Name | Type | Req | Description |
|---|---|---|---|
| hasMore | boolean | yes | True when at least one further page of results exists after this one. Request every result by incrementing 'page' until this is false. There is deliberately no total count: the length of the returned… |
| language | string | yes | The catalogue language this response was read in. |
| order | string | yes | 'asc' (default) or 'desc'; 'desc' by `releaseDate` lists the newest set first. |
| page | integer | yes | The zero-indexed page of results this response holds, whether it was requested or defaulted to. |
| sets | array | yes | One page of sets, in the requested language, after any 'contains' and 'platform' filters. Catalogues differ enormously in size — 220 sets in English against 2 in Polish — so a set missing here is mis… |
| size | integer | yes | The page size this response was built with, whether it was requested or defaulted to. It is the maximum number of results this page can hold, not the number it does hold — the last page holds fewer. |
| sort | string | yes | What the sets were ordered by, whether requested or defaulted to. |
No examples provided.
rank_card_prices ~567
Rank the cards matching `name`, `pokemon`, `pokedex`, `set` or `rarity` — at least one, matched as in search_cards — by one market's price, most valuable first unless `order` is 'asc'. Each card is ranked once, by its highest-priced printing in `rankMarket`: a row in `cards` gives that `variant`, its `price`, and the other market's price as `otherMarket`. Upstream cannot sort by price, so the first 300 matches are read; `truncated` says more matched, and `coverage` accounts for every card read, counting unpriced ones by the same `reason` codes get_card_pricing uses. `separatelyListedPrintings` counts printings sold separately and not ranked. A row's `warnings` flag markets more than 10× apart; the order still follows `rankMarket`. Prices show the native `amount` and a `convertedAmount` at the rate in `exchangeRates.rates`, for one copy in unspecified condition, before fees.
| Name | Type | Req | Description |
|---|---|---|---|
| basis | string | – | Which figure to rank by. 'market' is TCGplayer's market price and Cardmarket's trend; 'low' the lowest listing; the day averages are Cardmarket's alone. So an average needs `rankMarket` 'cardmarket'. |
| currency | string | yes | The currency to show prices in; it never changes the order. Each price is also given in its market's own currency. |
| language | string | – | Catalogue language. Names, values and set lists are localised (the Asian catalogues have their own set ids), so look values up in it; prices are the same in every language. |
| limit | integer | – | How many rows to return; fewer when fewer cards have a price. |
| name | string | – | Case-insensitive substring of the card name. Names repeat heavily; tell results apart by set and number. |
| order | string | – | 'desc' (default) puts the most valuable first. |
| pokedex | integer | – | Filter by a National Pokédex number. Matches any card depicting it. |
| pokemon | string | – | A Pokémon's name in the request language, resolved to its Pokédex number (echoed back) to find every card depicting it. |
| rankMarket | string | yes | The one market whose price orders the ranking; each row shows the other's too. |
| rarity | string | – | Filter by the print rarity ('None' for a card printed without one). |
| set | string | – | Filter to one set by id ('sv04.5') or printed name ('Paldean Fates'), ignoring case; a name several sets share covers them all. list_sets lists both. |
| Name | Type | Req | Description |
|---|---|---|---|
| basis | string | yes | The figure ranked by, whether requested or defaulted to. |
| cards | array | yes | The ranked cards, best first in the order asked. Cards with no price in the ranked market are not listed — 'coverage' counts them. |
| coverage | object | yes | How much of what matched the ranking actually covers. Nothing is left out without being counted here. |
| currency | string | yes | The requested currency, echoed. |
| exchangeRates | – | yes | The exchange rates every converted amount here used. Null when nothing needed converting, or when no rates could be fetched. |
| language | string | yes | The catalogue language this response was read in. |
| limit | integer | yes | The most rows this response could hold, whether requested or defaulted to. |
| order | string | yes | The order used, whether requested or defaulted to. |
| pokemon | object | – | What the `pokemon` filter resolved to. Absent when none was given. |
| rankMarket | string | yes | The market ranked by, echoed. |
| truncated | boolean | yes | True when more than 300 cards matched, so only the first 300 in the catalogue's own order were considered and a card beyond them may outrank everything here. Narrow the filters until this is false to… |
| warnings | array | yes | Anything that limits how far these numbers can be relied on, such as exchange rates that are stale or unavailable, or prices the two markets put more than 10× apart. Empty when nothing does. |
No examples provided.
search_cards ~951
Search the card catalogue; every filter is optional and they combine with AND. Exact filters (`type`, `energy`, `category`, `trainer`, `stage`, `rarity`, `illustrator`, `variant`, `suffix`, `regulation`) take values from list_card_field_values and match whole, with letter case corrected to the catalogue's — unless two values differ only by case, like suffixes 'EX' and 'ex', which is an error naming both. An unknown value is an error too, so an empty page means real values matched nothing. `name` and `effect` match substrings; `pokemon` finds every card depicting a Pokémon; `attack` and `ability` text is checked over the first 300 matches of the other filters, as `textSearch` reports. Results come in a fixed `sort` order, and `detail` sets how much of each card is returned. Read further pages while `hasMore` is true. Prices come from get_card_pricing, not from cards.
| Name | Type | Req | Description |
|---|---|---|---|
| ability | string | – | Case-insensitive text in an ability's name or effect. Checked over the first 300 matches of the other filters, which it needs at least one of; `textSearch` says whether that covered every match. |
| attack | string | – | Case-insensitive text in an attack's name or effect. Checked over the first 300 matches of the other filters, which it needs at least one of; `textSearch` says whether that covered every match. |
| category | string | – | Filter by the kind of card (Pokemon, Trainer or Energy). |
| detail | string | – | 'summary' (default): identity, set, platform, rarity and images. 'full' adds rules text, legality and every searchable field; it costs about three times the bytes. |
| effect | string | – | Case-insensitive substring of a Trainer or Energy card's effect text. |
| energy | string | – | Filter by an Energy card's class (Normal or Special). |
| hp | object | – | Filter by hit points. Both bounds inclusive. |
| illustrator | string | – | Filter by the credited artist. Some artists appear under two spellings; list_card_field_values with `contains` shows both. |
| language | string | – | Catalogue language. Names, values and set lists are localised (the Asian catalogues have their own set ids), so look values up in it; prices are the same in every language. |
| name | string | – | Case-insensitive substring of the card name. Names repeat heavily; tell results apart by set and number. |
| order | string | – | 'asc' (default) or 'desc'. |
| page | integer | – | Zero-indexed page. A page past the end is an empty success with `hasMore` false. |
| platform | string | – | 'TCG' for printed cards, 'TCG Pocket' for digital ones. |
| pokedex | integer | – | Filter by a National Pokédex number. Matches any card depicting it. |
| pokemon | string | – | A Pokémon's name in the request language, resolved to its Pokédex number (echoed back) to find every card depicting it. |
| rarity | string | – | Filter by the print rarity ('None' for a card printed without one). |
| regulation | string | – | Filter by the regulation mark letter. |
| retreat | object | – | Filter by retreat cost, where 0 is free. Both bounds inclusive. |
| set | string | – | Filter to one set by id ('sv04.5') or printed name ('Paldean Fates'), ignoring case; a name several sets share covers them all. list_sets lists both. |
| size | integer | – | Results per page; only `hasMore` says whether more exist. |
| sort | string | – | Order by `id` (default, unique, so pages never overlap) or `name`, alphabetically ignoring case. Cards cannot be ordered by release date. |
| stage | string | – | Filter by a Pokémon's evolution stage (Basic, Stage1, …). |
| suffix | string | – | Filter by the name suffix (EX, GX, V, ex, …). Pokémon TCG Pocket's ex cards are recorded as 'EX'. |
| trainer | string | – | Filter by a Trainer card's subtype (Item, Supporter, …). |
| type | string | – | Filter by a Pokémon card's type (Fire, Water, …). A dual-type card matches either type. |
| variant | string | – | Filter by a printing the card exists in (normal, holo, reverse, firstEdition). True of most cards in several variants at once. |
| Name | Type | Req | Description |
|---|---|---|---|
| cards | array | yes | One page of matching cards, in the requested language, in the shape 'detail' names. A summary carries the card's id, number, name, set, platform, rarity and images; a full card adds its rules text (a… |
| detail | string | yes | The level of detail this response was built with, whether it was requested or defaulted to. It decides which shape the cards below take. |
| hasMore | boolean | yes | True when at least one further page of results exists after this one. Request every result by incrementing 'page' until this is false. There is deliberately no total count: the length of the returned… |
| language | string | yes | The catalogue language this response was read in. |
| order | string | yes | The direction of the order, whether requested or defaulted to. |
| page | integer | yes | The zero-indexed page of results this response holds, whether it was requested or defaulted to. |
| pokemon | object | – | What the `pokemon` filter resolved to. Absent when none was given. |
| size | integer | yes | The page size this response was built with, whether it was requested or defaulted to. It is the maximum number of results this page can hold, not the number it does hold — the last page holds fewer. |
| sort | string | yes | What the matches were ordered by, whether requested or defaulted to. |
| textSearch | object | – | How much an `attack` or `ability` search covered. Absent when neither was given. |
No examples provided.
How do I install the uk.co.leewinder/tcgdex MCP server?
uk.co.leewinder/tcgdex runs locally as an npm package, launched with npx -y @leewinder/mcp-tcgdex. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
npm · @leewinder/mcp-tcgdex
claude mcp add uk-co-leewinder-tcgdex -- npx -y @leewinder/mcp-tcgdex
What is the uk.co.leewinder/tcgdex MCP server?
uk.co.leewinder/tcgdex is an MCP server listed in the public MCP registry as uk.co.leewinder/tcgdex. MCP server exposing the TCGdex Pokémon TCG API to LLM tools. This page covers its npm package (@leewinder/mcp-tcgdex).
Is the uk.co.leewinder/tcgdex MCP server safe to use?
uk.co.leewinder/tcgdex scores 82 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. It declares no install or post-install scripts. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the uk.co.leewinder/tcgdex MCP server expose?
uk.co.leewinder/tcgdex exposes 7 tools: list_card_field_values, list_sets, search_cards, get_set, get_card, and 2 more. Their descriptions and schemas cost roughly 3,055 tokens of context every time the server is loaded.
Is the uk.co.leewinder/tcgdex MCP server still maintained?
uk.co.leewinder/tcgdex is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the uk.co.leewinder/tcgdex MCP server under?
uk.co.leewinder/tcgdex declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.