MCP Server

Voxcars (Portugal)

eu.voxs/voxcars-pt
Commerce & Retail Search & Research Public & reachable MCP 2026-07-28

What this MCP does

Searches Portuguese used-car listings, retrieves vehicle details, compares similar cars, provides market price statistics, and searches automotive articles.

find_similar_cars
Given one listing, find comparable ones: same make, similar year, mileage and price band. Use this when the user likes a car but wants alternatives — 'find me something similar', 'the same but cheaper', 'what else is around this price'. Pass `maxPrice` for the cheaper case; without it, comparables are drawn from a band around the reference price. Comparability is by structure (make/model/year/km/price), not by text similarity: it answers 'is this well priced for what it is', which a keyword search cannot.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['slug'], 'properties': {'slug': {'type': 'string', 'description': 'Slug of the reference listing, as returned by search_cars or get_car_detail.'}, 'limit': {'type': 'number', 'description': 'Maximum number of comparables (default 6, max 20).'}, 'maxPrice': {'type': 'number', 'description': "Optional budget ceiling, in EUR. Use it for 'similar but cheaper'; it overrides the default band around the reference price."}}}
Output schema
{'type': 'object', 'required': ['market', 'reference', 'total', 'cars'], 'properties': {'cars': {'type': 'array', 'items': {'type': 'object', 'required': ['slug', 'url', 'title', 'make', 'model', 'currency', 'publishedAt'], 'properties': {'km': {'type': ['number', 'null']}, 'url': {'type': 'string', 'description': "Canonical listing page on this market's domain."}, 'body': {'type': ['string', 'null']}, 'fuel': {'type': ['string', 'null']}, 'make': {'type': 'string'}, 'slug': {'type': 'string', 'description': 'Stable identifier; pass to get_car_detail or find_similar_cars.'}, 'year': {'type': ['number', 'null']}, 'model': {'type': 'string'}, 'price': {'type': ['number', 'null'], 'description': 'null means the source does not publish a price (on request).'}, 'title': {'type': 'string'}, 'source': {'type': ['string', 'null'], 'description': 'Aggregator platform the listing came from; null when published directly with us.'}, 'variant': {'type': ['string', 'null']}, 'currency': {'type': 'string', 'description': 'ISO 4217 code of this market.'}, 'district': {'type': ['string', 'null']}, 'power_cv': {'type': ['number', 'null'], 'description': 'Engine power in metric horsepower (CV/PS).'}, 'condition': {'type': ['string', 'null']}, 'sourceUrl': {'type': ['string', 'null'], 'description': 'Original listing URL at the source. Cite this alongside url.'}, 'sellerType': {'enum': ['STAND', 'PARTICULAR', None], 'type': ['string', 'null']}, 'publishedAt': {'type': 'string', 'description': 'ISO 8601 date the listing was first seen at the source.'}, 'transmission': {'type': ['string', 'null']}}}}, 'total': {'type': 'number', 'description': 'Comparables returned.'}, 'market': {'type': 'string'}, 'currency': {'type': 'string'}, 'reference': {'type': 'object', 'properties': {'km': {'type': ['number', 'null']}, 'url': {'type': 'string', 'description': "Canonical listing page on this market's domain."}, 'body': {'type': ['string', 'null']}, 'fuel': {'type': ['string', 'null']}, 'make': {'type': 'string'}, 'slug': {'type': 'string', 'description': 'Stable identifier; pass to get_car_detail or find_similar_cars.'}, 'year': {'type': ['number', 'null']}, 'model': {'type': 'string'}, 'price': {'type': ['number', 'null'], 'description': 'null means the source does not publish a price (on request).'}, 'title': {'type': 'string'}, 'source': {'type': ['string', 'null'], 'description': 'Aggregator platform the listing came from; null when published directly with us.'}, 'variant': {'type': ['string', 'null']}, 'currency': {'type': 'string', 'description': 'ISO 4217 code of this market.'}, 'district': {'type': ['string', 'null']}, 'power_cv': {'type': ['number', 'null'], 'description': 'Engine power in metric horsepower (CV/PS).'}, 'condition': {'type': ['string', 'null']}, 'sourceUrl': {'type': ['string', 'null'], 'description': 'Original listing URL at the source. Cite this alongside url.'}, 'sellerType': {'enum': ['STAND', 'PARTICULAR', None], 'type': ['string', 'null']}, 'publishedAt': {'type': 'string', 'description': 'ISO 8601 date the listing was first seen at the source.'}, 'transmission': {'type': ['string', 'null']}}, 'description': 'The listing the comparables are measured against, echoed back for the comparison.'}}}
get_car_detail
Get the complete record of one used-car listing in Portugal by its slug. Use this after search_cars when the user asks about a specific car: full description, features, photos, seller, and the original source URL to cite.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['slug'], 'properties': {'slug': {'type': 'string', 'description': 'Unique listing slug, as returned by search_cars.'}}}
Output schema
{'type': 'object', 'required': ['slug', 'url', 'title', 'make', 'model', 'currency', 'publishedAt'], 'properties': {'km': {'type': ['number', 'null']}, 'url': {'type': 'string', 'description': "Canonical listing page on this market's domain."}, 'body': {'type': ['string', 'null']}, 'fuel': {'type': ['string', 'null']}, 'make': {'type': 'string'}, 'slug': {'type': 'string', 'description': 'Stable identifier; pass to get_car_detail or find_similar_cars.'}, 'year': {'type': ['number', 'null']}, 'color': {'type': ['string', 'null']}, 'doors': {'type': ['number', 'null']}, 'model': {'type': 'string'}, 'price': {'type': ['number', 'null'], 'description': 'null means the source does not publish a price (on request).'}, 'seats': {'type': ['number', 'null']}, 'title': {'type': 'string'}, 'origin': {'type': ['string', 'null'], 'description': 'NACIONAL = domestic; IMPORTADO = imported.'}, 'photos': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Up to 5 image URLs.'}, 'source': {'type': ['string', 'null'], 'description': 'Aggregator platform the listing came from; null when published directly with us.'}, 'variant': {'type': ['string', 'null']}, 'currency': {'type': 'string', 'description': 'ISO 4217 code of this market.'}, 'district': {'type': ['string', 'null']}, 'engineCc': {'type': ['number', 'null']}, 'features': {'type': 'array', 'items': {'type': 'string'}}, 'power_cv': {'type': ['number', 'null'], 'description': 'Engine power in metric horsepower (CV/PS).'}, 'condition': {'type': ['string', 'null']}, 'sourceUrl': {'type': ['string', 'null'], 'description': 'Original listing URL at the source. Cite this alongside url.'}, 'sellerType': {'enum': ['STAND', 'PARTICULAR', None], 'type': ['string', 'null']}, 'description': {'type': ['string', 'null']}, 'publishedAt': {'type': 'string', 'description': 'ISO 8601 date the listing was first seen at the source.'}, 'transmission': {'type': ['string', 'null']}}}
get_price_stats
Get price statistics for a slice of the Portugal used-car market: how many listings match, the median price, the p25–p75 range, the median price per kilometre and a breakdown by body type. Use this when the user asks what something costs, whether an asking price is fair, or how two makes compare — instead of listing individual cars. Takes the same filters as search_cars and describes exactly the set that tool would return, so the two never disagree. Reports medians and quartiles rather than averages, because car prices have a long right tail and a single luxury listing moves an average.
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'fuel': {'enum': ['GASOLINE', 'DIESEL', 'ELECTRIC', 'HYBRID', 'PLUG_IN_HYBRID', 'LPG'], 'type': 'string', 'description': 'Fuel type. GASOLINE = gasolina, ELECTRIC = eléctrico, HYBRID = full hybrid, PLUG_IN_HYBRID = PHEV.'}, 'make': {'type': 'string', 'description': 'Make slug (e.g. toyota, bmw, volkswagen). Not free text — the slug is the same in every market.'}, 'kmMax': {'type': 'number', 'description': 'Maximum kilometres on the odometer.'}, 'model': {'type': 'string', 'description': 'Model slug (e.g. corolla, serie-3, golf). Requires `make` to disambiguate.'}, 'yearMax': {'type': 'number', 'description': 'Maximum registration year.'}, 'yearMin': {'type': 'number', 'description': 'Minimum registration year.'}, 'bodyType': {'enum': ['SUV', 'SEDAN', 'HATCHBACK', 'COMBI', 'COUPE', 'CABRIO', 'MINIVAN', 'PICKUP'], 'type': 'string', 'description': 'Body style. SEDAN = berlina, HATCHBACK = citadino, COMBI = carrinha, CABRIO = descapotável, MINIVAN = monovolume.'}, 'district': {'type': 'string', 'description': 'District or region inside the market (e.g. Lisboa, Porto, Berlin, Madrid). Matched exactly.'}, 'priceMax': {'type': 'number', 'description': 'Maximum price in the market currency. Listings with no published price are excluded by either bound.'}, 'priceMin': {'type': 'number', 'description': 'Minimum price in the market currency.'}, 'condition': {'enum': ['new', 'used', 'semi_new'], 'type': 'string', 'description': 'Vehicle condition. new = 0 km / registered this year; semi_new = <2 years and <20 000 km; used = everything else.'}}}
Output schema
{'type': 'object', 'required': ['market', 'currency', 'count', 'priced', 'byBodyType'], 'properties': {'count': {'type': 'number', 'description': 'Listings matching the filters, with or without a published price.'}, 'price': {'type': ['object', 'null'], 'properties': {'p10': {'type': 'number', 'description': 'The bottom of the market: 10% of listings are cheaper.'}, 'p25': {'type': 'number', 'description': 'A quarter of listings are priced below this.'}, 'p75': {'type': 'number', 'description': 'A quarter of listings are priced above this.'}, 'p90': {'type': 'number', 'description': 'The top of the market: 10% of listings are dearer.'}, 'median': {'type': 'number', 'description': "The typical price — use this to answer 'how much'."}}, 'description': 'Price distribution, in percentiles. null when no matching listing publishes a price. There is deliberately no min or max: listings come from third-party sources and the extremes are set by data errors, not by the market.'}, 'market': {'type': 'string'}, 'priced': {'type': 'number', 'description': "Subset with a published price — the base of every figure below. A large gap to `count` means many listings in this slice are 'price on request'."}, 'currency': {'type': 'string'}, 'byBodyType': {'type': 'array', 'items': {'type': 'object', 'required': ['body', 'count'], 'properties': {'body': {'type': 'string'}, 'count': {'type': 'number'}, 'medianPrice': {'type': ['number', 'null']}}}, 'description': 'Up to 6 most represented body types, each with its own median.'}, 'pricePerKmMedian': {'type': ['number', 'null'], 'description': 'Median price per kilometre on the odometer, in the listing currency (order of magnitude 0.05–3). Small = the car has done a lot for its price.'}}}
search_articles
Search editorial articles about the used-car market in Portugal: buying guides, reviews, comparisons and market analysis. Use this when the user asks how something works — financing, warranty, IUC, IPO/ITV, the buying process — rather than asking for listings.
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'limit': {'type': 'number', 'description': 'Maximum number of results (default 5, max 10).'}, 'category': {'enum': ['GUIA', 'REVIEW', 'COMPARATIVO', 'MERCADO', 'GLOSSARIO', 'NOTICIA'], 'type': 'string', 'description': 'Article category.'}}}
Output schema
{'type': 'object', 'required': ['articles'], 'properties': {'articles': {'type': 'array', 'items': {'type': 'object', 'required': ['slug', 'title', 'url'], 'properties': {'dek': {'type': 'string'}, 'url': {'type': 'string'}, 'slug': {'type': 'string'}, 'title': {'type': 'string'}, 'category': {'type': 'string'}}}}}}
search_cars
Search current used-car listings for sale in Portugal. Use this whenever the user wants to find, compare or explore cars — by make, model, budget, mileage, fuel or district. Returns price, mileage, fuel, body and a citable listing URL, plus `total`: the exact number of listings matching the filters, which makes this tool usable to answer 'how many' questions. Listings are aggregated from stands and portals and refreshed daily; each result carries `publishedAt`. Prefer the broadest filters that answer the question and report `total` as a floor, not a census.
Read only Idempotent
Input schema
{'type': 'object', 'properties': {'fuel': {'enum': ['GASOLINE', 'DIESEL', 'ELECTRIC', 'HYBRID', 'PLUG_IN_HYBRID', 'LPG'], 'type': 'string', 'description': 'Fuel type. GASOLINE = gasolina, ELECTRIC = eléctrico, HYBRID = full hybrid, PLUG_IN_HYBRID = PHEV.'}, 'make': {'type': 'string', 'description': 'Make slug (e.g. toyota, bmw, volkswagen). Not free text — the slug is the same in every market.'}, 'page': {'type': 'number', 'description': '1-based page number. Use with `total` to walk a large result set.'}, 'sort': {'enum': ['recent', 'price_asc', 'price_desc', 'km_asc', 'year_desc'], 'type': 'string', 'description': 'Result order. Default `recent` (most recently seen first).'}, 'kmMax': {'type': 'number', 'description': 'Maximum kilometres on the odometer.'}, 'limit': {'type': 'number', 'description': 'Results per page (default 10, max 20).'}, 'model': {'type': 'string', 'description': 'Model slug (e.g. corolla, serie-3, golf). Requires `make` to disambiguate.'}, 'yearMax': {'type': 'number', 'description': 'Maximum registration year.'}, 'yearMin': {'type': 'number', 'description': 'Minimum registration year.'}, 'bodyType': {'enum': ['SUV', 'SEDAN', 'HATCHBACK', 'COMBI', 'COUPE', 'CABRIO', 'MINIVAN', 'PICKUP'], 'type': 'string', 'description': 'Body style. SEDAN = berlina, HATCHBACK = citadino, COMBI = carrinha, CABRIO = descapotável, MINIVAN = monovolume.'}, 'district': {'type': 'string', 'description': 'District or region inside the market (e.g. Lisboa, Porto, Berlin, Madrid). Matched exactly.'}, 'priceMax': {'type': 'number', 'description': 'Maximum price in the market currency. Listings with no published price are excluded by either bound.'}, 'priceMin': {'type': 'number', 'description': 'Minimum price in the market currency.'}, 'condition': {'enum': ['new', 'used', 'semi_new'], 'type': 'string', 'description': 'Vehicle condition. new = 0 km / registered this year; semi_new = <2 years and <20 000 km; used = everything else.'}}}
Output schema
{'type': 'object', 'required': ['market', 'currency', 'total', 'page', 'hasMore', 'cars'], 'properties': {'cars': {'type': 'array', 'items': {'type': 'object', 'required': ['slug', 'url', 'title', 'make', 'model', 'currency', 'publishedAt'], 'properties': {'km': {'type': ['number', 'null']}, 'url': {'type': 'string', 'description': "Canonical listing page on this market's domain."}, 'body': {'type': ['string', 'null']}, 'fuel': {'type': ['string', 'null']}, 'make': {'type': 'string'}, 'slug': {'type': 'string', 'description': 'Stable identifier; pass to get_car_detail or find_similar_cars.'}, 'year': {'type': ['number', 'null']}, 'model': {'type': 'string'}, 'price': {'type': ['number', 'null'], 'description': 'null means the source does not publish a price (on request).'}, 'title': {'type': 'string'}, 'source': {'type': ['string', 'null'], 'description': 'Aggregator platform the listing came from; null when published directly with us.'}, 'variant': {'type': ['string', 'null']}, 'currency': {'type': 'string', 'description': 'ISO 4217 code of this market.'}, 'district': {'type': ['string', 'null']}, 'power_cv': {'type': ['number', 'null'], 'description': 'Engine power in metric horsepower (CV/PS).'}, 'condition': {'type': ['string', 'null']}, 'sourceUrl': {'type': ['string', 'null'], 'description': 'Original listing URL at the source. Cite this alongside url.'}, 'sellerType': {'enum': ['STAND', 'PARTICULAR', None], 'type': ['string', 'null']}, 'publishedAt': {'type': 'string', 'description': 'ISO 8601 date the listing was first seen at the source.'}, 'transmission': {'type': ['string', 'null']}}}}, 'page': {'type': 'number'}, 'shown': {'type': 'number'}, 'total': {'type': 'number', 'description': 'Exact number of listings in this market matching the filters, across all pages.'}, 'market': {'type': 'string', 'description': 'ISO country code of this market.'}, 'hasMore': {'type': 'boolean'}, 'currency': {'type': 'string'}, 'pageSize': {'type': 'number'}}}
search_cars_by_description
Search Portugal listings by describing the car in plain language, matched against listing text by meaning rather than keywords. Use this for wants that are not filter fields — 'a family SUV good in the snow', 'a low-mileage hybrid for the city', 'a used 4x4 to restore'. Prefer search_cars for entirely structural queries (make/model/budget); use this when the request is descriptive. Combine both by passing structural filters here too — they act as hard constraints while the description only ranks. Results are ordered by relevance, so `total` is the number matching the structural filters, not the number that fit the description.
Read only Idempotent
Input schema
{'type': 'object', 'required': ['description'], 'properties': {'fuel': {'enum': ['GASOLINE', 'DIESEL', 'ELECTRIC', 'HYBRID', 'PLUG_IN_HYBRID', 'LPG'], 'type': 'string', 'description': 'Fuel type. GASOLINE = gasolina, ELECTRIC = eléctrico, HYBRID = full hybrid, PLUG_IN_HYBRID = PHEV.'}, 'make': {'type': 'string', 'description': 'Make slug (e.g. toyota, bmw, volkswagen). Not free text — the slug is the same in every market.'}, 'kmMax': {'type': 'number', 'description': 'Maximum kilometres on the odometer.'}, 'limit': {'type': 'number', 'description': 'Maximum number of results (default 10, max 20).'}, 'yearMin': {'type': 'number', 'description': 'Minimum registration year.'}, 'bodyType': {'enum': ['SUV', 'SEDAN', 'HATCHBACK', 'COMBI', 'COUPE', 'CABRIO', 'MINIVAN', 'PICKUP'], 'type': 'string', 'description': 'Body style. SEDAN = berlina, HATCHBACK = citadino, COMBI = carrinha, CABRIO = descapotável, MINIVAN = monovolume.'}, 'priceMax': {'type': 'number', 'description': 'Maximum price in the market currency. Listings with no published price are excluded by either bound.'}, 'description': {'type': 'string', 'description': 'What the user is looking for, in their own words. Full phrases work better than keywords. Pass the qualities here and the hard limits in the other arguments.'}}}
Output schema
{'type': 'object', 'required': ['market', 'total', 'shown', 'cars'], 'properties': {'cars': {'type': 'array', 'items': {'type': 'object', 'required': ['slug', 'url', 'title', 'make', 'model', 'currency', 'publishedAt'], 'properties': {'km': {'type': ['number', 'null']}, 'url': {'type': 'string', 'description': "Canonical listing page on this market's domain."}, 'body': {'type': ['string', 'null']}, 'fuel': {'type': ['string', 'null']}, 'make': {'type': 'string'}, 'slug': {'type': 'string', 'description': 'Stable identifier; pass to get_car_detail or find_similar_cars.'}, 'year': {'type': ['number', 'null']}, 'model': {'type': 'string'}, 'price': {'type': ['number', 'null'], 'description': 'null means the source does not publish a price (on request).'}, 'title': {'type': 'string'}, 'source': {'type': ['string', 'null'], 'description': 'Aggregator platform the listing came from; null when published directly with us.'}, 'variant': {'type': ['string', 'null']}, 'currency': {'type': 'string', 'description': 'ISO 4217 code of this market.'}, 'district': {'type': ['string', 'null']}, 'power_cv': {'type': ['number', 'null'], 'description': 'Engine power in metric horsepower (CV/PS).'}, 'condition': {'type': ['string', 'null']}, 'sourceUrl': {'type': ['string', 'null'], 'description': 'Original listing URL at the source. Cite this alongside url.'}, 'sellerType': {'enum': ['STAND', 'PARTICULAR', None], 'type': ['string', 'null']}, 'publishedAt': {'type': 'string', 'description': 'ISO 8601 date the listing was first seen at the source.'}, 'transmission': {'type': ['string', 'null']}}}, 'description': 'Ordered by relevance to the description, most relevant first.'}, 'shown': {'type': 'number'}, 'total': {'type': 'number', 'description': 'Listings matching the structural filters. The description narrows the ranking, not this count.'}, 'market': {'type': 'string'}, 'currency': {'type': 'string'}}}
Added
search_articles
Sept. 17, 2026, 12:39 p.m.
Added
get_car_detail
Sept. 17, 2026, 12:39 p.m.
Added
find_similar_cars
Sept. 17, 2026, 12:39 p.m.
Added
get_price_stats
Sept. 17, 2026, 12:39 p.m.
Added
search_cars_by_description
Sept. 17, 2026, 12:39 p.m.
Added
search_cars
Sept. 17, 2026, 12:39 p.m.