ebay-mcp
This server provides a full eBay buyer-side workflow integration, enabling search, watchlist management, bidding, and purchasing through a safety-gated MCP interface.
Search & Item Discovery
search— Search eBay listings by keyword with filters for category, condition, price range, currency, sort order, and marketplaceget_item— Fetch full details for a specific item by ID, including description, shipping, seller info, and return terms
MyeBay Reading
get_watchlist— View your currently watched itemsget_active_bids— See auctions where you have active bidsget_won_items/get_purchase_history— List items won or purchasedget_lost_items— View auctions you bid on but didn't win
Watchlist Management
add_to_watchlist/remove_from_watchlist— Manage your eBay watchlist (reversible, no money committed)
Money-Committing Actions (safety-gated: confirm-amount match, $500 cap, human-in-the-loop OS dialog)
place_bid— Place a proxy bid on an auctionbuy_now— Instantly purchase a Buy It Now listingmake_best_offer— Submit a Best Offer on eligible listings
Authentication
start_user_auth/complete_user_auth— OAuth2 flow to obtain and manage user tokens
Server Management
server_info— Get server version, active host (sandbox/production), and config locationslist_hosts— List all configured hosts with their status and credential availability
Allows interacting with eBay's APIs to search items, manage watchlist, place bids, buy items, and retrieve purchase history.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ebay-mcp search for vintage leather jacket"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 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, ...)— TradingPlaceOfferwithAction=Bid. Proxy bid on an auction.buy_now(item_id, confirm_amount, ...)— TradingPlaceOfferwithAction=Purchase. Commits to a Buy-It-Now sale.make_best_offer(item_id, offer_amount, confirm_amount, ...)— TradingPlaceOfferwithAction=BestOffer. Submits an offer the seller can accept/counter/decline.
Safety stack (every money tool):
Confirm-amount gate. Every call requires
confirm_amountexactly 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.$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 >= amounton the tool call. Lower overrides refuse withreason: "override_too_low".Operator-wide: set
EBAY_MCP_ALLOW_HIGH_VALUE=1in the MCP server's environment.
Human-in-the-loop confirm dialog. After the programmatic gates clear, the MCP pops a topmost, system-modal Yes/No dialog (Windows:
MessageBoxWvia 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 areason: "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 saySandbox host (no real money)..Active-host visibility. Successful calls against
default_host = "production"include awarningfield in the response ("PRODUCTION HOST — this call committed real money on eBay.").server_info()flags the active host before any call.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
Related MCP server: SlimWeb Client MCP
Install
Not yet on PyPI. From source:
git clone https://github.com/acato/ebay-mcp
cd ebay-mcp
uv sync
uv run ebay-mcpWindows: 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:
uv python install 3.12
uv venv --python 3.12 --python-preference only-managed --clear
uv syncVerify: 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 → Application Keysets → Sandbox. Copy examples/config.toml to ~/.config/ebay-mcp/config.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— overridescert_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
claude mcp add ebay-mcp -- uv run --directory /path/to/ebay-mcp ebay-mcpUse with Claude Desktop
Add to claude_desktop_config.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 — architecture, tool surface, safety patterns, OAuth flow
CONTRIBUTING.md — dev setup, sandbox testing, release process
License
Apache 2.0. See LICENSE and 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.
Available Tools
15 toolsadd_to_watchlistA
Add an item to the authenticated user's watchlist.
Trading API AddToWatchList. Fully reversible — call
remove_from_watchlist with the same item_id to undo.
Args:
item_id: numeric eBay item ID (from search, get_item, etc.)
host: configured host. Defaults to default_host.
Returns:
dict with host, item_id, added: True, and
watch_list_count (total items in the watchlist after the
operation). Raises ValueError on empty item_id.
On eBay-side errors (item ended, already watched, etc.) the
Trading API raises TradingApiError with details.
Inputs: item_id (required), host. Returns: object
buy_nowA
Purchase a Buy It Now listing immediately at the listed price.
Trading API PlaceOffer with Action=Purchase. The buyer commits to pay the listing's BIN price; eBay creates the order on success.
PRODUCTION HOST WARNING: when the active host is "production", a successful call commits real money on eBay. Inspect server_info() or list_hosts() before committing.
Args: item_id: numeric eBay item ID. Get from search() or get_item(). confirm_amount: must equal the listing's Buy-It-Now price exactly. The repeated dollar amount is a safety gate against stale prices or typos. Look up the current price with get_item() right before calling. quantity: number of units to purchase (default 1). Multi-quantity BIN listings can have a per-buyer limit; eBay rejects with TradingApiError if violated. currency: ISO currency code matching the listing (default "USD"). max_bid_override: optional ceiling that authorizes amounts above the $500 per-call safety cap. Pass a value >= confirm_amount to bypass the cap for this call. host: configured host name. Defaults to default_host.
Returns: On success: dict with host, item_id, action="Purchase", amount, currency, quantity, placed=True, and (on production) a warning. On safety-gate failure: structured refusal payload. Raises ValueError / TradingApiError as in place_bid.
Inputs: item_id (required), confirm_amount (required), quantity, currency, +2 more. Returns: object
complete_user_authA
Finish OAuth2 user auth by exchanging the authorization code for tokens.
The code is the value of the code query parameter in the URL eBay
redirected to after start_user_auth's auth_url. Optionally pass state
to verify against what start_user_auth issued (CSRF defense).
Args:
code: the authorization code from eBay's redirect URL.
state: optional — the state value from the redirect URL. If provided,
must match what start_user_auth stored. Mismatch returns a
structured refusal payload.
host: which configured host to authenticate against. Defaults to
config's default_host. Must match the host used in
start_user_auth.
Returns: On success: {host, authenticated: true, access_expires_at, refresh_expires_at} On state mismatch: {refused: true, reason: "state_mismatch", host, message: ...}
Inputs: code (required), state, host. Returns: object
get_active_bidsA
Return auctions where the user has a currently-active bid.
Trading API GetMyeBayBuying.BidList. Includes both winning and outbid items still in their bidding period.
Same response shape as get_watchlist. Empty hits + total=0 means
you have no active bids.
Inputs: limit, offset, host. Returns: object
get_itemA
Fetch full details for a single eBay item by ID.
Args:
item_id: the eBay item ID (e.g., "v1|353528728623|0"). Get these from
search() results.
marketplace: eBay marketplace ID (default "EBAY_US").
host: which configured host to use. Defaults to config's default_host.
Returns: Full item dict including description, shipping options, seller details, return terms, item location, and the standard summary fields. If the item doesn't exist or has ended, returns {"item_id": item_id, "host": host, "missing": true}.
Inputs: item_id (required), marketplace, host. Returns: object
get_lost_itemsA
Return auctions where the user bid but did not win.
Trading API GetMyeBayBuying.LostList. Default lookback ~30 days; older items roll off.
Same response shape as get_watchlist.
Inputs: limit, offset, host. Returns: object
get_watchlistA
Return the authenticated user's watched items.
Uses Trading API GetMyeBayBuying with the WatchList container.
Requires that the user has authenticated via start_user_auth +
complete_user_auth for the chosen host.
Args: limit: items per page (1-200). Default 100. offset: pagination offset. Trading API pages from 1; we translate. host: configured host name. Defaults to default_host.
Returns:
dict with host, container, total, limit, offset, and
hits (a list of item summaries: item_id, title, price, currency,
ends_at, bid_count, seller, web_url, listing_type,
quantity_available).
Inputs: limit, offset, host. Returns: object
get_won_itemsA
Return items the user won at auction or bought via Buy It Now.
Trading API GetMyeBayBuying.WonList. This is your effective "purchase history" for the eBay-native default lookback window (eBay shows the last 30 days by default; older items roll off the WonList container).
Same response shape as get_watchlist.
Inputs: limit, offset, host. Returns: object
list_hostsA
List every configured host with its status (default flag and cert availability).
Useful for diagnosing why a tool call against a particular host might fail before you make the call.
Inputs: no named parameters. Returns: result
make_best_offerA
Submit a Best Offer on a listing that has Best Offer enabled.
Trading API PlaceOffer with Action=BestOffer. The seller can accept, counter, or decline; this call only places the offer.
PRODUCTION HOST WARNING: when the active host is "production" and the seller accepts, the offer becomes a binding sale at the offer amount.
Args:
item_id: numeric eBay item ID. Must have Best Offer enabled —
check buying_options on get_item() output for "BEST_OFFER".
offer_amount: the price the buyer offers, in currency. Must be
> 0. Many sellers configure auto-decline below a threshold.
confirm_amount: must equal offer_amount exactly. Safety gate.
quantity: number of units the offer covers (default 1).
currency: ISO currency code matching the listing (default "USD").
max_bid_override: optional ceiling that authorizes offer amounts
above the $500 per-call safety cap. Pass a value >=
offer_amount to bypass.
host: configured host name. Defaults to default_host.
Returns: On success: dict with host, item_id, action="BestOffer", amount, currency, quantity, placed=True, optionally best_offer_id (for follow-up via Trading GetBestOffer / Accept flows), and (on production) a warning. On safety-gate failure: structured refusal payload. Raises ValueError / TradingApiError as in place_bid.
Inputs: item_id (required), offer_amount (required), confirm_amount (required), quantity, +3 more. Returns: object
place_bidA
Place a proxy bid on an eBay auction.
Trading API PlaceOffer with Action=Bid. eBay treats max_bid_amount as a proxy ceiling — it bids the minimum needed to outbid the current high bidder, and continues raising up to max_bid_amount as competing bids come in.
PRODUCTION HOST WARNING: when the active host is "production", a successful call commits real money on eBay. Inspect server_info() or list_hosts() before committing.
Args:
item_id: numeric eBay item ID. Get from search() or get_item().
max_bid_amount: the proxy bid ceiling in currency. Must be > 0.
confirm_amount: must equal max_bid_amount exactly. The repeated
dollar amount is a safety gate against typos.
quantity: number of units (default 1; only relevant for
multi-quantity auctions).
currency: ISO currency code matching the listing (default "USD").
Must match the listing's currency or eBay refuses.
max_bid_override: optional ceiling that authorizes amounts above
the $500 per-call safety cap. Pass a value >= max_bid_amount
to bypass the cap for this call. Lower values are refused.
host: configured host name. Defaults to default_host. The active
host (sandbox vs production) is surfaced in the response.
Returns: On success: dict with host, item_id, action="Bid", amount, currency, placed=True, current_price, minimum_to_outbid, high_bidder, and (on production) a warning field. On safety-gate failure: structured refusal payload (refused=True, reason, message, plus the offending values). Raises ValueError on empty item_id, non-positive amounts, etc. On eBay-side errors (listing ended, currency mismatch, insufficient bid, etc.) raises TradingApiError.
Inputs: item_id (required), max_bid_amount (required), confirm_amount (required), quantity, +3 more. Returns: object
remove_from_watchlistA
Remove an item from the authenticated user's watchlist.
Trading API RemoveFromWatchList. Fully reversible — call
add_to_watchlist with the same item_id to undo.
Args: item_id: numeric eBay item ID currently on the watchlist. host: configured host. Defaults to default_host.
Returns:
dict with host, item_id, removed: True, and
watch_list_count (total items in the watchlist after the
operation). Raises ValueError on empty item_id. eBay-side
errors (item not on watchlist, etc.) surface as TradingApiError.
Inputs: item_id (required), host. Returns: object
searchA
Search eBay items via the Browse API.
Args:
query: keyword search string. Required.
category_id: numeric eBay category ID to restrict the search.
condition: one of NEW, LIKE_NEW, NEW_OTHER, USED_EXCELLENT,
USED_VERY_GOOD, USED_GOOD, USED_ACCEPTABLE, FOR_PARTS_OR_NOT_WORKING,
MANUFACTURER_REFURBISHED, CERTIFIED_REFURBISHED, or several other
refurbished tiers. Case-sensitive.
min_price: minimum item price (in currency).
max_price: maximum item price (in currency).
currency: ISO currency code for the price filter (default "USD").
sort: one of "best_match" (default), "price_asc", "price_desc",
"newly_listed", "ending_soonest".
limit: number of hits per page. Default 20, hard cap 200.
offset: pagination offset.
marketplace: eBay marketplace ID (default "EBAY_US"). Other examples:
"EBAY_GB", "EBAY_DE", "EBAY_IT".
host: which configured host to use ("sandbox" or "production"). If
omitted, uses the config's default_host.
Returns: dict with: - host: which host was actually targeted - total: total matching items per eBay - limit, offset, next_offset (None when there's no next page) - hits: list of item summaries (item_id, title, price, currency, condition, seller, image_url, ends_at, buying_options, web_url, bid_count if applicable)
Inputs: query (required), category_id, condition, min_price, +7 more. Returns: object
server_infoA
Return server version, active host, and configuration locations.
The active_host field reflects what default_host is set to (or what
would be used when a tool call omits the host parameter). When set to
"production", the response includes a warning field — real money is
at stake on bid/buy operations.
Inputs: no named parameters. Returns: object
start_user_authA
Begin OAuth2 user authentication for buyer-side eBay operations.
Watchlist, MyeBay reads, bidding, and buying all require a user token.
This tool returns an auth_url for you (the human) to open in a browser.
After signing in and granting permissions, eBay redirects to the
configured redirect_uri with a code query parameter — pass that to
complete_user_auth to finalize.
Most workflows only run this once per host; tokens persist 18 months and auto-refresh.
Args:
host: which configured host to authenticate against. Defaults to
config's default_host.
Returns:
dict with host, auth_url, state, and instructions. The
auth_url is what the human needs to open; the state is
round-tripped to verify the callback genuinely came from this flow.
Inputs: host. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
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.
Maintenance
Related MCP Connectors
MCP server for Product Management
E-commerce MCP gateway: live product deals, attributed buy links, order tracking, flights.
Search eBay sold and active listings, browse categories, and retrieve item details.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMinimal MCP server for searching eBay listings via the Browse API, enabling keyword search with filters, sorting, pagination, and retrieving full item details.1MIT
- FlicenseNot gradedqualityDmaintenanceConsumer-side MCP server for Webless storefront operations, enabling catalog browsing, product search, and order lookup via tools.-
- AlicenseNot gradedqualityBmaintenanceAn MCP server providing AI assistants comprehensive access to eBay's Sell APIs for inventory management, order fulfillment, marketing, analytics, and more, with hosted multi-user and local modes.37 npm5MIT
- FlicenseNot gradedqualityDmaintenanceMCP server providing unified access to eBay, Shopify, Best Buy, and Etsy marketplace data via the Commerce API, enabling product searches and listing retrieval across multiple retailers.-