
Wraps the World Bank Open Data API with seven tools that let Claude search and query 29,500+ development indicators across 200+ countries and 60+ years of records. You can list topics and sources, search indicators by keyword or theme, pull country metadata with income levels and coordinates, and fetch time series data with flexible filtering by date range or most recent values. The data retrieval tool handles single countries, regional aggregates, or all entities at once, and explicitly surfaces null observations so you see gaps in the data. Built on the mcp-ts-core framework and available via stdio, streamable HTTP, or a public hosted endpoint at worldbank.caseyjhand.com/mcp. Reach for this when you need Claude to analyze economic indicators, compare development metrics across regions, or answer questions that require official World Bank statistics.
claude mcp add --transport http worldbank https://worldbank.caseyjhand.com/mcpRun in your terminal. Add --scope user to make it available in every project.
Review the command, arguments, and environment values before installing — MCP servers run with your local permissions.
Verified live against the running server on Jun 10, 2026.
worldbank_list_topicsLists 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.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.
No parameters — call it with no arguments.
worldbank_list_sourcesLists 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.2 paramsLists 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.
pageintegerper_pageintegerworldbank_list_countriesLists 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 indi...5 paramsLists 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 indi...
include_aggregatesbooleanincome_levelstringpageintegerper_pageintegerregionstringworldbank_get_countryFetches 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).1 paramsFetches 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).
country_code*stringworldbank_search_indicatorsSearches 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. When combined with topic_id or source_id, keyword filtering...5 paramsSearches 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. When combined with topic_id or source_id, keyword filtering...
pageintegerper_pageintegerquerystringsource_idstringtopic_idstringworldbank_get_indicatorFetches 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.1 paramsFetches 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.
indicator_id*stringworldbank_get_dataQueries 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 s...6 paramsQueries 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 s...
countries*valuedate_rangestringindicator_id*stringmrvintegerpageintegerper_pageintegerQuery 29,500+ World Bank development indicators for 200+ countries across 60+ years via MCP. STDIO or Streamable HTTP.
9 tools for browsing and querying the World Bank Open Data API:
| Tool | Description |
|---|---|
worldbank_list_topics | List all 21 World Bank thematic topics with descriptions |
worldbank_list_sources | List 70+ World Bank data sources (datasets) with pagination |
worldbank_list_countries | List countries and regional aggregates with ISO codes, region, income level, and coordinates |
worldbank_get_country | Fetch full metadata for a specific country or aggregate by ISO2, ISO3, or aggregate code |
worldbank_search_indicators | Search the 29,500+ indicator catalog by keyword, topic, or source |
worldbank_get_indicator | Fetch complete metadata for a single indicator: name, description, source, unit, and topics |
worldbank_get_data | Query indicator values for one or more countries across a time range or most-recent N values |
worldbank_get_poverty | Poverty headcount, gap, and severity at any poverty line, plus the Gini coefficient and decile shares, from the Poverty and Inequality Platform |
worldbank_search_projects | Search the World Bank lending portfolio by text, country, region, status, and board approval date |
worldbank_list_topicsList all 21 World Bank thematic topic categories.
worldbank_search_indicatorsworldbank_list_sourcesList the 70+ World Bank data sources (datasets).
worldbank_search_indicators by dataset origin (e.g. "2" for World Development Indicators, "6" for IDS)worldbank_list_countriesList countries and regional aggregates with metadata.
include_aggregates=true to include regional, income-group, and world aggregate entitiesworldbank_get_countryFetch full metadata for a single country or aggregate entity.
worldbank_search_indicatorsSearch the 29,500+ World Bank indicator catalog.
searchterm parameter does not filter, so keyword matching runs locally over the full catalog (or the full selected topic/source): every term must appear in the indicator ID, name, or description, in any word order, with punctuation ignoredGDP (current US$)) or ID (NY.GDP.MKTP.CD) returns it as the top hitworldbank_get_indicator resolves to the same oneNY.GDP.PCAP.CD, SP.POP.TOTL) feed directly into worldbank_get_dataquery, topic_id, source_id) alongside the resultsworldbank_get_indicatorFetch complete metadata for a known indicator ID.
worldbank_get_dataQuery indicator values for countries across time. The primary data-access tool.
"all" for every entry. At least one code is required — an empty value is rejected rather than read as "all"date_range for a period or range — annual (2020, 2010:2023), quarterly (2020Q1:2021Q4), or monthly (2020M01:2020M06) — or mrv for the N most recent available values (1–100). Mutually exclusive.date_range the API can't apply is enforced locally over the whole series, so observations outside the requested window are never returned as matchesnull values when data is not available for a country×year cell — common for sparse seriesnullCount per page to surface data sparsityisAggregate flag distinguishes all 78 regional, income-group, and lending-group aggregates from individual countriesmrv, page and page sizeworldbank_get_povertyPoverty and inequality estimates from the World Bank Poverty and Inequality Platform (PIP) — a separate dataset from the WDI series the other tools read.
poverty_line to use the international line of the PIP release currently served, which is echoed back on every rowestimationType: "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 gap in the source data, not an error. surveyYear, surveyAcronym, and isInterpolated sit alongside themfill_gaps defaults to true, so years the surveys don't reach come back as PIP's own estimate rather than as an empty result or a hole in the series. Survey rows win wherever one exists, so a single-year batch can carry real distributions for some economies and labelled estimates for others, and a full-history query returns a row per year with the real distribution on the survey years. Set fill_gaps=false for survey-derived rows onlywelfare_type pins results to income or consumption surveys, which are not directly comparable; thirty-five economies publish both and return a row for eachreporting_level narrows to one, and every row states its ownyear accepts a four-digit year, "all" for the full history, or "MRV" for the most recent available. Coverage starts in 1963worldbank_search_projectsThe World Bank lending portfolio — the individual loans, credits, and grants the Bank finances — rather than the statistics the other tools read. A third upstream API, on its own host, with its own envelope and conventions.
query across project names, abstracts, and objectives, combined with exact filters on countries, region, status, and a board-approval date window. Every filter is an AND, and every multi-value filter is an OR within itselfBR, IN, ZA) — the one place this server departs from the ISO3 codes its other tools take, because the Projects API keys on ISO2. Multi-country operations carry a World Bank regional code instead (3A, 4E), two characters like the rest. An ISO3 code is rejected at the schema with a message naming the difference, rather than being passed upstream where it would come back as a silent zero-hit. worldbank_get_country reports a country's iso2 field for either formstatus is a closed set (Active, Closed, Dropped, Pipeline) and region is the nine World Bank operational regions, both enforced by the schema — a typo in either can't reach upstream and read back as "no results"include_abstract is off by default. Abstracts run to a median of roughly 1,200 characters and are published for about half the portfolio, so a full page of them roughly doubles the response — turn it on once the result set is small enough to read| Type | Name | Description |
|---|---|---|
| Resource | worldbank://indicator/{indicatorId} | Indicator metadata by ID — name, description, source, unit, and topics |
| Resource | worldbank://country/{countryCode} | Country metadata by ISO2, ISO3, or aggregate code — region, income level, capital, coordinates |
Both resources return a structured not-found error with a recovery hint for an unknown ID or code. An upstream outage, timeout, or 5xx keeps its own classification, so a transient failure is distinguishable from a bad identifier.
Built on @cyanheads/mcp-ts-core:
none, jwt, oauth)in-memory, filesystem, Supabase, Cloudflare KV/R2/D1World Bank-specific:
null observations and nullCount surfaced rather than silently droppedisAggregate flag on every country/data row to distinguish individual countries from aggregate entitiesAgent-friendly output:
worldbank_search_indicators names worldbank_list_topics for topic IDs, worldbank_get_data names worldbank_search_indicators for indicator discoveryreason codes and actionable recovery hints on every toolpage, pages, total) across all list/search/data toolsAdd the following to your MCP client configuration file.
{
"mcpServers": {
"worldbank-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/worldbank-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"worldbank-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/worldbank-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
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
git clone https://github.com/cyanheads/worldbank-mcp-server.git
cd worldbank-mcp-server
bun install
All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Environment variables:
| Variable | Description | Default |
|---|---|---|
MCP_TRANSPORT_TYPE | Transport: stdio or http | stdio |
MCP_HTTP_PORT | HTTP server port | 3010 |
MCP_HTTP_HOST | HTTP server hostname | 127.0.0.1 |
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_SESSION_MODE | HTTP session handling: stateful, stateless, or auto. This server holds no per-session state; .env.example and the Docker image both set stateless | auto (resolves to stateful) |
MCP_LOG_LEVEL | Log level (debug, info, warning, error) | info |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1 | in-memory |
OTEL_ENABLED | Enable OpenTelemetry | false |
OTEL_EXPORTER_OTLP_ENDPOINT | OTLP exporter endpoint | none |
WORLDBANK_API_BASE_URL | World Bank Indicators API base URL override | https://api.worldbank.org/v2 |
WORLDBANK_PIP_BASE_URL | Poverty and Inequality Platform API base URL override | https://api.worldbank.org/pip/v1 |
WORLDBANK_PROJECTS_BASE_URL | Projects API base URL override | https://search.worldbank.org/api/v3 |
WORLDBANK_DEFAULT_PER_PAGE | Default page size for list/search/data operations | 50 |
WORLDBANK_CATALOG_CACHE_TTL_MS | Lifetime of the in-process reference caches — the indicator catalog behind keyword-only search and the aggregate-code set behind isAggregate; 0 disables both | 3600000 |
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
| Directory | Purpose |
|---|---|
src/mcp-server/tools | Tool definitions (*.tool.ts). Nine tools covering topics, sources, countries, indicators, data, poverty, and projects. |
src/mcp-server/resources | Resource definitions. Indicator and country metadata resources. |
src/services/worldbank | World Bank Indicators API service layer — API client and domain types. |
src/services/pip | Poverty and Inequality Platform API service layer — separate client and domain types. |
src/services/projects | Projects API service layer — separate client and domain types. |
src/config | Server-specific environment variable parsing and validation with Zod. |
tests/ | Unit and integration tests, mirroring the src/ structure. |
See CLAUDE.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for logging, ctx.state for storagecreateApp() arraysIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
MCP_LOG_LEVELdefault: infoMinimum log level for output: 'debug', 'info', 'notice', 'warning', 'error'.
WORLDBANK_API_BASE_URLdefault: https://api.worldbank.org/v2World Bank API base URL override.
WORLDBANK_DEFAULT_PER_PAGEdefault: 50Default page size for list, search, and data operations.
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_AUTH_MODEdefault: noneAuthentication mode: 'none', 'jwt', or 'oauth'.