Skip to main content
Glama
README.md
<p align="center">
  <a href="https://decilion.com">
    <img src="https://raw.githubusercontent.com/Decilion/gho-mcp/v0.7.0/assets/decilion-banner.png" alt="Decilion" width="100%">
  </a>
</p>

# gho-mcp

A Model Context Protocol (MCP) server that gives AI assistants like Claude direct access to the **World Health Organization's Global Health Observatory (GHO)**, built for comparative health systems research.

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)
[![MCP](https://img.shields.io/badge/protocol-MCP-orange)](https://modelcontextprotocol.io)

---

## What it does

`gho-mcp` wraps the [WHO GHO OData API](https://www.who.int/data/gho/info/gho-odata-api) (`https://ghoapi.azureedge.net/api`) in a small set of task-shaped MCP tools so an AI assistant can answer questions like:

- *"Build me a comparative health systems profile for Peru."*
- *"Plot maternal mortality across the Andean countries since 2010."*
- *"What's the UHC service coverage gradient by World Bank income group?"*
- *"Does the tobacco indicator support sex disaggregation?"*

Country names, ISO3 codes, WHO region codes (`AFR`, `AMR`, etc.), and World Bank income-group codes (`WB_HI`, `WB_UMI`, etc.) are all accepted interchangeably. CSV export is built in.

## Why this exists

Raw API access for global health data is *technically* possible from an AI assistant with tool access, but in practice it's painful: indicator codes are cryptic (`WHOSIS_000001` is "life expectancy at birth"), countries must be ISO3 codes, OData filter syntax is unforgiving, and every cross-country comparison becomes a loop. `gho-mcp` collapses the friction so an LLM can stay focused on the analysis.

The tool design reflects how comparative-health-systems researchers actually work: country profiles, regional and income-group benchmarks, sex-disaggregated time series, and metadata for citation.

## Install

Requires **Python 3.11 or newer** and an MCP client that can launch local
stdio servers. Check `python3 --version` (Windows: `py -3 --version`) and use
a supported interpreter before creating the environment. No WHO API key is required.
The shell examples below use macOS/Linux.

Install **0.7.0** from [PyPI](https://pypi.org/project/mcp-server-gho/0.7.0/) in a virtual environment:

```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install mcp-server-gho==0.7.0
```

On Windows PowerShell, use:

```powershell
py -3 -m venv .venv
.\.venv\Scripts\python.exe -m pip install mcp-server-gho==0.7.0
```

The same wheel and source archive are also available in the
[GitHub release](https://github.com/Decilion/gho-mcp/releases/tag/v0.7.0).

For an editable source installation:

```bash
git clone https://github.com/Decilion/gho-mcp.git
cd gho-mcp
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e .
```

### Connect your MCP client

Use the absolute path to the executable in the environment where you installed
this package: `.venv/bin/gho-mcp` on macOS/Linux, or
`.venv\Scripts\gho-mcp.exe` on Windows. In JSON, escape Windows backslashes,
for example `C:\\Users\\you\\project\\.venv\\Scripts\\gho-mcp.exe`.
Merge the entry into any existing `mcpServers` object instead of replacing it.

**Claude Code:**

```bash
claude mcp add --transport stdio --scope user gho -- /absolute/path/to/.venv/bin/gho-mcp
```

`--scope user` makes the server available across Claude Code projects.
Use `--scope local` if you want it only in the current project.

**Claude Desktop:** add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "gho": {
      "command": "/absolute/path/to/.venv/bin/gho-mcp"
    }
  }
}
```

**Codex CLI:**

```bash
codex mcp add gho -- /absolute/path/to/.venv/bin/gho-mcp
```

This writes an entry to `~/.codex/config.toml`. List or remove with `codex mcp list` / `codex mcp remove gho`.

**Other MCP-compatible clients** (Cursor, Cline, Continue, etc.): point them at the `gho-mcp` console script in your venv. The MCP protocol is the same across clients; only the registration UI differs.

Restart your client. The `gho` server should appear with all tools, the `gho://topics/{topic_id}` resource, and the `compare_health_systems` prompt available.

### Verify the installation

```bash
python -m pip show mcp-server-gho
```

On Windows, use `.\.venv\Scripts\python.exe -m pip show mcp-server-gho`.
After registering and restarting your client, ask it to call `gho`'s
`topics_index` tool. This checks the connection without fetching WHO data.
The server exposes **15 tools**. Running `gho-mcp` alone in a terminal
starts a stdio process that waits for an MCP client; it is not a web server.

If the server is missing, verify the absolute executable path, install into that
same environment, and restart the client. If WHO is temporarily unavailable,
retain the error and retry later; an upstream failure does not mean no data exists.

## Updating

Version **0.7.0** includes the September 2026 correctness and reliability fixes
listed in the [changelog](https://github.com/Decilion/gho-mcp/blob/v0.7.0/CHANGELOG.md#070---2026-09-14). Upgrade from
PyPI with `python -m pip install --upgrade mcp-server-gho`,
or update an editable source checkout as follows.

The unpinned upgrade command selects the newest compatible PyPI release.
Use `mcp-server-gho==0.7.0` to reproduce the version documented here.

From your existing clone, with its virtual environment active:

```bash
git pull --ff-only
python -m pip install -e .
```

Restart the MCP client so its server process loads the updated code and tool
schemas. Installation resolves declared dependencies: both servers require
`mcp>=1.15.0,<2` and `httpx>=0.27.0`; GHED additionally requires
`openpyxl>=3.1.0` and `filelock>=3.16,<4`.

### Response compatibility in 0.7.0

Comparisons and CSV exports retain the existing columns and append
`spatial_dim_type`, `time_dim_type`, `dim1_type`, `dim1`, `dim2_type`, `dim2`,
`dim3_type`, and `dim3`. Latest-year selection now preserves each complete
population combination; outputs can contain more rows than in 0.6.1. Include
those dimensions when grouping or pivoting, or choose a population with
`dim_filters`. `sex` is null when Dim1 represents a different dimension.

Profiles add `indicator_dim_filters` and per-indicator `selection_status`.
Ambiguous or incomplete latest-year populations return null headline values
with an explanation. Consumers should inspect this status before using a value.
Comparisons report unsupported group codes and missing requested countries.
For multi-chunk queries, `source.params` is empty and `source.requests` contains
the exact requests and continuation metadata. Unsupported identifiers and aliases
raise errors; failed dimension lookups preserve their upstream errors.

## Tool reference

Tables show defaults; capped limits are clamped to at least 1 and at most the
listed maximum. Raising a limit beyond that maximum does not fetch more data.

Tool signatures below show the **canonical parameter names**, omitting deprecated
aliases. Unknown arguments are rejected, so getting the names right matters. In particular: `country` is singular, `countries` is the list form, year filters are `year_start` / `year_end` (not `year_from` / `year_to`).

`find_country_code` also accepts the deprecated `country_name` alias. Pass
either `country` or `country_name`, not both.
`get_indicator_data` similarly accepts deprecated `region_code` in place of
`country`. Use `country` for countries, WHO regions and income-group codes.

### Discovery

| Tool | Signature | Purpose |
|---|---|---|
| `list_indicators` | `(skip=0, top=50)` | Paginated list of all GHO indicators; `top` capped at 200 |
| `search_indicators` | `(query, top=50)` | Case-insensitive substring search on indicator names; `top` capped at 200 |
| `topics_index` | `()` | Curated map of comparative-health-systems topics → indicator codes |
| `list_dimensions` | `()` | All GHO dimensions (COUNTRY, REGION, SEX, AGEGROUP, etc.) |
| `get_dimension_values` | `(dimension_code)` | Allowed values for a dimension |
| `find_country_code` | `(country)` | Resolve country name → ISO3 code |
| `list_income_groups` | `()` | World Bank income-group spatial codes |
| `list_curated_country_groups` | `()` | Decilion's curated groupings (LAC, LAC_TERRITORIES, OECD, LDC, SSA, MENA, etc.); see Regional analysis below |
| `resolve_country_group_membership` | `(group)` | Return the ISO3 list for one curated group |

### Indicator detail

| Tool | Signature | Purpose |
|---|---|---|
| `get_indicator_metadata` | `(indicator_code)` | Full metadata record for citation |
| `describe_indicator_dimensions` | `(indicator_code, sample_size=200)` | What disaggregations (sex, age, residence) an indicator uses; `sample_size` capped at 1,000 |

### Data

| Tool | Signature | Purpose |
|---|---|---|
| `get_indicator_data` | `(indicator_code, country=None, year_start=None, year_end=None, sex=None, dim_filters=None, top=100)` | Single indicator with optional spatial/temporal/sex/dim filters; `top` capped at 1,000 |
| `compare_countries` | `(indicator_code, countries=None, country_group=None, year_start=None, year_end=None, sex=None, dim_filters=None, latest_only=False, top=1000, format="rows")` | One indicator × N spatial units × year range, tidy rows or CSV; `top` capped at 5,000 |
| `country_profile` | `(country, year=None, indicator_codes=None, indicator_dim_filters=None)` | Parallel-fetched headline indicators for one country |
| `get_indicator_data_raw` | `(indicator_code, filter=None, top=100, orderby=None, select=None)` | Expert escape-hatch; pass-through OData query for advanced disaggregations (wealth quintile, residence, education, custom Dim2 values); `top` capped at 5,000 |

### Resources and prompts

- **Resource** `gho://topics/{topic_id}`: readable view of a curated topic and its indicator codes
- **Prompt** `compare_health_systems(countries, topic)`: guided template for cross-country comparative analysis

## Population selection and query coverage

`latest_only=True` retains the latest year for each country and full dimension
combination. Age bands, residence areas and other subgroups remain separate;
`sex` is filled only when Dim1 represents sex. Discover dimensions first and
use `dim_filters` to compare a specific population. Indicators without a sex
dimension, such as physician density, must be queried without `sex="both"`.
Dimension discovery samples data and reports its own truncation flags.

For an explicit custom profile population, pass per-indicator filters:

```python
country_profile("Colombia", indicator_codes=["SDGPM25"],
                indicator_dim_filters={"SDGPM25": {"Dim1": "RESIDENCEAREATYPE_TOTL"}})
```

`country_profile(year=...)` selects the latest observation **at or before** that
year, not necessarily in that year. Inspect each returned reference year.
Profiles select within the latest available year after applying filters. They
prefer known WHO aggregate codes, otherwise report a unique labeled population.
If several populations remain, no headline value is chosen. The profile query
fetches up to 50 rows per indicator. When a capped page does not include an older
year, the latest-year population set may be incomplete and no value is selected.
Each profile indicator includes the exact query, truncation flags and selection
status. Apply filters or use the data tools to investigate unresolved results.

Comparisons cap rows **per chunk of up to 10 countries**, not per country. An
alphabetically earlier country's observations can consume the entire allowance.
Check `missing_requested_codes`, `truncated` and `possibly_truncated`; split into
smaller country lists or narrow filters to establish coverage. A missing result
is not proof that WHO has no data. `source.requests` records each exact HTTP
query and its continuation link. For several chunks, `filter` is a readable
summary and `source.params` is empty, rather than containing an invented query.

Curated groups use exact ISO3 membership. `unsupported_group_codes` and a warning
report members absent from GHO dimensions. A group with no supported members
raises an error even when explicit countries are also supplied.

## Regional analysis

Both `gho-mcp` and `ghed-mcp` expose the same curated country groupings beyond what WHO and the World Bank publish as built-in dimensions. Pass `country_group="LAC"` (or any of the codes below) on the data tools and the server resolves to the right ISO3 list without you having to enumerate codes by hand.

### Available groups

These are the definitions bundled with this release, last verified in the source
on **2026-05-06**. The World Bank region lists use **FY2026** definitions; they are
not a live classification service. Member counts describe the curated lists,
not the number of economies with observations in either WHO database.

| Code | Definition | Members |
|---|---|---|
| `LAC` | 33 sovereign Latin American & Caribbean states (PAHO/Decilion convention) | 33 |
| `LAC_TERRITORIES` | World Bank's 42-economy LAC region: sovereign states plus territories (Aruba, Cayman Islands, Curaçao, Puerto Rico, etc.) | 42 |
| `EAP` | World Bank East Asia & Pacific (FY2026) | 38 |
| `ECA` | World Bank Europe & Central Asia | 58 |
| `MENA` | World Bank "Middle East, North Africa, Afghanistan and Pakistan" (FY2026) | 23 |
| `MENA_EXCL_ISR_MLT` | MENA without Israel and Malta | 21 |
| `NAR` | World Bank North America (Bermuda, Canada, USA) | 3 |
| `SAS` | World Bank South Asia (FY2026; without AFG and PAK, now in MENA) | 6 |
| `SSA` | World Bank Sub-Saharan Africa | 48 |
| `LDC` | UN Least Developed Countries | 44 |
| `OECD` | OECD member countries | 38 |

Aliases include natural-language ("Latin America and Caribbean", "Sub-Saharan Africa", "Least Developed Countries") and official codes (`LCN`, `SSF`, etc.). Two read-only tools, `list_curated_country_groups` and `resolve_country_group_membership`, let an assistant inspect or expand the lists at runtime.

### Using `country_group=` on the data tools

`country_group=` merges (deduplicated) with any explicit `countries=` list. GHED additionally combines `region` / `income` filters using AND semantics. The following examples identify which server supports each call:

```text
compare_countries(indicator_code="oops_che", country_group="LAC",
                  latest_only=True)                               # GHED
compare_countries(indicator_code="WHOSIS_000001", country_group="OECD",
                  year_start=2010, year_end=2023)                 # GHO
list_curated_country_groups()                                     # both
resolve_country_group_membership("LAC")                           # both; returns 33 ISO3 codes

# ghed-mcp also exposes:
build_research_panel(indicator_codes=["che_gdp", "gghed_che"],
                     country_group="OECD", year_start=2000, year_end=2024)
summarize_country_group(indicator_code="ext_che", country_group="LDC",
                        latest_only=True)
list_countries(country_group="LAC", income="High")                # LAC HICs
```

Curated members are validated as exact ISO3 codes, without fuzzy name matching. GHO reports unsupported members through `unsupported_group_codes` and warnings. An entirely unsupported group raises an error. Each source has different geographic and indicator coverage, so inspect the resolved and missing-country lists before comparing regional results. User-supplied `countries=` are resolved separately; unsupported three-letter identifiers and aliases whose target is absent from GHO dimensions raise an error. Exact country names take precedence over partial name matching.

### Membership cadence

The lists are static Python data bundled with each package. Membership changes
require a new package release and an upgrade; reinstalling the same version does
not refresh them. WHO region/income values come from the respective data source
and should not be assumed to represent historical classifications for every year.

The `LAST_VERIFIED` constant in `country_groups.py` records the bundled review
date. Consult the authoritative sources for subsequent changes:

- World Bank country and lending groups: <https://datahelpdesk.worldbank.org/knowledgebase/articles/906519>
- UN Least Developed Countries: <https://policy.desa.un.org/least-developed-countries>
- OECD members: <https://www.oecd.org/en/about/members-partners.html>

Re-check before time-sensitive group comparisons and at least annually. See the
[UN graduation updates](https://www.un.org/ldcportal/content/support-ldc-graduation)
for scheduled changes; the package does not automatically remove graduating LDCs.

The same `country_groups.py` definitions live in both `ghed-mcp` and `gho-mcp` (canonical source: `ghed-mcp`). Their intended group membership matches, but supported countries and available observations can differ by source.

## Examples

Each block below shows a natural-language prompt and a sketch of the underlying
MCP tool calls. These calls illustrate arguments for your assistant; they are not
standalone Python scripts. Actual values and coverage depend on the WHO source.

**Country profile**

> *"Give me a Colombia health systems profile."*

The assistant calls `country_profile(country="Colombia")` and returns life expectancy, HALE, IMR, U5MR, MMR, UHC index, DTP3 coverage, skilled birth attendance, doctor and nurse density, premature NCD mortality, and TB incidence for each indicator's latest available year, with both-sex, all-age and total-residence populations preferred when explicitly coded. Each selected value includes its actual population dimensions. Ambiguous or incomplete latest-year populations return `selection_status="ambiguous"` or `"incomplete"` and a null value, so a subgroup is never silently treated as a national total.

**Comparative LAC analysis**

> *"Compare maternal mortality across the Andean countries since 2010."*

The assistant calls:

```python
compare_countries(
    indicator_code="MDG_0000000026",
    countries=["Colombia", "Ecuador", "Peru", "Bolivia", "Venezuela"],
    year_start=2010,
    latest_only=False,
    format="csv",
)
```

and gets a CSV ready to drop into any spreadsheet, statistical package, or charting tool.

**Income-group gradient**

> *"What's life expectancy by World Bank income group in 2021?"*

The assistant calls `compare_countries("WHOSIS_000001", countries=["WB_HI","WB_UMI","WB_LMI","WB_LI"], year_start=2021, year_end=2021, sex="both")` and compares the returned estimates, units and reference years. Calculate any
gap from the retrieved values; no fixed difference is assumed.

## From CSV output to analysis tools

`compare_countries(..., format="csv")` returns a CSV string under the `csv` key. Two common downstream paths:

**To pandas**, for time-series analysis or modelling (optional: install
`pandas` and `matplotlib` in your analysis environment):

```python
import io, pandas as pd

# csv_text is the value of result["csv"] from compare_countries
df = pd.read_csv(io.StringIO(csv_text))
df["year"] = df["year"].astype(int)
# First select one indicator and population with the tool's sex/dim_filters.
# Stop if multiple populations or duplicate observations would be combined.
population = ["spatial_dim_type", "time_dim_type", "dim1_type", "dim1",
              "dim2_type", "dim2", "dim3_type", "dim3"]
if len(df[population].drop_duplicates()) > 1:
    raise ValueError("Select one comparable population before pivoting.")
if df.duplicated(["country_code", "year"]).any():
    raise ValueError("Resolve duplicate country-year observations before pivoting.")
df = df.pivot(index="year", columns="country_code", values="value")
df.plot(title="Selected indicator and population by country")
```

**To any external tool** (Excel, Google Sheets, R, Stata, Tableau, charting platforms, etc.):

```python
with open("data.csv", "w", encoding="utf-8", newline="") as f:
    f.write(csv_text)
```

The columns `country_code`, `country_name`, `year`, `sex`, `value`, `value_display`, `low`, `high`, `indicator_name`, `spatial_dim_type`, `time_dim_type`, `dim1_type`, `dim1`, `dim2_type`, `dim2`, `dim3_type`, `dim3` preserve population identity in both rows and CSV and are tidy-format-friendly and map cleanly into most analysis or visualization workflows. For wide-format / per-country columns, pivot first (`pandas` snippet above).

## Advanced queries

The friendly tools cover spatial, temporal and sex filters, plus equality filters on Dim1/Dim2/Dim3 and their types through `dim_filters`. Use `get_indicator_data_raw` for custom OData expressions or selected output fields:

```text
get_indicator_data_raw(
    indicator_code="MDG_0000000026",
    filter="SpatialDim eq 'BRA' and TimeDim ge 2010",
    select="SpatialDim,TimeDim,Dim1Type,Dim1,Dim2Type,Dim2,Dim3Type,Dim3,NumericValue",
    top=20,
)
```

Inspect what disaggregations an indicator supports with `describe_indicator_dimensions(indicator_code)` first; it samples observations and lists the Dim1/Dim2/Dim3 types and values seen in the sample.

## Topics covered by `topics_index`

- `health_outcomes`: life expectancy, HALE, IMR, U5MR, MMR, adult mortality
- `service_coverage`: UHC index, DTP3, measles, ANC, skilled birth attendance
- `health_workforce`: doctors, nurses & midwives, dentists, pharmacists per 10k
- `health_financing`: health spending as % GDP, OOP share, per-capita CHE
- `ncd_burden`: premature NCD mortality, hypertension, obesity, smoking
- `infectious_diseases`: TB, HIV, malaria, hepatitis, water access
- `child_health`: stunting, wasting, exclusive breastfeeding, immunization
- `risk_factors`: tobacco, alcohol, obesity, physical inactivity
- `mental_health`: suicide, mental health workforce
- `environment_climate`: PM2.5, WASH (water/sanitation/hygiene)
- `medicines_access`: essential medicines availability
- `quality_safety`: antimicrobial resistance, hospital safety proxies
- `equity_sdg`: SDG-aligned indicators for equity framing

## Development

The 2026-09-14 regression suite contains 77 tests. GitHub Actions runs it
on Python 3.11, 3.12, 3.13 and 3.14 against the minimum and latest compatible MCP SDK,
then builds both distributions and checks wheel imports outside the checkout.

```bash
python -m pip install -e ".[dev]"
python -m pytest
```

Tests mock the WHO API; no network access required for the standard suite. A weekly GitHub Actions workflow validates that the curated indicator codes still resolve against the live API and opens an issue if anything rots.

Release procedure: [RELEASING.md](https://github.com/Decilion/gho-mcp/blob/main/RELEASING.md).

## Limitations

- The GHO OData feed is read-only and unauthenticated. Aggregate values (regional, income-group, global) are computed by WHO; this server does not recompute them.
- Detailed health expenditure data lives in the separate [GHED database](https://apps.who.int/nha/database); a few GHED indicators are mirrored in GHO but not the full set.
- Some indicators are sparse for recent years. `describe_indicator_dimensions`
  inspects a sample of populations, not complete country/year availability. Query
  the required countries and years and inspect missing-country and truncation flags.
- Availability depends on the WHO OData service. Changes to endpoints, indicator
  codes or response schemas may require a server update.

## About the WHO Global Health Observatory

The [WHO Global Health Observatory](https://www.who.int/data/gho) (GHO) is the World Health Organization's central platform for global health statistics. It is the authoritative source of internationally comparable indicators on:

- **Sustainable Development Goals** health monitoring (SDG 3 and related targets)
- **Universal Health Coverage**: service coverage index, financial protection, essential medicines availability
- **Major disease burden**: HIV, tuberculosis, malaria, hepatitis, NCDs, mental health
- **Health system inputs**: workforce density, immunization coverage, health expenditure
- **Risk factors**: tobacco, alcohol, obesity, air pollution, WASH
- **Equity dimensions**: disaggregations by sex, age, residence, wealth quintile, and education where source data permits

The GHO underpins WHO's annual *World Health Statistics* report, regional health reviews, and country-level briefings used by ministries of health, multilateral institutions, and global health researchers worldwide. The data is free and openly published through the OData API this server wraps, and through the [official portal](https://www.who.int/data/gho) with its own visualizations, dashboards, and downloads.

**This MCP server is plumbing.** The data, the indicator definitions, the methodological work, and the country-level data validation are all WHO's. If you use values retrieved through this server, please:

- **Cite WHO as the source.** The `source` block on every data response includes the exact endpoint, parameters, and retrieval timestamp to make this straightforward.
- **Visit the [GHO portal](https://www.who.int/data/gho)** for indicator metadata, methodology notes, and the official visualizations. The MCP exposes the data: the portal provides the canonical context.
- **Read the [*World Health Statistics*](https://www.who.int/data/gho/publications) annual report** for WHO's curated narrative analysis of what the data shows.

The GHO is a public good. The most valuable contribution any user can make is to support and reference WHO's underlying data work.

## Built by

[Decilion](https://decilion.com) provides global health consulting across Latin
America and the Caribbean, including applied AI for global health.

This server is one of Decilion's open-source contributions to the global health data community. It pairs with [`ghed-mcp`](https://github.com/Decilion/ghed-mcp) for detailed health-expenditure analysis. If you use it in research, a brief acknowledgment is appreciated but not required.

## License

MIT. See [LICENSE](https://github.com/Decilion/gho-mcp/blob/v0.7.0/LICENSE).

TDQS

A3.9/5.0

Scored across 15 tools

Disambiguation3/5

compare_countries and get_indicator_data overlap heavily—both fetch observations for one indicator with country/region/income filters, year ranges, sex, and dimension filters—differing mainly in multi-country support. get_indicator_data_raw is clearly distinct as raw OData, and discovery tools are mostly distinct, but the two friendly data-fetch tools create real selection ambiguity.

Naming Consistency4/5

Most tools follow a clear verb_noun pattern (list_dimensions, get_indicator_metadata, search_indicators, resolve_country_group_membership). A few nouns like topics_index and country_profile, plus compare_countries, deviate slightly, but there is no mixed casing or unpredictable verb style.

Tool Count4/5

15 tools is within the ideal range and covers discovery, metadata, retrieval, and raw access. The count is slightly inflated by the get_indicator_data vs compare_countries overlap, so not every tool feels strictly necessary, but the overall scope is manageable.

Completeness5/5

For a read-only health data API, the surface is complete: indicator discovery, dimension introspection, country/group resolution, metadata, friendly and raw data access, and a multi-indicator country profile are all present. No obvious dead ends exist; even advanced queries have an escape hatch via raw OData.

Maintenance

ActivityMaintained
ResponsivenessNo issues