worldbank-mcp-server

v0.3.2 pre-1.0

Query 29,500+ World Bank development indicators for 200+ countries across 60+ years via MCP. STDIO or Streamable HTTP.

worldbank.caseyjhand.com/mcp
claude mcp add --transport http worldbank-mcp-server https://worldbank.caseyjhand.com/mcp
codex mcp add worldbank-mcp-server --url https://worldbank.caseyjhand.com/mcp
{
  "mcpServers": {
    "worldbank-mcp-server": {
      "url": "https://worldbank.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http worldbank-mcp-server https://worldbank.caseyjhand.com/mcp
{
  "mcpServers": {
    "worldbank-mcp-server": {
      "command": "bunx",
      "args": [
        "mcp-remote",
        "https://worldbank.caseyjhand.com/mcp"
      ]
    }
  }
}
{
  "mcpServers": {
    "worldbank-mcp-server": {
      "type": "http",
      "url": "https://worldbank.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://worldbank.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-07-28","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

9

worldbank_list_topics

open-world

Lists all 21 World Bank thematic topics (Economy & Growth, Health, Education, etc.) with descriptions. Use to browse the indicator space or find a topic_id for worldbank_search_indicators.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "worldbank_list_topics",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
view source ↗

worldbank_list_sources

open-world

Lists the 70+ World Bank data sources (datasets) such as World Development Indicators, IDS, and Doing Business. Returns source IDs and names for use as source_id in worldbank_search_indicators. Supports pagination.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "worldbank_list_sources",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "page": {
      "default": 1,
      "description": "Pagination page number (1-based).",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "per_page": {
      "description": "Results per page (default: server default, max: 100).",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    }
  },
  "required": [
    "page"
  ],
  "additionalProperties": false
}
view source ↗

worldbank_list_countries

open-world

Lists countries and regional aggregates with metadata: ISO codes, region, income level, capital, and coordinates. Filterable by region code (e.g. EAS, SSF, NAC) and income level (LIC, LMC, UMC, HIC). By default, excludes regional/income-group aggregate entries and returns individual countries only. Set include_aggregates=true to also see region, income group, and world aggregate entities.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "worldbank_list_countries",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "region": {
      "description": "Filter by World Bank region code. Valid codes: EAS (East Asia & Pacific), ECS (Europe & Central Asia), LCN (Latin America & Caribbean), MEA (Middle East & North Africa), NAC (North America), SAS (South Asia), SSF (Sub-Saharan Africa).",
      "type": "string"
    },
    "income_level": {
      "description": "Filter by income group code: LIC (Low income), LMC (Lower middle income), UMC (Upper middle income), HIC (High income).",
      "type": "string"
    },
    "include_aggregates": {
      "default": false,
      "description": "When true, includes regional, income-group, and world aggregate entries alongside individual countries. Default false (individual countries only).",
      "type": "boolean"
    },
    "page": {
      "default": 1,
      "description": "Pagination page number (1-based).",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "per_page": {
      "description": "Results per page (default: server default, max: 300).",
      "type": "integer",
      "minimum": 1,
      "maximum": 300
    }
  },
  "required": [
    "include_aggregates",
    "page"
  ],
  "additionalProperties": false
}
view source ↗

worldbank_get_country

open-world

Fetches full metadata for a specific country or aggregate entity: region, income level, capital, coordinates, and lending type. Accepts ISO2 codes (US, DE), ISO3 codes (USA, DEU), or World Bank aggregate codes (EAS, HIC, WLD).

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "worldbank_get_country",
    "arguments": {
      "country_code": "<country_code>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "country_code": {
      "type": "string",
      "minLength": 1,
      "description": "Country code. Accepts ISO2 (US), ISO3 (USA), or aggregate code (EAS, HIC, WLD). Use worldbank_list_countries to browse valid codes."
    }
  },
  "required": [
    "country_code"
  ],
  "additionalProperties": false
}
view source ↗

worldbank_search_indicators

open-world

Searches the 29,500+ World Bank indicator catalog by keyword, topic, or source. Returns indicator IDs and metadata for chaining into worldbank_get_data. At least one of query, topic_id, or source_id must be provided. A keyword query matches every term against indicator ID, name, and description, in any word order, across the whole catalog or the whole selected topic or source; punctuation in the query is ignored. Exact ID or name matches rank first, then whole-phrase matches, then ID/name matches, then description-only matches. Each indicator ID appears once, even where the catalog publishes it under two sources. Use worldbank_list_topics for topic IDs, worldbank_list_sources for source IDs.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "worldbank_search_indicators",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "description": "Keyword search terms — an indicator name, ID, or any words from either (e.g. \"GDP per capita\", \"NY.GDP.MKTP.CD\", \"CO2 emissions\"). Every term must match; punctuation is ignored. At least one of query, topic_id, or source_id must be provided.",
      "type": "string"
    },
    "topic_id": {
      "description": "Filter by topic ID (e.g. \"1\" for Agriculture, \"3\" for Economy & Growth). Use worldbank_list_topics to browse valid IDs.",
      "type": "string"
    },
    "source_id": {
      "description": "Filter by data source ID (e.g. \"2\" for World Development Indicators). Use worldbank_list_sources to browse valid IDs.",
      "type": "string"
    },
    "page": {
      "default": 1,
      "description": "Pagination page number (1-based).",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "per_page": {
      "description": "Results per page (default: server default, max: 100).",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    }
  },
  "required": [
    "page"
  ],
  "additionalProperties": false
}
view source ↗

worldbank_get_indicator

open-world

Fetches complete metadata for a single World Bank indicator by its ID: name, description, source dataset, source organization, unit, and thematic topics. Use worldbank_search_indicators to discover indicator IDs if you only know the concept.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "worldbank_get_indicator",
    "arguments": {
      "indicator_id": "<indicator_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "indicator_id": {
      "type": "string",
      "minLength": 1,
      "description": "Indicator code (e.g. NY.GDP.PCAP.CD, SP.POP.TOTL). Use worldbank_search_indicators to find valid IDs."
    }
  },
  "required": [
    "indicator_id"
  ],
  "additionalProperties": false
}
view source ↗

worldbank_get_data

open-world

Queries World Bank indicator values for one or more countries across a time range. The primary data-access tool — use worldbank_search_indicators to find indicator_id values. Returns observations with null values when data is not available for a country×year cell (common for sparse series). Specify either date_range (historical analysis) or mrv (most recent N values), not both. For "all" countries, use pagination (per_page up to 1000) — the API returns several hundred entries per indicator.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "worldbank_get_data",
    "arguments": {
      "indicator_id": "<indicator_id>",
      "countries": "<countries>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "indicator_id": {
      "type": "string",
      "minLength": 1,
      "description": "Indicator code to query (e.g. NY.GDP.PCAP.CD, SP.POP.TOTL). Use worldbank_search_indicators to find valid IDs."
    },
    "countries": {
      "anyOf": [
        {
          "type": "string",
          "pattern": "[^\\s;]",
          "description": "A single country code or \"all\"."
        },
        {
          "minItems": 1,
          "type": "array",
          "items": {
            "type": "string",
            "description": "A country code."
          },
          "description": "An array of country codes."
        }
      ],
      "description": "Country codes. Accepts: ISO2 (US, CN), ISO3 (USA, CHN), regional aggregate codes (EAS, LCN, MEA, SAS, SSF, ECS, NAC), income group codes (HIC, UMC, LMC, LIC), world code (WLD), or \"all\" for every entry (use pagination). Pass a single string or an array of codes for multi-country queries. At least one code is required — an empty value is rejected rather than treated as \"all\"."
    },
    "date_range": {
      "description": "Time window to filter observations to. Accepts a whole year (`2020`), a quarter (`2020Q1`), or a month (`2020M03`), or a range of two periods of the same type separated by a colon, earliest first (`2010:2023`, `2020Q1:2021Q4`, `2020M01:2020M06`). A window and an observation match whenever the periods overlap, so a year window also selects the quarters and months inside it. A window covering no part of the series returns zero observations rather than the full series. Mutually exclusive with mrv.",
      "type": "string",
      "pattern": "^\\s*(?:\\d{4}(?::\\d{4})?|\\d{4}[Qq][1-4](?::\\d{4}[Qq][1-4])?|\\d{4}[Mm](?:0[1-9]|1[0-2])(?::\\d{4}[Mm](?:0[1-9]|1[0-2]))?)?\\s*$"
    },
    "mrv": {
      "description": "Return the N most recent available values per country (1–100), clamped upstream to the length of the series. Rows are mrv × countries, so page through them with per_page. Mutually exclusive with date_range.",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "page": {
      "default": 1,
      "description": "Pagination page number (1-based).",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "per_page": {
      "description": "Results per page (default: server default, max: 1000). Use higher values for \"all\" country queries.",
      "type": "integer",
      "minimum": 1,
      "maximum": 1000
    }
  },
  "required": [
    "indicator_id",
    "countries",
    "page"
  ],
  "additionalProperties": false
}
view source ↗

worldbank_get_poverty

open-world

Queries poverty and inequality estimates from the World Bank Poverty and Inequality Platform (PIP) for one or more countries. Returns the poverty headcount ratio, poverty gap, and poverty severity at any poverty line, plus mean and median welfare and population. This is also the tool for inequality and distribution questions — survey-based rows carry the Gini coefficient, mean log deviation, polarization, and the ten decile income/consumption shares, because PIP returns poverty and inequality in the same row. PIP is a separate dataset from the WDI series worldbank_get_data reads: it measures welfare in PPP dollars per person per day and covers individual economies only, so regional and income-group aggregate codes are not accepted. Every row reports how it was produced. estimationType "survey" rows carry the full inequality block; "interpolation", "extrapolation", and "CMD estimation" rows are gap-filled estimates for years no survey covers, and their gini, mld, polarization, and decileShares are null — a documented gap in the source data, not an error.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "worldbank_get_poverty",
    "arguments": {
      "countries": "<countries>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "countries": {
      "anyOf": [
        {
          "type": "string",
          "pattern": "[^\\s;,]",
          "description": "A single country code, a comma-separated list, or \"all\"."
        },
        {
          "minItems": 1,
          "type": "array",
          "items": {
            "type": "string",
            "description": "A country code."
          },
          "description": "An array of country codes."
        }
      ],
      "description": "Country codes. PIP identifies economies by ISO3 code (IND, USA, BRA); \"all\" returns every economy it covers. Pass a single code, an array, or one string separated by commas or semicolons. Regional, income-group, and world aggregate codes (WLD, SSF, HIC) are not served by this dataset — query the individual economies instead."
    },
    "year": {
      "description": "Reporting year to return. A four-digit year (2022), \"all\" for the full history, or \"MRV\" for the most recent year available. Omitted behaves as \"all\". PIP coverage starts in 1963 and runs to the current year.",
      "type": "string",
      "pattern": "^\\s*(?:\\d{4}|all|MRV)?\\s*$"
    },
    "poverty_line": {
      "description": "Poverty line in PPP dollars per person per day — any threshold, not only the published ones. Omitted uses the international poverty line of the PIP release currently served, so the applied value is echoed back on every row as povertyLine rather than assumed here. The poverty line does not affect the inequality fields, which describe the whole distribution.",
      "type": "number",
      "minimum": 0,
      "maximum": 2700
    },
    "welfare_type": {
      "description": "Restrict results to one welfare measure. Surveys measure either income or consumption and the two are not directly comparable, so a cross-country comparison is safer pinned to one. Omitted returns whichever each economy publishes, and both where an economy publishes both — thirty-five do, and those return two rows per year.",
      "anyOf": [
        {
          "type": "string",
          "const": ""
        },
        {
          "type": "string",
          "enum": [
            "income",
            "consumption"
          ],
          "description": "Restrict to surveys measuring income, or to those measuring consumption."
        }
      ]
    },
    "reporting_level": {
      "description": "Restrict results to one reporting level. Most economies publish a national figure only; ten publish a split and return an extra row per year for it, China with all three levels and the rest pairing national with either urban or rural. Every row states its own reportingLevel.",
      "anyOf": [
        {
          "type": "string",
          "const": ""
        },
        {
          "type": "string",
          "enum": [
            "national",
            "urban",
            "rural"
          ],
          "description": "Restrict to the national, urban, or rural estimate."
        }
      ]
    },
    "fill_gaps": {
      "default": true,
      "description": "When true (the default), any year the surveys do not cover falls back to PIP's own estimate for it instead of being left out — so a single-year query still answers, and a full-history query returns a row per year rather than only the survey years. Those fallback rows carry no inequality data. Set false to return survey-derived rows only, accepting an empty result for years no survey covers.",
      "type": "boolean"
    },
    "page": {
      "default": 1,
      "description": "Pagination page number (1-based).",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "per_page": {
      "description": "Results per page (default: server default, max: 1000). \"all\" countries across \"all\" years runs to a few thousand rows.",
      "type": "integer",
      "minimum": 1,
      "maximum": 1000
    }
  },
  "required": [
    "countries",
    "fill_gaps",
    "page"
  ],
  "additionalProperties": false
}
view source ↗

worldbank_search_projects

open-world

Searches the World Bank lending portfolio — the individual loans, credits, and grants the Bank finances — by free text, country, region, status, and board approval date. Returns the project ID, name, borrowing country, region, status, board approval and closing dates, total commitment in USD, financing instrument, major sectors, and a link to the project page. This is the operations catalogue, not the statistics catalogue: use it for "what is the World Bank funding in Kenya", "which climate adaptation projects are active", or "how much was committed to education in South Asia since 2020". For development statistics and time series, use worldbank_search_indicators and worldbank_get_data instead. Countries are identified by ISO2 code here (BR, IN, ZA), which is the one place this server departs from the ISO3 codes its other tools take — worldbank_get_country reports a country's iso2 field for either form, and multi-country operations carry a World Bank regional code such as 3A instead. Every filter is an exact match upstream and combines with the others by AND, so a narrow search can legitimately return nothing; when it does, the response says whether the country codes matched anything on their own.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "worldbank_search_projects",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "description": "Free-text search across project names, abstracts, and objectives. Every word must appear, so extra words narrow the result. Omit to browse the portfolio by filter alone, newest board approvals first.",
      "type": "string"
    },
    "countries": {
      "description": "Borrowing countries, by the two-character code this API keys on: ISO2 for an economy (BR), or a World Bank regional code for a multi-country operation (3A for Africa, 4E for East Asia and Pacific). Several codes are combined as OR — a project matching any of them is returned. Omit for every country.",
      "anyOf": [
        {
          "type": "string",
          "description": "A single two-character code, or a comma- or semicolon-separated list of them."
        },
        {
          "type": "array",
          "items": {
            "type": "string",
            "description": "A two-character country code."
          },
          "description": "An array of two-character codes."
        }
      ]
    },
    "status": {
      "description": "Lifecycle stages to include, combined as OR. \"Active\" is under implementation, \"Pipeline\" is approved but not yet effective, \"Closed\" has finished disbursing, and \"Dropped\" was abandoned before approval. Most of the portfolio is closed, so omitting this returns mostly historical operations.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "Active",
          "Closed",
          "Dropped",
          "Pipeline"
        ]
      }
    },
    "region": {
      "description": "World Bank operational regions to include, combined as OR. These are the lending regions the portfolio is organized by, not the WDI aggregate codes worldbank_get_data accepts.",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "East Asia and Pacific",
          "Europe and Central Asia",
          "Latin America and Caribbean",
          "Middle East, North Africa, Afghanistan, and Pakistan",
          "South Asia",
          "Eastern and Southern Africa",
          "Western and Central Africa",
          "Africa",
          "Other"
        ]
      }
    },
    "approved_from": {
      "description": "Earliest board approval date, as YYYY-MM-DD and inclusive. Board approval is the date the Bank committed to the operation; pipeline projects carry a scheduled date in the future.",
      "anyOf": [
        {
          "type": "string",
          "const": ""
        },
        {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
          "description": "Earliest board approval date to include."
        }
      ]
    },
    "approved_to": {
      "description": "Latest board approval date, as YYYY-MM-DD and inclusive.",
      "anyOf": [
        {
          "type": "string",
          "const": ""
        },
        {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
          "description": "Latest board approval date to include."
        }
      ]
    },
    "include_abstract": {
      "default": false,
      "description": "Include each project's abstract. Abstracts run long — a median of roughly 1,200 characters — so a full page of them roughly doubles the response; leave this off while narrowing a search and turn it on once the result set is small enough to read. Projects that publish no abstract report null either way, which appliedFilters.includeAbstract distinguishes.",
      "type": "boolean"
    },
    "page": {
      "default": 1,
      "description": "Pagination page number (1-based).",
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
    },
    "per_page": {
      "description": "Results per page (default: server default, max: 1000, which is also the most the API will return for one request).",
      "type": "integer",
      "minimum": 1,
      "maximum": 1000
    }
  },
  "required": [
    "include_abstract",
    "page"
  ],
  "additionalProperties": false
}
view source ↗

Resources

2

Indicator metadata for a known World Bank indicator ID: name, description, source, and thematic topics. Stable reference URI — use worldbank_search_indicators to discover indicator IDs.

uri worldbank://indicator/{indicatorId} mime application/json

Country metadata for a known country or aggregate code: ISO codes, region, income level, capital, and coordinates. Accepts ISO2 (US), ISO3 (USA), or World Bank aggregate codes (EAS, HIC). Use worldbank_list_countries to browse valid codes.

uri worldbank://country/{countryCode} mime application/json