divar-mcp
This server provides a read-only, agent-friendly API for interacting with Iran's divar.ir classifieds marketplace, covering search, detailed post reading, pricing insights, deal hunting, and market monitoring.
Search listings:
divar_searchfinds live ads with filters like query, city, category, price range (Toman), photo-only, district IDs, brand/model, and client-side recency filtering (max_age_hours), with pagination and custom sort.Read full post details:
divar_get_postreturns full description, structured attributes (brand, year, mileage), images, Jalali/ISO dates, city/district, and a district ID usable for filtering.Find similar posts:
divar_similar_postsfetches comparable listings for a given post (same category/brand/city) excluding itself.Price analysis:
divar_price_analysisprovides price distribution (median, percentiles, suggested ask range, price bands) to decide what to ask for an item.Appraise a listing:
divar_appraise_postjudges whether a post is below/fair/above market, with percentile, delta vs median, confidence, and cheaper alternatives.Find deals:
divar_find_dealsranks underpriced listings with adeal_scoreand per-deal reasons (caveat: verify low prices).Market breakdown:
divar_market_breakdownshows median price per district, price bands, and freshness.Watch for new listings:
divar_watch_create,divar_watch_check,divar_watch_list,divar_watch_deletelet you save searches and check for only never-seen-before posts (cron-friendly).Track price trends:
divar_price_trendbuilds a local day-by-day price history for a filter.Export bulk data:
divar_exportwrites CSV (Excel-safe Persian) or JSONL to disk, returning the file path.Meta and discovery:
divar_statuschecks divar.ir reachability and stats;divar_helpmaps capabilities;divar_list_citiesanddivar_list_categorieslook up valid cities/categories;divar_post_filtersshows available filter widgets;divar_search_urlgenerates a human-openable divar.ir URL.Structured output: All tools return
structuredContentand declareoutputSchemafor easy parsing.Self-repairing errors: Incorrect city/category inputs return closest valid suggestions instead of failures.
Read-only and polite: No writes to Divar, no contact data, rate-limited, and no API key required.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@divar-mcpWhat's the market price for iPhone 13 in Tehran?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
divar-mcp
An agent-grade MCP server for divar.ir, Iran's largest classifieds marketplace (دیوار). Search live listings, read a post in full, price an item, appraise someone else's listing, hunt underpriced stock, watch a search over time, and export bulk rows, all from any MCP client.
Read-only, no account, no API key, no dependencies. Works from inside Iran and from anywhere else divar.ir's API is reachable.
19 tools | find, read, value, appraise, hunt, watch, export, plus self-diagnosis and a capability map |
5 resources | cities, categories, verified slugs, status, help as readable MCP resources |
4 prompts | price-an-item, appraise-listing, find-deals, watch-market |
structured output | every tool declares an |
self-repairing errors | a wrong city or category comes back with the closest real values and a hint |
conservative by design | read-only, no contact details, polite rate limits, no fabricated links |
یک MCP سرور کامل برای کار با آگهیهای دیوار: جستوجو، خواندن آگهی، قیمتگذاری، ارزیابی آگهی دیگران، پیدا کردن زیرقیمتها، دیدهبانی جستوجو و خروجی CSV. فقط خواندنی، بدون کلید API، بدون وابستگی.
Why this exists
Divar has no public MCP server. The divar-ir/* GitHub org is Divar's own internal code-search tooling, not marketplace access. The official API (Kenar / کنار دیوار) needs an approved app, an API key and OAuth, which is a partner programme, not a read path. Everything else out there is Playwright page-scraping with no MCP surface, no filters and no pagination.
This server talks to the same JSON endpoints divar.ir's own web app uses, and wraps them in the shape an agent actually needs.
Related MCP server: leboncoin-mcp
Install
# run straight from git, no install
uvx --from git+https://github.com/shojaee76-cmyk/divar-mcp divar-mcp
# or install it
pip install git+https://github.com/shojaee76-cmyk/divar-mcpRequires Python 3.10+. There are no third-party dependencies.
Connect a client
Claude Desktop / Claude Code (claude_desktop_config.json):
{
"mcpServers": {
"divar": {
"command": "uvx",
"args": ["--from", "git+https://github.com/shojaee76-cmyk/divar-mcp", "divar-mcp"]
}
}
}Cursor / Cline / Windsurf — same shape, command + args.
Hermes Agent (~/.hermes/config.yaml):
mcp_servers:
divar:
command: uvx
args: ["--from", "git+https://github.com/shojaee76-cmyk/divar-mcp", "divar-mcp"]Tools
Find and read
Tool | What it gives an agent |
| Live listings: |
| One listing in full: description, structured attributes (brand/model, year, mileage...), image URLs, Jalali text and ISO 8601 dates, city/district, district id, category breadcrumb. |
| Comparables for an existing listing: same category, brand/model and city, excluding itself. |
| A |
Value and decide
Tool | What it gives an agent |
| Price distribution of live comparables: min, p25, p40, median, p75, max, mean, suggested ask range, price bands, freshness split, and a per-district median table. The "what should I ask?" tool. |
| Judges one listing: |
| Ranks listings below the live market with an explainable |
| Where the stock sits: median price per district (busiest first), price bands, freshness. |
Watch and export
Tool | What it gives an agent |
| Save a named search; today's listings become the quiet baseline. |
| Returns only listings a watch has never reported before. Cron-friendly "anything new?" |
| Manage saved watches. |
| Local day-by-day price history for an exact filter. Every search records a price point, so the series grows with use. Says |
| Walks pages and writes CSV (utf-8-sig, Excel-safe Persian) or JSONL to disk, returning the absolute path. Bulk work stays out of the model's context. |
Meta
Tool | What it gives an agent |
| Is divar.ir reachable right now (latency, or a clear hint when it is not), dataset sizes, store size, cache counters. First call when something looks broken. |
| Capability map: tool index, units, dataset sizes and recipes for the common jobs. No network call. |
| Cities by Persian name, ASCII slug or id; a miss returns the closest names. |
| Category slugs by Persian or English text with breadcrumb parents; a miss returns the closest slugs. |
| Which filter widgets Divar currently exposes for a city/category. |
All prices are Toman (Divar displays Toman; its internal schema.org price is Rial, 10x larger). Dates come back as both the Jalali text and ISO 8601 with +03:30.
Resources and prompts
MCP clients that support them get read-only resources instead of tool calls:
divar://cities city id, Persian name and ASCII slug for every harvested city
divar://categories category slugs with Persian names and parents
divar://cities/slugs the validated city page slug map
divar://status dataset + store + cache stats, no network probe
divar://help the capability mapAnd four prompts that encode the workflows: price-an-item, appraise-listing, find-deals, watch-market.
Built for agents, not just for humans
Every tool declares an
outputSchemaand returnsstructuredContent, so a client can parse results instead of regexing prose.Errors repair themselves. A wrong category returns
suggestionswith the closest real slugs and ahint; a wrong city returns the closest real names. Unknown tools return the list of valid ones. Nothing fails with a bare 400.Inputs are forgiving. Cities accept an id (
1), a Persian name (تهران), or an ASCII slug (tehran), case-insensitively. Categories accept a slug or a Persian name.ROOTis understood as "everything".Every result carries
meta: requests made, cached responses, elapsed seconds, rate-limit and cache settings, so an agent can tell a free call from an expensive one.Annotations on every tool (
readOnlyHint,idempotentHint,openWorldHint) so a client can gate the two tools that write local files or local state.Brief by default. Search returns 10 compact fields per row;
brief: falsereturns everything.
Example agent use
"My iPhone 13 is in good shape. What should I ask in Tehran right now?"
The agent calls divar_list_categories("موبایل") → mobile-phones, then divar_price_analysis(query="آیفون ۱۳", category="mobile-phones", city="تهران", pages=2), and answers with the median, the active band, the district table, and fresh comparables with links.
"Is this listing overpriced? https://divar.ir/v/gaxi5lYL"
divar_appraise_post → verdict, percentile, confidence, cheaper alternatives.
"Find a Peugeot 206 under 700 million in Karaj or Tehran, photo-only, posted this week."
divar_search(query="پژو ۲۰۶", cities=["کرج","تهران"], price_max=700000000, has_photo=true, max_age_hours=168).
"Tell me whenever a cheap 206 shows up."
divar_watch_create(name="206-karaj", query="پژو ۲۰۶", city="کرج"), then divar_watch_check("206-karaj") on a schedule.
CLI (same engine, for humans and cron)
divar search "پژو ۲۰۶" --city tehran --price-max 900000000 --has-photo --sort price_asc
divar price "آیفون ۱۳" --category موبایل --pages 3 # printed as a readable summary
divar deals "پژو ۲۰۶" --category light --min-discount 0.1
divar appraise https://divar.ir/v/gaxi5lYL
divar breakdown "پژو" --city تهران # median price per district
divar trend "آیفون ۱۳" --days 60
divar watch create --name 206 --query "پژو ۲۰۶" --city کرج
divar watch check --name 206
divar export "لپتاپ" --pages 5 --format csv
divar status
divar helpdivar-mcp --list-tools prints the raw tool schemas, --resources and --prompts list those, and divar-mcp --call divar_search --args '{"query":"پژو","city":"1"}' runs one tool without a client.
Performance
Latency to divar.ir is dominated by two things: a TCP+TLS handshake per request, and the polite delay between requests. Both are handled:
Keep-alive sockets. The client holds one HTTP connection per thread, so a multi-request tool pays for the handshake once instead of once per page. Idle sockets that Divar has closed are detected and reconnected transparently.
A shared client. The MCP server is long lived, so the same client (and its sockets and cache) is reused across tool calls instead of rebuilt per call.
A response cache. Identical requests inside
DIVAR_CACHE_TTL(default 180 seconds) are served locally. SetDIVAR_CACHE_TTL=0to disable it entirely.Batched local writes. The SQLite store runs in WAL mode with relaxed fsync and one commit per page of listings instead of one per row.
Every result's meta block reports connections_reused, requests_made and
elapsed_seconds, so the effect is visible from a client:
python tools/bench.py --mode before # fresh client + urllib + no cache
python tools/bench.py --mode transport # keep-alive, cache off
python tools/bench.py --mode warm # keep-alive + cacheMeasured against the real API from an Iranian line (--repeat 3, medians, cache
disabled so only the transport is compared):
Tool | before | keep-alive | speedup | repeat call |
| 1.59s | 1.11s | 1.43x | 0.00s |
| 2.78s | 1.40s | 1.99x | 0.00s |
| 2.46s | 1.72s | 1.43x | 0.00s |
| 3.92s | 2.59s | 1.51x | 0.00s |
| 4.07s | 2.44s | 1.67x | 0.00s |
| 1.23s | 0.75s | 1.64x | 0.00s |
total | 16.05s | 10.01s | 1.60x | 0.00s |
Tools that make several requests gain most (a handshake saved per request); a repeated identical call inside the cache TTL costs nothing. Numbers vary with the line: treat them as a median of the hour they were taken, not a promise.
Tuning knobs, all optional environment variables:
Variable | Default | Meaning |
|
| seconds a response stays cached; |
|
|
|
| unset |
|
|
| minimum seconds between requests (be polite) |
|
| per-request timeout in seconds |
| platform data dir | path to the local SQLite store |
| unset |
|
How it works
The server talks to the same JSON endpoints the divar.ir web app uses (discovered from Divar's own JS bundles and verified against the live API):
Endpoint | Use |
| listing search, filters, cursor pagination |
| filter schema for a city/category |
| single post view |
Things worth knowing if you fork this:
Filters are protobuf-
Anyencoded.categoryis{"str": {"value": "<slug>"}},priceis{"number_range": {"minimum": n, "maximum": n}},districtsis{"repeated_string": {"value": ["208"]}}(numeric district ids),has-photois{"boolean": {}}(presence = true),brand_modelis a repeating string.pageis ignored by the API. Real pagination is a cursor: echo backpagination.data(last_post_date,pelle_max_score,filters_hash,cumulative_widgets_count,page,layer_page) withpage/layer_pageincremented. This server does that for you (pages=3).Divar's own recency filter (
recent_ads) does not filter. Verified:3hand7dreturn identical result sets, so recency filtering is done client-side from the parsed Persian relative time (max_age_hours).District filtering needs numeric ids, which only appear inside a post's TAGS payload.
divar_get_postexposes it asdistrict_id.Jalali dates are converted (
۳۱ شهریور ۱۴۰۵→2026-09-22T00:06:00+03:30) so an agent can reason about age without a Hijri library.Category slugs come from Divar's own SEO breadcrumbs (
mobile-phones→mobile-tablet→electronic-devices), so the vocabulary and Persian names are real, not guessed.Web links need a real slug. A Persian city name in the path is wrong, and divar.ir answers with the same SPA shell for any slug, so a slug is published only when it came from Divar's payload and its
city_idmatched the query.tools/harvest_city_slugs.pygrows that verified map.Divar's own SEO headline is off by one ("صفحه ۲" on the first page). Harmless, but do not read it as a page number.
Local state (listing observations, price history, watches) lives in SQLite outside the package: %LOCALAPPDATA%\divar-mcp\store.db on Windows, ~/.divar-mcp/store.db elsewhere, overridable with DIVAR_STORE. Set DIVAR_STORE_DISABLE=1 for a fully stateless run.
One-click launcher
launchers/DIVAR search.bat (double-click, or the Desktop shortcut) asks for a phrase, a city and an optional budget, prints live listings with prices, and offers to open the matching divar.ir page in Chrome.
Politeness and legality
Read-only for Divar. This server never creates, edits, deletes, reports or messages anything there. The only writes are local files (
divar_export, the SQLite store, watch definitions).No phone numbers or contact data. Divar does not expose seller contact details to logged-out clients and this server never tries to obtain them (no auth bypass, no
GetContactWeb, no PII harvesting).Rate limited. Default one request per 0.8s with an LRU response cache, well under Divar's ~30 requests/minute throttle. Tune with
DIVAR_MIN_INTERVAL,DIVAR_TIMEOUT,DIVAR_CACHE_TTL.Unofficial. Not affiliated with or endorsed by Divar (Hezardastan / Cafe Bazaar). It reads public listings the way a browser does. Respect Divar's terms and local law; if you need write access or official data, use Kenar.
Development
git clone https://github.com/shojaee76-cmyk/divar-mcp && cd divar-mcp
uv venv && uv pip install -e ".[dev]"
pytest # offline: parsers, store, analytics, MCP protocol, SDK interop
DIVAR_LIVE=1 pytest tests/test_live.py -v # hits the real API (needs an Iran-reachable line)
python tools/smoke.py # CLI -> MCP end to end, no network
python tools/verify_publish.py # repo blobs vs this working treeThe offline suite runs entirely on captured fixtures (tests/fixtures/*.json, real payloads from a live search and two live post views) plus temp-file stores, so parsers, analytics and watch logic are all tested without a network. The protocol suite boots the real server process and, when the official mcp SDK is installed, drives it with mcp.client.stdio to prove interop.
tools/ holds the reverse-engineering and harvesting scripts (probe*.py, harvest_cities.py, harvest_categories.py, harvest_city_slugs.py, build_data.py). Run python tools/build_data.py after re-harvesting to refresh the bundled data.
Roadmap
Optional
kenarbackend for authenticated workflows (your own listings) when the user supplies a keyDistrict-level price history once the store has a few weeks of observations
Saved-search diffing pushed by a scheduler (the watch tools are the storage side of this)
License
MIT. See LICENSE.
Available Tools
8 toolsdivar_get_postA
Full public detail for one divar.ir post: title, description, price in Toman, structured attributes (brand/model, year, mileage, ...), image URLs, Jalali and ISO posted/updated dates, city/district, category breadcrumb and its district id (usable as a divar_search filter).
| Name | Required | Description | Default |
|---|---|---|---|
| token | Yes | Post token (gaxi5lYL) or any divar.ir post URL. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of behavioral disclosure. It signals a read-only public fetch by describing the returned fields, but it does not mention error behavior, invalid tokens, missing posts, or rate/access limitations. This is minimally adequate but not comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one well-structured sentence that front-loads the purpose and then efficiently lists the concrete data fields returned. Every clause adds useful information and there is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with no output schema, the description thoroughly covers what will be returned, including dates, location, attributes, and category info. It even connects the district id to a sibling tool for follow-up search. It could still mention invalid-token behavior, but nothing essential to invoking it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is only one parameter and the schema already fully documents it as 'Post token (gaxi5lYL) or any divar.ir post URL.' The description adds no additional parameter-level semantics, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies a specific action (retrieve full public detail) on a specific resource (one divar.ir post) and enumerates what is included. This distinguishes it from sibling tools like divar_search or divar_similar_posts, which handle lists or related posts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for one post' implies it should be used when a specific post token or URL is available, and the mention that district id is usable as a divar_search filter hints at downstream use. However, it does not explicitly say when to use this tool versus alternatives or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
divar_list_categoriesA
Look up divar.ir category slugs by Persian or English text, with their breadcrumb parents. Use the slug in divar_search/divar_price_analysis.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Text to match, e.g. "موبایل" or "car". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses useful traits such as Persian/English text matching and that results include breadcrumb parents, but it does not explain behavior when the optional query is omitted or describe the return format.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two compact, front-loaded sentences with no filler. It states the purpose first and then the practical follow-up usage, making every sentence valuable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity tool with one optional parameter and no output schema, the description covers purpose, supported languages, returned parent breadcrumbs, and downstream usage. The only notable gap is not addressing behavior when 'query' is omitted.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents 'query' with 100% coverage, so the baseline is 3. The description adds useful context about matching Persian or English text and the intended slug usage, but it does not need to provide much more for a single simple parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb and resource: 'Look up divar.ir category slugs by Persian or English text.' It also clarifies the output includes breadcrumb parents and explicitly connects the result to downstream tools like divar_search/divar_price_analysis, distinguishing this lookup from search/post tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage context: 'Use the slug in divar_search/divar_price_analysis.' This tells an agent when this tool is relevant, though it does not explicitly mention alternatives or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
divar_list_citiesA
Look up divar.ir city ids by Persian name (or list them all).
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Persian city name (e.g. "مشهد"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden of behavioral disclosure. It states the tool can either look up a specific city or list all cities, which is useful. However, it doesn't disclose details like whether the query is case-sensitive, whether it returns partial matches, what the output format looks like, or whether it makes a network request. For a simple lookup tool, this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that is concise and front-loaded. It states the primary action ('look up divar.ir city ids'), the input ('by Persian name'), and the alternative behavior ('or list them all') without any wasted words. Every part earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple lookup tool with one optional parameter and no output schema, the description is nearly complete. It tells the agent what the tool does and how to use it. The only missing context is the exact output format (e.g., a list of {id, name} pairs), but since there is no output schema, a brief note on the return shape would have been helpful. Still, the tool is simple enough that an agent can likely infer the output.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: the only parameter 'query' is described as a Persian city name with an example. The description adds the behavior that omitting the query lists all cities, which is valuable and not in the schema. However, it doesn't add more detail about the parameter's format (e.g., normalization, exact match vs. fuzzy). Baseline 3 is appropriate since the schema already covers the parameter well.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: looking up divar.ir city IDs by Persian name, with the option to list all cities. It uses a specific verb ('look up') and resource ('divar.ir city ids'), and the optional listing behavior is explicitly mentioned. This distinguishes it from sibling tools like divar_search or divar_list_categories, which focus on other aspects of the Divar API.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool: when you need to map a Persian city name to its ID, or when you need the full list of city IDs. It doesn't explicitly state when not to use it or name alternatives, but the context is clear enough for an agent to select it over siblings like divar_search or divar_list_categories. A small gap is the lack of explicit exclusion, but the purpose is so specific that it's nearly self-evident.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
divar_post_filtersB
Show which filters divar.ir exposes for a city/category (price range, districts, photo-only).
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | City id (e.g. "1") or Persian name (e.g. "تهران"). | |
| category | No | Divar category slug, e.g. mobile-phones, light, buy-residential. See divar_list_categories. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. 'Show' reasonably implies a read-only operation, and the filter examples give some sense of the output, but the description does not disclose response format, optional-parameter behavior, or any limitations. It is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no filler. Every element—the action, resource, and representative filter examples—earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple introspection tool with two optional, well-described parameters and no output schema, the description adequately conveys what the tool returns at a conceptual level. It could specify behavior when no city/category is provided, but this is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already explains 'city' and 'category' clearly with examples. The description mentions 'city/category' in passing but adds no new semantic detail, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('show') and resource ('which filters divar.ir exposes'), with concrete examples (price range, districts, photo-only). It clearly identifies a filtering/introspection purpose, though it does not explicitly contrast with sibling tools like divar_search or divar_search_url.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use this tool versus alternatives, nor are there exclusions or prerequisites. The description states the parameters (city/category) but does not say what happens when they are omitted or how this tool relates to the sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
divar_price_analysisA
Price distribution of comparable live listings for an item, to decide what to ask before posting an ad (median, p25/p75, suggested ask range, price bands, freshness, cheapest and priciest samples). Prices in Toman.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | City id (e.g. "1") or Persian name (e.g. "تهران"). | |
| pages | No | Cursor pages to sample (1-6, default 2 ~= 48 posts). | |
| query | No | Product text, e.g. "آیفون ۱۳". | |
| category | No | Divar category slug, e.g. mobile-phones, light, buy-residential. See divar_list_categories. | |
| price_max | No | Price in Toman (not Rial). | |
| price_min | No | Price in Toman (not Rial). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It does reveal that the tool analyzes 'live listings' and 'comparable' items, and it notes the currency unit (Toman). However, it does not explain how pagination/sampling works, whether a city or query is required for meaningful results, or any limits or error conditions. This is partial but not complete transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler, front-loading the core purpose before listing the output components. The parenthetical enumeration is information-dense but slightly unwieldy. It earns a 4 for efficiency and clarity, not a 5 because the formatting could be more structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there is no output schema and no annotations, the description covers the key contract: what kind of analysis is performed, what metrics are returned, and the unit of measure. It lacks exact return format details and behavior when optional parameters are omitted, but it provides enough for an agent to decide when and how to invoke it. This is strong but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers all six parameters with 100% description coverage, so the baseline is 3. The tool description adds strategic context ('comparable live listings' and decision purpose) but does not introduce new parameter-level semantics beyond what the schema already states, and it repeats the Toman unit already present in price parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: computing the price distribution of comparable live listings for a specific decision (what to ask before posting an ad). It lists concrete output components such as median, p25/p75, suggested ask range, price bands, and samples, which makes the purpose specific. However, it does not explicitly name or contrast sibling tools like divar_search or divar_similar_posts, so it doesn't fully achieve sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear when-to-use context: 'to decide what to ask before posting an ad'. This tells an agent the intended scenario and implicitly distinguishes it from listing/search tools. It does not provide explicit exclusions or direct comparisons to alternative tools, which would warrant a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
divar_searchA
Search live divar.ir listings (Iran's largest classifieds). Read-only, no account needed. Supports text query, city, category, Toman price range, photo-only, district ids and brand/model, with cursor pagination. Returns normalized rows (token, title, price in Toman, city, district, relative time, image, url).
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | City id (e.g. "1") or Persian name (e.g. "تهران"). | |
| sort | No | Client-side sort of the sampled rows. | |
| limit | No | Return at most this many rows. | |
| pages | No | Cursor pages to fetch (1-5, default 1). | |
| query | No | Free-text search, Persian (e.g. "پژو ۲۰۶"). | |
| category | No | Divar category slug, e.g. mobile-phones, light, buy-residential. See divar_list_categories. | |
| has_photo | No | Only posts with photos. | |
| page_size | No | Rows per page (max 60, default 24). | |
| price_max | No | Price in Toman (not Rial). | |
| price_min | No | Price in Toman (not Rial). | |
| brand_model | No | Exact brand/model string, e.g. "samsung galaxy s21 5g" (from divar_get_post). | |
| district_ids | No | Divar numeric district ids (e.g. ["208"]). Get them from divar_get_post district_id. | |
| max_age_hours | No | Drop posts older than this (Divar's own recency filter is unreliable; this is client-side). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the operation is read-only and requires no account, and it reveals cursor pagination and the exact normalized return fields, all beyond what the schema alone provides.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is roughly 80 words, front-loaded with the main purpose and followed by compact feature and return-value statements. Every sentence carries useful information, though the enumeration of parameters partially duplicates schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 13 parameters and no output schema, this description covers key contextual aspects: read-only access, no account requirement, live listings, cursor pagination, and exact normalized row fields. It does not describe error behavior or page/limit interaction, but these are minor given the thorough schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description restates the parameter categories (query, city, category, Toman price range, photo-only, district ids, brand/model) but adds no new semantic meaning beyond the schema's own parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action, 'Search live divar.ir listings', naming the resource and context. It clearly states what the tool does, though it does not explicitly differentiate it from sibling tools like divar_get_post or divar_price_analysis.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no explicit guidance on when to use this tool versus alternatives such as divar_get_post or divar_similar_posts. It mentions read-only/no account, which implies safe general searching, but it does not tell the agent when to prefer this over sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
divar_search_urlA
Build a divar.ir web URL for a search, so a human can open it in a browser.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | City id (e.g. "1") or Persian name (e.g. "تهران"). | |
| query | No | ||
| category | No | Divar category slug, e.g. mobile-phones, light, buy-residential. See divar_list_categories. | |
| price_max | No | Price in Toman (not Rial). | |
| price_min | No | Price in Toman (not Rial). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the full burden of behavioral disclosure. It states the tool builds a URL, which implies a pure construction task, but it does not explicitly confirm there are no network side effects, what the return value looks like, or how invalid parameters are handled. This leaves the agent with uncertainty about the tool's actual behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler, front-loading the action ('Build a divar.ir web URL') and then stating the human-use purpose. Every word earns its place; it is as concise as possible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (a URL constructor with 5 optional parameters) and no annotations or output schema, the description covers the core purpose. It does not detail return format or error behavior, but for this simple utility the description is sufficient for an agent to correctly understand the tool's role. The missing annotation coverage keeps it from a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 80%, so the input schema already documents most parameters (city, category, price units). The description itself adds no parameter-level meaning, but per the rubric the baseline is 3 when coverage is high. The description does not compensate for the one undocumented parameter ('query').
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Build') and resource ('divar.ir web URL for a search'), and adds the purpose 'so a human can open it in a browser.' This clearly distinguishes it from sibling divar_search, which presumably returns programmatic results. The action and scope are immediately understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'so a human can open it in a browser' implies the intended use case, but the description gives no explicit when-not-to-use guidance or mention of alternative tools like divar_search. An agent must infer when this URL-builder should be chosen over the programmatic search tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
divar_similar_postsA
Comparable listings for an existing post: same category, brand/model and city, excluding the post itself. Useful for a seller checking competition or a buyer checking the price.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | City id (e.g. "1") or Persian name (e.g. "تهران"). | |
| limit | No | Max comparables (default 12). | |
| token | Yes | Post token or divar.ir URL. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses key behaviors: filtering by category/brand/model/city and excluding the input post. However, it does not mention potential errors, authentication requirements, rate limits, or output format. The added context is useful but not comprehensive for a tool with zero annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no extraneous words. The function and criteria are front-loaded, followed by concise use cases. Every sentence earns its place, making it highly effective and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations, the description should explain what the response contains. It states 'comparable listings' but does not specify the format (e.g., list of post tokens, full post objects, or metadata). It also omits error handling or edge cases. Given the tool's simplicity and the availability of divar_get_post for details, it is partially complete but lacks important contextual depth.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for all three parameters, so the baseline is 3. The description adds context that the token determines category/brand/model and city is a filter, but does not provide extra parameter-level details beyond the schema's own descriptions. It reinforces meaning rather than adding new information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: returns comparable listings for an existing post, with specific criteria (same category, brand/model, city) and exclusion of the post itself. It distinguishes itself from siblings like divar_search (general search) and divar_get_post (single post retrieval) by focusing on similarity based on an existing token.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage context: 'useful for a seller checking competition or a buyer checking the price'. It clearly implies when to use the tool (when you have an existing post and want comparables) but does not explicitly mention alternatives or when not to use it, such as when a general search is more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.1.0- First observed
divar_get_post - First observed
divar_list_categories - First observed
divar_list_cities - First observed
divar_post_filters - First observed
divar_price_analysis - First observed
divar_search - First observed
divar_search_url - First observed
divar_similar_posts
TDQS
Scored across 8 tools
Each tool targets a distinct concern: searching, fetching details, analyzing prices, finding similar posts, and listing metadata (cities, categories, filters). Even the two analysis tools (price_analysis vs similar_posts) are clearly differentiated by their purpose—one focuses on price distribution, the other on comparable listings. No real ambiguity exists.
All tools share the 'divar_' prefix, which provides a clear namespace. The pattern is mostly verb_noun (search, get_post, list_cities) but some are noun phrases (price_analysis, similar_posts, post_filters). The style is consistent (snake_case) and readable, though not perfectly uniform in verb usage.
Eight tools is ideal for a read-only classifieds analysis server. Each tool serves a distinct role in the workflow—discovering, inspecting, analyzing, and building URLs—without unnecessary overlap or bloat. The count is well-scoped for the stated purpose.
The server covers the core read-only lifecycle: search, get detail, price analysis, similar items, and lookups for cities, categories, and filters. It lacks a method to post or manage listings, but that's outside its declared read-only scope. Minor gaps like district-level listing or user info are non-essential for the intended use case.
Maintenance
Related MCP Connectors
Scrape, crawl and search the web for AI agents via MCP.
Live Google Maps business search, review, and photo data for AI agents over MCP.
Pay-per-use tool marketplace for AI agents. Search, price-check, and call APIs via MCP.
Web search, browser automation, scraping, crawling and CAPTCHA solving for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA read-only MCP server that gives LLM agents live access to OpenSooq, the largest classifieds marketplace in Kuwait, enabling search, pricing, seller reputation, and deal finding.2MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to search and consult Leboncoin classified ads through the MCP protocol, with tools for ad search, detail retrieval, user profiles, and category/region listings.MIT
- AlicenseAqualityAmaintenanceEnables AI agents to search and monitor Dutch and Belgian classifieds (Marktplaats and 2dehands) for listings, seller profiles, and categories.52MIT
- FlicenseNot gradedqualityBmaintenanceEnables AI agents to search and retrieve Yad2 real estate listings (for rent or sale) using MCP tools, with data scraped via GitHub Actions and served from a Cloudflare D1 database.-