get_item
Fetch detailed Vinted item info including price, photos, and seller details by item ID or URL. Automatically falls back to HTML scraping when API is unavailable.
Instructions
Fetch complete item details by Vinted item ID (with country) or by a direct Vinted item URL. Returns title, price, currency, brand, size, condition, full description, all photo URLs, creation date, item URL, favourite count, and seller username/ID. Automatically falls back to HTML scraping when the JSON API is unavailable.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| itemId | No | Numeric Vinted item ID, e.g. 5678901234 | |
| url | No | Full Vinted item URL, e.g. "https://www.vinted.fr/items/5678901234-nike-air-max". Country is inferred from the URL automatically. | |
| country | No | Country site (required when using itemId; inferred automatically when url is provided) | |
| browser | No | Use headless browser for retrieval. Requires optional Playwright deps; only needed for items blocked by bot detection. |
Implementation Reference
- src/ops/get-item.ts:29-59 (handler)Primary handler function for the 'get_item' tool. Parses input (itemId/url/country), decides whether to use a headless browser or the API, and returns the complete ItemDetail.
export async function opGetItem( client: VintedClient, input: { itemId?: number; url?: string; country?: Country; browser?: boolean }, ): Promise<ItemDetail> { const { id, country } = parseItemRef(input); const useBrowser = input.browser ?? (process.env.VINTED_BROWSER === '1' || process.env.VINTED_STEALTH === '1'); if (!useBrowser) return getItem(client, id, country); const data: any = await fetchItemDetailsViaBrowser(id, country, { proxyUrl: client.proxyUrl }); const i = data.item ?? data; return { id: Number(i.id ?? id), title: String(i.title ?? ''), price: String(i.price?.amount ?? i.price ?? ''), currency: String(i.price?.currency_code ?? i.currency ?? ''), brand: i.brand_dto?.title ?? i.brand, size: i.size_title ?? i.size, condition: i.status, description: i.description, photos: (i.photos ?? []).map((p: any) => p.full_size_url ?? p.url).filter(Boolean), createdAt: i.created_at_ts ?? i.created_at, url: i.url ?? `https://${DOMAIN[country]}/items/${id}`, favouriteCount: i.favourite_count, seller: { id: Number(i.user?.id ?? 0), username: String(i.user?.login ?? i.user?.username ?? ''), }, raw: i, }; } - src/mcp.ts:46-58 (schema)MCP tool registration with input schema for 'get_item'. Defines itemId (integer), url (string), country (enum), and browser (boolean) as input properties.
{ name: 'get_item', description: 'Fetch complete item details by Vinted item ID (with country) or by a direct Vinted item URL. Returns title, price, currency, brand, size, condition, full description, all photo URLs, creation date, item URL, favourite count, and seller username/ID. Automatically falls back to HTML scraping when the JSON API is unavailable.', inputSchema: { type: 'object', properties: { itemId: { type: 'integer', description: 'Numeric Vinted item ID, e.g. 5678901234' }, url: { type: 'string', description: 'Full Vinted item URL, e.g. "https://www.vinted.fr/items/5678901234-nike-air-max". Country is inferred from the URL automatically.' }, country: { type: 'string', enum: COUNTRIES, description: 'Country site (required when using itemId; inferred automatically when url is provided)' }, browser: { type: 'boolean', default: false, description: 'Use headless browser for retrieval. Requires optional Playwright deps; only needed for items blocked by bot detection.' }, }, }, }, - src/mcp.ts:220-220 (registration)MCP request handler switch case that dispatches the 'get_item' tool name to the opGetItem function.
case 'get_item': result = await opGetItem(c, a as any); break; - src/ops/get-item.ts:15-27 (helper)Helper function that parses the input to extract item ID and country from either a URL or direct itemId/country arguments.
export function parseItemRef(input: { itemId?: number; url?: string; country?: Country }): { id: number; country: Country } { if (input.url) { const m = input.url.match(URL_RE); if (!m) throw new Error(`Invalid Vinted URL: ${input.url}`); return { id: Number(m[2]), country: DOMAIN_TO_CC[m[1].toLowerCase()] ?? 'fr' }; } if (input.itemId) { const c = input.country ?? 'fr'; if (!COUNTRIES.includes(c)) throw new Error(`Unknown country: ${c}`); return { id: input.itemId, country: c }; } throw new Error('Provide itemId or url'); } - src/client/endpoints.ts:58-88 (helper)Low-level API client function that fetches item details from Vinted API endpoint, with HTML/JSON-LD fallback when the API fails.
export async function getItem( client: VintedClient, itemId: number, country: Country = 'fr', ): Promise<ItemDetail> { try { const data = await client.apiGet<{ item: any }>(country, `/api/v2/items/${itemId}/details`); const i = data.item ?? data; return { id: Number(i.id), title: String(i.title ?? ''), price: String(i.price?.amount ?? i.price ?? ''), currency: String(i.price?.currency_code ?? i.currency ?? ''), brand: i.brand_dto?.title ?? i.brand, size: i.size_title ?? i.size, condition: i.status, description: i.description, photos: (i.photos ?? []).map((p: any) => p.full_size_url ?? p.url).filter(Boolean), createdAt: i.created_at_ts ?? i.created_at, url: i.url ?? `https://${DOMAIN[country]}/items/${itemId}`, favouriteCount: i.favourite_count, seller: { id: Number(i.user?.id ?? 0), username: String(i.user?.login ?? i.user?.username ?? ''), }, raw: i, }; } catch (err) { return getItemFromHtml(client, itemId, country, err); } }