@cyanheads/who-gho-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@cyanheads/who-gho-mcp-servershow under-five mortality for India in 2020"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Public Hosted Server: https://who-gho.caseyjhand.com/mcp
Overview
WHO Global Health Observatory (GHO) data — 3,059 indicators across 194 member states. Search the indicator catalog, discover country, region, income-group, and sex filter dimensions, and query data rows from any MCP client. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
Tools
Tool | Description |
| Search the GHO indicator catalog by keyword in indicator names |
| Browse the full indicator catalog with pagination |
| Fetch indicator names and supported filter dimensions for up to 10 codes |
| List all dimension type codes available in the GHO API |
| List valid codes and labels for a dimension type (COUNTRY, REGION, SEX, etc.) |
| Query data rows for an indicator with spatial, temporal, and dimension filters |
Resources
Resource | Description |
| Indicator name and supported filter dimensions for a single code |
| First 100 values for a dimension type |
| One explicit page of a dimension type's values |
| One explicit page, narrowed to a parent code |
Each mirrors data also reachable via who_get_indicator_metadata and who_list_dimension_values — useful for clients that inject resources as context but don't call tools.
Related MCP server: unicefstats-mcp
Capability reference
who_search_indicators tool
Substring match on indicator names — try terms like
"life expectancy","immunization","mortality","diabetes", or"HIV"Returns indicator codes and display names for use with
who_query_indicator_dataOffset-based pagination (
offset, default 0) withlimitdefault 20, max 100; reportstotalCount,hasMore,pageInfo,nextOffsetAn offset at or beyond
totalCountreturns an empty page; ano_resultserror is raised only when nothing matches at all
who_list_indicators tool
No keyword required — lists all 3,059+ catalog indicators
Offset-based pagination via
limit(default 50, max 500) andoffsetReturns
totalCountandhasMorefor iteration
who_get_indicator_metadata tool
Accepts 1–10 indicator codes per call, fetched in parallel
Returns the full indicator name and supported dimension types (e.g.
COUNTRY,SEX,REGION,AGEGROUP) for each resolved codeRoughly 1,300 catalog indicators have no dimension listing upstream — those return
dimensions: []plus adimensionsNotepointing at a sample data row'sdim1Type/dim2Type, not a not-foundCodes absent from the catalog land in
notFoundrather than raising an error; the call fails only when none of the requested codes resolve
who_list_dimensions tool
No inputs — returns every dimension type code and human-readable title in the GHO catalog
Common types:
COUNTRY,REGION,SEX,WORLDBANKINCOMEGROUP,AGEGROUPUse to discover codes before calling
who_list_dimension_values
who_list_dimension_values tool
Returns codes and labels for the dimension's values (e.g. the 234 country entries, the 43 WHO region codes), plus optional parent-hierarchy fields (
parentCode,parentLabel,parentDimension)parent_codenarrows hierarchical dimensions —dimension: "COUNTRY"withparent_code: "EUR"returns the 58 countries in the WHO European RegionDeterministic ordering by
Code; offset-based pagination (offset) withlimitdefault 100, max 500 —GHO(3,103 values) andDHSMICSGEOREGION(4,932) need pagingA
parent_codethat matches nothing returns an empty page, not an error; only an unfiltered empty result means the dimension itself does not existAn unpaired UTF-16 surrogate in
dimensionfails as a typedmalformed_identifiervalidation error
who_query_indicator_data tool
Spatial filters are mutually exclusive per call:
country_codes(ISO 3166-1 alpha-3),region_codes(WHO regions), orincome_group_codes(World Bank groups) — supplying more than one is a validation erroryear_from/year_totime range;sex(SEX_BTSX,SEX_FMLE,SEX_MLE) applies only when the indicator's first cross-cutting dimension is SEX, otherwise usedim1_valueinclude_uncertainty(default true) addslow/highbounds;sort(year_descdefault oryear_asc) with a total row ordering so paging never repeats or drops rowsOffset-based pagination with
limitdefault 200, max 1000; reportstotalRows,hasMore,pageInfo,nextOffsetTyped failure reasons:
indicator_not_found,no_data,ambiguous_spatial_filter,invalid_year_range,invalid_query,malformed_identifier
who://indicator/{indicatorCode}/metadata resource
Indicator name and supported filter dimensions as
application/jsonindicatorCodecomes fromwho_search_indicatorsorwho_list_indicatorsEmpty
dimensionscarries adimensionsNotewhen the upstream dimension table lists none for the code, rather than reporting a missing indicatorReturns a 404 error only when the code resolves to neither a catalog name nor any dimension rows
who://dimension/{dimensionCode}/values resource
Bare URI returns the first 100 values for the dimension (
dimensionCodefromwho_list_dimensions), asapplication/jsonRegistered separately from the two paged variants below because the MCP SDK's RFC 6570 matcher treats every URI query variable as required — one template cannot serve both a bare and a paged form
An unfiltered empty result means the dimension code does not exist
who://dimension/{dimensionCode}/values{?limit,offset} resource
limit(1–500) andoffsetmust both be present in the URI — the query variables are required, not optionalSame page fields as the bare URI:
totalCount,hasMore,nextOffset, and an optionalnoticeAn offset at or beyond
totalCountreturns an empty page, not an error
who://dimension/{dimensionCode}/values{?limit,offset,parentCode} resource
Adds
parentCodeto narrow to one parent value, e.g.parentCode="EUR"for countries in the WHO European Region;limit,offset, andparentCodemust all be present in the URIA
parentCodethat matches nothing returns an empty page, not an error — read the unfiltered URI to confirm the dimension itself existsSame output shape as the bare and paged resources:
dimension,values,totalCount,hasMore,nextOffset,notice
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
WHO GHO-specific:
Full coverage of the WHO GHO OData API v2 — indicators, dimensions, dimension values, and data queries
Configurable base URL and request timeout (
GHO_BASE_URL,GHO_REQUEST_TIMEOUT_MS) for custom or mirrored deploymentsParallel metadata fan-out for multi-code indicator lookups
Deterministic, total row/value ordering — pagination never repeats or drops rows across pages
Agent-friendly output:
Tool descriptions encode the cross-tool workflow — agents discover the right call order (search → metadata → query) from descriptions alone
Structured pagination signaling (
hasMore,nextOffset,pageInfo, andtruncatedon the data-query tool) so agents can decide whether to page furtherDiscriminated, typed error reasons with a
recoveryhint on every failure pathDistinct empty-page vs. not-found semantics — paging past the end, an unmatched filter, and a genuinely missing code each report differently instead of colliding into one generic empty result
Getting started
Public Hosted Instance
A public instance is available at https://who-gho.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"who-gho-mcp-server": {
"type": "streamable-http",
"url": "https://who-gho.caseyjhand.com/mcp"
}
}
}Self-Hosted / Local
Add the following to your MCP client configuration file.
{
"mcpServers": {
"who-gho-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/who-gho-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"who-gho-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/who-gho-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with Docker:
{
"mcpServers": {
"who-gho-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/who-gho-mcp-server:latest"]
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.4.0 or higher (or Node.js ≥24).
No API key required — the WHO GHO API is public.
Installation
Clone the repository:
git clone https://github.com/cyanheads/who-gho-mcp-server.gitNavigate into the directory:
cd who-gho-mcp-serverInstall dependencies:
bun installConfigure environment:
cp .env.example .env
# edit .env and set optional overridesConfiguration
Variable | Description | Default |
| Transport: |
|
| HTTP server port |
|
| HTTP endpoint path where the MCP server is mounted |
|
| HTTP session posture: |
|
| Public origin override for TLS-terminating reverse-proxy deployments | none |
| Authentication: |
|
| Log level ( |
|
| Opt-in Bun-only forced-GC pressure loop (ms). Try |
|
| Directory for log files (Node.js only) |
|
| Storage backend: |
|
| WHO GHO OData API base URL (override for custom/mirrored deployments) |
|
| HTTP request timeout in milliseconds |
|
| Enable OpenTelemetry |
|
See .env.example for the full list of optional overrides.
Running the server
Local development
Build and run the production version:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdioRun checks and tests:
bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite
Docker
docker build -t who-gho-mcp-server .
docker run --rm -p 3010:3010 who-gho-mcp-serverThe Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/who-gho-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| Resource definitions. Indicator metadata and dimension values resources. |
| WHO GHO OData API service layer — HTTP client, query builder, types. |
|
|
| Unit and integration tests, mirroring the |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor logging,ctx.statefor storageRegister new tools and resources in the
createApp()arraysWrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
WHO GHO MCP — World Health Organization Global Health Observatory (free, no auth)
Query 29,500+ World Bank development indicators for 200+ countries across 60+ years.
OWID MCP — Our World in Data chart/indicator access (free, no auth)
World Bank World Development Indicators: curated country-year economy, health, education and more.
Related MCP Servers
- AlicenseBqualityDmaintenanceProvides access to the World Health Organization's Global Health Observatory data, enabling AI assistants to search, retrieve, and analyze comprehensive health indicators, country statistics, disease burden data, and regional health trends through WHO's OData API.1MIT
- AlicenseAqualityCmaintenanceMCP server for UNICEF child development statistics. Query 790+ child-focused indicators across 200+ countries with disaggregations by sex, age, wealth quintile, and residence. No API key required.960 PyPI6MIT
- AlicenseAqualityAmaintenanceA Model Context Protocol (MCP) server that gives AI assistants direct access to the World Health Organization's Global Health Observatory (GHO) for comparative health systems research.15MIT
- AlicenseNot gradedqualityBmaintenanceEnables querying World Health Organization Global Health Observatory data via natural language, free and without authentication.375 npmMIT