Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
DIVAR_MCP_PROXYNoOptional HTTP proxy for every request to api.divar.ir. The server ignores system proxy variables; set this to use a proxy, e.g. http://host:port.
DIVAR_MCP_STATENoOptional path to the state file used for saved watches and price history. Defaults to ~/.divar-mcp/state.json.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
dv_categoriesA

The Divar category tree (236 nodes, up to 4 levels): slug, Persian name, path and whether it is a leaf.

Use to find the category slug for dv_search and the other tools (leaf slugs such as light = cars and vans, apartment-sell, apartment-rent, mobile-phones). Filters exist per category: dv_filters.

dv_filtersA

Every filter a category supports: key, type, Persian label, unit and the allowed options.

Use before dv_search when you need more than price and district. Pass the keys in filters: number_range -> {'size': {'min': 80, 'max': 120}}, repeated_string -> {'rooms': ['دو']}, str -> {'gearbox': 'automatic'}, boolean -> {'parking': true}. lazy filters (districts, brand_model) have long option lists: use dv_filter_options or the districts / brand_model arguments of dv_search. Rent categories filter credit (deposit) and rent, sale categories price; both in Toman.

dv_filter_optionsA

Allowed values of a filter: brand and model keys (161 car brands), districts, or any option list.

With query it uses Divar's own typed search (best way to turn 'پراید' into the key 'Pride 111'). Without it: all brands (key, title, model count), or the models of one brand. Pass the keys to dv_search as brand_model / filters.

dv_suggestA

What Divar's search box would suggest for some text, and which categories the text belongs to.

Use to find the right category and a good query when the user only gave a product name. Each suggestion has the category slug and a probability; categories are guesses for the bare word. Next: dv_search.

dv_parse_queryA

Turn a plain Persian request into dv_search arguments: city, neighbourhoods, price bounds, category and leftover words.

A rule-based helper, not a language model: it finds a city and its neighbourhoods by name, amounts with میلیارد / میلیون / هزار (with زیر, کمتر از, تا, بالای, حداقل or از ... تا ...), a category from Divar's own guess for the leftover words, and moves rental words (اجاره, رهن) to the matching rent category. search can be passed to dv_search as it is; check notes for what was assumed. An area like '80 متری' becomes a size filter of ±10%. Rooms, year or mileage are not extracted: use dv_filters.

dv_postA

Everything public about one ad: price in Toman, specs, features, description, images, map position, seller type.

Prices: price (sale) or deposit + rent (rental; rent 0 + full_deposit = رهن کامل); negotiable true when the seller gave none; suspect_price marks placeholder prices. specs are the Persian spec rows of the ad (mileage, year, area, rooms...). lat/lon are fuzzed by about 500 m for most categories. shared_housing flags همخانه ads. No phone number: Divar shows it only to logged-in users, use url to contact the seller. Next: dv_similar, dv_appraise (is the price fair), dv_seller, dv_compare.

dv_postsA

Details of up to 10 ads in one call (compact: specs and one image, description cut at 300 characters).

Use to read a shortlist from dv_search. An ad that was removed shows an error instead of failing the call.

dv_compareA

Side by side: the price of each ad and only the specs that differ (the identical ones are listed once).

Gives cheapest, per other ad cheapest_saves_pct (how much less the cheapest costs than that ad; per metre when every priced ad has an area, see compared_by), the differing spec rows with each ad's value, shared specs, and features one ad has and another lacks. Works across ads of the same kind (two cars, two flats); specs are the Persian rows of each ad.

dv_sellerA

The seller behind an ad: how many personal and business ads they have, the business card (name, brand_token) and their ads.

Use to judge a seller (one flat or fifty cars?) and to list their other ads. For a dealer's whole page call dv_dealer with the brand_token (dv_post does not give one). A personal seller has no business card (seller_kind). No phone number or identity is exposed.

dv_dealerA

A business account's public page: name, active ad count, member since and its first 11 ads.

Divar's web API gives only the first batch of a dealer's ads (no paging); search with the dealer's name or use the ad filters for more. Ads are compact rows (token, title, price, district, age, photos, tag); the ad link is url_prefix + token and age_h is hours since the last bump.

dv_similarA

Ads similar to one ad: same brand/model (or category) and neighbourhood, widening step by step until enough are found.

Divar has no similar-ads endpoint; this searches the ad's own breadcrumb (brand+district, brand, category+district, category). basis names the levels used, narrowest first. Sorted newest first. For property, ads priced over 5x or under a fifth of this ad, or whose title area is under 0.4x or over 2.5x of its area (a 950B bulk listing next to a 180 m flat), are left out and counted in excluded_outliers. Next: dv_compare, dv_appraise.

dv_marketA

Asking-price statistics of a search: min, p10, p25, median, p75, p90, max, mean; split by district and by day.

Scans the newest pages pages (about 25 ads each) and drops negotiable and suspect prices (excluded) and, from the statistics, prices under a tenth of the median. Sale searches give price; rentals give rent and deposit (Toman). by_district lists the busiest neighbourhoods with ad count and median; per_day shows how many ads were posted per UTC date and their median, a rough trend. These are what sellers ask, not what deals close at, and a sample of the newest ads, not the whole market: use a narrow query or filters (one model, one area) for a meaningful median. Next: dv_cheapest, dv_best_for_budget, dv_appraise.

dv_appraiseA

Is an ad's price (or a price you have in mind) high or low compared with similar ads? Percentile, verdict, confidence.

With a token: compares its price (or monthly rent) with similar ads found from its own breadcrumb (brand + district, widening step by step). Without: give price plus category/query/filters. Returns percentile (share of comparable ads that are cheaper), verdict ('insufficient comparables', with no lean either way, when confidence is low and the call would be "well below/above market"), vs_median_pct, the fair band p25-p75 and confidence (high: 40+ comparable ads at the first level, medium: 15+, else low). Comparisons ignore year, mileage, area and condition: refine with filters/query, or dv_compare against specific ads. Asking prices only.

dv_statusA

Is Divar reachable and how fast: version, a live latency check, caches and local watch state.

Call first when other tools fail (it tells a blocked network from a bad argument). The check is one small request to Divar. The server instructions describe the usual tool order (cities and categories, then dv_search, then dv_post).

dv_searchA

Search Divar ads in one or more cities by category, text and filters; compact cards, prices in Toman.

Card fields are described in the server instructions; age_h is hours since the last bump, image comes only with thumbnails, and suspect_price includes 'outlier' (at or under a tenth of the fetched median, 5+ priced ads). Newest first; the first 1-3 rows may be promoted older ads. Continue with next_cursor as cursor. Filters the category lacks come back in ignored; an empty Persian query is retried once with letters folded. Next: dv_post, dv_compare, dv_cheapest, dv_market.

dv_countA

How many active ads match a search, in one cheap call (capped: 10,000 means '10,000 or more').

Use to size a market, to test whether a filter combination is too narrow, or to compare cities and districts before fetching ads. Same arguments as dv_search.

dv_cheapestA

The cheapest ads of a search, cheapest first. Skips negotiable ads, placeholder or absurd prices and far-below-median outliers.

Divar cannot sort by price, so this scans the newest pages pages (about 25 ads each) and ranks them: raise pages for a wider scan or narrow with filters. Rent categories rank by monthly rent (deposit shown too). Ads under 10% of the median (include_outliers shows them) are usually not the thing searched for: a 100,000 Toman 'car' is a transfer slip or a deposit. The answer says how many ads were scanned and skipped. Next: dv_post, dv_compare.

dv_best_for_budgetA

Within a budget: the best-value ads (furthest below their peers' median) and the most you can get (closest to the budget).

Scans the newest pages pages capped at budget. Each best_value ad has a deal_score (0-100) with reasons (distance below budget_median, photos, freshness; penalties for prices over 70% under the median and for notice, parking or co-op titles). Ads under 20% of the uncapped market_median and bait titles (وامدار, قدرالسهم, اقساط, پیش‌فروش...; kept if the word is in query / keywords) are dropped into skipped_implausible. Property for sale ranks by price per m2; the top 6 ad pages are opened for publish time, floor, parking and elevator (the caveat says the rest are unchecked). An unrealistic budget returns an empty best_value with a note. Use a narrow query or brand: a mixed category's median means nothing. Next: dv_appraise, dv_post.

dv_find_dealsA

Ads priced well below the median of the same search, without a budget: scored deals, with bait and junk prices removed.

Scans the newest pages pages and keeps ads min_discount_pct to 70% below the median (price per m2 for property for sale). Left out: suspect and placeholder prices, ads under 20% of the median (deposits, parts, bait), bait or co-op titles (وامدار, قدرالسهم, اقساط, پیش‌فروش...; unless you ask for the word) and notice / parking titles. Use a narrow query or filters: the median of a mixed category means nothing. Asking prices only. Next: dv_post, dv_appraise, dv_compare.

dv_new_sinceA

Ads published after a moment, newest first: poll this to watch a search (a new flat, a cheap car) without repeats.

Call it, remember latest, and pass it as since next time: only ads newer than that come back. Promoted old ads are excluded by date. more is true when the page limit was reached and even more new ads exist. Nothing is stored or pushed: the caller (or a scheduler) decides when to poll.

dv_exportA

The ads of a search as CSV or JSON lines text, ready to save to a spreadsheet or analyse.

Same arguments as dv_search. Columns: token, title, price, deposit, rent (Toman), district, posted (UTC), photos, seller, info, url. Missing prices are empty. The text is in data; write it to a file yourself.

dv_nearbyA

Ads on the map around a GPS point, nearest first, with coordinates, distance, price chips and a thumbnail.

Up to 200 ads per area are available (total_in_area is the true count). Pin positions are fuzzed by about 500 m for most categories (approximate_location), so distances are approximate. A category is required (Divar's map returns nothing without one). Map prices are rounded in the site's display (1.5 billion = 1,500,000,000); sale pins give the total price and, for homes, price_per_m2. Next: dv_post for details.

dv_citiesA

City ids for a name (1,177 cities; Tehran is 1, Mashhad 3). Returns id, name, URL slug, province id and centre.

Use first when you need a city for another tool (they also accept the name directly). Persian letter variants (ي/ی, ك/ک) are matched. Next: dv_districts for the neighbourhoods of a city, dv_search to look for ads.

dv_districtsA

Neighbourhoods (محله) of one city with ids, centre point and the main streets inside (Tehran has about 450).

Use to get the district ids for a districts filter, or to pick coordinates for dv_nearby. dv_search and the other search tools take district names directly. Next: dv_neighbours for adjacent areas.

dv_neighboursA

Neighbourhoods adjacent to a district, to widen a neighbourhood search to the surrounding area.

districts is Divar's own adjacency list, which is short for some areas (Vanak lists one). nearest adds the closest districts of city by centroid distance (within 3 km, up to 6) so a widened search is not too narrow. Pass the ids (or names) as districts to dv_search.

dv_locateA

The city, neighbourhood and street address of a GPS point.

Gives the city id and district id to use as filters. The street address is only known inside covered areas. Next: dv_nearby for ads around the point.

dv_place_searchA

Map autocomplete: turn a landmark or street name into coordinates and a bounding box.

Use the returned lat/lon with dv_nearby (ads around a place) or dv_locate. Persian text works best.

dv_place_mappingA

Convert old Divar place ids to the current ones (Divar merged and renumbered places).

Use when an id from an old link or saved data returns nothing. mapping has the renumbered ids only; unchanged are current city ids; unverified ids are not in the renumber table and are not cities (districts cannot be checked here: see dv_districts).

dv_boundaryA

Neighbourhood borders of a city from Divar's GeoJSON: the city's bounding box, or one neighbourhood's polygon.

Without district: the city bounding box [min_lon, min_lat, max_lon, max_lat] and the neighbourhoods with id, centre and box. With district: a GeoJSON Feature of that neighbourhood (coordinates [lon, lat], thinned to max_points per ring, so the shape is approximate). Use to draw an area or test a point against it; for a point's own neighbourhood use dv_locate. Next: dv_nearby with the centre.

dv_watchA

Save a search and later get only the ads that appeared since the last check; stored in a local file, nothing is pushed.

create takes the search arguments of dv_search (validated once, then stored with the current time as the mark). check runs dv_new_since for the watch and moves the mark to the newest ad it returned, so the next check shows only newer ads; it does not run by itself: call it from a schedule or when asked. The file is ~/.divar-mcp/state.json (override with DIVAR_MCP_STATE); it holds only your searches. Next: dv_post for a new ad.

dv_price_trendA

The median asking price of a search over the days you have checked it: records one point per day in a local file.

Divar keeps no price history, so the trend starts with your first call and grows each day you call it again (a scheduler helps). Each call scans the newest pages pages, stores median / quartiles / count for today (a second call the same UTC day replaces it) and returns the last 90 points with change_pct since the previous day. Use a narrow query: a mixed category's median is noise. For a one-off distribution use dv_market.

Prompts

Interactive templates invoked by user choice

NameDescription
compare_adsCompare 2-6 Divar ads and say which to pick.
best_under_budgetFind the best Divar ads for a budget.
appraise_listingCheck whether a Divar ad's price is fair.
watch_marketWatch a Divar search for new ads and track its price.

Resources

Contextual data attached and managed by the client

NameDescription
cities_resourceAll 1,177 cities: id, name, slug, province_id.
categories_resourceThe category tree, flat: slug, name, parent, leaf.

TDQS

A4/5.0

Scored across 31 tools

Disambiguation4/5

Most tools have clearly distinct outputs, and the descriptions helpfully clarify boundaries (e.g. search vs count vs export vs cheapest vs market). However, several search-derived analysis tools (dv_cheapest, dv_best_for_budget, dv_find_deals, dv_market, dv_price_trend, dv_appraise) and the watch/new-since pair overlap enough that an agent could still hesitate.

Naming Consistency5/5

Every tool uses the same dv_ prefix and lowercase snake_case, with readable noun/verb phrases such as dv_search, dv_post, dv_filters, and dv_price_trend. No mixed conventions or casing issues appear.

Tool Count2/5

31 tools is above the 25+ threshold and feels heavy for a single MCP surface, even for a rich marketplace domain. Several tools could be consolidated or made optional subcommands, and some tools (dv_status, dv_place_mapping) are thin relative to the total.

Completeness4/5

The read/search/analysis lifecycle is well covered: categories, filters, city/district lookup, search, export, details, seller, dealer, price stats, compare, watch, and trend. Gaps are mostly write/account operations such as creating or editing ads, messaging/contact, or deleting saved watches, which may be outside the read-only scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues