Query 29,500+ World Bank development indicators for 200+ countries across 60+ years.
Query 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, 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 |
| 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, ECS, LCN, MEA, NAC, SAS, SSF) and income level (LIC, LMC, UMC, HIC); an invalid code is a typed invalid_filter errorinclude_aggregates=true adds regional, income-group, and world aggregate entries, distinguished by 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 is required; a topic and a source together narrow to indicators in bothquery, topic_id, and source_id; paginated up to 100 per pageworldbank_get_indicator tool., _, or - — all, a list, or any other character is rejectedindicator_not_found error pointing to worldbank_search_indicatorsworldbank_get_data toolWLD, or all alone for every entry; an empty value is rejected rather than read as alldate_range (a year, quarter, or month, or a colon-separated range of the same period type, earliest first) and mrv (1–100 most recent values) are mutually exclusive; a reversed range or all mixed with codes is rejected before any requestvalue: null; nullCount per page surfaces sparsity, and isAggregate distinguishes aggregates from individual countriessourceScoped, naming the source and the applied dimension_value (a release, classification, sector, or counterpart area)appliedFiltersworldbank_get_poverty toolpoverty_line (defaults to the international line of the applied PPP vintage); the same row carries the Gini coefficient, mean log deviation, polarization, and ten decile sharesestimationType: "survey" rows carry the full inequality block; interpolation/extrapolation/CMD estimation rows are gap-filled and null out gini, mld, polarization, and decileShares — fill_gaps (default true) controls whether gap-filled years are returned at allwelfare_type (income/consumption) and reporting_level (national/urban/rural) narrow results; ppp_version picks the PPP vintage, defaulting to the newestyear accepts a four-digit year, all, or MRV; coverage starts in 1963per_page, since PIP itself has no paginationworldbank_search_projects toolquery across project names, abstracts, and objectives, combined by AND with exact filters on countries, region (World Bank operational regions), status (Active, Closed, Dropped, Pipeline), and a board-approval date window (approved_from/approved_to, real calendar days, earliest first)BR, IN, ZA) or a two-character World Bank regional code (3A, 4E) — the one place this server departs from the ISO3 codes its other tools take; an ISO3 code is rejected as invalid_country_code rather than silently returning zero hitsinclude_abstract (off by default) always returns each abstract whole, capping a page at 8 projects instead of 80 to keep responses within ~50 KBworldbank://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 |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1 | in-memory |
OTEL_ENABLED | Enable OpenTelemetry | false |
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_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 and source-scoped country codes, each source-scoped dataset's concept/country/period/dimension listings, and the PIP versions listing behind ppp_version; 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.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y @cyanheads/worldbank-mcp-serverMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-cyanheads-worldbank-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/worldbank-mcp-server"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceio.github.cyanheads/worldbank-mcp-server works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.