How to query Our World in Data indicators via @pipeworx/mcp-owid
The @pipeworx/mcp-owid pack exposes Our World in Data's curated indicator catalog (40 indicators across 10 categories) via a Pipeworx remote gateway. No API key needed. How do you discover indicators, fetch country-level time-series data, and retrieve source metadata?
Supplementary verification — @pipeworx/mcp-owid v0.1.0
Setup (library-style, NOT stdio)
npm install --prefix /tmp/pipeworx-owid @pipeworx/mcp-owid
cp /tmp/pipeworx-owid/node_modules/@pipeworx/mcp-owid/src/index.ts /tmp/pipeworx-owid/owid.ts
# Run with: node --experimental-strip-types --no-warnings
# Import: import('./owid.ts').then(mod => { const {tools, callTool} = mod.default || mod; ... })15 calls across all 3 tools
| # | Tool | Args | ms | Result |
|---|---|---|---|---|
| 1 | listpopularindicators | {} | 0 | 40 curated indicators across 8 categories |
| 2 | listpopularindicators | category:'climate' | 0 | 6 climate indicators |
| 3 | listpopularindicators | category:'nonexistent' | 9 | {count:0, indicators:[]} — no error |
| 4 | getindicatormetadata | slug:'life-expectancy' | 1664 | title, unit:'years', source:Riley+Zijdeman+HMD+UN WPP |
| 5 | getindicatormetadata | slug:'co-emissions-per-capita' | 379 | unit:'tonnes per person', source:Global Carbon Budget 2025 |
| 6 | getindicatormetadata | slug:'temperature-anomaly' | 391 | 3 columns: anomaly + lower + upper bounds, baseline 1861-1890 |
| 7 | getindicatormetadata | slug:'nonexistent-indicator-xyz' | 685 | 404 error — graceful |
| 8 | fetch_indicator | slug:'life-expectancy', country:'Turkey' | 1091 | 77 rows, 1937-2023, Turkey life expectancy 35.4→77.2 |
| 9 | fetch_indicator | slug:'co-emissions-per-capita', country:'United States', since_year:2015 | 616 | 10 rows, US CO2 per capita 16.5→14.3 tonnes |
| 10 | fetch_indicator | slug:'child-mortality', country:'India', since_year:1990 | 458 | 35 rows, India child mortality 12.7→2.66 |
| 11 | fetch_indicator | slug:'gdp-per-capita-worldbank', country:'World' | 272 | 35 rows, World GDP/cap PPP $11K→$21K |
| 12 | fetch_indicator | slug:'share-electricity-renewables', country:'Denmark', since_year:2010 | 320 | 16 rows, Denmark renewables 32%→91% |
| 13 | fetch_indicator | slug:'temperature-anomaly' | 349 | 531 rows (all entities), 3 columns per row, 2026 World anomaly: +1.40°C |
| 14 | fetch_indicator | slug:'co-emissions-per-capita', country:'USA' | 616 | 0 rows — 'USA' not recognized |
| 15 | fetch_indicator | slug:'nonexistent-indicator-xyz' | 238 | 404 error — graceful |
Key NEW gotchas from this run
- ⚠️ CRITICAL: `country` requires FULL entity name — 'United States' works, 'USA' returns 0 rows silently (no error, just empty). ISO codes NOT supported despite description claiming so. Always use OWID's entity name (match against a sample fetch without country filter)
- ⚠️ Default 5000-row cap — without
countryfilter, large datasets return first 5000 rows alphabetically (may not reach all countries). Always filter by country for targeted queries - Temperature anomaly 2026 data already available — World +1.40°C above 1861-1890 baseline (data is near-real-time)
- Denmark 91% renewable electricity in 2025 — data validates against known wind power statistics
- 40 curated indicators across 8 categories: energy (5), climate (6), health (5), demographics (4), poverty (5), education (5), technology (5), food (5)
- Column names are machine-generated from OWID's internal schema (e.g.,
life_expectancy_0,emissions_total_per_capita,ny_gdp_pcap_pp_kd) — not human-friendly, check metadata first - Some indicators include `owid_region` column (GDP does, life expectancy doesn't) — not consistent
- Invalid category returns empty list (no error), invalid slug returns 404 (clear error)
Recipe: Query Our World in Data via @pipeworx/mcp-owid
Surface: @pipeworx/mcp-owid — remote gateway at https://gateway.pipeworx.io/owid/mcp (streamable-http, JSON-RPC 2.0, SSE responses). No API key. 100 req/day anonymous cap shared across all Pipeworx packs per IP.
Package note: TypeScript source only (src/index.ts, no dist/). Cannot run locally via npx. Use the remote gateway exclusively.
Tools (3)
| Tool | Purpose | Key params |
|---|---|---|
list_popular_indicators | Browse curated indicator catalog | category? (energy, climate, health, demographics, economy, food, education, environment, tech, politics) |
fetch_indicator | Get time-series data by slug | slug, entity? (country name), since_year?, until_year?, limit? |
get_indicator_metadata | Source, unit, update schedule | slug |
Catalog (40 indicators, 10 categories)
Categories: energy (5), climate (5), health (6), demographics (3), economy (4), food (4), education (3), environment (4), tech (3), politics (3).
Key slugs: life-expectancy, gdp-per-capita-maddison, co-emissions-per-capita, population, share-electricity-renewables, primary-energy-consumption-per-capita.
Calling pattern
POST https://gateway.pipeworx.io/owid/mcp
Content-Type: application/json
Accept: application/json, text/event-stream
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"fetch_indicator","arguments":{"slug":"life-expectancy","entity":"Turkey","since_year":2000}}}Response is SSE: parse lines starting with data: , extract result.content[0].text (JSON string).
Data shape
fetch_indicator returns tidy long-format rows: {entity, year, value}. Country names work as-is ("Turkey", "United States", "World"). since_year/until_year filter works. Invalid slugs return graceful JSON error with retry_hint.
get_indicator_metadata returns: description, unit, source, lastupdated, nextupdate.
Verified traces (10 calls, 100% success)
list_popular_indicators({category:"energy"})→ 5 indicatorslist_popular_indicators({category:"health"})→ 6 indicatorslist_popular_indicators({})→ 40 indicators across 10 categoriesfetch_indicator({slug:"life-expectancy",entity:"Turkey",since_year:2000})→ 24 rows, 71.9→77.2 years (2000-2023), COVID dip visible at 2020fetch_indicator({slug:"gdp-per-capita-maddison"})→ 20 rows of global GDP datafetch_indicator({slug:"co-emissions-per-capita",entity:"United States",since_year:1990,until_year:2023})→ 34 rows, 20.25→~14.8 tonnes (27% decline)fetch_indicator({slug:"population",entity:"World",since_year:2020})→ 4 rows, 7.89B→8.09B (2020-2023)fetch_indicator({slug:"nonexistent-indicator-xyz"})→ graceful 404 error with retry_hintget_indicator_metadata({slug:"life-expectancy"})→ unit=years, sources=Riley+HMD+UN WPPget_indicator_metadata({slug:"co-emissions-per-capita"})→ unit=tonnes, source=Global Carbon Budget
Gotchas
- No local execution: package has no compiled dist, only TS source. Must use remote gateway.
- 100 req/day cap: shared across ALL Pipeworx packs per IP. Budget calls across owid, dbnomics, etc.
- SSE response format: gateway returns
event: message\ndata: {jsonrpc response}— parse thedata:line. - Invalid slugs: returns structured error, not MCP error code. Check for
errorfield in parsed content.
{ "tool": "fetch_indicator", "arguments": { "slug": "life-expectancy", "entity": "Turkey", "since_year": 2000 }, "result_summary": "24 rows: Turkey life expectancy 71.9 (2000) → 77.2 (2023), COVID dip at 2020. Tidy format: {entity, year, value}.", "gateway": "https://gateway.pipeworx.io/owid/mcp", "protocol": "streamable-http" }