Skip to main content
Glama

doctoreto-mcp: Doctoreto MCP server for AI agents

Let your AI agent find the right Iranian doctor on Doctoreto (دکترتو). An unofficial, read-only MCP server for Doctoreto, the Iranian doctor appointment and online consultation site: search doctors by speciality, city and visit type, compare visit fees, see free appointment times, read reviews, and find hospitals, labs and clinic offers, from Claude, Cursor or Copilot.

PyPI Python CI MCP Registry License: MIT

Install in Cursor Install in VS Code

For AI agents · Quick start · What it can do · Tools · FAQ · فارسی


For AI agents

  • What: unofficial MCP server (model context protocol) for Doctoreto (دکترتو, doctoreto.com), the Iranian doctor appointment and online consultation site. Queries work in Persian or English; prices are in Toman.

  • Install: uvx doctoreto-mcp or claude mcp add doctoreto -- uvx doctoreto-mcp. Transport: stdio. Needs uv (Python 3.10+).

  • Auth: none, no API key or account. Optional DOCTORETO_MCP_PROXY (HTTP proxy URL, or a comma-separated list tried one at a time); system proxy settings are ignored.

  • Access: read-only. It cannot log in, book, pay or post a review, so no confirmation is needed before calling any tool. Give the user the doctor's page link to book.

  • Tools: 14, all prefixed dt_. Start with dt_suggest (free phrase to doctors and slugs), dt_search_doctors, dt_doctor, dt_free_slots; dt_search_centers and dt_search_offers for hospitals, labs and clinic offers.

  • Typical sequence: dt_search_doctors -> dt_doctor -> dt_free_slots -> dt_reviews.

  • Use when: the user wants to find a doctor in Iran, compare visit fees (office, phone, text, video), see free appointment times, or look up centers, labs and fixed-price clinic offers.

  • Do not use when: the user wants to actually book or pay, or needs medical advice.

  • Output: compact JSON. Prices in Toman, dates Gregorian (YYYY-MM-DD, Jalali given next to them), times Tehran local. Doctors, centers and offers use a 6-character id (or the page URL); a name slug alone cannot be resolved. Use dt_doctor for online prices.

  • Privacy: no phone numbers and no reviewer names are returned.

  • Machine-readable: server.json and the iran-mcp catalog (TOOLS.md, servers.json, llms.txt).

Related MCP server: snapp-mcp

Why

On Doctoreto (doctoreto.com) a doctor card shows a name and a rating, but the things you decide on are a few clicks deeper: which offices the doctor has, what the visit costs at the office (often hidden on the page), what a phone or video consultation costs, and when the next free time actually is. An agent with doctoreto-mcp reads the search, the doctor's services and the slot picker, and hands you the booking link:

You: A cardiologist in Pasdaran, Tehran, as soon as possible. What does the visit cost?

Agent: calls dt_search_doctors(city="tehran", speciality="cardiologist", neighborhood="pasdaran", has_free_slot=True) → dt_doctor(doctor="xqbEWZ") → dt_free_slots(consultation_id=1943, days=7)

Service

Fee

Paid when booking

Next free

Office visit, Pasdaran

250,000

0

Tue 6 Oct, 10:00 (25 free times that day)

Phone call, 15 minutes

750,000

750,000

Tue 6 Oct, 10:00

دکتر کامبیز پرآذران, subspecialist in cardiology: 408 reviews, 92% recommend, about 36 minutes wait at the office. The office fee is paid at the office. Book here: https://doctoreto.com/doctor/dr-kambiz-parazaran/xqbEWZ

Real tool output from 2026-10-06; prices and free times change all the time. Prices are in Toman.

Every reply is compact JSON with empty values left out, so it does not flood the agent's context.

What it can do

  • Find doctors by speciality, city, neighborhood, name, gender, insurance and visit type (office, phone, text, video, instant)

  • Soonest first: sort by the earliest free slot, by popularity or by number of bookings; search near a point

  • Real prices: office visit fee (also when the site hides it), online consultation prices, deposits

  • Free times: free appointment times per day for any office or online service, up to a month ahead

  • Reviews: stars, recommend rate, waiting time, per-category averages; reviewer names are never returned

  • Centers: hospitals, clinics, laboratories, imaging, pharmacies (24h, state/private, map search), hours and insurances

  • Clinic offers: fixed-price procedures (ultrasound, echo, laser, check-ups) with deposits and free times

  • Health magazine: background articles on conditions and tests

  • Read-only by design: no login, no booking, no payment; the agent gives you the link to book

Example prompts:

  • "A female dermatologist in Shiraz with a free slot this week, and her visit fee?"

  • "Which pediatricians offer a video call today, and how much is it?"

  • "A 24-hour pharmacy near Vanak Square."

  • "How much is an echocardiography at a Doctoreto clinic in Tehran, and when is the next free time?"

  • "Compare the phone consultation prices of cardiologists in Isfahan who accept Tamin Ejtemaei insurance."

  • یک متخصص گوش و حلق و بینی در محدوده سعادت‌آباد با بیمه تامین اجتماعی

  • نزدیک‌ترین نوبت خالی متخصص زنان در شیراز و هزینه ویزیت او چقدر است؟

  • آزمایشگاه‌های شبانه‌روزی در تهران را پیدا کن.

Quick start

You need uv. No API key or account.

claude mcp add doctoreto -- uvx doctoreto-mcp

Settings → Developer → Edit Config, then add:

{
  "mcpServers": {
    "doctoreto": { "command": "uvx", "args": ["doctoreto-mcp"] }
  }
}

Click Install in Cursor above, or add the Claude Desktop block to ~/.cursor/mcp.json (or .cursor/mcp.json in a project).

Click Install in VS Code above, or add to .vscode/mcp.json:

{
  "servers": {
    "doctoreto": { "type": "stdio", "command": "uvx", "args": ["doctoreto-mcp"] }
  }
}
codex mcp add doctoreto -- uvx doctoreto-mcp

Or in ~/.codex/config.toml:

[mcp_servers.doctoreto]
command = "uvx"
args = ["doctoreto-mcp"]

Add to ~/.gemini/settings.json:

{
  "mcpServers": {
    "doctoreto": { "command": "uvx", "args": ["doctoreto-mcp"] }
  }
}

Add the Claude Desktop block to ~/.codeium/windsurf/mcp_config.json.

It's a standard stdio MCP server: run uvx doctoreto-mcp, or pip install doctoreto-mcp and run doctoreto-mcp.

Tools

Doctors, centers and offers are identified by a 6-character id (xqbEWZ, the last part of doctoreto.com/doctor/dr-kambiz-parazaran/xqbEWZ); every tool also accepts the page URL itself.

Tool

What it does

dt_suggest

Free phrase → matching doctors, speciality slugs, service tags and centers

dt_search_doctors

Doctors by city, speciality, neighborhood, name, gender, insurance, visit type, free slot; sorting

dt_specialities

Speciality list with the slugs the search needs

dt_cities

City slug and id; cities that have a speciality, with doctor counts

dt_neighborhoods

Neighborhoods of a city and nearby cities, with doctor counts

dt_insurances

Basic and supplementary insurers with their ids

Tool

What it does

dt_doctor

Profile, every office and online service with fee, deposit, address and next free time, review summary

dt_free_slots

Free appointment times per day for one service (office, phone, video, offer, lab), up to 31 days

dt_reviews

Reviews of a doctor, center or offer: stars, text, labels, waiting time, replies (no names)

Tool

What it does

dt_search_centers

Hospitals, clinics, labs, imaging, pharmacies by city, type, 24h, state/private, or near a point

dt_center

One center: hours, departments, insurances, lab rules, bookable services, doctors

Tool

What it does

dt_search_offers

Fixed-price procedures and packages by text, city, speciality, price range, doctor or place

dt_offer

One offer: price, deposit, provider, terms, variants with their free times

dt_health_articles

Doctoreto health magazine articles on a condition, test or treatment

All 14 tools are annotated readOnlyHint: true and return compact structured JSON, so they don't flood the agent's context.

How it works

  AI agent  (Claude, Cursor, Copilot, ...)
      │
      │  MCP over stdio
      ▼
  doctoreto-mcp  (runs on your machine)
      │
      │  HTTPS (JSON)
      ├──────▶  api.doctoreto.com   (doctors, slots, reviews, centers, offers)
      └──────▶  doctoreto.com/blog   (health magazine)

doctoreto-mcp runs locally and calls the same public endpoints the Doctoreto website uses. There's no hosted server in between, no API key, and nothing about you is sent anywhere else. Requests use a Chrome-like TLS fingerprint and headers, go out at most 2 at a time with a short random pause, and retry twice on timeouts, 5xx and 429. Only GET requests are ever made.

Good to know

  • Prices are in Toman. For an office visit fee is what you pay at the office and pay_online_now what is charged when booking (usually 0). For phone, text and video fee is the online price. A missing fee means the doctor lists none (null and empty values are left out of results; false and 0 are kept).

  • Use dt_doctor for online prices. The search list and the profile show a phone price three times the one on the booking page; dt_doctor reads the booking box, which matches the page.

  • Dates are Gregorian YYYY-MM-DD (1405-07-22 = 2026-10-14); times are Tehran local. Jalali dates are given next to them.

  • Booking happens on the site. It needs an SMS code, so the agent finds the doctor and time and gives you the page link.

  • Insurance: few doctors list insurances, so insurance_ids narrows a search a lot. Centers list theirs in dt_center; the center search ignores insurance filters.

  • Reviews: doctor and center reviews come newest first, offer reviews oldest first; each review date is the Tehran day, as on the page.

  • Search pages hold exactly limit doctors, also when the site mixes sponsored doctors in. dt_search_offers and the non-map dt_search_centers cut the site's page (about 40 / 20 items) to limit and report on_page.

  • Lists: dt_specialities and dt_insurances return up to limit entries (defaults cover the whole list) plus total, and are cached for an hour together with dt_cities. Long review, about, description and terms texts are cut (400 to 800 characters); full_text=true on dt_doctor, dt_reviews, dt_center and dt_offer returns them whole.

  • Photos and offices: search cards and dt_doctor carry the doctor's photo URL (image). In a search card, earliest_free.place_id matches an offices[].id, so you can tell which office has the first free slot.

  • Privacy: no phone numbers and no reviewer names are returned.

  • What it does not do: no login, booking, payment, reviews or chat, and no medical advice. Please keep request rates reasonable.

  • Checked against the website: on 2026-10-06 every tool's output was compared with the live doctoreto.com pages (names, fees, free times per day, review order, search totals and order, centers, offers).

FAQ

This unofficial MCP server wraps the public endpoints the Doctoreto website itself uses, so Claude, Cursor or Copilot can search doctors, compare visit fees and read free times.

Add the server with claude mcp add doctoreto -- uvx doctoreto-mcp (or use the Cursor and VS Code buttons above, or the config for your client in Quick start), then ask in Persian or English, for example "a cardiologist in Pasdaran, Tehran, as soon as possible".

It is unofficial, open source (MIT) and free. It is read-only, needs no account or API key, and runs on your machine without sending data to any other server.

No, and that's deliberate. It has no login and never calls the booking, payment, review or chat endpoints. The agent finds the doctor, the service and a free time; you book on doctoreto.com with your own phone number.

Doctoreto's API needs the 6-character id, not the name slug. Paste the whole page URL (https://doctoreto.com/doctor/<slug>/<id>), or let the agent search by the doctor's Persian name.

No geo block was seen: direct calls and calls through a proxy in Turkey both worked (2026-10-06). Cloud servers were not tested; if Doctoreto blocks one, set DOCTORETO_MCP_PROXY.

The filters may be too narrow (an insurance plus a neighborhood often is). Drop a filter, or check the slugs with dt_suggest, dt_specialities or dt_neighborhoods. An unknown city or speciality slug returns an error.

The site's search list and doctor profile show a phone consultation price three times the one on the booking page. dt_doctor reads the booking box, so its prices match what you pay.

Use the full path to uvx (where uvx on Windows, which uvx on macOS/Linux) as command.

npx @modelcontextprotocol/inspector uvx doctoreto-mcp

Configuration

Variable

Default

Meaning

DOCTORETO_MCP_PROXY

unset

Optional HTTP proxy URL for every request, e.g. http://user:pass@host:port; system proxy settings are ignored. A comma-separated list is used one at a time: the next proxy takes over when one is blocked or cannot connect

If Doctoreto ever serves a bot-check page, install doctoreto-mcp[browser] and run patchright install chromium; a headless browser then clears it once and the cookies are reused.

فارسی: سرور MCP دکترتو (نوبت&zwnj;دهی پزشک)

doctoreto-mcp یک سرور MCP غیررسمی برای دکترتو (سایت نوبت&zwnj;دهی اینترنتی پزشک و مشاوره آنلاین) است که به دستیار هوش مصنوعی شما (Claude، Cursor، Copilot و ...) اجازه می&zwnj;دهد در میان پزشکان ایران، پزشک مناسب را بر اساس تخصص، شهر، محله، بیمه و نوع ویزیت (حضوری، تلفنی، متنی، تصویری) پیدا کند، هزینه ویزیت و زمان&zwnj;های خالی نوبت را ببیند، نظرات بیماران را بخواند و بیمارستان، آزمایشگاه و خدمات دکترتو کلینیک را هم جست&zwnj;وجو کند.

چه کارهایی می&zwnj;کند

  • جستجوی پزشک بر اساس تخصص، شهر، محله، نام، جنسیت، بیمه و نوع ویزیت، با مرتب&zwnj;سازی بر اساس نزدیک&zwnj;ترین نوبت.

  • هزینه ویزیت حضوری (حتی وقتی سایت آن را نشان نمی&zwnj;دهد) و قیمت مشاوره تلفنی، متنی و تصویری.

  • نوبت خالی هر پزشک یا خدمت، تا یک ماه جلوتر.

  • نظرات بیماران: امتیاز، درصد توصیه، زمان انتظار (بدون نام نظردهنده).

  • مراکز درمانی: بیمارستان، کلینیک، آزمایشگاه، مرکز تصویربرداری و داروخانه (از جمله شبانه&zwnj;روزی)، با ساعت کاری و بیمه&zwnj;های پذیرفته&zwnj;شده.

  • خدمات دکترتو کلینیک با قیمت ثابت (سونوگرافی، اکو، لیزر، چک&zwnj;آپ) و مجله سلامت.

نکته&zwnj;ها

  • فقط خواندنی است: وارد حساب نمی&zwnj;شود، نوبت رزرو نمی&zwnj;کند و پرداخت نمی&zwnj;کند؛ لینک صفحه پزشک را برای رزرو می&zwnj;دهد. توصیه پزشکی نیست.

  • همه قیمت&zwnj;ها به تومان است. تاریخ&zwnj;ها میلادی هستند و کنارشان تاریخ شمسی هم آمده؛ ساعت&zwnj;ها به وقت تهران است.

  • شماره تلفن و نام نظردهندگان را برنمی&zwnj;گرداند.

  • کلید API لازم نیست و روی سیستم خود شما اجرا می&zwnj;شود و به هیچ سرور واسطی داده نمی&zwnj;فرستد.

نصب (اول uv را نصب کنید). در Claude Code:

claude mcp add doctoreto -- uvx doctoreto-mcp

در Claude Desktop، Cursor و بقیه برنامه&zwnj;ها همان تنظیم بخش Quick start را بگذارید.

نمونه پرسش&zwnj;ها

  • «یک متخصص قلب در پاسداران تهران با نزدیک&zwnj;ترین نوبت خالی، با هزینه ویزیت»

  • «متخصص گوش و حلق و بینی در سعادت&zwnj;آباد با بیمه تامین اجتماعی»

  • «ویزیت تصویری کدام متخصص کودکان امروز نوبت دارد و قیمتش چقدر است؟»

Development

git clone https://github.com/sepehr071/doctoreto-mcp && cd doctoreto-mcp
uv sync
uv run ruff check . && uv run ruff format --check .
uv run python -m pytest -q          # offline, against recorded responses
uv run python -m pytest -m live -q  # real APIs
uv build

Tools live in src/doctoreto_mcp/search.py, doctor.py, centers.py, offers.py and info.py; each is a typed async function with a docstring that tells the agent when to use it. Issues and PRs are welcome, especially new tools and fixes for API changes.

Releases: bump the version in pyproject.toml and server.json, then push a v* tag. GitHub Actions tests, publishes to PyPI and the MCP Registry, and creates the GitHub Release.

Disclaimer

Unofficial and not affiliated with or endorsed by Doctoreto. It is read-only and uses the public endpoints of the doctoreto.com website, which can change without notice. It gives information, not medical advice. Please keep request rates reasonable.

If this saves you clicks, a star helps others find it.

Author

Built and maintained by Sepehr Radmard (سپهر رادمرد). Connect on LinkedIn or follow @sepehr071 on GitHub for more MCP servers for Iranian websites, all listed in iran-mcp. If this saves you time, a star on the repo helps other people find it.

License

MIT

Available Tools

14 tools
dt_centerCenter detailsA
Read-onlyIdempotent

A center's page: address, coordinates, departments, services, accepted insurances, attributes, opening hours, lab admission rules, bookable services with consultation_id (for dt_free_slots) and its doctors (hash ids for dt_doctor, with each doctor's earliest free slot).

Doctor private offices (type office) have no center page: use dt_doctor. Next: dt_free_slots, dt_doctor, dt_reviews(of='center').

NameRequiredDescriptionDefault
centerYesCenter hash id ('YNrrOb') or page URL ('https://doctoreto.com/center/raz-shiraz-lap/YNrrOb').
doctorsNoHow many of its doctors to list (0 = none).
full_textNoReturn complete texts instead of cutting long ones.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly/idempotent/openWorld/destructive=false, so the safety profile is covered. The description adds substantive behavioral context beyond that: the returned content structure, the consultation_id needed for dt_free_slots, doctor hash ids for dt_doctor, and each doctor's earliest free slot. It does not cover pagination or rate limits, but for a read-only detail endpoint that is minor.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The response content is front-loaded, followed by the exclusion and routing lines, with no filler. It is dense and slightly run-on in the field list, but every clause carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly takes on the burden of describing return content and chaining keys (consultation_id, doctor hash ids), and annotations cover safety. Params are schema-documented. It stops short of explaining vaguer fields like 'attributes' or 'lab admission rules', leaving a small residual gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all three parameters (center, doctors, full_text) are fully documented in the schema with formats and bounds. The description mentions consultation_id and doctor ids, but those are output fields, not parameter guidance, so it adds little beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource precisely and enumerates what a center page returns (address, coordinates, departments, services, insurances, opening hours, bookable services, doctors). It also differentiates from the dt_doctor sibling by noting that private offices have no center page. The retrieval verb is only implied by 'A center's page:' rather than stated, which keeps it just under a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit exclusion ('Doctor private offices (type office) have no center page: use dt_doctor') and a routing line ('Next: dt_free_slots, dt_doctor, dt_reviews(of=center)'), so the agent knows the alternatives and follow-ups. It does not explicitly position dt_center against dt_search_centers, so the when-to-use is strong but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_citiesCitiesA
Read-onlyIdempotent

Find a city's slug (for search filters) and numeric id (for dt_suggest); main cities first.

With speciality: only main cities that have such doctors, with counts (a search may find more elsewhere). Next: dt_search_doctors(city=slug) or dt_neighborhoods.

NameRequiredDescriptionDefault
limitNoMax cities.
queryNoPart of the city name in Persian or the slug, e.g. 'شیراز'.
specialityNoOnly cities that have doctors of this speciality, with counts, e.g. 'cardiologist'.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds behavior beyond that: result ordering (main cities first) and the caveat that the speciality-filtered list is limited to main cities with counts and may understate what a full search returns. It doesn't discuss pagination explicit behavior, but the value-add is real.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short lines: purpose and ordering first, conditional speciality behavior second, next-step routing third. No filler sentences; every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description must convey what comes back — and it does: slug, numeric id, ordering, and count-augmented results under speciality. Combined with the fully-described parameters, an agent has everything needed to call and consume this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description goes further by explaining the purpose of the returned slug and id and by clarifying that speciality restricts to main cities and adds counts — semantics not present in the schema's one-line parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: it finds a city's slug (for search filters) and numeric id (for dt_suggest), and explicitly notes main cities come first. It names the two downstream tools the outputs feed, so an agent can distinguish it from dt_suggest and dt_search_doctors without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing: 'Next: dt_search_doctors(city=slug) or dt_neighborhoods', plus a documented conditional branch explaining what the speciality filter changes and warning that a broader search may find more elsewhere. When-to-use and what-to-do-next are both spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_doctorDoctor profileA
Read-onlyIdempotent

A doctor's profile with every bookable service, its price in Toman and its next free time.

services[] lists each office and online visit with consultation_id (input of dt_free_slots), fee (office visit: paid at the office; online: the online price), pay_online_now (charged when booking), the office address and coordinates, and next_free. Also about text, review summary (count, recommend percent, 1-5 category averages), office waiting time, treated conditions and photo. Long texts are cut (about 800 chars); full_text returns them whole. Next: dt_free_slots, dt_reviews.

NameRequiredDescriptionDefault
doctorYesDoctor hash id ('xqbEWZ') or page URL ('https://doctoreto.com/doctor/dr-kambiz-parazaran/xqbEWZ').
full_textNoReturn complete texts instead of cutting long ones.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), but the description adds real behavioral context: long texts are truncated around 800 chars unless full_text is set, and it disambiguates fee semantics (office visit paid at the office vs. online price, and pay_online_now charged at booking). It does not mention auth requirements, rate limits, or behavior on an invalid/unknown doctor id.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The opening sentence is front-loaded with the essential purpose, and the follow-up sentence enumerates the payload fields efficiently. It is dense—almost a schema dump in prose—but nearly every clause carries information an agent needs, with only minor redundancy in listing photo/about text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description carries the full burden of describing the return shape, and it does so thoroughly (services[], fee, pay_online_now, address, next_free, review summary, waiting time, conditions, photo). Combined with the full_text toggle and the onward-tool routing, an agent has everything needed to call it and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 still adds value beyond the schema by giving the concrete truncation threshold (~800 chars) that the schema only gestures at with 'cutting long ones'. The 'doctor' parameter accepts a hash id or full page URL per the schema, and the description does not restate or contradict that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states exactly what the resource is and what it contains: a doctor's profile with every bookable service, its price in Toman, and its next free time. It also differentiates from siblings by explaining that consultation_id from services[] is the input of dt_free_slots, so an agent knows this is the detail/hub tool rather than a search tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly routes the agent onward ('Next: dt_free_slots, dt_reviews') and explains the data handoff (consultation_id feeds dt_free_slots), which is genuine when-to-use guidance. It stops short of stating when NOT to use it (e.g., vs. dt_search_doctors for discovery), so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_free_slotsFree appointment slotsA
Read-onlyIdempotent

Free appointment times of one service (office visit, phone/video call, clinic offer, lab admission).

Returns only days with free times: date, weekday, Jalali date and free start times (HH:MM, Tehran local). Past times today are dropped. bookable_until is the last day opened (often ~30 days ahead). Text consultations usually have no slots.

NameRequiredDescriptionDefault
daysNoNumber of days to check from start_date.
start_dateNoFirst day, Gregorian YYYY-MM-DD; default today (Tehran), e.g. '2026-10-14'.
consultation_idYesConsultation id from dt_doctor services[], dt_center bookable[] or dt_offer variants[], e.g. 1943.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive/openWorld, so the safety profile is covered. The description adds genuinely useful behavior beyond that: only days with free times are returned, past times today are dropped, `bookable_until` is the last opened day (~30 days), times are Tehran local, and text consultations typically yield nothing. It stops short of auth or error behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first sentence, then return fields and caveats follow in an efficient block with no filler. Slightly dense parenthetical enumeration and a dangling sentence on text consultations keep it from being maximally tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and does it well (date, weekday, Jalali date, free start times, bookable_until). It omits invalid-consultation_id or empty-result behavior, but for a read-only listing tool the essential context is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 reinforces the Tehran-local time convention and the free-slot window but adds little syntax or defaulting detail beyond the schema's own descriptions of days, start_date, and consultation_id.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence names a specific resource and verb-mapping ('Free appointment times of one service') and enumerates the service variants it covers, which no sibling tool does. An agent can distinguish it from dt_doctor (service listing) or dt_center without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the description notes text consultations usually have no slots and the schema says the consultation_id comes from dt_doctor/dt_center/dt_offer, but that wiring lives in the schema, not the description. There is no explicit when-to-use/when-not statement or named alternative for slot discovery.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_health_articlesHealth articlesA
Read-onlyIdempotent

Search Doctoreto's health magazine (about 5,000 articles) for background on a condition, test or treatment.

Returns title, link, publish date and a summary; set text_chars to read the articles. General information only, not medical advice: for a diagnosis book a doctor (dt_search_doctors).

NameRequiredDescriptionDefault
limitNoMax articles.
queryYesDisease, test, drug or treatment in Persian, e.g. 'فشار خون' or 'آزمایش تیروئید'.
text_charsNoCharacters of article text to include per article; 0 = summary only.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the description only needs to add context. It does: it discloses the returned fields (title, link, publish date, summary) and the cost/behavior switch that text_chars controls. No auth, rate-limit, or ordering details are given, which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences plus a routing caveat; the purpose and corpus size are front-loaded, and every clause (returned fields, text_chars behavior, the not-medical-advice boundary) earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly compensates by listing the return fields and explaining the summary-vs-full-text behavior. Combined with a 100%-covered input schema and rich annotations, an agent has everything needed to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds practical meaning beyond the schema by explaining that setting text_chars is how you actually 'read the articles' rather than just naming it. limit and query are left entirely to the schema, which documents them well.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Search Doctoreto's health magazine') with scale context (~5,000 articles) and the intended subject matter (condition, test, treatment). It is clearly distinguishable from sibling tools like dt_search_doctors and dt_reviews.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use ('for background on a condition, test or treatment') and when-not ('General information only, not medical advice: for a diagnosis book a doctor'), naming the alternative tool dt_search_doctors. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_insurancesInsurancesA
Read-onlyIdempotent

List basic and supplementary insurers with the ids dt_search_doctors(insurance_ids=...) takes.

total counts all matches. Few doctors list insurances, so the filter narrows a search a lot; centers list theirs in dt_center.

NameRequiredDescriptionDefault
limitNoMax insurers (about 84 exist).
queryNoPart of the insurer's name in Persian, e.g. 'تامین' or 'آتیه'.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, openWorld, non-destructive), yet the description adds real behavior: `total` counts all matches (relevant since there is no output schema) and the domain fact that few doctors list insurances, so filtering narrows results sharply. That is useful context beyond the structured fields, though pagination/limit interaction is not discussed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the verb+resource and the downstream link, then two short supporting sentences with no filler. Slightly clipped phrasing ('the ids dt_search_doctors(...) takes') costs a little readability but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter, no-output-schema lookup, the description supplies the missing pieces: the `total` return field and the reason the filter matters. It is essentially complete for correct invocation, with only limit/pagination behavior left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with limit (max 200, ~84 exist) and query (Persian name fragment, examples) already fully documented. The description adds nothing about the parameters themselves, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (basic and supplementary insurers) and immediately ties it to its downstream consumer, dt_search_doctors(insurance_ids=...). It also explicitly differentiates from dt_center for centers, so the agent can place it among siblings without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Makes the use case concrete by naming the parameter the returned ids feed into (insurance_ids on dt_search_doctors) and routes centers to dt_center. It stops short of an explicit when-to-use/when-not statement or a note on when the filter is worth applying versus searching without it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_neighborhoodsNeighborhoodsA
Read-onlyIdempotent

Neighborhoods of a city (most doctors first) and nearby cities, each with a doctor count.

District groupings (منطقه 3, غرب) are filters too. Next: dt_search_doctors(city=..., neighborhood=slug).

NameRequiredDescriptionDefault
cityYesCity slug from dt_cities, e.g. 'tehran'.
limitNoMax neighborhoods.
queryNoPart of the neighborhood name in Persian or slug, e.g. 'پاسداران'.
specialityNoCount only doctors of this speciality, e.g. 'cardiologist'.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive, open-world. The description adds behavior they cannot express: results are ordered by doctor count, each entry carries a count, and nearby cities are included alongside the city's own neighborhoods.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences plus a fragment; the ordering/scoping fact is front-loaded and the chained call is last where it belongs. Minimal waste, though the district-grouping sentence is slightly terse and ambiguous about which parameter accepts it.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no annotation gaps to fill, the description covers what an agent needs: what comes back (neighborhoods with counts, nearby cities), how it is ordered, and the follow-up call. Remaining gaps are minor, e.g. how nearby cities are represented in the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so city, limit, query and speciality are fully documented in the schema; baseline is 3. The only description-level addition is that district groupings (منطقه 3, غرب) also function as filter values, which is peripheral to this tool's own parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the resource clearly: neighborhoods of a city plus nearby cities, each with a doctor count, ordered most-doctors-first. It is distinguishable from dt_cities (cities) and dt_search_doctors (doctors), though the distinction is inferred from the resource rather than stated against siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete next-step workflow: dt_search_doctors(city=..., neighborhood=slug), which tells the agent this tool is the lookup stage before a doctor search, and notes district groupings are usable as filters. No explicit when-not-to-use guidance or named alternative for the same job.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_offerClinic offer detailsA
Read-onlyIdempotent

One clinic offer in full: price, discount, deposit, who performs it and where, description, terms, capacity, expiry, rating, and bookable variants with consultation_id for dt_free_slots.

NameRequiredDescriptionDefault
offerYesOffer hash id ('ArraJa'), numeric id ('129311') or page URL.
full_textNoReturn complete texts instead of cutting long ones.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, covering the safety profile. The description adds that long texts are cut by default unless full_text is set, which is useful, but says nothing about auth, rate limits, or error cases for a non-existent offer.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero filler; the only cost is that the long comma-separated field list reads as inventory rather than prioritized information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly carries the burden of explaining what comes back, listing the returned fields and variants. It is complete for a read tool, though it omits error behavior for invalid or missing offers.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (offer id formats, full_text truncation) are already fully documented in the schema. The description adds no syntax or format detail beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource ('one clinic offer') and scope ('in full'), then enumerates the returned fields, so an agent can distinguish it from dt_search_offers without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the retrieval framing, and the mention of `consultation_id` for dt_free_slots hints at a follow-up workflow. However, it never states when to call this vs dt_search_offers or dt_center, and gives no exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_reviewsReviewsA
Read-onlyIdempotent

Patient reviews (doctors and centers newest first, offers oldest first): stars 1-5, recommends, text (cut at 400 chars unless full_text), labels, visit type, reason, office waiting time, date (Gregorian + Jalali) and reply.

No sort or filter upstream: to find low ratings, page through (pages = total / limit). The summary (count, recommend percent, category averages) is in dt_doctor.

NameRequiredDescriptionDefault
idYesHash id or page URL of the doctor, center or offer, e.g. 'xqbEWZ'.
ofYesWhose reviews: a doctor, a center or a clinic offer.
pageNo1-based page number.
limitNoReviews per page.
full_textNoReturn complete texts instead of cutting long ones.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnly, idempotent, non-destructive), and the description adds real behavioral context: sort order differs by entity (newest first for doctors/centers, oldest first for offers), text truncation at 400 chars unless full_text, and the absence of upstream sort/filter. It does not mention rate limits or what the response envelope looks like, keeping it at a 4.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the resource and what it returns, then behavior, then the usage tip. The parenthetical list of returned fields is dense but every clause carries information; no filler sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-value burden and does list the returned fields (stars, recommends, text, labels, visit type, reason, waiting time, date in Gregorian and Jalali, reply). It references a 'total' for computing pages without saying where that value comes from, a small gap for a paginated tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% (baseline 3), and the description still adds meaning beyond it — the 400-character truncation threshold tied to full_text and the pagination formula tying limit to total. That is genuine additive detail over the schema's generic 'return complete texts' wording.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (patient reviews) with its scope (doctors, centers, offers) and immediately clarifies per-entity ordering. It also differentiates by routing summary data to the sibling dt_doctor, so an agent can tell it apart from dt_doctor without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit usage technique: 'No sort or filter upstream: to find low ratings, page through (pages = total / limit)', plus a pointer to dt_doctor for the summary. It lacks an explicit when-not/alternative carve-out beyond that one redirection, so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_search_centersSearch centersA
Read-onlyIdempotent

Find hospitals, clinics, infirmaries, laboratories, imaging centers and pharmacies with filters.

Cards carry the hash id for dt_center. With near_lat and near_lon it searches a square around the point sorted by distance; dense areas return only part of the centers and count the rest in more_in_area. Without them limit cuts the upstream page (on_page items). No insurance filter: see dt_center. Next: dt_center, dt_reviews(of='center').

NameRequiredDescriptionDefault
cityNoCity slug from dt_cities, e.g. 'tehran'.
nameNoPart of the center's name in Persian, e.g. 'قلب'.
pageNo1-based page number.
typeNoKind of center, e.g. 'laboratory'.
limitNoCenters per page (the API pages by 20).
near_latNoLatitude of a point in Iran, e.g. 35.7575.
near_lonNoLongitude of a point in Iran, e.g. 51.4100.
open_24hNoOnly centers open around the clock (pharmacies, hospitals).
ownershipNoState (public) or private.
radius_kmNoWith near_lat/near_lon: half-width of the square searched, in km.
specialityNoDepartment / speciality slug from dt_specialities, e.g. 'ophthalmologist'.
service_tagNoService tag slug from dt_suggest, e.g. 'mri'.
neighborhoodNoNeighborhood slug from dt_neighborhoods, with city only, e.g. 'pasdaran'.
online_lab_admissionNoOnly laboratories that take online admission bookings.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description goes further with non-obvious behavior: proximity search returns a square around the point sorted by distance, dense areas return only a partial set with the remainder counted in `more_in_area`, and without coordinates `limit` truncates the upstream page rather than filtering. It also discloses the output card key (`id`). It stops short of anything about rate limits or error behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in one sentence, then behavior in a short second block; nothing is decorative. Some phrasing is telegraphic ('Cards carry the hash `id`') and the near/remote pagination distinction takes a second read, but the density is justified for a 14-parameter search tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 14 optional parameters and no output schema, the description does the heavy lifting: it explains what gets returned (cards keyed by `id`), how paging behaves in both search modes, and the truncation signal `more_in_area`. Missing only a sketch of the overall response envelope, but the agent has enough to call and interpret results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds cross-parameter semantics the schema cannot express: radius_km is only meaningful together with near_lat/near_lon, it defines a square half-width rather than a circle, and limit interacts with the API's 20-item page size differently depending on whether coordinates were supplied. That materially reduces misuse of these 14 parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a concrete verb and an explicit enumeration of the resource it covers (hospitals, clinics, infirmaries, laboratories, imaging centers, pharmacies), which cleanly scopes it away from dt_search_doctors and dt_search_offers without needing to name them. An agent knows immediately this is the facility-search tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives real routing guidance: 'No insurance filter: see dt_center' names the alternative for a filter this tool lacks, and 'Next: dt_center, dt_reviews(of=center)' tells the agent how to drill down after a hit. It also implicitly distinguishes the near_lat/near_lon path from the plain-listing path, though it never states an explicit exclusion or prerequisite condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_search_doctorsSearch doctorsA
Read-onlyIdempotent

Search doctors by city, speciality, neighborhood, service tag, name, gender, insurance and visit type.

Cards carry the hash id for dt_doctor; online prices are not in cards (use dt_doctor). Next: dt_doctor -> dt_free_slots.

NameRequiredDescriptionDefault
cityNoCity slug from dt_cities, e.g. 'tehran'. Omit for the whole country.
nameNoDoctor's name in Persian (part is enough), e.g. 'پرآذران'.
pageNo1-based page number.
sortNodefault = site ranking (sponsored first); popular = reviews and recommend rate.default
limitNoDoctors per page (about 1 KB each).
genderNoOnly male or only female doctors.
near_latNoLatitude of a point in Iran, e.g. 35.7575.
near_lonNoLongitude of a point in Iran, e.g. 51.4100.
specialityNoSpeciality slug from dt_specialities or dt_suggest, e.g. 'cardiologist'.
visit_typeNoOnly doctors offering this visit; instant = on-call phone/text now.
service_tagNoService or symptom tag slug from dt_suggest, e.g. 'echocardiography'.
neighborhoodNoNeighborhood slug from dt_neighborhoods, with city only, e.g. 'pasdaran'.
has_free_slotNoOnly doctors with a free appointment slot.
insurance_idsNoInsurance ids from dt_insurances (any of them), e.g. [1]. Few doctors list insurances.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the bar is lower; the description still adds genuinely useful payload context that no schema provides — result cards carry the hash `id` for dt_doctor and omit online prices. It does not mention auth needs, pagination limits, or result caps beyond what the schema implies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short front-loaded sentences: the filter summary first, then the payload caveat, then the follow-up workflow. Every sentence carries information and nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 14-parameter read tool with no output schema, the description covers the essentials an agent needs: what filters exist, what a card contains, what it omits, and where to go next. It stops short of describing result shape or pagination behavior in full, but annotations already carry the safety profile.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% across all 14 parameters, so each filter's slug source, defaults, and examples are already documented in the schema. The description's filter list restates those dimensions in aggregate without adding syntax or constraints, which is the expected baseline-3 case.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Search) and resource (doctors) and enumerates the filterable facets, making it easy to distinguish from dt_search_centers. It also names the downstream tools that operate on a result (dt_doctor, dt_free_slots), so the agent knows exactly what this tool returns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent away from this tool for pricing ('online prices are not in cards (use dt_doctor)') and names the follow-up chain 'dt_doctor -> dt_free_slots'. There is no explicit when-not-to-use for search itself (e.g. vs dt_suggest for slug discovery), but the context and alternative are clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_search_offersSearch clinic offersA
Read-onlyIdempotent

Search clinic offers: fixed-price procedures and packages (ultrasound, laser, dental, check-ups).

Cards give price and discounted price (Toman), pay_online (the deposit when payment is deposit_online, the rest at the place) and the default consultation_id for dt_free_slots. No sort. limit cuts the upstream page (on_page items): raise it to see the rest, page jumps a whole page. Next: dt_offer, dt_free_slots, dt_reviews(of='offer').

NameRequiredDescriptionDefault
cityNoCity slug from dt_cities, e.g. 'tehran'.
pageNo1-based page number.
limitNoOffers to return from the page (the API pages by about 40).
queryNoService in Persian, e.g. 'سونوگرافی' or 'لیزر'.
centerNoOnly offers at this place (hash id), e.g. 'ZWpOLy'.
doctorNoOnly offers of this doctor (hash id or page URL).
max_priceNoMaximum price in Toman, e.g. 2000000.
min_priceNoMinimum price in Toman, e.g. 1000000.
specialityNoSpeciality slug, e.g. 'cardiologist'.
service_tagNoService tag slug, e.g. 'rhinoplasty'.
neighborhoodNoNeighborhood slug, e.g. 'pasdaran'.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive/openWorld, so safety is covered. The description adds genuinely non-obvious behavior: pagination cuts an upstream page of ~40 items so `limit` should be raised to see the rest while `page` jumps a whole page, and it discloses the card payload (price, discounted price in Toman, pay_online as deposit vs pay-at-place, a default consultation_id).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose, then behavior, then next steps in four short lines with no wasted sentence. The telegraphic style ('No sort.', 'the rest at the place') is efficient but slightly terse, costing a point for minor ambiguity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 11 optional params, no output schema, and 100% schema coverage, the description supplies what structured fields cannot: pagination mechanics and the shape/meaning of returned cards. It omits any mention of the filter family (city, query, center, doctor, price bounds), which is acceptable since the schema documents each with examples, but a one-line hint would have completed the picture.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 still goes beyond the schema by explaining the interaction between `limit` and the upstream `on_page` size and how `page` complements it, and by defining what the returned price/pay_online fields mean, which the schema does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Search clinic offers') plus the concrete content (fixed-price procedures and packages: ultrasound, laser, dental, check-ups). It distinguishes itself from the detail sibling by naming dt_offer as the next step, so an agent can tell listing from single-offer retrieval without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'Next:' line explicitly routes to dt_offer, dt_free_slots, and dt_reviews(of='offer'), which is strong chaining guidance, and 'No sort' forecloses a plausible wrong assumption. It does not, however, contrast this tool with near-neighbors like dt_search_centers or dt_search_doctors for the case when the user thinks in terms of a place or a person rather than an offer.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_specialitiesSpecialitiesA
Read-onlyIdempotent

List specialities with the slug dt_search_doctors needs; total counts all matches.

level is specialist, subspecialist, fellowship or general; parent is the broader speciality (interventional cardiology -> cardiologist). Prefer query. Next: dt_search_doctors(speciality=slug).

NameRequiredDescriptionDefault
limitNoMax entries (about 100 exist).
queryNoPart of the name or slug, e.g. 'قلب' or 'cardio'. Omit for all.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds genuinely new domain behavior: that `total` counts all matches regardless of limit, the four-value level taxonomy, and the parent/child relationship (interventional cardiology -> cardiologist). It does not discuss pagination or result ordering, but the additions are substantive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight fragments with zero filler; the downstream purpose is front-loaded in the first clause. The level/parent semantics are packed into a single line and the next-step call is stated last, which is the right order for an agent that will act on it.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, two-parameter list tool with no output schema, it covers purpose, semantics of the values returned, and the downstream call. It stops short of describing the per-item record shape (slug/name/level/parent fields), which the absence of an output schema leaves slightly underspecified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (query, limit) are already fully documented with examples and defaults, giving a baseline of 3. The description's 'Prefer `query`' is a mild usage nudge but adds no syntax, matching strategy, or format detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (list specialities) and immediately frames its purpose in terms of a downstream need: producing the slug that dt_search_doctors consumes. An agent can distinguish it from siblings like dt_suggest or dt_cities without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit workflow routing — 'Prefer `query`' and 'Next: dt_search_doctors(speciality=slug)' — which tells the agent both how to call it and what to do with the result. It stops short of stating exclusions or naming alternative tools for the same need, so it is clear context rather than a full when/when-not rule set.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dt_suggestSuggest doctors, specialities and centersA
Read-onlyIdempotent

Search-box suggestions: doctors (hash id), speciality slugs, service tags and centers for a free phrase.

E.g. 'قلب' -> speciality 'cardiologist'. Doctors match by name, so for a speciality use the slug. Next: dt_search_doctors, dt_doctor or dt_center.

NameRequiredDescriptionDefault
limitNoMax items of each kind.
queryYesWhat the user typed, in Persian: a doctor's name, a speciality or a symptom, e.g. 'قلب' or 'پرآذران'.
city_idNoNumeric city id from dt_cities to rank one city first, e.g. 2200 (Tehran).

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnly, idempotent, non-destructive, openWorld). The description adds genuinely useful behavioral detail beyond them: what each suggestion kind looks like (hash id vs slug vs tag), and the semantic caveat that doctors match by name only. It stops short of covering empty-result or ordering behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Extremely tight: a one-line purpose, a clarifying example, and a routing line. The most important information (what it returns) is front-loaded with zero filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does the work of describing result kinds and their identifier formats, which is the critical missing piece for an agent. It could go slightly further on result structure or ordering, but an agent has enough to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so query, limit and city_id are fully documented in structured fields. The description only adds a slight nuance about slug-vs-name matching for the query term, which is close to what the schema example already conveys. Baseline 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific function (search-box suggestions), enumerates the four result kinds (doctors by hash id, speciality slugs, service tags, centers), and scopes it to a free-text phrase. It is clearly a lightweight autocomplete-style tool, distinct from dt_search_doctors and dt_center, which it names.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete routing rule and the exact follow-up tools ('Next: dt_search_doctors, dt_doctor or dt_center'), plus a usage hint that speciality lookups should use the returned slug rather than the doctor name. It lacks an explicit when-not-to-use clause (e.g. for full result sets) but the context is clear.

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.

  1. 14 tool updatesv0.3.0
    • Changeddt_center6 fields changed
      • changedInput schema / properties / center / description
        Previous value: -"Center hash id from a search ('YNrrOb') or its page URL ('https://doctoreto.com/center/raz-shiraz-lap/YNrrOb')."New value: +"Center hash id ('YNrrOb') or page URL ('https://doctoreto.com/center/raz-shiraz-lap/YNrrOb')."
      • removedInput schema / properties / center / title
        Removed value: -"Center"
      • removedInput schema / properties / doctors / title
        Removed value: -"Doctors"
      • addedInput schema / properties / full_text
        Added value: +{
        +  "default": false,
        +  "description": "Return complete texts instead of cutting long ones.",
        +  "type": "boolean"
        +}
      • removedInput schema / title
        Removed value: -"dt_centerArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_centerDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_cities5 fields changed
      • removedInput schema / properties / limit / title
        Removed value: -"Limit"
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / properties / speciality / title
        Removed value: -"Speciality"
      • removedInput schema / title
        Removed value: -"dt_citiesArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_citiesDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_doctor5 fields changed
      • changedInput schema / properties / doctor / description
        Previous value: -"Doctor hash id from a search ('xqbEWZ') or the doctor's page URL ('https://doctoreto.com/doctor/dr-kambiz-parazaran/xqbEWZ'). The slug alone cannot be resolved."New value: +"Doctor hash id ('xqbEWZ') or page URL ('https://doctoreto.com/doctor/dr-kambiz-parazaran/xqbEWZ')."
      • removedInput schema / properties / doctor / title
        Removed value: -"Doctor"
      • addedInput schema / properties / full_text
        Added value: +{
        +  "default": false,
        +  "description": "Return complete texts instead of cutting long ones.",
        +  "type": "boolean"
        +}
      • removedInput schema / title
        Removed value: -"dt_doctorArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_doctorDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_free_slots6 fields changed
      • changedInput schema / properties / consultation_id / description
        Previous value: -"Consultation id of one service, from dt_doctor services[], dt_center services[] or dt_offer variants[], e.g. 1943."New value: +"Consultation id from dt_doctor services[], dt_center bookable[] or dt_offer variants[], e.g. 1943."
      • removedInput schema / properties / consultation_id / title
        Removed value: -"Consultation Id"
      • removedInput schema / properties / days / title
        Removed value: -"Days"
      • removedInput schema / properties / start_date / title
        Removed value: -"Start Date"
      • removedInput schema / title
        Removed value: -"dt_free_slotsArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_free_slotsDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_health_articles5 fields changed
      • removedInput schema / properties / limit / title
        Removed value: -"Limit"
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / properties / text_chars / title
        Removed value: -"Text Chars"
      • removedInput schema / title
        Removed value: -"dt_health_articlesArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_health_articlesDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_insurances4 fields changed
      • addedInput schema / properties / limit
        Added value: +{
        +  "default": 100,
        +  "description": "Max insurers (about 84 exist).",
        +  "maximum": 200,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"dt_insurancesArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_insurancesDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_neighborhoods6 fields changed
      • removedInput schema / properties / city / title
        Removed value: -"City"
      • removedInput schema / properties / limit / title
        Removed value: -"Limit"
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / properties / speciality / title
        Removed value: -"Speciality"
      • removedInput schema / title
        Removed value: -"dt_neighborhoodsArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_neighborhoodsDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_offer5 fields changed
      • addedInput schema / properties / full_text
        Added value: +{
        +  "default": false,
        +  "description": "Return complete texts instead of cutting long ones.",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / offer / description
        Previous value: -"Offer hash id ('ArraJa'), numeric id ('129311') or page URL ('https://doctoreto.com/offer/ArraJa')."New value: +"Offer hash id ('ArraJa'), numeric id ('129311') or page URL."
      • removedInput schema / properties / offer / title
        Removed value: -"Offer"
      • removedInput schema / title
        Removed value: -"dt_offerArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_offerDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_reviews8 fields changed
      • addedInput schema / properties / full_text
        Added value: +{
        +  "default": false,
        +  "description": "Return complete texts instead of cutting long ones.",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / id / description
        Previous value: -"Hash id or page URL of the doctor, center or offer, e.g. 'xqbEWZ' or 'https://doctoreto.com/center/raz-shiraz-lap/YNrrOb'."New value: +"Hash id or page URL of the doctor, center or offer, e.g. 'xqbEWZ'."
      • removedInput schema / properties / id / title
        Removed value: -"Id"
      • removedInput schema / properties / limit / title
        Removed value: -"Limit"
      • removedInput schema / properties / of / title
        Removed value: -"Of"
      • removedInput schema / properties / page / title
        Removed value: -"Page"
      • removedInput schema / title
        Removed value: -"dt_reviewsArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_reviewsDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_search_centers16 fields changed
      • removedInput schema / properties / city / title
        Removed value: -"City"
      • removedInput schema / properties / limit / title
        Removed value: -"Limit"
      • removedInput schema / properties / name / title
        Removed value: -"Name"
      • removedInput schema / properties / near_lat / title
        Removed value: -"Near Lat"
      • removedInput schema / properties / near_lon / title
        Removed value: -"Near Lon"
      • removedInput schema / properties / neighborhood / title
        Removed value: -"Neighborhood"
      • removedInput schema / properties / online_lab_admission / title
        Removed value: -"Online Lab Admission"
      • removedInput schema / properties / open_24h / title
        Removed value: -"Open 24H"
      • removedInput schema / properties / ownership / title
        Removed value: -"Ownership"
      • removedInput schema / properties / page / title
        Removed value: -"Page"
      • removedInput schema / properties / radius_km / title
        Removed value: -"Radius Km"
      • removedInput schema / properties / service_tag / title
        Removed value: -"Service Tag"
      • removedInput schema / properties / speciality / title
        Removed value: -"Speciality"
      • removedInput schema / properties / type / title
        Removed value: -"Type"
      • removedInput schema / title
        Removed value: -"dt_search_centersArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_search_centersDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_search_doctors18 fields changed
      • removedInput schema / properties / city / title
        Removed value: -"City"
      • removedInput schema / properties / gender / title
        Removed value: -"Gender"
      • removedInput schema / properties / has_free_slot / title
        Removed value: -"Has Free Slot"
      • removedInput schema / properties / insurance_ids / title
        Removed value: -"Insurance Ids"
      • removedInput schema / properties / limit / title
        Removed value: -"Limit"
      • removedInput schema / properties / name / title
        Removed value: -"Name"
      • removedInput schema / properties / near_lat / title
        Removed value: -"Near Lat"
      • removedInput schema / properties / near_lon / title
        Removed value: -"Near Lon"
      • removedInput schema / properties / neighborhood / title
        Removed value: -"Neighborhood"
      • removedInput schema / properties / page / title
        Removed value: -"Page"
      • removedInput schema / properties / service_tag / title
        Removed value: -"Service Tag"
      • changedInput schema / properties / sort / description
        Previous value: -"default = site ranking (sponsored first), popular = review count and recommend rate, earliest = soonest free slot, most_booked = most bookings."New value: +"default = site ranking (sponsored first); popular = reviews and recommend rate."
      • removedInput schema / properties / sort / title
        Removed value: -"Sort"
      • removedInput schema / properties / speciality / title
        Removed value: -"Speciality"
      • changedInput schema / properties / visit_type / description
        Previous value: -"Only doctors offering this visit: office (in person), phone, text (chat), video, instant (on-call phone/text now), any_online."New value: +"Only doctors offering this visit; instant = on-call phone/text now."
      • removedInput schema / properties / visit_type / title
        Removed value: -"Visit Type"
      • removedInput schema / title
        Removed value: -"dt_search_doctorsArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_search_doctorsDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_search_offers14 fields changed
      • removedInput schema / properties / center / title
        Removed value: -"Center"
      • removedInput schema / properties / city / title
        Removed value: -"City"
      • changedInput schema / properties / doctor / anyOf
        Previous value: -[
        -  {
        -    "description": "Doctor hash id from a search ('xqbEWZ') or the doctor's page URL ('https://doctoreto.com/doctor/dr-kambiz-parazaran/xqbEWZ'). The slug alone cannot be resolved.",
        -    "maxLength": 300,
        -    "minLength": 6,
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "description": "Doctor hash id ('xqbEWZ') or page URL ('https://doctoreto.com/doctor/dr-kambiz-parazaran/xqbEWZ').",
        +    "maxLength": 300,
        +    "minLength": 6,
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / doctor / title
        Removed value: -"Doctor"
      • removedInput schema / properties / limit / title
        Removed value: -"Limit"
      • removedInput schema / properties / max_price / title
        Removed value: -"Max Price"
      • removedInput schema / properties / min_price / title
        Removed value: -"Min Price"
      • removedInput schema / properties / neighborhood / title
        Removed value: -"Neighborhood"
      • removedInput schema / properties / page / title
        Removed value: -"Page"
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / properties / service_tag / title
        Removed value: -"Service Tag"
      • removedInput schema / properties / speciality / title
        Removed value: -"Speciality"
      • removedInput schema / title
        Removed value: -"dt_search_offersArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_search_offersDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_specialities5 fields changed
      • addedInput schema / properties / limit
        Added value: +{
        +  "default": 150,
        +  "description": "Max entries (about 100 exist).",
        +  "maximum": 300,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • changedInput schema / properties / query / description
        Previous value: -"Part of the name in Persian or the slug, e.g. 'قلب' or 'cardio'. Omit for all."New value: +"Part of the name or slug, e.g. 'قلب' or 'cardio'. Omit for all."
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"dt_specialitiesArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_specialitiesDictOutput",
        -  "type": "object"
        -}New value: +null
    • Changeddt_suggest5 fields changed
      • removedInput schema / properties / city_id / title
        Removed value: -"City Id"
      • removedInput schema / properties / limit / title
        Removed value: -"Limit"
      • removedInput schema / properties / query / title
        Removed value: -"Query"
      • removedInput schema / title
        Removed value: -"dt_suggestArguments"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "title": "dt_suggestDictOutput",
        -  "type": "object"
        -}New value: +null
  2. 14 tool updatesv0.1.0
    • First observeddt_center
    • First observeddt_cities
    • First observeddt_doctor
    • First observeddt_free_slots
    • First observeddt_health_articles
    • First observeddt_insurances
    • First observeddt_neighborhoods
    • First observeddt_offer
    • First observeddt_reviews
    • First observeddt_search_centers
    • First observeddt_search_doctors
    • First observeddt_search_offers
    • First observeddt_specialities
    • First observeddt_suggest

TDQS

A4.2/5.0

Scored across 14 tools

Disambiguation5/5

Tools are cleanly partitioned into search (dt_search_doctors/centers/offers), detail lookups (dt_doctor/center/offer), reference data (dt_specialities/cities/neighborhoods/insurances), and single-purpose helpers (dt_suggest, dt_reviews, dt_free_slots, dt_health_articles). Descriptions explicitly state the 'Next:' chaining, so overlapping-sounding pairs like dt_suggest vs dt_search_doctors are clearly distinguished. No two tools appear to do the same thing.

Naming Consistency5/5

Every tool uses the dt_ snake_case prefix with a predictable split: dt_search_* for searches and dt_<noun> for detail/listing endpoints (dt_doctor, dt_center, dt_offer, dt_reviews, dt_free_slots). The convention is applied uniformly across all 14 tools.

Tool Count5/5

14 tools is well-scoped for a doctor/center discovery domain, with each tool earning its place across search, detail, reference, and content functions. Nothing feels redundant or padded.

Completeness4/5

The discovery-to-availability funnel (search -> detail -> free slots -> reviews, plus offers and articles) is fully covered with no dead ends for information gathering. The only notable gap is the absence of an actual booking tool despite consultation_id/free-slot data being surfaced, so agents can inform but not complete a booking.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to search the doktor.mx directory for over 56,000 verified doctors and medical specialists across Mexico. It provides tools for verifying professional licenses, finding specialists by symptoms or conditions, and checking medical insurance compatibility.
    10
    10 npm
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to search Snappfood restaurants and SnappMarket stores across Iran, compare true order costs including packaging and delivery, read menus, minimum orders, ETAs and reviews, and surface live flash deals. All operations are read-only, with no login, basket, ordering or payment access.
    21
    928 PyPI
    35
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to search and compare the cheapest flights, trains, buses, private taxis and hotels across Iran, including free seats, baggage allowances, refund rules and exact prices, for a single date or across weeks. All 22 tools are read-only and return compact structured JSON, so an agent can plan multi-mode trips and hotel stays without logging in or booking.
    22
    22
    570 PyPI
    2
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to search Iranian doctors, hospitals and clinics by specialty, city, name, gender and online visit, then read profiles, ratings, insurances, patient reviews, visit prices in Toman and free appointment times. Read-only, with no login, booking or payment, so users compare options and get a profile link to book themselves.
    12
    595 PyPI
    3
    MIT