Skip to main content
Glama

get-air-quality

Retrieve air pollution data for any city, including European Air Quality Index and pollutant levels, to assess environmental conditions.

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:598-639 (handler)
    The MCP tool handler function. Calls getAirQualityForCity, handles result or error, and returns formatted MCP content (text error or JSON data).
    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 } ] }; } }
  • Core helper function implementing the air quality tool logic: geocodes city, fetches current and hourly European AQI data from APIs, processes into structured format with location, current, hourly, and raw 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:588-640 (registration)
    Registration of the 'get-air-quality' tool on the MCP server, specifying name, description, input schema, and handler.
    // Register the air quality tool 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 } ] }; } } );
  • Input schema using Zod for validating the 'city' parameter.
    { 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 tool.
    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; }

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