Skip to main content
Glama

🩺 exiryab-mcp: ExirYab MCP server for AI agents

Official, read-only MCP server that lets your AI agent find Iranian doctors on ExirYab (اکسیریاب, exiryab.com). Search by name, city and specialty, and get the doctor's profile link, clinics, phones, working hours and map location (Google Maps, Neshan, Balad), all from Claude, Cursor or Copilot.

PyPI Python CI MCP Registry License: MIT

Install in Cursor Install in VS Code

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


For AI agents

  • What: Official MCP server for ExirYab (اکسیریاب, exiryab.com), a directory of Iranian doctors. Queries in Persian work best.

  • Install: claude mcp add exiryab -- uvx exiryab-mcp (stdio, needs uv and Python 3.10+).

  • Auth: none. Optional EXIRYAB_MCP_PROXY sets an HTTP proxy for every request.

  • Access: read-only. There is no booking or login; give the user the doctor's profile url and clinic phones.

  • Tools: 3, all prefixed ey_: ey_search_doctors, ey_cities, ey_specialties.

  • Typical sequence: ey_search_doctors -> (if a name or word is unclear) ey_cities / ey_specialties -> ey_search_doctors again.

  • Use when: the user wants to find a specific doctor or the best doctors of a specialty in an Iranian city, with address, phone, hours and map.

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

  • Output: compact JSON. A best_match plus alternatives, a confidence (high, medium, low, ranking, none) and warnings. Clinic weekly_hours maps an English weekday to shifts ([] = closed).

  • Skill: skills/exiryab/SKILL.md has the usage rules for agents.

  • Machine-readable: server.json, the site's llms.txt, and the catalog of Iranian MCP servers awesome-iran-mcp.

Related MCP server: healthcare

Why

ExirYab (exiryab.com) lists doctors across Iran with their specialties, offices, hospitals and clinics. People usually remember half a name ("Dr. Mohammadi, the cardiologist in Tehran"), and the agent has to turn that into the right person and tell them where to go. exiryab-mcp calls ExirYab's public API, which does the name matching on the server (titles, Arabic letters, spacing, partial names) and returns the best match with alternatives:

You: Find Dr. Malek Mohammadi, a cardiologist in Tehran. Where is the office?

Agent: calls ey_search_doctors(name="ملک محمدی", city="تهران", specialty="قلب")

Dr. Mousa Malek Mohammadi (cardiology, Tehran). Profile: https://exiryab.com/dr/36370-.../ I also found other cardiologists in Tehran if you want alternatives.

What it can do

  • 🔎 Find a doctor by name, full or partial, with optional city and specialty, and tell you how sure the match is

  • 🏆 Top doctors of a specialty in a city or a whole province when no name is given

  • 🏥 Clinics: type (office, hospital, clinic), address, district, phones, working hours per weekday

  • 🗺️ Map location: coordinates plus Google Maps, directions, Neshan and Balad links

  • 🏷️ Resolve words: Persian city and specialty names, with doctor counts

  • 🔒 Read-only by design: no login, no booking, no payment

Quick start

You need uv.

claude mcp add exiryab -- uvx exiryab-mcp

Settings → Developer → Edit Config, then add:

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

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

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

{
  "servers": {
    "exiryab": { "type": "stdio", "command": "uvx", "args": ["exiryab-mcp"] }
  }
}

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

Then just ask:

  • "Find Dr. Mohammadi, the cardiologist in Tehran, and give me the office phone."

  • "The best pediatricians in Fars province, with a map link."

  • "Which heart specialties are there, and how many doctors does each have?"

  • دکتر ملک محمدی متخصص قلب در تهران را پیدا کن و آدرس مطبش را روی نشان بده.

How it works

  AI agent  (Claude, Cursor, Copilot, ...)
      │
      │  MCP over stdio
      ▼
  exiryab-mcp  (runs on your machine)
      │
      │  HTTPS (JSON)
      └──────▶  exiryab.com/api/v1  (doctors/search, cities, specialties)

The API is public and needs no key. It is limited to 60 requests per minute per IP and answers are cached for up to a day.

Tools

Tool

What it does

ey_search_doctors

Best match plus alternatives for a name, city (or province) and specialty, with profile URL, clinics, phones, hours and map links

ey_cities

Cities with doctors, their province and doctor count, most doctors first

ey_specialties

Specialties with doctor count and parent specialty, most doctors first

All 3 tools are annotated readOnlyHint: true and return compact structured JSON.

Good to know

  • Persian input works best. Titles such as «دکتر» are ignored, and «ي»/«ك» and spacing differences are handled on the server.

  • City words in the name are used as filters: name="محمدی قلب تهران" searches for Mohammadi among Tehran cardiologists.

  • A province works as a city: city="فارس" searches the whole province.

  • Filters can be dropped: when a name matches nobody with the given specialty or city, the server drops that filter and says so in understood.dropped_filters and warnings.

  • confidence: high = one clear match; medium = a good match but others are close, so confirm with the user; low = weak matches only; ranking = no name was given; none = nothing found.

  • similar alternatives are padding (same specialty and area), not people with the name you asked for.

  • verified means the medical council card was checked and the mobile confirmed; managed_by_doctor means the doctor confirmed their mobile.

FAQ

Yes. ExirYab publishes a small public JSON API at https://exiryab.com/api/v1 (search, cities, specialties), and this MCP server wraps it for Claude, Cursor and Copilot.

It is official (made by ExirYab), open source (MIT) and free. It is read-only, needs no account or API key, and runs on your machine.

No. It gives the doctor's profile link and clinic phones; booking happens with the doctor or on the profile page.

The API allows 60 requests per minute per IP. Wait a minute and try again.

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

npx @modelcontextprotocol/inspector uvx exiryab-mcp

Configuration

Variable

Default

Meaning

EXIRYAB_MCP_PROXY

unset

HTTP proxy for every request, e.g. http://user:pass@host:port

EXIRYAB_MCP_BASE_URL

https://exiryab.com

API base URL, e.g. a local ExirYab for development

فارسی: سرور MCP اکسیریاب

exiryab-mcp سرور MCP رسمی اکسیریاب است که به دستیار هوش مصنوعی شما (Claude، Cursor، Copilot و ...) اجازه می‌دهد پزشکان ایران را با نام، شهر و تخصص پیدا کند و لینک صفحه پزشک، مطب‌ها، تلفن‌ها، ساعت کاری و موقعیت روی نقشه (گوگل‌مپ، نشان، بلد) را بگیرد.

  • فقط خواندنی است: ورود، نوبت‌دهی و پرداخت ندارد.

  • نام پزشک را کامل یا ناقص بنویسید؛ «دکتر» و تفاوت «ی/ي» و فاصله‌ها در سرور حل می‌شود.

  • به جای شهر می‌توانید نام استان را بدهید.

  • روی سیستم خود شما اجرا می‌شود و فقط به API عمومی exiryab.com وصل می‌شود.

نصب در Claude Code:

claude mcp add exiryab -- uvx exiryab-mcp

بعد بپرسید: «یک متخصص اطفال خوب در شیراز با آدرس و لینک نقشه.»

Development

git clone https://github.com/sshnevis/exiryab-mcp && cd exiryab-mcp
uv sync
uv run pytest            # offline, against recorded responses
uv run pytest -m live    # real API (EXIRYAB_MCP_LIVE_BASE_URL=http://localhost:5082 for a local ExirYab)
uv run ruff check .

Tools live in src/exiryab_mcp/doctors.py and lookup.py; each is a typed async function with a docstring that tells the agent when to use it.

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

The directory is for finding doctors and is not medical advice. Please keep request rates reasonable.

License

MIT

Available Tools

3 tools
ey_citiesList citiesA
Read-onlyIdempotent

Cities that have doctors on exiryab.com, with their province and doctor count, most doctors first.

Use it to find the exact Persian city name for ey_search_doctors(city=...), or to check whether a town is covered. total counts every match, not only the ones returned.

NameRequiredDescriptionDefault
limitNoMax cities to return.
queryNoPart of the Persian name, e.g. 'شیر' or 'قلب'. Omit to list the largest.

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent and openWorld, so safety is covered. The description adds the non-obvious behavioral trait that `total` counts every match rather than only returned rows, which materially affects how an agent interprets results. It does not explain pagination/limit interaction, but the schema handles limit.

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 sentences, each earning its place: inventory, purpose/routing, and result-semantics caveat. Front-loaded with what the tool returns.

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?

Output schema exists and annotations are rich, so the description needn't explain return shape. It covers what the tool is for, how it links to the sibling search tool, and the one result-interpretation gotcha an agent could otherwise get wrong.

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% and both parameters (limit, query with Persian-name example) are fully documented there. The description adds only indirect meaning via the `total` vs returned distinction, 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 (cities with doctors on exiryab.com) plus the returned fields (province, doctor count) and the sort order. This is clearly distinguishable from ey_search_doctors and ey_specialties 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?

Explicitly names the downstream alternative and the condition that selects it: resolve the exact Persian city name for ey_search_doctors(city=...) or check coverage. 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.

ey_search_doctorsFind a doctorA
Read-onlyIdempotent

Find an Iranian doctor on exiryab.com by name, city and/or specialty: the best match plus alternatives, each with profile URL, clinics, phones, working hours and map links.

Give at least one of name, city, specialty (Persian works best). With a name, the server ranks by how well the name matches and drops filters that leave no match (see understood.dropped_filters and warnings). Without a name, it returns the top-ranked doctors for the city and specialty.

confidence: high = one clear match for the name; medium = a good match but others are close, so confirm with the user; low = only weak name matches; ranking = no name was given; none = nothing found. match.kind per doctor: name, partial_name, similar (padding: same specialty and area, not the name asked for) or ranking. Clinic weekly_hours maps an English day to its shifts ('17:00-19:00'); an empty list means closed that day.

NameRequiredDescriptionDefault
cityNoPersian city name ('تهران', 'شیراز') or a province name ('فارس') to search the whole province. Use ey_cities for the exact spelling.
nameNoDoctor's name in Persian, full or partial ('موسی ملک محمدی', 'دکتر محمدی'). Titles like «دکتر» are ignored; city or specialty words inside it ('محمدی قلب تهران') are used as filters.
specialtyNoPersian specialty, exact or a key word: 'قلب' resolves to «قلب و عروق», 'اطفال' to «کودکان (اطفال)». Use ey_specialties to see the options.
alternativesNoHow many other doctors to return after the best match.

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, but the description goes further and discloses non-obvious runtime behavior: filter dropping surfaced via `understood.dropped_filters` and `warnings`, name-match ranking, and the `match.kind` values including that 'similar' is padding rather than the requested name. The `confidence` tier semantics (notably 'medium' meaning ask the user) materially change how an agent should act on a result.

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 purpose and the input constraint, then layered detail — no wasted throat-clearing. The confidence/match.kind block is dense and partially overlaps the output schema, but its interpretation guidance ('confirm with the user') is not something the schema can convey.

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?

Covers input constraints, the two search modes, result ranking, dropped filters, per-doctor match classification, confidence interpretation, and even the `weekly_hours` day-to-shift encoding. With an output schema present, nothing further is needed for an agent to call this 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 a constraint the schema lacks entirely (zero required parameters yet at least one of name/city/specialty is needed) and notes Persian input works best and that `alternatives` counts doctors after the best match. It doesn't restate the maxLength/minimum bounds, which the schema already handles.

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?

A specific verb plus resource (find an Iranian doctor on exiryab.com) scoped by name, city, and/or specialty, with a preview of what comes back. It reads clearly against the reference-lookup siblings, though the description itself never names ey_cities/ey_specialties to draw the boundary explicitly.

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?

States the hard prerequisite ('Give at least one of name, city, specialty') and then branches the two main modes: with a name it ranks by name match and drops empty filters; without a name it ranks by city and specialty. It also tells the agent to confirm with the user when confidence is medium, which is actionable routing guidance rather than description filler.

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

ey_specialtiesList specialtiesA
Read-onlyIdempotent

Medical specialties on exiryab.com with their doctor count, most doctors first; sub-specialties name their parent.

Use it to turn a word like 'قلب' or 'پوست' into the exact specialty for ey_search_doctors(specialty=...) when the user's word is ambiguous (heart: «قلب و عروق» cardiology or «جراح قلب» heart surgery).

NameRequiredDescriptionDefault
limitNoMax specialties to return.
queryNoPart of the Persian name, e.g. 'شیر' or 'قلب'. Omit to list the largest.

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior3/5

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

Annotations already declare read-only, idempotent, non-destructive and open-world, so safety is fully covered. The description adds useful context on ordering and on sub-specialties exposing a `parent` field, but since an output schema exists it does not need to describe return values and says nothing further about behavior beyond ordering.

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 tight sentences/paragraphs with no filler; the resource-plus-ordering fact is front-loaded and the routing advice follows immediately. Everything present 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?

For a two-parameter read-only lookup with full schema coverage, rich annotations and an output schema, the description supplies exactly the missing pieces: what the catalog contains, its ordering, the parent linkage, and the disambiguation workflow that motivates calling it.

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%: 'query' is already documented as a partial Persian name with 'شیر'/'قلب' examples and the omit-to-list-largest behavior, and 'limit' is fully bounded. The description repeats the same word-matching idea rather than adding format or semantics beyond the schema, so the baseline of 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?

The first clause names the concrete resource (medical specialties on exiryab.com), what each entry carries (doctor count), the sort order (most doctors first) and the sub-specialty/parent relationship. This is enough for an agent to distinguish it from ey_search_doctors and ey_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 Guidelines5/5

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

The second paragraph states the exact trigger — resolving an ambiguous Persian lay term ('قلب', 'پوست') into a canonical specialty string — and names the downstream call it feeds, ey_search_doctors(specialty=...). The cardiology-vs-heart-surgery example makes the ambiguity case concrete, so when-to-use is explicit rather than inferred.

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. 3 tool updatesv0.1.0
    • First observedey_cities
    • First observedey_search_doctors
    • First observedey_specialties

TDQS

A4.4/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a distinct role: ey_search_doctors performs the actual lookup, while ey_cities and ey_specialties are enumerations that feed exact filter values into the search. The descriptions explicitly cross-reference this relationship, leaving no realistic chance of misselection.

Naming Consistency4/5

All tools share a consistent `ey_` prefix and snake_case, with clear domain-oriented names. The only minor deviation is that one is verb-led (search_doctors) while the other two are noun-only (cities, specialties), which is natural for enumeration vs action but slightly breaks a single pattern.

Tool Count4/5

Three tools is lean but well-motivated: a rich search endpoint plus two small lookup vocabularies. Nothing feels redundant, though the surface is thin enough that a single additional tool (e.g. fetch doctor by URL) could be justified.

Completeness4/5

The search tool already returns profiles, clinics, phones, hours and map links, and the two enumerations cover the full filter vocabulary, so the core directory workflow is closed. A direct profile-by-URL/ID retrieval and any booking/contact operations are absent, but reasonable workarounds exist.

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
    50 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables finding doctors in Romania by county, speciality, language, name, and weekly availability, with fuzzy name matching and nearby-county fallback.
    37 npm
    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
    101 PyPI
    4
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to search Iranian doctors by speciality, city, neighborhood, insurance and visit type, compare office and online consultation fees, check free appointment times up to a month ahead, and read reviews. Also covers hospitals, clinics, labs, pharmacies, fixed-price clinic offers and health articles, all read-only so booking happens on the site via a returned link.
    14
    91 PyPI
    2
    MIT