@cyanheads/who-gho-mcp-server
Public Hosted Server: https://who-gho.caseyjhand.com/mcp
Tools
6 tools for working with WHO Global Health Observatory data:
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 |
who_search_indicators
Search the WHO GHO indicator catalog by keyword.
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) over the filtered result set; reportstotalCount,hasMore,pageInfo,nextOffsetDefault limit 20, max 100
who_list_indicators
Browse the full indicator catalog with offset-based pagination.
No keyword required — lists all 3,059+ indicators
Pagination via
limit(default 50, max 500) andoffsetReturns
totalandhasMorefor iteration
who_get_indicator_metadata
Fetch metadata for one to ten indicator codes in a single call.
Returns the full indicator name and the dimension types it supports (e.g.
COUNTRY,SEX,REGION,AGEGROUP)Call before
who_query_indicator_datato confirm which filter dimensions are validRoughly 1,300 catalog indicators have no dimension listing upstream — those return
dimensions: []plus adimensionsNotepointing atdim1Type/dim2Typeon a sample data row, not a not-foundCodes absent from the catalog are reported in
notFoundrather than raising an error
who_list_dimensions
List all dimension type codes available in the GHO API.
Returns every dimension type with its human-readable title
Common types:
COUNTRY,REGION,SEX,WORLDBANKINCOMEGROUP,AGEGROUPUse to discover codes before calling
who_list_dimension_values
who_list_dimension_values
List valid filter values for a single dimension type.
Returns codes and labels for the dimension's values (e.g. the 234 country entries, the 43 WHO region codes)
Includes optional parent hierarchy fields (
parentCode,parentLabel,parentDimension)parent_codenarrows hierarchical dimensions —dimension: "COUNTRY",parent_code: "EUR"returns the 58 country entries in the WHO European RegionDeterministic ordering by
Codewith offset-based pagination (offset); returnstotalCount,hasMore,pageInfo,nextOffsetDefault limit 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 does not existUse to confirm exact codes before passing them to
who_query_indicator_data
who_query_indicator_data
Query data rows for a single WHO GHO indicator.
Spatial filters (mutually exclusive):
country_codes(ISO 3166-1 alpha-3),region_codes(WHO regions), orincome_group_codes(World Bank groups)Time range filter:
year_from/year_toSex filter:
SEX_BTSX(both),SEX_FMLE,SEX_MLE— only applies when the indicator uses SEX as its first cross-cutting dimensionArbitrary
dim1_valuefor indicators using non-SEX cross-cutting dimensionsOptional uncertainty interval bounds (
low/high) viainclude_uncertainty(default true)Deterministic row ordering (
sort:year_descdefault oryear_asc) with offset-based pagination (offset); returnstotalRows,hasMore,pageInfo,nextOffsetDefault limit 200, max 1000
Primary data tool in the find-then-query workflow
Resources
Type | URI | Description |
Resource |
| Indicator name and supported filter dimensions for a single code |
Resource |
| First 100 values for a dimension type |
Resource |
| One explicit page of a dimension type's values |
Resource |
| One explicit page, narrowed to a parent code |
The three dimension-value URIs are registered separately because the MCP SDK's RFC 6570 matcher treats every query variable as required — a single template with optional variables would stop matching the bare URI. Supply every variable a template names.
Recommended workflow
who_search_indicators— find indicator codes by keywordwho_get_indicator_metadata— confirm which filter dimensions the indicator supportswho_query_indicator_data— fetch data with country/region/year/sex filters
To look up filter codes: who_list_dimensions → who_list_dimension_values.
Features
Built on @cyanheads/mcp-ts-core:
Declarative tool definitions — single file per tool, framework handles registration and validation
Unified error handling across all tools
Pluggable auth (
none,jwt,oauth)Swappable storage backends:
in-memory,filesystem,Supabase,Cloudflare KV/R2/D1Structured logging with optional OpenTelemetry tracing
Runs locally (stdio/HTTP) or on Cloudflare Workers from the same codebase
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 for custom or mirrored deployments
Parallel metadata fan-out for multi-code indicator lookups
Agent-friendly output:
Tool descriptions encode the cross-tool workflow — agents discover the right call order from descriptions alone
Structured truncation signaling (
truncated,truncatedNote,hasMore) so agents can decide whether to paginateDiscriminated error codes with
recoveryhints on every failure path
Getting started
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.3.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 installConfiguration
All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:
Variable | Description | Default |
| Transport: |
|
| HTTP server port |
|
| HTTP endpoint path where the MCP server is mounted |
|
| 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 |
|
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
Project structure
Directory | Purpose |
| Tool definitions ( |
| Resource definitions. Indicator metadata and dimension values resources. |
| WHO GHO OData API service layer — HTTP client, query builder, types. |
| Server-specific environment variable parsing and validation with Zod. |
| 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()arrays
Contributing
Issues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.