doctoreto-mcp
<!-- mcp-name: io.github.sepehr071/doctoreto-mcp -->
<div align="center">
<img src="https://raw.githubusercontent.com/sepehr071/doctoreto-mcp/main/.github/banner.png" alt="doctoreto-mcp: unofficial Doctoreto MCP server for Claude, Cursor and Copilot" width="100%">
# doctoreto-mcp: Doctoreto MCP server for AI agents
**Let your AI agent find the right Iranian doctor on Doctoreto (دکترتو).**<br>
An unofficial, read-only MCP server for [Doctoreto](https://doctoreto.com), the Iranian doctor appointment and online consultation site:<br>
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.
[](https://pypi.org/project/doctoreto-mcp/)
[](https://pypi.org/project/doctoreto-mcp/)
[](https://github.com/sepehr071/doctoreto-mcp/actions/workflows/ci.yml)
[](https://registry.modelcontextprotocol.io/?q=doctoreto-mcp)
[](https://github.com/sepehr071/doctoreto-mcp/blob/main/LICENSE)
[](https://cursor.com/en/install-mcp?name=doctoreto&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyJkb2N0b3JldG8tbWNwIl19)
[](https://vscode.dev/redirect/mcp/install?name=doctoreto&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22doctoreto-mcp%22%5D%7D)
[For AI agents](#for-ai-agents) · [Quick start](#quick-start) · [What it can do](#what-it-can-do) · [Tools](#tools) · [FAQ](#faq) · [فارسی](#فارسی)
</div>
---
## 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](https://docs.astral.sh/uv/getting-started/installation/) (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`](https://github.com/sepehr071/doctoreto-mcp/blob/main/server.json) and the [iran-mcp catalog](https://github.com/sepehr071/iran-mcp) (`TOOLS.md`, `servers.json`, `llms.txt`).
## 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
<sub>Real tool output from 2026-10-06; prices and free times change all the time. Prices are in Toman.</sub>
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."
- <span dir="rtl">یک متخصص گوش و حلق و بینی در محدوده سعادت‌آباد با بیمه تامین اجتماعی</span>
- <span dir="rtl">نزدیک‌ترین نوبت خالی متخصص زنان در شیراز و هزینه ویزیت او چقدر است؟</span>
- <span dir="rtl">آزمایشگاه‌های شبانه‌روزی در تهران را پیدا کن.</span>
## Quick start
You need [uv](https://docs.astral.sh/uv/getting-started/installation/). No API key or account.
<details open>
<summary><b>Claude Code</b></summary>
```bash
claude mcp add doctoreto -- uvx doctoreto-mcp
```
</details>
<details>
<summary><b>Claude Desktop</b></summary>
Settings → Developer → Edit Config, then add:
```json
{
"mcpServers": {
"doctoreto": { "command": "uvx", "args": ["doctoreto-mcp"] }
}
}
```
</details>
<details>
<summary><b>Cursor</b></summary>
Click **Install in Cursor** above, or add the Claude Desktop block to `~/.cursor/mcp.json` (or `.cursor/mcp.json` in a project).
</details>
<details>
<summary><b>VS Code (Copilot agent mode)</b></summary>
Click **Install in VS Code** above, or add to `.vscode/mcp.json`:
```json
{
"servers": {
"doctoreto": { "type": "stdio", "command": "uvx", "args": ["doctoreto-mcp"] }
}
}
```
</details>
<details>
<summary><b>Codex CLI</b></summary>
```bash
codex mcp add doctoreto -- uvx doctoreto-mcp
```
Or in `~/.codex/config.toml`:
```toml
[mcp_servers.doctoreto]
command = "uvx"
args = ["doctoreto-mcp"]
```
</details>
<details>
<summary><b>Gemini CLI</b></summary>
Add to `~/.gemini/settings.json`:
```json
{
"mcpServers": {
"doctoreto": { "command": "uvx", "args": ["doctoreto-mcp"] }
}
}
```
</details>
<details>
<summary><b>Windsurf</b></summary>
Add the Claude Desktop block to `~/.codeium/windsurf/mcp_config.json`.
</details>
<details>
<summary><b>Anything else</b></summary>
It's a standard stdio MCP server: run `uvx doctoreto-mcp`, or `pip install doctoreto-mcp` and run `doctoreto-mcp`.
</details>
## 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.
<details open>
<summary><b>Find a doctor</b> (6)</summary>
| 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 |
</details>
<details open>
<summary><b>One doctor</b> (3)</summary>
| 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) |
</details>
<details open>
<summary><b>Centers</b> (2)</summary>
| 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 |
</details>
<details open>
<summary><b>Clinic offers and reading</b> (3)</summary>
| 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 |
</details>
All 14 tools are annotated `readOnlyHint: true` and return compact structured JSON, so they don't flood the agent's context.
## How it works
```text
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
<details>
<summary><b>Is there a Doctoreto API or MCP server for AI agents?</b></summary>
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.
</details>
<details>
<summary><b>How do I use Doctoreto with Claude, Cursor or Copilot?</b></summary>
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](#quick-start)), then ask in Persian or English, for example "a
cardiologist in Pasdaran, Tehran, as soon as possible".
</details>
<details>
<summary><b>Is it official, safe and free?</b></summary>
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.
</details>
<details>
<summary><b>Can it book an appointment for me?</b></summary>
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.
</details>
<details>
<summary><b>"slug alone cannot be resolved"</b></summary>
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.
</details>
<details>
<summary><b>Do I need an Iranian IP?</b></summary>
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`.
</details>
<details>
<summary><b>A search returns 0 doctors</b></summary>
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.
</details>
<details>
<summary><b>Why does the phone price differ from the website?</b></summary>
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.
</details>
<details>
<summary><b>Claude Desktop says <code>uvx</code> is not found</b></summary>
Use the full path to `uvx` (`where uvx` on Windows, `which uvx` on macOS/Linux) as `command`.
</details>
<details>
<summary><b>How do I debug what the agent sees?</b></summary>
```bash
npx @modelcontextprotocol/inspector uvx doctoreto-mcp
```
</details>
## 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.
<a id="فارسی"></a>
## فارسی: سرور MCP دکترتو (نوبت‌دهی پزشک)
<div dir="rtl">
**doctoreto-mcp** یک سرور MCP غیررسمی برای [دکترتو](https://doctoreto.com) (سایت نوبت‌دهی اینترنتی پزشک و مشاوره آنلاین) است که به دستیار هوش مصنوعی شما (Claude، Cursor، Copilot و ...)
اجازه می‌دهد در میان پزشکان ایران، پزشک مناسب را بر اساس تخصص، شهر، محله، بیمه و نوع ویزیت (حضوری، تلفنی، متنی، تصویری) پیدا کند، هزینه ویزیت و زمان‌های خالی نوبت
را ببیند، نظرات بیماران را بخواند و بیمارستان، آزمایشگاه و خدمات دکترتو کلینیک را هم جست‌وجو کند.
**چه کارهایی می‌کند**
- **جستجوی پزشک** بر اساس تخصص، شهر، محله، نام، جنسیت، بیمه و نوع ویزیت، با مرتب‌سازی بر اساس نزدیک‌ترین نوبت.
- **هزینه ویزیت** حضوری (حتی وقتی سایت آن را نشان نمی‌دهد) و قیمت مشاوره تلفنی، متنی و تصویری.
- **نوبت خالی** هر پزشک یا خدمت، تا یک ماه جلوتر.
- **نظرات بیماران**: امتیاز، درصد توصیه، زمان انتظار (بدون نام نظردهنده).
- **مراکز درمانی**: بیمارستان، کلینیک، آزمایشگاه، مرکز تصویربرداری و داروخانه (از جمله شبانه‌روزی)، با ساعت کاری و بیمه‌های پذیرفته‌شده.
- **خدمات دکترتو کلینیک** با قیمت ثابت (سونوگرافی، اکو، لیزر، چک‌آپ) و **مجله سلامت**.
**نکته‌ها**
- فقط خواندنی است: وارد حساب نمی‌شود، نوبت رزرو نمی‌کند و پرداخت نمی‌کند؛ لینک صفحه پزشک را برای رزرو می‌دهد. توصیه پزشکی نیست.
- همه قیمت‌ها به تومان است. تاریخ‌ها میلادی هستند و کنارشان تاریخ شمسی هم آمده؛ ساعت‌ها به وقت تهران است.
- شماره تلفن و نام نظردهندگان را برنمی‌گرداند.
- کلید API لازم نیست و روی سیستم خود شما اجرا می‌شود و به هیچ سرور واسطی داده نمی‌فرستد.
**نصب** (اول [uv](https://docs.astral.sh/uv/getting-started/installation/) را نصب کنید). در Claude Code:
</div>
```bash
claude mcp add doctoreto -- uvx doctoreto-mcp
```
<div dir="rtl">
در Claude Desktop، Cursor و بقیه برنامه‌ها همان تنظیم بخش [Quick start](#quick-start) را بگذارید.
**نمونه پرسش‌ها**
- «یک متخصص قلب در پاسداران تهران با نزدیک‌ترین نوبت خالی، با هزینه ویزیت»
- «متخصص گوش و حلق و بینی در سعادت‌آباد با بیمه تامین اجتماعی»
- «ویزیت تصویری کدام متخصص کودکان امروز نوبت دارد و قیمتش چقدر است؟»
</div>
## Development
```bash
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](https://registry.modelcontextprotocol.io), and creates the GitHub Release.
## Related servers
- [iran-mcp](https://github.com/sepehr071/iran-mcp): catalog of all Iranian-service MCP servers
- [paziresh24-mcp](https://github.com/sepehr071/paziresh24-mcp) for Iranian doctors, profiles and free appointment slots on Paziresh24
- [jabama-mcp](https://github.com/sepehr071/jabama-mcp) for Iranian stays and villa rentals on Jabama
- [iran-news-mcp](https://github.com/sepehr071/iran-news-mcp) for Iranian news
## 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
<a href="https://www.linkedin.com/in/sepehr-radmard"><img src="https://raw.githubusercontent.com/sepehr071/iran-mcp/main/assets/author-banner.png" alt="Sepehr Radmard: open-source MCP servers for the Iranian web. LinkedIn: linkedin.com/in/sepehr-radmard" width="100%"></a>
Built and maintained by **Sepehr Radmard** (سپهر رادمرد). Connect on [LinkedIn](https://www.linkedin.com/in/sepehr-radmard) or follow [@sepehr071 on GitHub](https://github.com/sepehr071) for more MCP servers for Iranian websites, all listed in [iran-mcp](https://github.com/sepehr071/iran-mcp). If this saves you time, a star on the repo helps other people find it.
## License
[MIT](https://github.com/sepehr071/doctoreto-mcp/blob/main/LICENSE)
TDQS
Scored across 14 tools
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.
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.
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.
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.