Skip to main content
Glama
Divar Intelligence MCP
by omidgharib

Divar Intelligence MCP

سرور مستقل و غیررسمی برای جست‌وجو، مقایسه، بررسی قیمت و پایش آگهی‌های دیوار. داده‌ها با منبع، تازگی، وضعیت نامعلوم و محدودیت پوشش ارائه می‌شوند. این پروژه عملیات انتشار آگهی، پرداخت، پیام به فروشنده یا دریافت شماره تلفن انجام نمی‌دهد.

اجرا در ویندوز

Python 3.11 یا جدیدتر لازم است. از داخل پوشهٔ پروژه:

python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[dev]"
.\.venv\Scripts\python.exe -m divar_mcp status

یا از scripts/setup.ps1 استفاده کنید. متغیرهای نمونه در .env.example هستند؛ این فایل به‌صورت خودکار بارگذاری نمی‌شود. تنظیمات را در محیط فرایند یا بخش env کلاینت MCP قرار دهید.

حالت واقعی و اجرای محلی MCP

$env:DIVAR_PROVIDER = "public"
$env:DIVAR_STATE_DIR = "$PWD\.state"
.\.venv\Scripts\python.exe -m divar_mcp serve

این فرمان MCP را روی stdio اجرا می‌کند و منتظر کلاینت می‌ماند؛ رابط چت یا صفحهٔ وب جداگانه‌ای باز نمی‌کند. فایل آمادهٔ اتصال در examples/mcp.local.json است. مسیر Python و پوشهٔ وضعیت را در صورت جابه‌جایی پروژه اصلاح کنید.

نمایش آفلاین، بدون نیاز به اینترنت

$env:DIVAR_PROVIDER = "fixture"
.\.venv\Scripts\python.exe -m divar_mcp serve

این حالت دادهٔ ساختگی و مشخص‌شده به‌عنوان نمونه دارد. لینک‌های آن مثال قالب هستند و نباید به‌عنوان آگهی واقعی معرفی شوند.

اتصال رسمی کنار

$env:DIVAR_PROVIDER = "kenar"
$env:DIVAR_KENAR_API_KEY = "your-approved-app-key"
.\.venv\Scripts\python.exe -m divar_mcp serve

آداپتر رسمی از مسیرهای مستند جست‌وجو، جزئیات و assets استفاده می‌کند. کلید و مجوز SEARCH_POST را خودتان از کنار تهیه کنید. سهمیه و مجاز بودن کاربرد پایش باید برای برنامهٔ شما روشن باشد. صفحه‌بندی برای مسیر جست‌وجوی رسمی فرض نشده است و پوشش آن صریحاً نمونهٔ محدود گزارش می‌شود. هیچ تغییر مسیر خودکار به تأمین‌کنندهٔ عمومی انجام نمی‌شود.

HTTP

برای اتصال محلی بدون احراز هویت، فعال‌سازی صریح لازم است:

$env:DIVAR_ALLOW_LOCAL_HTTP = "1"
.\.venv\Scripts\python.exe -m divar_mcp serve --transport http --host 127.0.0.1 --port 8765

نشانی MCP: http://127.0.0.1:8765/mcp.

برای استفادهٔ چند حساب، DIVAR_HTTP_TOKENS را یک نگاشت JSON از توکن‌های تصادفی حداقل ۲۴ کاراکتری به شناسهٔ حساب قرار دهید. هر درخواست به هویت حاصل از Bearer token متصل می‌شود؛ نام کاربر پارامتر ابزارها نیست. Origin و Host با فهرست مجاز کنترل می‌شوند؛ برای دامنهٔ اختصاصی، DIVAR_ALLOWED_HOSTS و DIVAR_ALLOWED_ORIGINS را تنظیم کنید. توکن‌ها را در مخزن ثبت نکنید.

این نسخه از Bearer token ازپیش‌تنظیم‌شده استفاده می‌کند. جریان کامل OAuth برای ثبت و ورود عمومی مشتریان MCP و استقرار SaaS خودکار پیاده نشده است.

Related MCP server: divar-mcp

ابزارها

پروفایل core دارای ۱۲ ابزار است:

  • کشف و ورودی: dv_resolve_entities، dv_filter_schema، dv_parse_search.

  • دریافت: dv_search، dv_get_listing، dv_get_listings.

  • تصمیم: dv_similar، dv_compare، dv_rank، dv_market_snapshot، dv_assess_price.

  • وضعیت: dv_status.

پروفایل پیش‌فرض advanced مجموعاً ۳۱ ابزار دارد و موارد زیر را اضافه می‌کند:

  • dv_count و dv_market_history.

  • dv_nearby، dv_geocode، dv_locate، dv_boundaries، dv_neighbours، dv_place_mapping.

  • dv_seller_summary و dv_dealer_summary؛ فقط اطلاعات عمومیِ قابل دسترسی.

  • dv_watch_create، dv_watch_list، dv_watch_update، dv_watch_delete، dv_watch_check، dv_watch_events، dv_watch_ack.

  • dv_price_history و dv_export_results.

منابع MCP شامل شهرها، دسته‌ها، طرح فیلتر و خروجی‌های موقتِ متعلق به همان حساب هستند. چهار prompt برای بودجه، مقایسه، ارزیابی قیمت و پایش موجود است. فهرست دقیق ورودی‌ها و خروجی‌ها در docs/tool-catalog.json قرار دارد.

نمونهٔ فراخوانی

{
  "name": "dv_search",
  "arguments": {
    "request": {
      "city": "tehran",
      "category": "apartment-rent",
      "max_deposit_toman": 500000000,
      "max_price_toman": 20000000,
      "constraints": [{"field":"parking","value":true,"required":true}],
      "verify_details": true,
      "limit": 5,
      "pages": 2
    }
  }
}

در دستهٔ اجاره، حدود price_toman مربوط به اجارهٔ ماهانه‌اند؛ ودیعه حدود جدا دارد. match_status=unknown یعنی شرط ضروری تأیید نشده است و رتبه‌بندی آن مورد را کنار می‌گذارد. وجود فیلتر در طرح بالادست به‌تنهایی اثبات اعمال واقعی آن نیست.

search_scope محدودهٔ درخواستیِ حل‌شده را نگه می‌دارد؛ شهر و دستهٔ خود آگهی فقط از شاهد منبع پر می‌شوند. اگر فهرست، دستهٔ واقعی را ندهد، آن مقدار نامعلوم می‌ماند تا جزئیات خوانده شود. رتبه‌بندی به‌صورت محدود جزئیات را می‌خواند تا این ابهام را کاهش دهد.

برای ادامه، همان درخواست را همراه next_cursor به cursor بدهید. نتایج باقی‌ماندهٔ صفحه در SQLite نگهداری می‌شوند؛ cursor متعلق به حساب و جست‌وجوی مشخص است و دو ساعت اعتبار دارد. مرتب‌سازی قیمت روی نمونهٔ برگشتی است و ارزان‌ترینِ کل بازار را تضمین نمی‌کند.

پایش و اعلان

ساخت پایش فقط پیکربندی را ذخیره می‌کند. یکی از این دو روش را برای اجرای آن انتخاب کنید:

.\.venv\Scripts\python.exe -m divar_mcp serve --with-worker
# یا یک فرایند جدا با همان provider و DIVAR_STATE_DIR:
.\.venv\Scripts\python.exe -m divar_mcp worker
# یک نوبت برای زمان‌بند بیرونی:
.\.venv\Scripts\python.exe -m divar_mcp worker --once

پیش‌فرض، آگهی‌های موجود را خط مبنا قرار می‌دهد؛ include_existing=true آن‌ها را هم رویداد می‌کند. هر بخش اسکن و رویدادهایش با هم در تراکنش ثبت می‌شوند؛ cursor اسکن از نشانگر خواندن رویدادها جداست. dv_watch_events خواندن و dv_watch_ack تأیید دریافت است. در صورت انقضای cursor یا محدودیت منبع، شکاف پوشش اعلام می‌شود؛ پایش خوراک کامل و تضمین‌شدهٔ همهٔ بازار نیست.

اگر مقصد HTTPS در DIVAR_NOTIFICATION_URL و در صورت نیاز توکن آن در DIVAR_NOTIFICATION_TOKEN تنظیم شود، worker رویدادها را با کلید Idempotency تحویل می‌دهد و خطا را برای تلاش بعدی نگه می‌دارد. ابزارهای MCP نمی‌توانند مقصد دلخواه تعیین کنند. تحویل از نوع «حداقل یک بار» است؛ گیرنده باید کلید رویداد را برای حذف تکرار مصرف کند. بدون این تنظیم، هیچ پیام بیرونی ارسال نمی‌شود.

قرارداد و محدودیت‌ها

  • مبالغ صحیح و به تومان، با نوع مبلغ و شاهد استخراج؛ ودیعه، اجاره و فروش مستقل‌اند.

  • «خیر»، «نامعلوم»، «توافقی» و صفرِ صریح با هم فرق دارند.

  • زمان انتشار، ترتیب نمایش/نردبان و مشاهدهٔ سیستم جدا هستند. عدم دسترسی به معنی فروش نیست.

  • جزئیات به‌صورت محدود، حداکثر ۱۰ مورد در هر فراخوانی جست‌وجو، تکمیل می‌شوند؛ محدودیت‌های باقی‌مانده آشکار می‌مانند.

  • ارزیابی تخصصی در گوشی، خودرو و مسکن قواعد مشابهت دارد و در نبود حداقل شاهد کافی خودداری می‌کند. ارزیابی قیمت معامله یا کارشناسی اصالت نیست.

  • قیمت اجاره به‌صورت دوبعدی مقایسه می‌شود؛ نرخ تبدیل ودیعه فقط با پارامتر صریح کاربر وارد رتبه‌بندی می‌شود.

  • تأمین‌کنندهٔ عمومی مستندشده نیست و ممکن است دسترسی را رد کند؛ خطای ۴۰۳، سهمیه و Retry-After مخفی نمی‌شوند. دورزدن چالش، چرخش پراکسی و ورود خودکار وجود ندارد.

  • SQLite برای اجرای محلی و چند فرایند روی همان فایل طراحی شده است. استقرار توزیع‌شدهٔ چند میزبان به پایگاه/صف مشترک و مدیریت اسرار مناسب نیاز دارد.

  • تاریخچه از شروع مشاهده ساخته می‌شود؛ دادهٔ گذشته اختراع نمی‌شود. جابه‌جایی میانهٔ نمونهٔ روزانه لزوماً تغییر قیمت همان کالاها نیست.

  • محتوا و نقل‌قول آگهی دادهٔ غیرقابل‌اعتمادند؛ دستور اجرای ابزار محسوب نمی‌شوند. پالایش شماره‌های رایج، تضمین حذف تمام صورت‌های ممکن اطلاعات شخصی نیست.

  • محدودیت درخواست پیش‌فرضِ محلی ۱۰۰۰ در روز UTC و فاصلهٔ ۲ ثانیه است؛ این تنظیم، سهمیهٔ تأییدشدهٔ دیوار نیست و آن را افزایش نمی‌دهد.

تست و توسعه

.\.venv\Scripts\python.exe -m pytest
.\.venv\Scripts\python.exe -m ruff check src tests scripts
.\.venv\Scripts\python.exe -m ruff format --check src tests scripts
.\.venv\Scripts\python.exe scripts/smoke.py --provider fixture

scripts/smoke.py --provider public درخواست واقعی فقط‌خواندنی می‌فرستد؛ پیش‌فرض آن fixture است. آزمون رسمیِ زنده به کلید کنار نیاز دارد. تست‌های عادی از پاسخ‌های کنترل‌شده استفاده می‌کنند.

گزارش بررسی انجام‌شده در docs/verification.md ثبت شده است؛ شامل ۶۶ تست موفق و آزمون واقعی جست‌وجو، جزئیات و ادامهٔ نتایج.

تحلیل اولیه در docs/analysis-fa.md و معماری اجراشده در docs/architecture.md هستند. کدهای انتخاب‌شده از پروژهٔ MIT در src/divar_mcp/_vendor قرار دارند و مجوزشان در licenses/sepehr071-MIT.txt حفظ شده است. از کد، متن یا برندِ مخزن محدودِ mmdju کپی نشده است؛ شرح کامل در THIRD_PARTY_NOTICES.md آمده است.

Available Tools

31 tools
dv_assess_priceB
Read-onlyIdempotent

Compare asking price against like-for-like ads or abstain. Evidence quality is a heuristic, never a probability or certified valuation.

Inputs: listing (required), request. Returns: data, warnings, schema_version

dv_boundariesB
Read-onlyIdempotent

Get published public neighbourhood outlines, simplified by the source helper; not cadastral boundaries.

Inputs: city, district. Returns: data, warnings, schema_version

dv_compareB
Read-onlyIdempotent

Compare supplied ads and unresolved facts. For rentals, show a deposit/rent Pareto frontier without inventing a conversion rate.

Inputs: listings (required). Returns: data, warnings, schema_version

dv_countC
Read-onlyIdempotent

Public upstream approximate count or an explicitly labelled returned-sample count. Local constraints are not a source-wide count.

Inputs: request (required). Returns: data, warnings, schema_version

dv_dealer_summaryC
Read-onlyIdempotent

Read the publicly accessible first batch of a dealer page; permission failures remain explicit.

Inputs: brand_token (required). Returns: data, warnings, schema_version

dv_export_resultsB

Create a bounded, owner-scoped one-hour export resource; CSV cells are protected against formula execution.

Inputs: request (required), format. Returns: data, warnings, schema_version

dv_filter_schemaC
Read-onlyIdempotent

Discover category filter types and units. Schema presence is not proof that the source enforces a filter.

Inputs: category (required), city. Returns: data, warnings, schema_version

dv_geocodeB
Read-onlyIdempotent

Find a public landmark/place near a map centre; not an exact personal address lookup.

Inputs: query (required), lat, lon. Returns: data, warnings, schema_version

dv_get_listingA
Read-onlyIdempotent

Read public details of a token or HTTPS divar.ir listing URL; preserve missing/false/zero and separate rent/deposit.

Inputs: listing (required), refresh. Returns: listing, schema_version

dv_get_listingsB
Read-onlyIdempotent

Read 1-10 listings with an independent result or actionable error for each member.

Inputs: listings (required), refresh. Returns: items, schema_version

dv_locateB
Read-onlyIdempotent

Resolve a point's city/district using the public place endpoint; location accuracy is source-dependent.

Inputs: lat (required), lon (required). Returns: data, warnings, schema_version

dv_market_historyB

Record one asking-price sample per UTC day or read saved points. History starts when first recorded; composition changes are not item-price changes.

Inputs: request (required), record. Returns: data, warnings, schema_version

dv_market_snapshotB
Read-onlyIdempotent

Describe asking-price samples by category/transaction. Filter sale/rent/deposit independently and report coverage.

Inputs: request (required). Returns: data, warnings, schema_version

dv_nearbyB
Read-onlyIdempotent

Public map listings near a point. Coordinates/distances may be approximate; unsupported providers fail explicitly.

Inputs: lat (required), lon (required), category (required), query, +1 more. Returns: data, warnings, schema_version

dv_neighboursC
Read-onlyIdempotent

List adjacent and nearby neighbourhoods with the helper's distinct bases preserved.

Inputs: district_id (required), city. Returns: data, warnings, schema_version

dv_place_mappingB
Read-onlyIdempotent

Map old public place identifiers to current IDs; unresolved identifiers remain unverified.

Inputs: ids (required). Returns: data, warnings, schema_version

dv_price_historyB
Read-onlyIdempotent

Return this owner's observations of this listing, starting at first observation. It is not a retroactive market index.

Inputs: listing (required), limit. Returns: data, warnings, schema_version

dv_rankC
Read-onlyIdempotent

Rank the scanned sample by explicit preferences and supported price evidence. Optional monthly deposit opportunity-cost rate is an assumption, not a market fact.

Inputs: request (required), mode, monthly_deposit_rate. Returns: data, warnings, schema_version

dv_resolve_entitiesB
Read-onlyIdempotent

Resolve city/district/category names or canonical model keys. Options depend on the configured provider.

Inputs: kind (required), city, query, category. Returns: data, warnings, schema_version

dv_seller_summaryA
Read-onlyIdempotent

Read public seller summary where available. No login, phone lookup or fallback on access denial.

Inputs: listing (required). Returns: data, warnings, schema_version

dv_similarC
Read-onlyIdempotent

Find like-for-like items; reject unknown/different critical specs and explain exclusions. Optional request narrows the sample.

Inputs: listing (required), request. Returns: data, warnings, schema_version

dv_statusA
Read-onlyIdempotent

Show provider capabilities, local budget and scheduler configuration. Does not claim live connectivity.

Inputs: no named parameters. Returns: data, warnings, schema_version

dv_watch_ackC

Acknowledge only this owner's received events; retries are idempotent.

Inputs: event_ids (required). Returns: data, warnings, schema_version

dv_watch_checkB

Scan a bounded watch chunk and atomically enqueue events before advancing the scan continuation.

Inputs: watch_id (required). Returns: data, warnings, schema_version

dv_watch_createB

Persist an owner-scoped watch. A worker must run checks. Existing results form a baseline unless explicitly included.

Inputs: name (required), request (required), recheck_missing, include_existing, +1 more. Returns: data, warnings, schema_version

dv_watch_deleteA
DestructiveIdempotent

Delete this owner's watch and its seen set; already-enqueued events remain available for audit/delivery.

Inputs: watch_id (required). Returns: data, warnings, schema_version

dv_watch_eventsA
Read-onlyIdempotent

Read durable events using an independent delivery cursor. Reading does not acknowledge or remove events.

Inputs: limit, watch_id, after_seq. Returns: data, warnings, schema_version

dv_watch_listA
Read-onlyIdempotent

List only this owner's saved watches, their continuation, coverage and last error.

Inputs: no named parameters. Returns: data, warnings, schema_version

dv_watch_updateA

Change a watch interval without discarding its pending scan or seen versions.

Inputs: watch_id (required), interval_seconds (required). Returns: data, warnings, schema_version

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.9/5.0

    Scored across 31 tools

    Disambiguation4/5

    Most tools have clearly distinct roles, especially the watch suite and search-pipeline tools. However, the market-analysis cluster (similar, compare, rank, assess_price, market_snapshot, market_history) could still be confused by an agent without careful reading, even though the descriptions explicitly differentiate them.

    Naming Consistency4/5

    All names use a consistent dv_ snake_case prefix and are readable. The main deviation is that many names are noun phrases (dv_status, dv_boundaries, dv_market_snapshot) rather than strict verb_noun patterns, but they remain predictable.

    Tool Count2/5

    31 tools is well above the typical 3-15 range and exceeds the 25+ threshold for 'too many'. While the domain is broad, the large surface increases selection burden and likely includes marginal additions.

    Completeness4/5

    The surface covers search, listing retrieval, market analytics, geospatial lookup, seller/dealer summaries, watch lifecycle, and export, which is broad and mostly complete. Minor gaps exist, such as no full pagination for dealer/seller listings and no contact or direct user-interaction tools, but these are likely domain-limited.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      B
      maintenance
      Enables AI agents to search and read Divar classified ads across Iranian cities, covering homes, cars, phones and more, with price statistics, deal finding, fair-price appraisal, ad comparison and map browsing. It is read-only, needs no account or API key, and returns compact JSON with prices in Toman.
      8
      31
      347 PyPI
      1
      MIT
    • A
      license
      B
      quality
      B
      maintenance
      Enables AI agents to compare prices across Iranian online and in-person shops, inspect each seller's offer with warranty and installment details, review roughly a year of price history, score deals, and find the cheapest shop for a whole basket. It is read-only, requires no account or API key, and runs locally for Claude, Cursor or Copilot.
      26
      209 PyPI
      1
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables AI agents to read public Iranian car-marketplace data, including filtered used-car ads, full ad details, new-car prices and history, spec comparisons, and magazine articles, without an API key.
      15
      2
      MIT