Skip to main content
Glama
cyanheads

@cyanheads/who-gho-mcp-server

by cyanheads

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

Public Hosted Server: https://who-gho.caseyjhand.com/mcp


Tools

6 tools for working with WHO Global Health Observatory data:

Tool

Description

who_search_indicators

Search the GHO indicator catalog by keyword in indicator names

who_list_indicators

Browse the full indicator catalog with pagination

who_get_indicator_metadata

Fetch indicator names and supported filter dimensions for up to 10 codes

who_list_dimensions

List all dimension type codes available in the GHO API

who_list_dimension_values

List valid codes and labels for a dimension type (COUNTRY, REGION, SEX, etc.)

who_query_indicator_data

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_data

  • Offset-based pagination (offset) over the filtered result set; reports totalCount, hasMore, pageInfo, nextOffset

  • Default 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) and offset

  • Returns total and hasMore for 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_data to confirm which filter dimensions are valid

  • Roughly 1,300 catalog indicators have no dimension listing upstream — those return dimensions: [] plus a dimensionsNote pointing at dim1Type/dim2Type on a sample data row, not a not-found

  • Codes absent from the catalog are reported in notFound rather 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, AGEGROUP

  • Use 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_code narrows hierarchical dimensions — dimension: "COUNTRY", parent_code: "EUR" returns the 58 country entries in the WHO European Region

  • Deterministic ordering by Code with offset-based pagination (offset); returns totalCount, hasMore, pageInfo, nextOffset

  • Default limit 100, max 500 — GHO (3,103 values) and DHSMICSGEOREGION (4,932) need paging

  • A parent_code that matches nothing returns an empty page, not an error; only an unfiltered empty result means the dimension does not exist

  • Use 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), or income_group_codes (World Bank groups)

  • Time range filter: year_from / year_to

  • Sex filter: SEX_BTSX (both), SEX_FMLE, SEX_MLE — only applies when the indicator uses SEX as its first cross-cutting dimension

  • Arbitrary dim1_value for indicators using non-SEX cross-cutting dimensions

  • Optional uncertainty interval bounds (low/high) via include_uncertainty (default true)

  • Deterministic row ordering (sort: year_desc default or year_asc) with offset-based pagination (offset); returns totalRows, hasMore, pageInfo, nextOffset

  • Default limit 200, max 1000

  • Primary data tool in the find-then-query workflow

Resources

Type

URI

Description

Resource

who://indicator/{indicatorCode}/metadata

Indicator name and supported filter dimensions for a single code

Resource

who://dimension/{dimensionCode}/values

First 100 values for a dimension type

Resource

who://dimension/{dimensionCode}/values{?limit,offset}

One explicit page of a dimension type's values

Resource

who://dimension/{dimensionCode}/values{?limit,offset,parentCode}

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.

  1. who_search_indicators — find indicator codes by keyword

  2. who_get_indicator_metadata — confirm which filter dimensions the indicator supports

  3. who_query_indicator_data — fetch data with country/region/year/sex filters

To look up filter codes: who_list_dimensionswho_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/D1

  • Structured 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 paginate

  • Discriminated error codes with recovery hints 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/mcp

Prerequisites

  • Bun v1.3.0 or higher (or Node.js ≥24).

  • No API key required — the WHO GHO API is public.

Installation

  1. Clone the repository:

git clone https://github.com/cyanheads/who-gho-mcp-server.git
  1. Navigate into the directory:

cd who-gho-mcp-server
  1. Install dependencies:

bun install

Configuration

All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:

Variable

Description

Default

MCP_TRANSPORT_TYPE

Transport: stdio or http

stdio

MCP_HTTP_PORT

HTTP server port

3010

MCP_HTTP_ENDPOINT_PATH

HTTP endpoint path where the MCP server is mounted

/mcp

MCP_PUBLIC_URL

Public origin override for TLS-terminating reverse-proxy deployments

none

MCP_AUTH_MODE

Authentication: none, jwt, or oauth

none

MCP_LOG_LEVEL

Log level (debug, info, warning, error, etc.)

info

MCP_GC_PRESSURE_INTERVAL_MS

Opt-in Bun-only forced-GC pressure loop (ms). Try 60000 if RSS grows under sustained HTTP load.

0 (disabled)

LOGS_DIR

Directory for log files (Node.js only)

<project-root>/logs

STORAGE_PROVIDER_TYPE

Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1

in-memory

GHO_BASE_URL

WHO GHO OData API base URL (override for custom/mirrored deployments)

https://ghoapi.azureedge.net/api/

GHO_REQUEST_TIMEOUT_MS

HTTP request timeout in milliseconds

30000

OTEL_ENABLED

Enable OpenTelemetry

false

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:stdio
  • Run checks and tests:

    bun run devcheck  # Lints, formats, type-checks, and more
    bun run test      # Runs the test suite

Project structure

Directory

Purpose

src/mcp-server/tools

Tool definitions (*.tool.ts). Six tools across indicator discovery, dimension lookup, and data queries.

src/mcp-server/resources

Resource definitions. Indicator metadata and dimension values resources.

src/services/gho

WHO GHO OData API service layer — HTTP client, query builder, types.

src/config

Server-specific environment variable parsing and validation with Zod.

tests/

Unit and integration tests, mirroring the src/ structure.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic

  • Use ctx.log for logging, ctx.state for storage

  • Register 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 test

License

This project is licensed under the Apache 2.0 License. See the LICENSE file for details.