get_aqi_by_city

Pack: waqi · Connect: https://pipeworx.io/mcp (see Connect below for a single-pack URL)

No MCP client? Call it directly: GET https://gateway.pipeworx.io/v1/tools/get_aqi_by_city for the schema, then POST the same URL with its arguments for the data.

Latest AQI for a city from the World Air Quality Index Project station network. Accepts “city” or “city, country” (e.g. “Rome, Italy”). The matched station is checked against the requested place: a station that is not plausibly in it (the upstream resolves “Venice” to Dayton, Ohio) is never served; the call errors naming what it matched and listing candidates, and the response carries a place block stating requested vs matched. Every reading carries measured_at, station identity, data_age_hours and freshness. A reading older than 24h is never returned as current: a reporting station within 100 km is used (station_selection=fallback_fresher_station; skipped_stale_station says what was passed over) or the call errors naming the station and its age. Returns AQI value, dominant pollutant, individual pollutant readings (PM2.5, PM10, O3, NO2, SO2, CO), temperature/humidity/pressure, and station info.

Parameters

NameTypeRequiredDescription
citystringyesCity name, optionally qualified by country or region after a comma (e.g., “beijing”, “los-angeles”, “Rome, Italy”, “Paris, Texas”)

Example call

Arguments

{
  "city": "beijing"
}

curl

curl -X POST https://gateway.pipeworx.io/waqi/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_aqi_by_city","arguments":{"city":"beijing"}}}'

TypeScript (@pipeworx/sdk)

import { Pipeworx } from '@pipeworx/sdk';
const pipeworx = new Pipeworx();

const result = await pipeworx.call('get_aqi_by_city', {
  "city": "beijing"
});

More examples

{
  "city": "new-delhi"
}

Response shape

Always returns: aqi, category, dominant_pollutant, station, measurements, measured_at, timezone, attributions

FieldTypeDescription
aqinumber | nullAir Quality Index value
categorystring | nullAQI category (Good/Moderate/Unhealthy/Hazardous)
dominant_pollutantstring | nullPrimary pollutant causing poor air quality
stationobject
measurementsobject
measured_atstring | nullISO timestamp of measurement
timezonestring | nullTimezone of station
attributionsarrayData sources and attributions
data_age_hoursnumber | nullHours since measured_at; null when the station reported no usable time
freshnessstringstale = older than freshness_bound_hours. get_aqi_by_city / get_aqi_by_location never return stale; get_aqi_by_station can
freshness_bound_hoursnumberAge above which a reading counts as stale (24)
placeobjectRequested vs matched place. The matched station is verified to be plausibly in the requested place; a mismatch is refused, never served
rejected_upstream_matchobjectPresent when station_selection=resolved_by_search: the upstream station that was refused as the wrong place
station_selectionstringfallback_fresher_station when the first-matched station had stopped reporting; absent otherwise
skipped_stale_stationobjectThe stale station that was passed over (id, name, measured_at, data_age_hours); present with station_selection
Full JSON Schema
{
  "type": "object",
  "properties": {
    "aqi": {
      "type": [
        "number",
        "null"
      ],
      "description": "Air Quality Index value"
    },
    "category": {
      "type": [
        "string",
        "null"
      ],
      "description": "AQI category (Good/Moderate/Unhealthy/Hazardous)"
    },
    "dominant_pollutant": {
      "type": [
        "string",
        "null"
      ],
      "description": "Primary pollutant causing poor air quality"
    },
    "station": {
      "type": "object",
      "properties": {
        "id": {
          "type": [
            "number",
            "null"
          ],
          "description": "Station identifier"
        },
        "name": {
          "type": [
            "string",
            "null"
          ],
          "description": "Station/city name"
        },
        "latitude": {
          "type": [
            "number",
            "null"
          ],
          "description": "Station latitude"
        },
        "longitude": {
          "type": [
            "number",
            "null"
          ],
          "description": "Station longitude"
        },
        "url": {
          "type": [
            "string",
            "null"
          ],
          "description": "Station information URL"
        }
      }
    },
    "measurements": {
      "type": "object",
      "properties": {
        "pm25": {
          "type": [
            "number",
            "null"
          ],
          "description": "PM2.5 concentration in µg/m³"
        },
        "pm10": {
          "type": [
            "number",
            "null"
          ],
          "description": "PM10 concentration in µg/m³"
        },
        "o3": {
          "type": [
            "number",
            "null"
          ],
          "description": "Ozone concentration in µg/m³"
        },
        "no2": {
          "type": [
            "number",
            "null"
          ],
          "description": "Nitrogen dioxide in µg/m³"
        },
        "so2": {
          "type": [
            "number",
            "null"
          ],
          "description": "Sulfur dioxide in µg/m³"
        },
        "co": {
          "type": [
            "number",
            "null"
          ],
          "description": "Carbon monoxide in µg/m³"
        },
        "temperature_c": {
          "type": [
            "number",
            "null"
          ],
          "description": "Temperature in Celsius"
        },
        "humidity_pct": {
          "type": [
            "number",
            "null"
          ],
          "description": "Humidity percentage"
        },
        "pressure_hpa": {
          "type": [
            "number",
            "null"
          ],
          "description": "Atmospheric pressure in hPa"
        },
        "wind_speed": {
          "type": [
            "number",
            "null"
          ],
          "description": "Wind speed"
        }
      }
    },
    "measured_at": {
      "type": [
        "string",
        "null"
      ],
      "description": "ISO timestamp of measurement"
    },
    "timezone": {
      "type": [
        "string",
        "null"
      ],
      "description": "Timezone of station"
    },
    "attributions": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Attribution source name"
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Attribution source URL"
          }
        }
      },
      "description": "Data sources and attributions"
    },
    "data_age_hours": {
      "type": [
        "number",
        "null"
      ],
      "description": "Hours since measured_at; null when the station reported no usable time"
    },
    "freshness": {
      "type": "string",
      "enum": [
        "fresh",
        "stale",
        "unknown"
      ],
      "description": "stale = older than freshness_bound_hours. get_aqi_by_city / get_aqi_by_location never return stale; get_aqi_by_station can"
    },
    "freshness_bound_hours": {
      "type": "number",
      "description": "Age above which a reading counts as stale (24)"
    },
    "place": {
      "type": "object",
      "description": "Requested vs matched place. The matched station is verified to be plausibly in the requested place; a mismatch is refused, never served",
      "properties": {
        "requested": {
          "type": "string",
          "description": "The city string as passed"
        },
        "requested_city": {
          "type": "string",
          "description": "City part sent to the upstream"
        },
        "requested_qualifier": {
          "type": [
            "string",
            "null"
          ],
          "description": "Country/region qualifier (after a comma, or trailing words), checked against the station"
        },
        "matched_station": {
          "type": [
            "string",
            "null"
          ],
          "description": "Name of the station that answered"
        },
        "matched_station_id": {
          "type": [
            "number",
            "null"
          ],
          "description": "Station id of the station that answered"
        },
        "matched_latitude": {
          "type": [
            "number",
            "null"
          ],
          "description": "Latitude of the matched station"
        },
        "matched_longitude": {
          "type": [
            "number",
            "null"
          ],
          "description": "Longitude of the matched station"
        },
        "place_match": {
          "type": "string",
          "enum": [
            "name_match",
            "exonym_match",
            "fuzzy_name_match"
          ],
          "description": "How the station name matched the requested city"
        },
        "qualifier_checked": {
          "type": "boolean",
          "description": "Whether a qualifier was supplied and verified"
        }
      }
    },
    "rejected_upstream_match": {
      "type": "object",
      "description": "Present when station_selection=resolved_by_search: the upstream station that was refused as the wrong place",
      "properties": {
        "id": {
          "type": [
            "number",
            "null"
          ]
        },
        "name": {
          "type": [
            "string",
            "null"
          ]
        },
        "reason": {
          "type": "string"
        }
      }
    },
    "station_selection": {
      "type": "string",
      "description": "fallback_fresher_station when the first-matched station had stopped reporting; absent otherwise"
    },
    "skipped_stale_station": {
      "type": "object",
      "description": "The stale station that was passed over (id, name, measured_at, data_age_hours); present with station_selection"
    }
  },
  "required": [
    "aqi",
    "category",
    "dominant_pollutant",
    "station",
    "measurements",
    "measured_at",
    "timezone",
    "attributions"
  ]
}

Connect

Add this to your MCP client config — every tool in the catalog, including this one — or use one-click install buttons:

{
  "mcpServers": {
    "pipeworx": {
      "url": "https://pipeworx.io/mcp"
    }
  }
}
Connect to just the waqi pack
{
  "mcpServers": {
    "waqi": {
      "url": "https://gateway.pipeworx.io/waqi/mcp"
    }
  }
}

See Getting Started for client-specific install steps.

Regenerated from source · build October 31, 2026