Skip to main content
Glama

get-air-quality

Retrieve detailed air pollution data for any city, including the European Air Quality Index and pollutant levels. Use this tool to monitor air quality and make informed decisions.

Instructions

Get air pollution data for any city including European Air Quality Index and pollutant levels

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cityYesThe name of the city to get air quality information for (e.g., 'New York', 'London', 'Tokyo')

Implementation Reference

  • main.ts:408-472 (handler)
    The core handler function that resolves city coordinates via geocoding API, fetches current and hourly air quality data from Open-Meteo air quality API, processes it with AQI categorization, and returns structured data including location, current, hourly forecasts, and raw data.
    // Get air quality data async function getAirQualityForCity(city: string): Promise<ProcessedAirQualityData | string> { // Step 1: Get coordinates for the city const geoUrl = `${CONFIG.GEOCODING_API}?name=${encodeURIComponent(city)}&count=1&language=en&format=json`; const geoResponse = await fetchWithRetry(geoUrl); const geoData: GeocodingResponse = await geoResponse.json(); // Handle city not found if (!geoData.results || geoData.results.length === 0) { return `❌ Sorry, I couldn't find a city named "${city}". Please check the spelling and try again.`; } const location = geoData.results[0]; // Step 2: Get air quality data const aqiUrl = `${CONFIG.AIR_QUALITY_API}?latitude=${location.latitude}&longitude=${location.longitude}&hourly=european_aqi,european_aqi_pm2_5,european_aqi_pm10,european_aqi_no2,european_aqi_o3,european_aqi_so2&current=european_aqi,european_aqi_pm2_5,european_aqi_pm10,european_aqi_no2,european_aqi_o3,european_aqi_so2`; const aqiResponse = await fetchWithRetry(aqiUrl); const aqiData: AirQualityResponse = await aqiResponse.json(); // Process and structure the air quality data const locationName = location.admin1 ? `${location.name}, ${location.admin1}, ${location.country}` : `${location.name}, ${location.country}`; const current = aqiData.current; const aqiInfo = getAqiLevel(current.european_aqi); const processedData: ProcessedAirQualityData = { location: { name: location.name, fullName: locationName, latitude: location.latitude, longitude: location.longitude, country: location.country, admin1: location.admin1 }, current: { time: current.time, formattedTime: formatTime(current.time), europeanAqi: current.european_aqi, aqiLevel: aqiInfo.level, aqiDescription: aqiInfo.description, pm25: current.european_aqi_pm2_5, pm10: current.european_aqi_pm10, no2: current.european_aqi_no2, o3: current.european_aqi_o3, so2: current.european_aqi_so2 }, hourly: aqiData.hourly.time.slice(0, 24).map((time, index) => { const aqi = aqiData.hourly.european_aqi[index]; const aqiInfo = getAqiLevel(aqi); return { time: time, formattedTime: formatTime(time), europeanAqi: aqi, aqiLevel: aqiInfo.level, pm25: aqiData.hourly.european_aqi_pm2_5[index], pm10: aqiData.hourly.european_aqi_pm10[index], no2: aqiData.hourly.european_aqi_no2[index], o3: aqiData.hourly.european_aqi_o3[index], so2: aqiData.hourly.european_aqi_so2[index] }; }), raw: aqiData }; return processedData; }
  • main.ts:589-640 (registration)
    MCP tool registration for 'get-air-quality' including description, Zod input schema validation, and inline async handler that calls the main getAirQualityForCity function, handles errors, and formats response as text content with JSON data.
    server.tool( 'get-air-quality', 'Get air pollution data for any city including European Air Quality Index and pollutant levels', { city: z.string() .min(1, "City name cannot be empty") .max(100, "City name is too long") .describe("The name of the city to get air quality information for (e.g., 'New York', 'London', 'Tokyo')") }, async({ city }) => { try { const result = await getAirQualityForCity(city); // If it's an error string, return it as text if (typeof result === 'string') { return { content: [ { type: "text", text: result } ] }; } // If it's processed data, return it as JSON string for structured access return { content: [ { type: "text", text: JSON.stringify(result, null, 2) } ] }; } catch (error) { console.error('Air quality fetch error:', error); const errorMessage = error instanceof Error && error.message.includes('fetch') ? `❌ Unable to fetch air quality data. Please check your internet connection and try again.` : `❌ Error: ${error instanceof Error ? error.message : 'Unknown error'}`; return { content: [ { type: "text", text: errorMessage } ] }; } } );
  • Zod schema for input parameters, validating the 'city' string with length constraints and description.
    { city: z.string() .min(1, "City name cannot be empty") .max(100, "City name is too long") .describe("The name of the city to get air quality information for (e.g., 'New York', 'London', 'Tokyo')") },
  • TypeScript interface defining the structure of processed air quality data returned by the handler, including location details, current AQI with categorization, hourly data, and raw API response.
    interface ProcessedAirQualityData { location: { name: string; fullName: string; latitude: number; longitude: number; country: string; admin1?: string; }; current: { time: string; formattedTime: string; europeanAqi: number; aqiLevel: string; aqiDescription: string; pm25: number; pm10: number; no2: number; o3: number; so2: number; }; hourly: Array<{ time: string; formattedTime: string; europeanAqi: number; aqiLevel: string; pm25: number; pm10: number; no2: number; o3: number; so2: number; }>; raw: AirQualityResponse; }
  • Utility helper to map numerical European AQI value to human-readable level and description, used in processing current and hourly air quality data.
    function getAqiLevel(aqi: number): { level: string; description: string } { if (aqi <= 20) return { level: 'Good', description: 'Air quality is good' }; if (aqi <= 40) return { level: 'Fair', description: 'Air quality is acceptable' }; if (aqi <= 60) return { level: 'Moderate', description: 'Air quality is moderate' }; if (aqi <= 80) return { level: 'Poor', description: 'Air quality is poor' }; if (aqi <= 100) return { level: 'Very Poor', description: 'Air quality is very poor' }; return { level: 'Hazardous', description: 'Air quality is hazardous' }; }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dimonets/mcp-weather-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server