Give Claude or ChatGPT Real eBay Sold Prices (Tool Calling and MCP)

Ask an AI assistant what a used Nintendo 64 sells for and you'll get a confident number. Ask where it came from and things get vague. eBay blocks most AI crawlers in its robots.txt and hides sold results behind a sign-in, so assistants are working from old or secondhand data.
The fix is a tool: give the agent a function that fetches real sold prices.
The failure to design against
One open-source eBay tool's issue tracker describes it well: the assistant "didn't surface the failed tool call and instead searched the web for completed listings," then answered anyway. The user got a number with no real data behind it.
So the tool's job isn't only to return prices. It has to make "I don't know" impossible to paper over.
The tool
// One tool, explicit statuses. Works for OpenAI, Anthropic or any tool-calling model.
export const soldPriceTool = {
name: "get_sold_prices",
description:
"Recent eBay sold prices (last 90 days) for an exact item. Use precise queries: brand + model, " +
"or card name + set + number + grade in quotes. Quote only the numbers returned. If status is not 'ok', say no reliable price is available.",
input_schema: {
type: "object",
properties: {
q: { type: "string", description: "e.g. 'nintendo 64 console' or 'charizard 4/102 \"psa 9\"'" },
condition: { type: "string", enum: ["new", "used", "for_parts"] },
},
required: ["q"],
},
};
export async function getSoldPrices({ q, condition }) {
const url = new URL("https://api.soldcomps.io/v1/sold");
url.searchParams.set("q", q);
if (condition) url.searchParams.set("condition", condition);
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.SALEHISTORY_KEY}` } });
if (!res.ok) return { status: "unavailable", http: res.status };
const d = await res.json();
const sales = d.count - d.stats.excluded;
if (sales === 0) return { status: "no_sales", query: q };
return {
status: sales < 5 ? "thin" : "ok",
median: d.stats.median, p25: d.stats.p25, p75: d.stats.p75, sales, currency: d.stats.currency,
recent: d.items.slice(0, 5).map((i) => ({ title: i.title, price: i.sold_price.value, sold_at: i.sold_at, url: i.url })),
};
}
Returning recent sales with links lets the model cite them, and lets the user check them.
As an MCP server
To use it from Claude Desktop or another MCP client, wrap the same function in a tiny MCP server:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { getSoldPrices } from "./sold.js";
const server = new McpServer({ name: "ebay-sold-prices", version: "1.0.0" });
server.tool(
"get_sold_prices",
"Recent eBay sold prices for an exact item. Quote only returned numbers.",
{ q: z.string(), condition: z.enum(["new", "used", "for_parts"]).optional() },
async (args) => ({ content: [{ type: "text", text: JSON.stringify(await getSoldPrices(args)) }] }),
);
await server.connect(new StdioServerTransport());
Register it in your client's MCP config with SALEHISTORY_KEY in its environment.
System prompt rules that help
- Use the tool for any "what's it worth / what does it sell for" question.
- Build precise queries; for cards, one query per grade.
- Quote the median and the sale count; link a recent sale.
- If the status isn't
ok, say there's no reliable price. Never estimate.
Why agents need a hosted source
An agent that scrapes eBay itself runs into the same walls scrapers do: the sign-in wall, IP blocks, and pages that parse as "0 results." A hosted API turns that into one call that either returns data or a clear error. Why empty results are the dangerous failure.
Frequently asked questions
Can ChatGPT or Claude look up eBay sold prices?
Not reliably on their own. eBay blocks most AI crawlers in robots.txt and requires sign-in for sold results, so assistants fall back to stale or secondhand data. Give them a tool that calls a sold-listings API.
Is there an eBay MCP server for sold prices?
You can build one in a few dozen lines: an MCP server with one tool that calls a sold-listings API and returns the median, range and recent sales. Clients like Claude Desktop can then use it.
How do I stop an AI agent from making up prices?
Return explicit statuses from the tool (ok, no_sales, unavailable), include the sale count, and instruct the model to quote only the tool's numbers and to say when there's no data.
Sources
- eBay robots.txt (August 2026) (accessed Oct 23, 2026)
- ebay-mcp issue #201: failed sold tool call hidden by the assistant (Oct 2026) (accessed Oct 23, 2026)
- Model Context Protocol: introduction (accessed Oct 23, 2026)
SaleHistory sells an eBay sold-listings API, so we have a commercial interest in this topic. We link primary sources so you can check our work. Spotted something out of date? Email hello@soldcomps.io.