ebay-mcp
# ebay-mcp
MCP server for eBay buyer-side workflows: search, watch, bid, buy, manage MyeBay. Hybrid stack — modern Buy/Browse REST API for search and item lookup, legacy Trading API (still functional in 2026) for everything stateful.
> ⚠️ **Beta (v0.5.0).** Browse + Trading APIs wired, sandbox + production both supported. All 15 tools are production live-verified — including the three money-commit tools which have been used to close real eBay transactions through the safety stack (confirm-amount gate + $500 cap + OS-modal Yes/No dialog). Read the [money commits](#money-commits-high-risk--safety-gated) section before enabling production.
## Scope
### Read-only (low risk)
- `search`, `get_item` (Browse API)
- `get_watchlist`, `get_active_bids`, `get_won_items`, `get_lost_items`, `get_purchase_history` (Trading API)
### Watchlist writes (low risk — no money commit)
- `add_to_watchlist`, `remove_from_watchlist`
### Money commits (high risk — safety-gated)
- `place_bid(item_id, max_bid_amount, confirm_amount, ...)` — Trading `PlaceOffer` with `Action=Bid`. Proxy bid on an auction.
- `buy_now(item_id, confirm_amount, ...)` — Trading `PlaceOffer` with `Action=Purchase`. Commits to a Buy-It-Now sale.
- `make_best_offer(item_id, offer_amount, confirm_amount, ...)` — Trading `PlaceOffer` with `Action=BestOffer`. Submits an offer the seller can accept/counter/decline.
**Safety stack (every money tool):**
1. **Confirm-amount gate.** Every call requires `confirm_amount` exactly equal to the bid/buy/offer amount. The LLM has to repeat the dollar figure; mismatches return a structured refusal payload (not an exception) so the LLM can read it and retry with corrected params.
2. **$500 per-call cap.** Amounts above $500 refuse with `reason: "cap_exceeded"`. Two ways to authorize a higher spend:
- **Per-call:** pass `max_bid_override >= amount` on the tool call. Lower overrides refuse with `reason: "override_too_low"`.
- **Operator-wide:** set `EBAY_MCP_ALLOW_HIGH_VALUE=1` in the MCP server's environment.
3. **Human-in-the-loop confirm dialog.** After the programmatic gates clear, the MCP pops a topmost, system-modal Yes/No dialog (Windows: `MessageBoxW` via ctypes; macOS/Linux: `tkinter.messagebox`) showing the tool, host, item ID, amount, currency, and quantity. The default button is **NO**, ESC cancels, and there is no auto-dismiss or timeout. Click YES to send the call to eBay; anything else returns a `reason: "user_declined"` refusal and no Trading call fires. There is intentionally **no env-var bypass** — tests stub the dialog directly. Production-host dialogs carry a `*** PRODUCTION HOST — REAL MONEY ***` header; sandbox dialogs say `Sandbox host (no real money).`.
4. **Active-host visibility.** Successful calls against `default_host = "production"` include a `warning` field in the response (`"PRODUCTION HOST — this call committed real money on eBay."`). `server_info()` flags the active host before any call.
5. **No silent half-commits.** No auth token cached → the underlying Trading API call raises before touching eBay, not mid-flight.
All money tools also surface eBay-side errors (insufficient bid, currency mismatch, listing ended, etc.) as `TradingApiError` with the parsed `Errors` block attached.
### Out of scope (v0)
- ❌ Selling side (use eBay's Sell API directly for that — different shape entirely)
- ❌ Snipe-bidding with auto-trigger (one tool call = one bid, no scheduling)
- ❌ Multi-account: v0 is one user account per host config; add multi-account later if needed
## Install
> Not yet on PyPI. From source:
```bash
git clone https://github.com/acato/ebay-mcp
cd ebay-mcp
uv sync
uv run ebay-mcp
```
### Windows: avoid Microsoft Store Python
If `uv` picks Microsoft Store Python (path under `\WindowsApps\PythonSoftwareFoundation...`) when creating the venv, the MCP runs fine from a terminal but fails to launch from GUI hosts like the Claude desktop app, IDE extensions, or scheduled tasks. You will see:
```
Unable to create process using "...\WindowsApps\PythonSoftwareFoundation.Python.3.12_...\python.exe"
```
Pin `uv` to a non-Store interpreter — uv's managed Python is easiest:
```powershell
uv python install 3.12
uv venv --python 3.12 --python-preference only-managed --clear
uv sync
```
Verify: `Get-Content .venv\pyvenv.cfg` — the `home =` line should point under `AppData\Roaming\uv\python\...`, **not** `\WindowsApps\`.
## Configure
Sandbox-first. Get your sandbox keyset from [developer.ebay.com](https://developer.ebay.com) → Application Keysets → Sandbox. Copy `examples/config.toml` to `~/.config/ebay-mcp/config.toml`:
```toml
default_host = "sandbox"
[hosts.sandbox]
app_id = "..." # SBX App ID (Client ID)
dev_id = "..." # Developer Account Dev ID
cert_id = "..." # SBX Cert ID (Client Secret) — env var preferred
redirect_uri = "https://localhost/oauth/callback"
# [hosts.production]
# app_id = "..."
# dev_id = "..."
# cert_id = "..."
# redirect_uri = "https://localhost/oauth/callback"
```
Per-host env vars override file values:
- `EBAY_MCP_<HOST>_CERT_ID` — overrides `cert_id` (recommended for production)
- `EBAY_MCP_<HOST>_APP_ID`, `EBAY_MCP_<HOST>_DEV_ID` — overrides for completeness
User-level OAuth tokens cache to `~/.config/ebay-mcp/token-cache-<host>.json` automatically after the manual authorization-code flow (see `auth.py` docs once Day 1b lands).
## Use with Claude Code
```bash
claude mcp add ebay-mcp -- uv run --directory /path/to/ebay-mcp ebay-mcp
```
## Use with Claude Desktop
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"ebay-mcp": {
"command": "C:\\Users\\you\\AppData\\Local\\Microsoft\\WinGet\\Links\\uv.exe",
"args": ["run", "--directory", "C:\\path\\to\\ebay-mcp", "ebay-mcp"]
}
}
}
```
## Documentation
- [DESIGN.md](DESIGN.md) — architecture, tool surface, safety patterns, OAuth flow
- [CONTRIBUTING.md](CONTRIBUTING.md) — dev setup, sandbox testing, release process
## License
Apache 2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE).
## Trademarks
"eBay" is a trademark of eBay Inc. This project is an independent integration with the standard eBay public APIs and is not affiliated with, endorsed by, or sponsored by eBay Inc.
TDQS
Scored across 15 tools
Each tool targets a distinct operation (search, watchlist CRUD, bidding, buying, auth, etc.). Overlapping tools like get_watchlist, get_active_bids, get_lost_items, get_won_items are clearly distinguished by state and documented. No ambiguity.
All tool names use lowercase with underscores and follow a consistent verb_noun pattern (e.g., add_to_watchlist, get_item, place_bid, buy_now, start_user_auth). No mixed conventions or cryptic names.
15 tools is well-scoped for the server's purpose (eBay buyer operations). Every tool covers a necessary function without redundancy, and the count is within the ideal 3-15 range.
Covers all core buyer actions: search, item details, authentication, watchlist, bidding, buying (BIN and Best Offer), and purchase history (won/lost/active). Minor gaps exist (e.g., no tool for seller messaging or order cancellation), but the primary workflow is complete.