Koskamo

who-gho-mcp-server

An MCP server that provides access to the WHO Global Health Observatory, allowing agents to search and query 3,102 health indicators across 194 member states. It supports filtering by country, region, year, and sex, and exposes tools for browsing indicators, listing dimensions, and retrieving specific data points.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

who-gho-mcp-server logo, by cyanheadsCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-06Published by cyanheads
MCP endpoint (Streamable HTTP)
https://who-gho.caseyjhand.com/mcp
Vendor documentation

What its tools do

6 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

6 of 6 have a description · 6 of 6 declare behavior hints · 5 of 5 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Search the WHO GHO indicator catalog by keyword
  • Query health data rows with spatial and temporal filters
  • List valid dimension codes like country or region
  • Browse the full indicator catalog with pagination

Source and maintenance

Community listingRegistry 0.4.0
Maintenance checked

Protocol and capabilities

Server
who-gho-mcp-server 0.4.0
MCP protocol negotiated in check
2025-11-25
Tools
6 advertised
Resources
1 advertised
Resource templates
5 advertised
Prompts
0 advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "logging": {},
  "prompts": {
    "listChanged": true
  },
  "resources": {
    "subscribe": true,
    "listChanged": true
  },
  "extensions": {
    "io.modelcontextprotocol/skills": {
      "directoryRead": true
    }
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

WHO Global Health Observatory MCP server. Use who_search_indicators or who_list_indicators to obtain indicator codes, who_get_indicator_metadata for available dimension types, and who_query_indicator_data for observations. Resolve dimension value codes through who_list_dimensions → who_list_dimension_values. Metadata does not identify dimension positions; inspect returned type/value pairs before positional filtering. The public upstream API needs no key.

Tools

6 advertised

who_list_dimensions — List GHO Dimension Types
Advertised by the server during the last successful anonymous check.
Advertised read-only

List all dimension type codes and human-readable titles available in the WHO Global Health Observatory API. Use this to discover valid dimension codes before calling who_list_dimension_values. Common dimensions include COUNTRY, REGION, SEX, WORLDBANKINCOMEGROUP, and AGEGROUP, but many additional types exist — this tool exposes them all.

who_list_dimensions input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {},
  "additionalProperties": false
}
who_list_dimensions output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "dimensions"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "description": "Machine-readable failure mode."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "dimensions": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "code",
          "title"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Dimension type code, e.g. \"COUNTRY\", \"SEX\", \"AGEGROUP\"."
          },
          "title": {
            "type": "string",
            "description": "Human-readable label for the dimension, e.g. \"Age Group\"."
          }
        },
        "description": "A single dimension type entry.",
        "additionalProperties": false
      },
      "description": "All available dimension types in the GHO catalog."
    }
  },
  "additionalProperties": false
}
who_list_dimensions annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
who_list_dimension_values — List GHO Dimension Values
Advertised by the server during the last successful anonymous check.
Advertised read-only

List valid codes and labels for a WHO GHO dimension type such as COUNTRY, REGION, SEX, WORLDBANKINCOMEGROUP, or AGEGROUP. Use this to discover valid filter values before calling who_query_indicator_data, or to confirm the WHO code for a country, including historical codes. Use who_list_dimensions to discover all available dimension type codes. Results are paged in a deterministic order — narrow hierarchical dimensions with parent_code (e.g. the countries in one WHO region), and page the rest with offset.

who_list_dimension_values input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "dimension"
  ],
  "properties": {
    "limit": {
      "type": "integer",
      "default": 100,
      "minimum": 1,
      "description": "Number of values to return per page. Default 100, max 500."
    },
    "offset": {
      "type": "integer",
      "default": 0,
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Zero-based offset into the values for this dimension and filter. Default 0. Read hasMore and nextOffset from the response to continue paging. An offset at or beyond totalCount returns an empty values array, not an error."
    },
    "dimension": {
      "type": "string",
      "minLength": 1,
      "description": "Dimension type code. Use who_list_dimensions to discover all available codes. Common values: COUNTRY, REGION, SEX, WORLDBANKINCOMEGROUP, AGEGROUP."
    },
    "parent_code": {
      "type": "string",
      "minLength": 1,
      "description": "Restrict results to values under one parent, e.g. dimension=\"COUNTRY\" with parent_code=\"EUR\" for the countries in the WHO European Region. Only hierarchical dimensions carry a parent; a filter that matches nothing returns an empty page for a valid dimension, not an error."
    }
  },
  "additionalProperties": false
}
who_list_dimension_values output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "dimension",
        "values",
        "totalCount",
        "offset",
        "hasMore",
        "pageInfo"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "dimension_not_found",
                "malformed_identifier"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `dimension_not_found`: An unfiltered lookup returned no values, or a filtered empty result was confirmed absent by the dimension metadata endpoint. `malformed_identifier`: dimension carries an unpaired UTF-16 surrogate, so it cannot be encoded into the request URL. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "notice": {
      "type": "string",
      "description": "Present when values were withheld, the parent_code filter matched nothing, or the requested offset ran past the end. Explains what to do next."
    },
    "offset": {
      "type": "number",
      "description": "Zero-based offset this page started at."
    },
    "values": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "code",
          "label"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Dimension value code used as a filter in who_query_indicator_data."
          },
          "label": {
            "type": "string",
            "description": "Human-readable label for this value."
          },
          "parentCode": {
            "type": "string",
            "description": "Parent value code, e.g. the WHO region code for a country entry."
          },
          "parentLabel": {
            "type": "string",
            "description": "Human-readable label for the parent value."
          },
          "parentDimension": {
            "type": "string",
            "description": "Parent dimension type, e.g. \"REGION\" for country entries."
          }
        },
        "description": "A single valid value for this dimension type.",
        "additionalProperties": false
      },
      "description": "Valid values for this dimension type, for the requested page."
    },
    "hasMore": {
      "type": "boolean",
      "description": "True when more values remain beyond this page. Pair with nextOffset to continue."
    },
    "pageInfo": {
      "type": "string",
      "description": "Human-readable page position, e.g. \"offset 0, showing 100 of 234\". Use to construct the next offset."
    },
    "dimension": {
      "type": "string",
      "description": "The requested dimension type code."
    },
    "nextOffset": {
      "type": "number",
      "description": "Offset to request for the next page. Absent when this page reached the end of the values."
    },
    "totalCount": {
      "type": "number",
      "description": "Total values for this dimension and filter, before the limit is applied."
    }
  },
  "additionalProperties": false
}
who_list_dimension_values annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
who_search_indicators — Search WHO GHO Indicators
Advertised by the server during the last successful anonymous check.
Advertised read-only

Search the WHO Global Health Observatory indicator catalog by words in the indicator name. Every whitespace-separated word must match independently as a case-insensitive substring, in any order; try "tuberculosis incidence", "sanitation basic", or "HIV". When no names match, an exact indicator-code lookup is attempted. Returns canonical indicator codes and names for who_query_indicator_data. Refine the query or page through the same result set with offset.

who_search_indicators input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "query"
  ],
  "properties": {
    "limit": {
      "type": "integer",
      "default": 20,
      "minimum": 1,
      "description": "Maximum number of indicators to return. Default 20, max 100."
    },
    "query": {
      "type": "string",
      "minLength": 1,
      "description": "Words to match independently in indicator names, or an exact indicator code."
    },
    "offset": {
      "type": "integer",
      "default": 0,
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Zero-based offset into the matches for this query. Default 0. Read hasMore and nextOffset from the response to continue paging. An offset at or beyond totalCount returns an empty indicators array, not an error."
    }
  },
  "additionalProperties": false
}
who_search_indicators output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "indicators",
        "effectiveQuery",
        "totalCount",
        "offset",
        "hasMore",
        "pageInfo"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "no_results"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `no_results`: No indicator names matched every search word and no exact indicator code resolved. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "notice": {
      "type": "string",
      "description": "Present when matches were withheld or the requested offset ran past the end of the result set. Explains how to reach the remaining matches."
    },
    "offset": {
      "type": "number",
      "description": "Zero-based offset this page started at."
    },
    "hasMore": {
      "type": "boolean",
      "description": "True when more matches remain beyond this page. Pair with nextOffset to continue."
    },
    "pageInfo": {
      "type": "string",
      "description": "Human-readable page position, e.g. \"offset 0, showing 20 of 3003\". Use to construct the next offset."
    },
    "indicators": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "indicatorCode",
          "indicatorName"
        ],
        "properties": {
          "indicatorCode": {
            "type": "string",
            "description": "Unique indicator code used in who_query_indicator_data, e.g. \"WHOSIS_000001\"."
          },
          "indicatorName": {
            "type": "string",
            "description": "Full indicator name, e.g. \"Life expectancy at birth (years)\"."
          }
        },
        "description": "An indicator entry with its code and name.",
        "additionalProperties": false
      },
      "description": "Matching indicators up to the requested limit."
    },
    "nextOffset": {
      "type": "number",
      "description": "Offset to request for the next page. Absent when this page reached the end of the matches."
    },
    "totalCount": {
      "type": "number",
      "description": "Total indicators matching the query in the catalog, before the limit is applied."
    },
    "effectiveQuery": {
      "type": "string",
      "description": "Keyword used for the catalog search, as received by the server."
    }
  },
  "additionalProperties": false
}
who_search_indicators annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
who_list_indicators — List WHO GHO Indicators
Advertised by the server during the last successful anonymous check.
Advertised read-only

Browse the WHO Global Health Observatory indicator catalog with pagination. Use when you want to explore indicators without a keyword, or to page through the full catalog. Use who_search_indicators when you have a keyword to narrow the results.

who_list_indicators input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "limit": {
      "type": "integer",
      "default": 50,
      "minimum": 1,
      "description": "Number of indicators to return per page. Default 50, max 500."
    },
    "offset": {
      "type": "integer",
      "default": 0,
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Zero-based offset for pagination. Default 0."
    }
  },
  "additionalProperties": false
}
who_list_indicators output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "indicators",
        "totalCount",
        "hasMore",
        "pageInfo"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "description": "Machine-readable failure mode."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "notice": {
      "type": "string",
      "description": "Requested and applied limit when the page was clamped."
    },
    "hasMore": {
      "type": "boolean",
      "description": "True when more indicators exist beyond the current page."
    },
    "pageInfo": {
      "type": "string",
      "description": "Human-readable page position, e.g. \"offset 0, showing 50 of 3102\". Use to construct the next offset."
    },
    "indicators": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "indicatorCode",
          "indicatorName"
        ],
        "properties": {
          "indicatorCode": {
            "type": "string",
            "description": "Unique indicator code used in who_query_indicator_data, e.g. \"WHOSIS_000001\"."
          },
          "indicatorName": {
            "type": "string",
            "description": "Full indicator name, e.g. \"Life expectancy at birth (years)\"."
          }
        },
        "description": "An indicator entry with its code and name.",
        "additionalProperties": false
      },
      "description": "Indicators for the requested page."
    },
    "totalCount": {
      "type": "number",
      "description": "Total number of indicators in the GHO catalog."
    }
  },
  "additionalProperties": false
}
who_list_indicators annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
who_get_indicator_metadata — Get WHO GHO Indicator Metadata
Advertised by the server during the last successful anonymous check.
Advertised read-only

Fetch metadata for WHO GHO indicator codes: the canonical code, full name, and supported dimensions (e.g. COUNTRY, REGION, SEX, YEAR, WORLDBANKINCOMEGROUP, AGEGROUP). Call this before who_query_indicator_data to confirm valid filter dimensions. Processes the first 10 entries and returns unprocessedCodes to submit next, accepting at most 1000 raw entries. With GHO_CLAMP_LIMITS=false, calls above 10 reject. Many valid indicators have no dimension listing upstream — those return an empty dimensions array with dimensionsNote. Processed codes absent from both the catalog and dimension table appear in notFound. No found entries raises all_not_found only when no unprocessed entries remain.

who_get_indicator_metadata input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "indicator_codes"
  ],
  "properties": {
    "indicator_codes": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "maxItems": 1000,
      "minItems": 1,
      "description": "Indicator codes, e.g. [\"WHOSIS_000001\", \"MDG_0000000026\"]. Processes the first ten and returns remaining entries for the next call; at most 1000 entries."
    }
  },
  "additionalProperties": false
}
who_get_indicator_metadata output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "indicators",
        "notFound"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "all_not_found"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `all_not_found`: No processed indicator code resolved and no unprocessed codes remain. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "notFound": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Indicator codes that resolved to neither a catalog name nor any dimension rows — they do not exist in the GHO catalog."
    },
    "indicators": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "indicatorCode",
          "indicatorName",
          "dimensions"
        ],
        "properties": {
          "dimensions": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "dimension",
                "dimensionName"
              ],
              "properties": {
                "dimension": {
                  "type": "string",
                  "description": "Dimension type code, e.g. \"COUNTRY\", \"SEX\", \"WORLDBANKINCOMEGROUP\"."
                },
                "dimensionName": {
                  "type": "string",
                  "description": "Human-readable dimension name, e.g. \"Country\", \"Sex\"."
                }
              },
              "description": "A dimension entry supported by this indicator.",
              "additionalProperties": false
            },
            "description": "Dimensions this indicator supports for filtering in who_query_indicator_data. Empty when the GHO dimension table lists none for this code — see dimensionsNote."
          },
          "indicatorCode": {
            "type": "string",
            "description": "Canonical catalog code when resolved; otherwise the requested dimension-only code."
          },
          "indicatorName": {
            "type": "string",
            "description": "Decoded catalog name; the code itself when only dimension metadata resolves."
          },
          "dimensionsNote": {
            "type": "string",
            "description": "Present only when dimensions is empty: explains that the listing is missing upstream rather than the indicator being absent, and how to recover the dimensions from a sample data row."
          }
        },
        "description": "Metadata for one indicator.",
        "additionalProperties": false
      },
      "description": "Metadata for each code that resolved to a catalog entry or dimension rows."
    },
    "unprocessedCodes": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Remaining request entries in their original order. Submit these codes next."
    }
  },
  "additionalProperties": false
}
who_get_indicator_metadata annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}
who_query_indicator_data — Query WHO GHO Indicator Data
Advertised by the server during the last successful anonymous check.
Advertised read-only

Query data rows for a single WHO GHO indicator with optional spatial, temporal, and dimension filters. Returns rows with numeric values, uncertainty intervals (Low/High), and spatial/time metadata. This is the primary data-fetching tool in the find-then-query workflow: use who_search_indicators to find the indicator code, optionally call who_get_indicator_metadata to confirm which filter dimensions are valid, then call this tool. Discover positional filters from returned dim1Type/dim1, dim2Type/dim2 and dim3Type/dim3 pairs; metadata alone does not identify a slot. Spatial filters are mutually exclusive per call: provide only one of country_codes, region_codes, or income_group_codes — mixing them triggers an error. Omitting all spatial filters returns all geographies (may be large; use limit to cap). The sex filter only applies when the indicator uses SEX as its first cross-cutting dimension — if not, the filter returns empty rows; check who_get_indicator_metadata first if uncertain. Rows are returned in a deterministic order (most recent first by default), so a capped result is the top of a defined slice rather than an arbitrary sample; page through the rest with offset.

who_query_indicator_data input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "indicator_code"
  ],
  "properties": {
    "sex": {
      "enum": [
        "SEX_BTSX",
        "SEX_FMLE",
        "SEX_MLE"
      ],
      "type": "string",
      "description": "Filter on sex dimension: SEX_BTSX (both sexes), SEX_FMLE (female), SEX_MLE (male). Only applies when the indicator uses SEX as its first cross-cutting dimension."
    },
    "sort": {
      "enum": [
        "year_desc",
        "year_asc"
      ],
      "type": "string",
      "default": "year_desc",
      "description": "Row ordering: \"year_desc\" (default) returns the most recent years first, \"year_asc\" the earliest first. Ties are broken by spatial code, then dimension, then row id."
    },
    "limit": {
      "type": "integer",
      "default": 200,
      "minimum": 1,
      "description": "Maximum number of data rows to return. Default 200, max 1000."
    },
    "offset": {
      "type": "integer",
      "default": 0,
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Zero-based row offset for pagination. Default 0. Pages are stable because rows are returned in a deterministic order — read hasMore and nextOffset from the response to continue. An offset at or beyond totalRows returns an empty rows array, not an error."
    },
    "year_to": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": -9007199254740991,
      "description": "End year (inclusive) for the time range filter, e.g. 2023."
    },
    "year_from": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": -9007199254740991,
      "description": "Start year (inclusive) for the time range filter, e.g. 2015."
    },
    "dim1_value": {
      "type": "string",
      "description": "Value filter for indicators whose first cross-cutting dimension is not SEX (e.g. an AGEGROUP code like \"YEARS05-14\"). Ignored when sex is also provided."
    },
    "dim2_value": {
      "type": "string",
      "description": "Value filter for the second cross-cutting dimension, e.g. AGEGROUP_DAYS0-27. Discover the position from returned dim2Type/dim2 pairs; metadata does not identify the slot. Empty strings are ignored with a notice."
    },
    "dim3_value": {
      "type": "string",
      "description": "Value filter for the third cross-cutting dimension, e.g. CHILDCAUSE_CH9. Discover the position from returned dim3Type/dim3 pairs; metadata does not identify the slot. Empty strings are ignored with a notice."
    },
    "region_codes": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "description": "WHO region codes to filter on, e.g. [\"AFR\",\"EUR\",\"AMR\",\"EMR\",\"SEAR\",\"WPR\"]. Returns the aggregate row for each named WHO region. To get country-level data for a region, use who_list_dimension_values with dimension=\"COUNTRY\" and parent_code set to the region code to retrieve WHO country codes, then pass those to country_codes. Use who_list_dimension_values with dimension=\"REGION\" to see all valid region codes. Mutually exclusive with country_codes and income_group_codes."
    },
    "country_codes": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "description": "WHO country codes to filter on, e.g. [\"JPN\",\"USA\",\"BRA\"], including historical codes such as ME1 and SDN736. Discover codes with who_list_dimension_values dimension=\"COUNTRY\". Mutually exclusive with region_codes and income_group_codes."
    },
    "indicator_code": {
      "type": "string",
      "minLength": 1,
      "description": "Indicator code to query, e.g. \"WHOSIS_000001\". Use who_search_indicators to find codes."
    },
    "income_group_codes": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "description": "World Bank income group codes, e.g. [\"WB_HI\",\"WB_LMI\",\"WB_LI\",\"WB_UMI\"]. Use who_list_dimension_values with dimension=\"WORLDBANKINCOMEGROUP\" to see all valid codes. Mutually exclusive with country_codes and region_codes."
    },
    "include_uncertainty": {
      "type": "boolean",
      "default": true,
      "description": "Include Low and High uncertainty interval bounds in output. Default true."
    }
  },
  "additionalProperties": false
}
who_query_indicator_data output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "rows",
        "appliedFilters",
        "totalRows",
        "totalCount",
        "offset",
        "hasMore",
        "pageInfo"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "rows": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "indicatorCode"
        ],
        "properties": {
          "low": {
            "type": "number",
            "description": "Lower bound of the uncertainty interval. Present when include_uncertainty is true and the upstream provides it."
          },
          "dim1": {
            "type": "string",
            "description": "First cross-cutting dimension value, e.g. \"SEX_BTSX\"."
          },
          "dim2": {
            "type": "string",
            "description": "Second cross-cutting dimension value."
          },
          "dim3": {
            "type": "string",
            "description": "Third cross-cutting dimension value."
          },
          "high": {
            "type": "number",
            "description": "Upper bound of the uncertainty interval. Present when include_uncertainty is true and the upstream provides it."
          },
          "year": {
            "type": "number",
            "description": "Year of the data point. Absent when the upstream row has no TimeDim (time-independent entries)."
          },
          "comments": {
            "type": "string",
            "description": "Data source notes or comments attached to this row."
          },
          "dim1Type": {
            "type": "string",
            "description": "First cross-cutting dimension type, e.g. \"SEX\"."
          },
          "dim2Type": {
            "type": "string",
            "description": "Second cross-cutting dimension type, e.g. \"AGEGROUP\"."
          },
          "dim3Type": {
            "type": "string",
            "description": "Third cross-cutting dimension type, e.g. CHILDCAUSE."
          },
          "spatialDim": {
            "type": "string",
            "description": "Spatial dimension value, e.g. \"JPN\", \"AFR\", \"WB_HI\"."
          },
          "displayValue": {
            "type": "string",
            "description": "Formatted display string as provided by WHO, e.g. \"84.5 [84.5-84.5]\"."
          },
          "numericValue": {
            "type": "number",
            "description": "Machine-readable numeric value."
          },
          "indicatorCode": {
            "type": "string",
            "description": "Indicator code for this row."
          },
          "parentLocation": {
            "type": "string",
            "description": "Name of the WHO region this row sits under, e.g. \"Western Pacific\" for a JPN row. Not a label for spatialDim itself — the upstream row carries no name for its own spatial entity. Absent when spatialDim is already a region or income group."
          },
          "spatialDimType": {
            "type": "string",
            "description": "Spatial dimension type: COUNTRY, REGION, WORLDBANKINCOMEGROUP, GLOBAL, etc."
          },
          "parentLocationCode": {
            "type": "string",
            "description": "Code of the WHO region this row sits under, e.g. \"WPR\". Pass to region_codes to query that region's own aggregate rows. Absent alongside parentLocation."
          }
        },
        "description": "A single data row from the GHO indicator dataset.",
        "additionalProperties": false
      },
      "description": "Data rows matching the query."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "indicator_not_found",
                "no_data",
                "ambiguous_spatial_filter",
                "invalid_year_range",
                "invalid_query",
                "malformed_identifier"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `indicator_not_found`: The indicator code returned HTTP 404 from the GHO API. `no_data`: The indicator exists but no data rows matched the applied filters. `ambiguous_spatial_filter`: More than one of country_codes, region_codes, or income_group_codes were provided. `invalid_year_range`: year_from is greater than year_to, so the time filter can match no rows. `invalid_query`: The GHO API rejected the generated OData query because a supplied filter value is not a valid literal. `malformed_identifier`: indicator_code carries an unpaired UTF-16 surrogate, so it cannot be encoded into the request URL. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "notice": {
      "type": "string",
      "description": "Present when rows were withheld or the requested offset ran past the end of the result set. Explains how to reach the remaining rows."
    },
    "offset": {
      "type": "number",
      "description": "Zero-based row offset this page started at."
    },
    "hasMore": {
      "type": "boolean",
      "description": "True when rows remain beyond this page. Pair with nextOffset to continue."
    },
    "pageInfo": {
      "type": "string",
      "description": "Human-readable page position, e.g. \"offset 0, showing 200 of 12936\". Use to construct the next offset."
    },
    "totalRows": {
      "type": "number",
      "description": "Total row count matching the query on the server (before the limit is applied)."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when the result was capped at the requested limit."
    },
    "nextOffset": {
      "type": "number",
      "description": "Offset to request for the next page. Absent when this page reached the end of the result set."
    },
    "totalCount": {
      "type": "number",
      "description": "Alias of totalRows for cross-tool consistency — total rows before the limit."
    },
    "appliedFilters": {
      "type": "object",
      "required": [
        "indicatorCode",
        "ordering"
      ],
      "properties": {
        "sex": {
          "type": "string",
          "description": "Sex filter value applied, if any."
        },
        "ordering": {
          "type": "string",
          "description": "Row ordering applied to the query, e.g. \"most recent first (year_desc)\"."
        },
        "dim1Value": {
          "type": "string",
          "description": "dim1_value filter applied, if any."
        },
        "dim2Value": {
          "type": "string",
          "description": "dim2_value filter applied, if any."
        },
        "dim3Value": {
          "type": "string",
          "description": "dim3_value filter applied, if any."
        },
        "yearRange": {
          "type": "string",
          "description": "Applied year range, e.g. \"2015–2023\". Absent when no year filter was set."
        },
        "indicatorCode": {
          "type": "string",
          "description": "Indicator code that was queried."
        },
        "spatialFilter": {
          "type": "string",
          "description": "Active spatial filter summary, e.g. \"country_codes: JPN,USA\" or \"region_codes: EUR\"."
        }
      },
      "description": "Filters that were applied to the query.",
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
who_query_indicator_data annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true
}

Prompts

0 advertised

No prompt definitions available.

Resources

1 advertised

who-gho-guide

Advertised by the server during the last successful anonymous check.

Use with who_* tools to compare WHO GHO health indicators across countries or aggregates, discover age/sex/cause dimension positions, and distinguish missing metadata or incomplete pages from missing data.

who-gho-guide URI
skill://who-gho-guide/SKILL.md

MIME type: text/markdown

who-indicator-metadata — who-indicator-metadata

Advertised by the server during the last successful anonymous check.

Metadata for a single WHO GHO indicator: canonical code, full name, and the dimension types it supports for filtering. Dimensions come back empty with a dimensionsNote when the GHO dimension table lists none for the code — that is a gap upstream, not a missing indicator. Stable and suitable as injectable context before calling who_query_indicator_data.

who-indicator-metadata URI template
who://indicator/{indicatorCode}/metadata

MIME type: application/json

who-dimension-values — who-dimension-values

Advertised by the server during the last successful anonymous check.

One page of valid values for a WHO GHO dimension type, in a deterministic order. Useful as injectable context when building queries with who_query_indicator_data. Use who_list_dimensions to discover valid dimension type codes. Returns the first 100 values; read totalCount and nextOffset to reach the rest.

who-dimension-values URI template
who://dimension/{dimensionCode}/values

MIME type: application/json

who-dimension-values-page — who-dimension-values-page

Advertised by the server during the last successful anonymous check.

One page of valid values for a WHO GHO dimension type, in a deterministic order. Useful as injectable context when building queries with who_query_indicator_data. Use who_list_dimensions to discover valid dimension type codes. Both limit and offset must be present in the URI.

who-dimension-values-page URI template
who://dimension/{dimensionCode}/values{?limit,offset}

MIME type: application/json

who-dimension-values-by-parent — who-dimension-values-by-parent

Advertised by the server during the last successful anonymous check.

One page of valid values for a WHO GHO dimension type, in a deterministic order. Useful as injectable context when building queries with who_query_indicator_data. Use who_list_dimensions to discover valid dimension type codes. Narrowed to one parent code; limit, offset, and parentCode must all be present in the URI. A filter that matches nothing returns an empty page for a valid dimension; an unknown dimension returns not-found.

who-dimension-values-by-parent URI template
who://dimension/{dimensionCode}/values{?limit,offset,parentCode}

MIME type: application/json

io.modelcontextprotocol/skills

Advertised by the server during the last successful anonymous check.

io.modelcontextprotocol/skills URI template
skill://{+path}

90-day uptime

A lightweight connection check about every six hours, sampled on hosts with many listings. It shows the server answered, not that its tools work.

Too few checks for a percentage yet (1 of 1 answered).

  1. 2026-11-07: 1 of 1 checks answered

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
626 ms
95th percentile latency
626 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 626 ms · metadata changed · 6 tool(s), 1 resource(s), 5 resource template(s), 0 prompt(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http who-gho-mcp-server-caseyjhand https://who-gho.caseyjhand.com/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add who-gho-mcp-server-caseyjhand --url https://who-gho.caseyjhand.com/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable who-gho-mcp-server-caseyjhand in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "who-gho-mcp-server-caseyjhand": {
      "url": "https://who-gho.caseyjhand.com/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "who-gho-mcp-server-caseyjhand": {
      "type": "streamableHttp",
      "url": "https://who-gho.caseyjhand.com/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start who-gho-mcp-server-caseyjhand and inspect its tools.
VS Code configuration
{
  "servers": {
    "who-gho-mcp-server-caseyjhand": {
      "type": "http",
      "url": "https://who-gho.caseyjhand.com/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http who-gho-mcp-server-caseyjhand https://who-gho.caseyjhand.com/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://who-gho.caseyjhand.com/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "who-gho-mcp-server-caseyjhand": {
      "serverUrl": "https://who-gho.caseyjhand.com/mcp"
    }
  }
}

Let your agent find its tools

Find servers like who-gho-mcp-server from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.