# Divar (pypi · divar-mcp)

Unofficial read-only Divar: search Iran's classified ads, cheapest and best-value ads, price checks.

- Trust score: 84/100 (high trust)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-22

## Components

- pypi · `divar-mcp`: 84/100 (this document), [markdown](https://verifymcp.io/servers/sepehr071-divar-mcp/divar-mcp.md), [page](https://verifymcp.io/servers/sepehr071-divar-mcp/divar-mcp)

## Channel facts

- Registry: `pypi`
- Package: `divar-mcp`
- Version: `0.2.1`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-22.

- **Supply Chain Security**: 100/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs hatchling.build at install time, a recognised build step with no custom scripting around it.
  - 1 of 35 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 97/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to sepehr071/divar-mcp).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 0 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 74/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 9754 tokens (~295/item across 33 items; 31 tools + 2 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 20/100
  - Stability observed for 6 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 31 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 33 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### How do I install the Divar MCP server?

Divar runs locally as a PyPI package, launched with uvx divar-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add sepehr071-divar-mcp -- uvx divar-mcp
```

### Cursor

```json
{
  "mcpServers": {
    "sepehr071-divar-mcp": {
      "command": "uvx",
      "args": [
        "divar-mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "sepehr071-divar-mcp": {
      "command": "uvx",
      "args": [
        "divar-mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add sepehr071-divar-mcp -- uvx divar-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "sepehr071-divar-mcp": {
      "type": "local",
      "command": [
        "uvx",
        "divar-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add sepehr071-divar-mcp --command uvx --arg divar-mcp
```

### Hermes

```yaml
mcp_servers:
  sepehr071-divar-mcp:
    command: "uvx"
    args: ["divar-mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "sepehr071-divar-mcp": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "divar-mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add sepehr071-divar-mcp -t stdio -c uvx -a divar-mcp
```

### Other

```json
{
  "mcpServers": {
    "sepehr071-divar-mcp": {
      "command": "uvx",
      "args": [
        "divar-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-22 (score 84, +16)

- [security regression] Tool safety: pass → unverified
- [security regression] Stability: 0.17 → unverified
- [security improvement] Malware scan: unverified → pass
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Schema quality: 100 → unverified
- [functional] Package version: 0.2.0 → 0.2.1

### 2026-10-20 (score 68, +1)

No change was recorded against any check on this day. Stability & Change Management went from 10 to 13. That category is still filling its 30-day observation window: 3 days of observed history at the previous scan, 4 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-19 (score 67, −15)

- [security regression] Malware scan: pass → unverified

### 2026-10-18 (score 82, +1)

- [security regression] Stability: 0.03 → unverified
- [security regression] Tool safety: pass → unverified
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Schema quality: 100 → unverified
- [functional] Package version: 0.1.0 → 0.2.0

### 2026-10-16 (score 81)

First indexed and scored.

## MCP tools (31)

### `dv_categories` (~165 tokens)

Browse categories

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.

Input parameters:

- `limit` (integer): Max categories to return.
- `parent` (string): List the direct children of this category slug, e.g. 'vehicles' or 'real-estate'. Omit for the 10 top-level categories.
- `query` (string): Part of a category name or slug, Persian or Latin: 'موبایل', 'apartment'.

### `dv_filters` (~222 tokens)

Category filters

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.

Input parameters:

- `category` (required): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.

### `dv_filter_options` (~272 tokens)

Filter options

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`.

Input parameters:

- `brand` (string): brand_model only: a brand key (e.g. 'Peugeot') to list its models.
- `category` (required): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `filter` (string): Filter key from dv_filters, usually 'brand_model' (cars, phones, ...) or 'districts'.
- `limit` (integer): Max options to return.
- `query` (string): Text to look up inside the filter, e.g. 'سمند' or 'ونک'. Without it the whole list (or one brand) is returned.

### `dv_suggest` (~140 tokens)

Search suggestions

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.

Input parameters:

- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `query` (string, required): Text as typed in the Divar search box, e.g. 'پراید', 'پژو'.

### `dv_parse_query` (~212 tokens)

Question to search

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.

Input parameters:

- `text` (string, required): A search as a person would write it, e.g. 'آپارتمان اجاره ونک زیر ۸ میلیارد' or 'پراید کرج تا ۲۰۰ میلیون'.

### `dv_post` (~262 tokens)

Ad details

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.

Input parameters:

- `full_text` (boolean): Do not cut the description (default cuts at 1500 characters).
- `max_images` (integer): How many full-size image URLs to return.
- `token` (string, required): Ad token: the last part of divar.ir/v/<slug>/<token> or `token` of a search result, e.g. 'gaRPIP2m'.

### `dv_posts` (~90 tokens)

Several ads

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.

Input parameters:

- `tokens` (array, required): Ad tokens, e.g. ['gaRPIP2m', 'gaRPYuZk'] (at most 10).

### `dv_compare` (~139 tokens)

Compare ads

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.

Input parameters:

- `tokens` (array, required): 2 to 6 ad tokens to compare.

### `dv_seller` (~156 tokens)

Seller and their ads

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.

Input parameters:

- `limit` (integer): Max of the seller's other ads to return.
- `token` (string, required): Ad token: the last part of divar.ir/v/<slug>/<token> or `token` of a search result, e.g. 'gaRPIP2m'.

### `dv_dealer` (~131 tokens)

Dealer page

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.

Input parameters:

- `brand_token` (string, required): Dealer id from dv_seller, e.g. 'ZbeypyTr'.

### `dv_similar` (~217 tokens)

Similar ads

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.

Input parameters:

- `limit` (integer): Max similar ads.
- `pages` (integer): Pages scanned per breadcrumb level.
- `token` (string, required): Ad token: the last part of divar.ir/v/<slug>/<token> or `token` of a search result, e.g. 'gaRPIP2m'.

### `dv_market` (~570 tokens)

Market price statistics

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.

Input parameters:

- `brand_model` (array): Vehicles, phones: brand/model, e.g. ['پژو 206'].
- `category` (string): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `districts` (array): Neighbourhood names or ids in the one city, e.g. ['ونک'].
- `exclude` (array): Drop ads whose title has any of these words.
- `filters` (object): Other category filters (keys from dv_filters): {'size': {'min': 80, 'max': 120}, 'rooms': ['دو'], 'parking': true}. Unknown keys are returned in `ignored`.
- `has_photo` (boolean): Only ads with photos.
- `keywords` (array): Words that must all be in the title.
- `max_age_hours` (number): Only ads bumped within this many hours.
- `max_deposit` (integer): Rent categories: deposit (ودیعه) in Toman.
- `max_price` (integer): Toman; monthly rent in rent categories.
- `min_deposit` (integer): Rent categories: deposit (ودیعه) in Toman.
- `min_price` (integer): Toman; monthly rent in rent categories.
- `pages` (integer): Result pages to merge, about 25 ads each.
- `query` (string): Free text in title or description, e.g. 'پراید 111'.
- `recent` (string): Published within '3h', '12h', '1d', '3d' or '7d'.

### `dv_appraise` (~460 tokens)

Is this price fair

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.

Input parameters:

- `brand_model` (array): Vehicles, phones: brand/model, e.g. ['پژو 206'].
- `category` (string): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `districts` (array): Neighbourhood names or ids in the one city, e.g. ['ونک'].
- `filters` (object): Other category filters (keys from dv_filters): {'size': {'min': 80, 'max': 120}, 'rooms': ['دو'], 'parking': true}. Unknown keys are returned in `ignored`.
- `pages` (integer): Pages scanned per comparison level.
- `price` (integer): Without a token: the price in Toman to check against the search below (monthly rent for rent categories).
- `query` (string): Free text in title or description, e.g. 'پراید 111'.
- `token` (string): An ad to appraise: its price is ranked against similar ads. Omit to appraise a price you give.

### `dv_status` (~78 tokens)

Server status

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_search` (~630 tokens)

Search ads

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.

Input parameters:

- `brand_model` (array): Vehicles, phones: brand/model, e.g. ['پژو 206'].
- `category` (string): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `cursor` (string): `next_cursor` of the previous call, for older ads.
- `districts` (array): Neighbourhood names or ids in the one city, e.g. ['ونک'].
- `exclude` (array): Drop ads whose title has any of these words.
- `filters` (object): Other category filters (keys from dv_filters): {'size': {'min': 80, 'max': 120}, 'rooms': ['دو'], 'parking': true}. Unknown keys are returned in `ignored`.
- `has_photo` (boolean): Only ads with photos.
- `keywords` (array): Words that must all be in the title.
- `limit` (integer): Max ads in the answer.
- `max_age_hours` (number): Only ads bumped within this many hours.
- `max_deposit` (integer): Rent categories: deposit (ودیعه) in Toman.
- `max_price` (integer): Toman; monthly rent in rent categories.
- `min_deposit` (integer): Rent categories: deposit (ودیعه) in Toman.
- `min_price` (integer): Toman; monthly rent in rent categories.
- `pages` (integer): Result pages to merge, about 25 ads each.
- `query` (string): Free text in title or description, e.g. 'پراید 111'.
- `recent` (string): Published within '3h', '12h', '1d', '3d' or '7d'.
- `sort` (string): 'newest' is Divar's own order (default, pages by cursor). 'cheapest' / 'expensive' sort the ads fetched in this call by price (Divar cannot sort by price).
- `thumbnails` (boolean): Include each ad's thumbnail URL in `image` (about 40 tokens per ad).

### `dv_count` (~376 tokens)

Count matching ads

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.

Input parameters:

- `brand_model` (array): Vehicles, phones: brand/model, e.g. ['پژو 206'].
- `category` (string): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `districts` (array): Neighbourhood names or ids in the one city, e.g. ['ونک'].
- `filters` (object): Other category filters (keys from dv_filters): {'size': {'min': 80, 'max': 120}, 'rooms': ['دو'], 'parking': true}. Unknown keys are returned in `ignored`.
- `has_photo` (boolean): Only ads with photos.
- `max_deposit` (integer): Rent categories: deposit (ودیعه) in Toman.
- `max_price` (integer): Toman; monthly rent in rent categories.
- `min_deposit` (integer): Rent categories: deposit (ودیعه) in Toman.
- `min_price` (integer): Toman; monthly rent in rent categories.
- `query` (string): Free text in title or description, e.g. 'پراید 111'.
- `recent` (string): Published within '3h', '12h', '1d', '3d' or '7d'.

### `dv_cheapest` (~555 tokens)

Find cheapest ads

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.

Input parameters:

- `brand_model` (array): Vehicles, phones: brand/model, e.g. ['پژو 206'].
- `category` (string): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `districts` (array): Neighbourhood names or ids in the one city, e.g. ['ونک'].
- `exclude` (array): Drop ads whose title has any of these words.
- `filters` (object): Other category filters (keys from dv_filters): {'size': {'min': 80, 'max': 120}, 'rooms': ['دو'], 'parking': true}. Unknown keys are returned in `ignored`.
- `has_photo` (boolean): Only ads with photos.
- `include_outliers` (boolean): Also list ads priced under 10% of the scanned median (usually deposits, parts or bait).
- `keywords` (array): Words that must all be in the title.
- `limit` (integer): Max ads in the answer.
- `max_age_hours` (number): Only ads bumped within this many hours.
- `max_price` (integer): Toman; monthly rent in rent categories.
- `min_price` (integer): Toman; monthly rent in rent categories.
- `min_realistic_price` (integer): Drop ads priced below this many Toman (seller junk prices like 1,000 are already flagged and skipped).
- `pages` (integer): Result pages to merge, about 25 ads each.
- `query` (string): Free text in title or description, e.g. 'پراید 111'.
- `recent` (string): Published within '3h', '12h', '1d', '3d' or '7d'.

### `dv_best_for_budget` (~598 tokens)

Best ads for a budget

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.

Input parameters:

- `brand_model` (array): Vehicles, phones: brand/model, e.g. ['پژو 206'].
- `budget` (integer, required): Maximum price in Toman (rent categories: monthly rent), e.g. 1500000000.
- `category` (string): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `districts` (array): Neighbourhood names or ids in the one city, e.g. ['ونک'].
- `exclude` (array): Drop ads whose title has any of these words.
- `filters` (object): Other category filters (keys from dv_filters): {'size': {'min': 80, 'max': 120}, 'rooms': ['دو'], 'parking': true}. Unknown keys are returned in `ignored`.
- `has_photo` (boolean): Only ads with photos.
- `keywords` (array): Words that must all be in the title.
- `limit` (integer): Ads per list.
- `max_age_hours` (number): Only ads bumped within this many hours.
- `min_price` (integer): Toman; monthly rent in rent categories.
- `pages` (integer): Result pages to merge, about 25 ads each.
- `query` (string): Free text in title or description, e.g. 'پراید 111'.
- `recent` (string): Published within '3h', '12h', '1d', '3d' or '7d'.

### `dv_find_deals` (~521 tokens)

Find deals

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.

Input parameters:

- `brand_model` (array): Vehicles, phones: brand/model, e.g. ['پژو 206'].
- `category` (string): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `districts` (array): Neighbourhood names or ids in the one city, e.g. ['ونک'].
- `exclude` (array): Drop ads whose title has any of these words.
- `filters` (object): Other category filters (keys from dv_filters): {'size': {'min': 80, 'max': 120}, 'rooms': ['دو'], 'parking': true}. Unknown keys are returned in `ignored`.
- `has_photo` (boolean): Only ads with photos.
- `keywords` (array): Words that must all be in the title.
- `limit` (integer): Max deals.
- `max_age_hours` (number): Only ads bumped within this many hours.
- `max_price` (integer): Toman; monthly rent in rent categories.
- `min_discount_pct` (integer): Only ads at least this many percent below the median.
- `min_price` (integer): Toman; monthly rent in rent categories.
- `pages` (integer): Result pages to merge, about 25 ads each.
- `query` (string): Free text in title or description, e.g. 'پراید 111'.
- `recent` (string): Published within '3h', '12h', '1d', '3d' or '7d'.

### `dv_new_since` (~506 tokens)

New ads since a time

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.

Input parameters:

- `brand_model` (array): Vehicles, phones: brand/model, e.g. ['پژو 206'].
- `category` (string): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `districts` (array): Neighbourhood names or ids in the one city, e.g. ['ونک'].
- `exclude` (array): Drop ads whose title has any of these words.
- `filters` (object): Other category filters (keys from dv_filters): {'size': {'min': 80, 'max': 120}, 'rooms': ['دو'], 'parking': true}. Unknown keys are returned in `ignored`.
- `has_photo` (boolean): Only ads with photos.
- `hours` (number): Used when `since` is omitted: ads from the last N hours.
- `keywords` (array): Words that must all be in the title.
- `limit` (integer): Max ads in the answer.
- `max_deposit` (integer): Rent categories: deposit (ودیعه) in Toman.
- `max_price` (integer): Toman; monthly rent in rent categories.
- `min_deposit` (integer): Rent categories: deposit (ودیعه) in Toman.
- `min_price` (integer): Toman; monthly rent in rent categories.
- `pages` (integer): Result pages to merge, about 25 ads each.
- `query` (string): Free text in title or description, e.g. 'پراید 111'.
- `since` (string): UTC timestamp like 2026-10-16T01:50:00Z (the `latest` of the previous call). Omit to use `hours`.

### `dv_export` (~488 tokens)

Export ads

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.

Input parameters:

- `brand_model` (array): Vehicles, phones: brand/model, e.g. ['پژو 206'].
- `category` (string): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `districts` (array): Neighbourhood names or ids in the one city, e.g. ['ونک'].
- `exclude` (array): Drop ads whose title has any of these words.
- `filters` (object): Other category filters (keys from dv_filters): {'size': {'min': 80, 'max': 120}, 'rooms': ['دو'], 'parking': true}. Unknown keys are returned in `ignored`.
- `format` (string): 'csv' (header + rows) or 'jsonl' (one JSON ad per line).
- `has_photo` (boolean): Only ads with photos.
- `keywords` (array): Words that must all be in the title.
- `limit` (integer): Max rows.
- `max_age_hours` (number): Only ads bumped within this many hours.
- `max_deposit` (integer): Rent categories: deposit (ودیعه) in Toman.
- `max_price` (integer): Toman; monthly rent in rent categories.
- `min_deposit` (integer): Rent categories: deposit (ودیعه) in Toman.
- `min_price` (integer): Toman; monthly rent in rent categories.
- `pages` (integer): Result pages to merge, about 25 ads each.
- `query` (string): Free text in title or description, e.g. 'پراید 111'.
- `recent` (string): Published within '3h', '12h', '1d', '3d' or '7d'.

### `dv_nearby` (~424 tokens)

Ads near a point

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.

Input parameters:

- `brand_model` (array): Vehicles, phones: brand/model, e.g. ['پژو 206'].
- `category` (string, required): Required: the map shows nothing without a category. Slug or Persian name, e.g. 'apartment-sell', 'apartment-rent', 'light'. List them with dv_categories.
- `filters` (object): Other category filters (keys from dv_filters): {'size': {'min': 80, 'max': 120}, 'rooms': ['دو'], 'parking': true}. Unknown keys are returned in `ignored`.
- `lat` (number, required): Latitude, e.g. 35.7. Get one from dv_place_search or dv_districts.
- `limit` (integer): Max ads in the answer.
- `lon` (number, required): Longitude, e.g. 51.4.
- `max_deposit` (integer): Rent categories: deposit (ودیعه) in Toman.
- `max_price` (integer): Toman; monthly rent in rent categories.
- `min_deposit` (integer): Rent categories: deposit (ودیعه) in Toman.
- `min_price` (integer): Toman; monthly rent in rent categories.
- `query` (string): Free text in title or description, e.g. 'پراید 111'.
- `radius_m` (integer): Search radius in metres.

### `dv_cities` (~145 tokens)

Find cities

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.

Input parameters:

- `limit` (integer): Max cities to return.
- `query` (string): City name or slug, Persian or Latin, e.g. 'مشهد', 'kar'. Omit for the 7 biggest cities.

### `dv_districts` (~150 tokens)

City neighbourhoods

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.

Input parameters:

- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `limit` (integer): Max neighbourhoods to return.
- `query` (string): Part of a neighbourhood name, e.g. 'ونک'.

### `dv_neighbours` (~158 tokens)

Adjacent neighbourhoods

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.

Input parameters:

- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `district_id` (integer, required): District id from dv_districts, e.g. 655.

### `dv_locate` (~92 tokens)

Locate a GPS point

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.

Input parameters:

- `lat` (number, required): Latitude inside Iran, e.g. 35.7.
- `lon` (number, required): Longitude inside Iran, e.g. 51.4.

### `dv_place_search` (~105 tokens)

Search a place on the map

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.

Input parameters:

- `lat` (number): Map centre latitude to bias results.
- `lon` (number): Map centre longitude to bias results.
- `query` (string, required): Landmark, mall, street or area, e.g. 'برج میلاد', 'ونک'.

### `dv_place_mapping` (~112 tokens)

Map old place ids

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).

Input parameters:

- `ids` (array, required): Old district/city ids saved from earlier Divar data.

### `dv_boundary` (~243 tokens)

City boundary

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.

Input parameters:

- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `district` (string): A neighbourhood name or id (e.g. 'ونک', '315') to get its polygon. Omit for the city's bounding box and its neighbourhoods.
- `limit` (integer): Max neighbourhoods listed in the overview.
- `max_points` (integer): Max vertices per polygon ring (the full outline is thinned).

### `dv_watch` (~507 tokens)

Saved watches

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.

Input parameters:

- `action` (string, required): 'create' saves a search, 'check' returns the ads newer than the last check and moves the mark, 'list' shows the saved searches, 'delete' removes one.
- `brand_model` (array): Vehicles, phones: brand/model, e.g. ['پژو 206'].
- `category` (string): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `districts` (array): Neighbourhood names or ids in the one city, e.g. ['ونک'].
- `exclude` (array): Drop ads whose title has any of these words.
- `filters` (object): Other category filters (keys from dv_filters): {'size': {'min': 80, 'max': 120}, 'rooms': ['دو'], 'parking': true}. Unknown keys are returned in `ignored`.
- `keywords` (array): Words that must all be in the title.
- `limit` (integer): check: max new ads per watch.
- `max_price` (integer): Toman; monthly rent in rent categories.
- `min_price` (integer): Toman; monthly rent in rent categories.
- `name` (string): create: a label for you, e.g. 'cheap Pride in Karaj'.
- `query` (string): Free text in title or description, e.g. 'پراید 111'.
- `watch_id` (string): check / delete: the id from 'create' or 'list'. check without it checks every watch.

### `dv_price_trend` (~362 tokens)

Price trend

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.

Input parameters:

- `brand_model` (array): Vehicles, phones: brand/model, e.g. ['پژو 206'].
- `category` (string): Category slug or Persian name, e.g. 'light' (cars), 'apartment-sell', 'apartment-rent', 'mobile-phones'.
- `city` (string): City name or id; several comma-separated, e.g. 'تهران', 'mashhad', 'تهران,کرج'.
- `districts` (array): Neighbourhood names or ids in the one city, e.g. ['ونک'].
- `filters` (object): Other category filters (keys from dv_filters): {'size': {'min': 80, 'max': 120}, 'rooms': ['دو'], 'parking': true}. Unknown keys are returned in `ignored`.
- `pages` (integer): Result pages to merge, about 25 ads each.
- `query` (string): Free text in title or description, e.g. 'پراید 111'.
- `record` (boolean): Store today's median so later calls can show the trend.

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/sepehr071-divar-mcp/divar-mcp#diagnostics

## Score history

- 2026-10-22: 84
- 2026-10-21: 68
- 2026-10-20: 68
- 2026-10-19: 67
- 2026-10-18: 82
- 2026-10-17: 81
- 2026-10-16: 81

## Common questions

### What is the Divar MCP server?

Divar is an MCP server listed in the public MCP registry as io.github.sepehr071/divar-mcp. Unofficial read-only Divar: search Iran's classified ads, cheapest and best-value ads, price checks. This page covers its PyPI package (divar-mcp).

### Is the Divar MCP server safe to use?

Divar scores 84 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 22 October 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Divar MCP server expose?

Divar exposes 31 tools: dv_categories, dv_filters, dv_filter_options, dv_suggest, dv_parse_query, and 26 more. Their descriptions and schemas cost roughly 9,086 tokens of context every time the server is loaded.

### Is the Divar MCP server still maintained?

Divar is still listed as active in the MCP registry. We last reached this channel on 22 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Divar MCP server under?

Divar declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- PyPI project: https://pypi.org/project/divar-mcp/
- Socket report: https://socket.dev/pypi/package/divar-mcp
- Repository: https://github.com/sepehr071/divar-mcp
- Changelog RSS feed: https://verifymcp.io/servers/sepehr071-divar-mcp/divar-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/sepehr071-divar-mcp/divar-mcp.json
- HTML version of this page: https://verifymcp.io/servers/sepehr071-divar-mcp/divar-mcp
