ebay-mcp
Expose eBay's marketplace to Claude over theModel Context Protocol. Claude can searchactive listings, analyse price distributions, surface deals priced below themarket median, and produce a market-research overview — all as structured JSON itcan reason about.
It answers questions like:
- What does a used Nintendo Switch OLED actually sell for right now?
- Find me listings priced well below the going rate.
- Give me a market overview: price spread, condition mix, who's selling, and shipping.
How it works
OAuth2 (client credentials)
│
┌────────┐ tools ┌──────┴───────┐ HTTPS ┌──────────────────┐
│ Claude │ ────────► │ ebay-mcp │ ────────► │ eBay Buy Browse │
│ │ ◄──────── │ MCP server │ ◄──────── │ API │
└────────┘ JSON └──────────────┘ └──────────────────┘
The server authenticates to eBay with the OAuth2 client-credentials grant(caching and refreshing the application token), calls the Buy Browse API,normalises the verbose responses into typed objects, and runs price/marketanalysis locally before handing JSON back to Claude.
The code is layered so the analysis is testable without the network:
config.py— environment-driven configuration.models.py— typed value objects parsed from eBay JSON.auth.py— OAuth token caching/refresh (concurrency-safe).client.py— the only module that talks to eBay; retries + filter grammar.analysis.py— pure price/deal/market functions.server.py— the MCP tools.
Tools
| Tool | What it does |
|---|---|
search_products |
Search active listings (sort, condition, price range, free-shipping filters). |
analyze_prices |
Price distribution for a query: min/max, mean, median, p25/p75/p90, stdev. |
find_deals |
Listings priced at least N% below the market median, ranked by discount. |
market_research |
Full overview: price stats, condition mix, price-by-condition, shipping, seller locations, observations. |
get_item_details |
Full details for a single listing by item id. |
All prices are isolated to a single currency and, unless noted, reflect totalcost (item + shipping).
Setup
Requires Python 3.10+ and an eBay developer account.
Create an application at https://developer.ebay.com/my/keys and copy theApp ID (Client ID) and Cert ID (Client Secret).
Install:
git clone https://github.com/luke-nielsen/ebay-mcp.git cd ebay-mcp python3 -m venv .venv && source .venv/bin/activate pip install -e ".[dev]"Configure credentials (copy
.env.exampleto.env, or export directly):export EBAY_CLIENT_ID=your-app-id export EBAY_CLIENT_SECRET=your-cert-idVerify connectivity:
ebay-mcp check ebay-mcp search "nintendo switch oled" --limit 5 ebay-mcp research "airpods pro 2"
Connecting to Claude
Add the server to your MCP host. For Claude Code:
claude mcp add ebay -- ebay-mcp serve
Or use the bundled .mcp.json (it reads EBAY_CLIENT_ID / EBAY_CLIENT_SECRETfrom your environment). The server speaks MCP over stdio.
Configuration
| Variable | Default | Description |
|---|---|---|
EBAY_CLIENT_ID |
— | App ID (Client ID). Required. |
EBAY_CLIENT_SECRET |
— | Cert ID (Client Secret). Required. |
EBAY_ENVIRONMENT |
production |
production or sandbox. |
EBAY_MARKETPLACE_ID |
EBAY_US |
e.g. EBAY_GB, EBAY_DE, EBAY_AU. |
EBAY_DELIVERY_COUNTRY |
— | Buyer country for shipping estimates. |
EBAY_DELIVERY_POSTAL_CODE |
— | Buyer postal code for shipping estimates. |
EBAY_TIMEOUT |
20 |
Per-request timeout (seconds). |
EBAY_MAX_RETRIES |
3 |
Retry attempts for transient failures. |
Development
pip install -e ".[dev]"
pytest # run the test suite
ruff check . # lint
The networking layer is exercised with httpx.MockTransport, so the full suiteruns offline and needs no credentials.
Notes & limitations
- Uses the Buy Browse API, which covers active listings. Sold/completedprice history requires eBay's restricted Marketplace Insights API and is out ofscope here; "market" statistics are therefore over current asking prices.
- The client-credentials token grants access to public search only — nouser-specific or order data.
- eBay rate limits the Browse API (default ~5,000 calls/day); the analysis toolsspend one call each.
License
MIT — see LICENSE.