
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.
World Bank Open Data across three separate upstream APIs — development indicators, poverty and inequality estimates, and the Bank's lending portfolio. Search the 29,500+ indicator catalog, query country-level time series, pull poverty and inequality metrics from the Poverty and Inequality Platform, and search active and historical lending projects from any MCP client. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
| 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, lending type, and coordinates, filterable by region, income level, and lending type |
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, the most recent N periods, or each country's latest N non-empty values, annually, quarterly, or monthly |
worldbank_get_poverty | Poverty headcount, gap, and severity at any poverty line for economies and PIP's regional, income-group, and lending-group aggregates, 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, financing window, and board approval date |
| Resource | Description |
|---|---|
worldbank://indicator/{indicatorId} | Indicator metadata by ID — name, description, source, unit, and topics |
worldbank://country/{countryCode} | Country metadata by ISO2, ISO3, or aggregate code — region, income level, capital, coordinates |
worldbank_list_topics tool1 Agriculture, 3 Economy & Growth) feed topic_id on worldbank_search_indicatorsworldbank_list_sources tool2 for World Development Indicators) feed source_id on worldbank_search_indicatorsworldbank_list_countries toolEAS, SSF, … plus membership groupings such as AFE, EUU, LDC), income level (LIC, LMC, UMC, HIC), and lending type (IDX, IBD, IDB, LNX), combined by AND; up to 150 per page (~50 KB)invalid_filter errorinclude_aggregates=true adds regional, income-group, and world aggregates, flagged isAggregateworldbank_get_country toolUS), ISO3 (USA), or World Bank aggregate code (EAS, HIC, WLD) — all or a list is rejected as multiple_countriescountry_not_found error with a recovery hint pointing to worldbank_list_countriesworldbank_search_indicators toolquery, topic_id, or source_id; every keyword term must match the indicator ID, name, or description, in any order; up to 100 per pageSP.DYN.LE00.IN ahead of SP.DYN.LE00.FE.IN)worldbank_get_indicator returns the wholeworldbank_get_indicator tool., _, or - — all, a list, or any other character is rejectedindicator_not_found error pointing to worldbank_search_indicatorsworldbank_get_data toolcountries as ISO2, ISO3, aggregate codes, WLD, or all alone; at most one of date_range (a year, quarter, or month, or a range of one type), mrv (the latest N periods across the countries), or mrnev (each country's own latest N values — Eritrea's GDP per capita at 2011, where mrv gives 2025 and null); frequency (annual, quarterly, monthly) picks the period form on series that publish several (CPTOTSAXN for Kenya, monthly, mrv: 3 → 2026M07–M05); up to 200 observations a page (~50 KB)isAggregate, and value: null for a missing cell, with nullCount per page and lastUpdated, the source's data vintage; every date_range, mrv, and mrnev read is checked for another query's cached answer and re-read once, and one that fails twice is an upstream_inconsistent error rather than a served resultsourceScoped with the release, classification, sector, or counterpart area applied (dimension_value)worldbank_get_poverty toolAFG), plus PIP's aggregates: WLD, regions (SSF, AFE), income groups (LMIC/LMC), and lending groups (IDX, IDB, IBD, REST); year as a year, all, or MRV; any poverty_line, defaulting to the applied PPP vintage's international line; up to 70 estimates a page (~50 KB)estimationType separates survey rows from gap-filled ones, whose inequality fields are null, and isAggregate flags aggregate rowsfill_gaps (default true) includes gap-filled years; welfare_type and reporting_level narrow economy results, and ppp_version picks the PPP vintageworldbank_search_projects toolquery combined by AND with countries (ISO3, ISO2, or a World Bank regional code such as 3A), region, status, financial_type, and a board-approval window (approved_from/approved_to); up to 80 projects a page, newest approval firstcountryCodes chain into the other tools, a bad code or unparseable query is a typed invalid_country_code / invalid_query error, and an empty result names the filter that emptied itinclude_abstract (off by default) adds abstracts at 8 projects a page, each cut at 5,000 charactersworldbank://indicator/{indicatorId} resourceapplication/json — name, description, unit, source dataset, source organization, and topicsindicatorId comes from worldbank_search_indicators; an unknown ID returns a typed not-found error with a recovery hint, while an upstream outage or timeout keeps its own classification instead of reading as a bad IDworldbank://country/{countryCode} resourceapplication/json — ISO codes, region, income level, capital, coordinatesall or a list is rejected; an unknown code returns a typed not-found error, distinct from a transient upstream failureBuilt on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
World Bank-specific:
searchterm parameter doesn't filternull 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 tooltotalCount, currentPage, totalPages) across all list/search/data tools, with a notice naming the pages that exist when a request runs past the endA public instance is available at https://worldbank.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"worldbank-mcp-server": {
"type": "streamable-http",
"url": "https://worldbank.caseyjhand.com/mcp"
}
}
}
Add 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"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"worldbank-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/worldbank-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
git clone https://github.com/cyanheads/worldbank-mcp-server.git
cd worldbank-mcp-server
bun install
cp .env.example .env
# edit .env and set optional overrides
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. The server declares stateless in code — it holds no per-session state — and a value set here overrides that declaration | stateless |
MCP_LOG_LEVEL | Log level (debug, info, notice, warning, error) | info |
LOG_TOOL_FAILURE_PAYLOADS | Log each failed tool call's arguments and result, redacted by key name and capped at LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES (default 16384). A secret inside a free-form value is not redacted | false |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1 | in-memory |
OTEL_ENABLED | Enable OpenTelemetry | false |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT | Opt-in OTLP log export (e.g. http://localhost:4318/v1/logs); the base OTEL_EXPORTER_OTLP_ENDPOINT never enables it | 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; worldbank_get_data, worldbank_list_countries, worldbank_search_projects, and worldbank_get_poverty still cap it at their own page limits | 50 |
WORLDBANK_CATALOG_CACHE_TTL_MS | Lifetime of the in-process reference caches — the indicator catalog behind keyword-only search, the country index behind isAggregate, source-scoped country codes, and poverty ISO2 codes, each source-scoped dataset's concept/country/period/dimension listings, and PIP's versions listing behind ppp_version, regions table behind aggregate codes, and economy list behind model-estimate-only economies; 0 disables them all | 3600000 |
See .env.example for the full list of optional overrides.
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 # Lint, format, typecheck, and more
bun run test # Runs the test suite
docker build -t worldbank-mcp-server .
docker run --rm -p 3010:3010 worldbank-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/worldbank-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| 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 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'.