# KH Merch Graph MCP Server > An MCP (Model Context Protocol) server that turns a Japanese secondhand-listing title/description for Kingdom Hearts merchandise into a canonical SKU match, condition-term explanation, bootleg caution flags, and a price/landed-cost estimate. ## What makes this different - The catalog behind this server is not scraped or LLM-inferred: every SKU is checked by a human against a primary source (official product page, etc.), recorded in `source_url`. - When match confidence is low, this server does not guess. Low-confidence matches are returned separately as `weak_matches`, never mixed into `candidates` — a calling agent should treat an empty `candidates` array as "probably not in the catalog," not as a failure. - This server never scrapes marketplaces itself (Bring Your Own Listing). You pass it listing text you already have; it never fetches or stores it beyond the single request. ## Connect - MCP endpoint (Streamable HTTP, no auth, JSON-RPC 2.0): `https://mcp.merchgraph.app/mcp` - Health check: `https://mcp.merchgraph.app/health` - Machine-readable reference of the same tool schemas below: `https://mcp.merchgraph.app/openapi.json` (documentation aid only — the real transport is MCP JSON-RPC over `/mcp`, not REST; call `tools/list` on `/mcp` for the authoritative, live schema) - Plain GET convenience endpoint for uptime/monitoring checks (same rate limit as `/mcp`, no usage logging): `GET https://mcp.merchgraph.app/v1/resolve?title=...` returns the same JSON as calling `resolve_listing` — this is for automated health checks, not the primary way to use this server (use MCP `/mcp` for that) ## Tools - `resolve_listing(title, description?, price_jpy?, platform?, url?)` — identify a listing's SKU, condition terms, bootleg-caution flags, and price-to-MSRP ratio. Each candidate includes `source_url` so you can verify it yourself. - `resolve_listings_batch(listings[])` — the same as `resolve_listing`, for up to 5 listings in one call (each item takes the same arguments). Results come back as an array in the same order as the input; an item that fails is `{ error }` instead of failing the whole call. For more than 5 listings, split into chunks of 5. Prefer this over calling `resolve_listing` once per listing. - `explain_product(sku_id | query)` — full detail on one SKU: product line, character, dimensions, rerelease history, primary source. - `discover(ip, character?, budget_jpy?, purpose?, limit?)` — browse the catalog by IP/character/budget/purpose. Does not confirm anything is currently listed for sale anywhere. - `estimate_landed_cost(price_jpy, sku_id|weight_g, dest_country, proxy?)` — proxy-service + shipping cost estimate to a destination country. - `report_correction(sku_id?, field, proposed_value, source_url?, note?)` — report a catalog error, or propose a new SKU, backed by a primary source. ## Scope and limits - Supported IP today: Kingdom Hearts only (`ip = "kingdom-hearts"`). Requests naming other franchises are noted (by keyword only) to help prioritize what to add next — they are not silently ignored, but they are also not answered yet. - Authenticity notes are caution flags for the calling agent to weigh, not a verdict that an item is genuine or fake. - Prices and landed-cost totals are estimates for planning, not quotes or appraisals. - `msrp_jpy` is always in yen. For items released outside Japan it is the original price (`price_local` + `currency`, e.g. 39.99 USD) converted at a fixed, periodically refreshed rate (`discover` returns the rates it used as `fx_rates_to_jpy`), so `budget_jpy` compares like with like. - This server does not browse, log in to, or purchase from any marketplace. It only interprets text you send it.