Skip to main content
Glama

get-forecast

Retrieve a 7-day weather forecast for any city, including daily temperatures, precipitation, and sunrise/sunset times, using the MCP Weather Server.

Instructions

Get 7-day weather forecast for any city including daily temperatures, precipitation, and sunrise/sunset times

Input Schema

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

Implementation Reference

  • main.ts:356-406 (handler)
    Core implementation of the get-forecast tool logic: geocodes the input city using Open-Meteo geocoding API, fetches 7-day daily forecast data (max/min temp, precip, weather code, sunrise/sunset), processes and formats the data into a structured ProcessedForecastData object with human-readable strings, handles city not found errors.
    async function getForecastForCity(city: string): Promise<ProcessedForecastData | 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 7-day forecast data const forecastUrl = `${CONFIG.WEATHER_API}?latitude=${location.latitude}&longitude=${location.longitude}&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,weather_code,sunrise,sunset&timezone=auto`; const forecastResponse = await fetchWithRetry(forecastUrl); const forecastData: ExtendedWeatherResponse = await forecastResponse.json(); // Process and structure the forecast data const locationName = location.admin1 ? `${location.name}, ${location.admin1}, ${location.country}` : `${location.name}, ${location.country}`; const processedData: ProcessedForecastData = { location: { name: location.name, fullName: locationName, latitude: location.latitude, longitude: location.longitude, country: location.country, admin1: location.admin1 }, daily: forecastData.daily.time.map((date, index) => ({ date: date, formattedDate: formatDate(date), maxTemperature: forecastData.daily.temperature_2m_max[index], formattedMaxTemperature: formatTemperature(forecastData.daily.temperature_2m_max[index]), minTemperature: forecastData.daily.temperature_2m_min[index], formattedMinTemperature: formatTemperature(forecastData.daily.temperature_2m_min[index]), precipitation: forecastData.daily.precipitation_sum[index], formattedPrecipitation: formatPrecipitation(forecastData.daily.precipitation_sum[index]), weatherCode: forecastData.daily.weather_code[index], weatherDescription: getWeatherDescription(forecastData.daily.weather_code[index]), sunrise: forecastData.daily.sunrise[index], formattedSunrise: formatTime(forecastData.daily.sunrise[index]), sunset: forecastData.daily.sunset[index], formattedSunset: formatTime(forecastData.daily.sunset[index]) })), raw: forecastData }; return processedData; }
  • main.ts:535-586 (registration)
    MCP server tool registration for 'get-forecast': includes name, description, Zod input schema for city parameter, and async handler function that calls getForecastForCity, handles errors, and returns result as formatted JSON text content.
    server.tool( 'get-forecast', 'Get 7-day weather forecast for any city including daily temperatures, precipitation, and sunrise/sunset times', { 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 forecast information for (e.g., 'New York', 'London', 'Tokyo')") }, async({ city }) => { try { const result = await getForecastForCity(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('Forecast fetch error:', error); const errorMessage = error instanceof Error && error.message.includes('fetch') ? `❌ Unable to fetch forecast 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 validation: requires a non-empty city string up to 100 chars with 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 forecast information for (e.g., 'New York', 'London', 'Tokyo')") },
  • TypeScript interface defining the structured output of the processed forecast data, including location info, array of daily forecasts with formatted fields, and raw API response.
    interface ProcessedForecastData { location: { name: string; fullName: string; latitude: number; longitude: number; country: string; admin1?: string; }; daily: Array<{ date: string; formattedDate: string; maxTemperature: number; formattedMaxTemperature: string; minTemperature: number; formattedMinTemperature: string; precipitation: number; formattedPrecipitation: string; weatherCode: number; weatherDescription: string; sunrise: string; formattedSunrise: string; sunset: string; formattedSunset: string; }>; raw: ExtendedWeatherResponse; }
  • Utility function for robust API fetching with timeout (10s), retry logic (3 attempts on abort/5xx), used by getForecastForCity for geocoding and forecast requests.
    async function fetchWithRetry(url: string, options: RequestInit = {}, retries: number = CONFIG.MAX_RETRIES): Promise<Response> { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), CONFIG.REQUEST_TIMEOUT); try { const response = await fetch(url, { ...options, signal: controller.signal }); clearTimeout(timeoutId); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } return response; } catch (error) { clearTimeout(timeoutId); if (retries > 0 && (error instanceof Error && (error.name === 'AbortError' || error.message.includes('HTTP 5')))) { await delay(CONFIG.RETRY_DELAY); return fetchWithRetry(url, options, retries - 1); } throw error; } }

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