getWeatherForecast
Retrieve precise weather forecasts for Swiss locations by specifying a location ID and optional date. Access detailed hourly and daily data with the LandiWetter MCP Server API.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Optional: The date for the forecast (yyyy-MM-dd). Defaults to today | |
| locationId | Yes | The location ID (e.g., G2661552) |
Implementation Reference
- src/index.js:83-151 (handler)Primary execution logic for the getWeatherForecast tool: validates date, fetches data via helper, formats detailed forecast output, handles errors.async ({ locationId, date }) => { try { // Use provided date or default to today const forecastDate = date ? new Date(date) : new Date(); // Validate date if (isNaN(forecastDate.getTime())) { return { content: [{ type: "text", text: "Invalid date format. Please use yyyy-MM-dd." }], isError: true }; } const forecast = await getWeatherForecast(locationId, forecastDate); // Handle error if forecast data is incomplete if (!forecast || !forecast.datum) { console.error('Invalid forecast data:', forecast); return { content: [{ type: "text", text: "Received invalid forecast data from API." }], isError: true }; } // Format the response nicely using the actual structure let formattedForecast = `Weather Forecast for date ${forecast.datum}:\n\n`; // Add general weather overview for the whole day if (forecast.ganzertag) { const dayData = forecast.ganzertag; formattedForecast += `### Daily Overview\n`; formattedForecast += `Temperature: ${dayData.uebersicht.mintemp} to ${dayData.uebersicht.maxtemp}\n`; formattedForecast += `Precipitation: ${dayData.niederschlag.menge} (Probability: ${dayData.niederschlag.wahrscheinlichkeit})\n`; formattedForecast += `Cloud coverage: ${dayData.niederschlag.wolken}\n`; formattedForecast += `Wind: ${dayData.wind.geschwindigkeit} from ${dayData.wind.richtung}\n`; formattedForecast += `Sunshine duration: ${dayData.sonne.dauer}\n\n`; } // Add time sections for detailed forecast if (forecast.abschnitte && forecast.abschnitte.length > 0) { formattedForecast += `### Hourly Forecast\n`; forecast.abschnitte.forEach(section => { formattedForecast += `\n${section.zeitvon} - ${section.zeitbis}:\n`; formattedForecast += `Temperature: ${section.uebersicht.mintemp} to ${section.uebersicht.maxtemp}\n`; formattedForecast += `Precipitation: ${section.niederschlag.menge} (Probability: ${section.niederschlag.wahrscheinlichkeit})\n`; formattedForecast += `Wind: ${section.wind.geschwindigkeit} from ${section.wind.richtung}\n`; }); } // Add general weather situation and outlook if available if (forecast.allgemeineLage) { formattedForecast += `\n### General Weather Situation\n${forecast.allgemeineLage}\n`; } if (forecast.aussichten) { formattedForecast += `\n### Outlook\n${forecast.aussichten}\n`; } return { content: [{ type: "text", text: formattedForecast }] }; } catch (error) { return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true }; } }
- src/index.js:33-45 (helper)Core helper function that constructs the API URL using locationId and formatted date, fetches forecast data from LandiWetter API via axios, returns raw data or throws error.async function getWeatherForecast(locationId, date) { try { const formattedDate = formatDate(date); const url = `https://www.landi.ch/weather/api/lokalprognose/de/${formattedDate}/${locationId}`; console.error('Weather API URL:', url); const response = await axios.get(url); console.error('Weather API Response:', JSON.stringify(response.data, null, 2)); return response.data; } catch (error) { console.error("Error fetching weather forecast:", error.message); throw new Error(`Failed to fetch weather forecast: ${error.message}`); } }
- src/index.js:79-82 (schema)Input schema using Zod for tool parameters: required locationId (string) and optional date (string).{ locationId: z.string().describe("The location ID (e.g., G2661552)"), date: z.string().optional().describe("Optional: The date for the forecast (yyyy-MM-dd). Defaults to today") },
- src/index.js:77-152 (registration)Tool registration via server.tool() specifying name, input schema, and handler function.server.tool( "getWeatherForecast", { locationId: z.string().describe("The location ID (e.g., G2661552)"), date: z.string().optional().describe("Optional: The date for the forecast (yyyy-MM-dd). Defaults to today") }, async ({ locationId, date }) => { try { // Use provided date or default to today const forecastDate = date ? new Date(date) : new Date(); // Validate date if (isNaN(forecastDate.getTime())) { return { content: [{ type: "text", text: "Invalid date format. Please use yyyy-MM-dd." }], isError: true }; } const forecast = await getWeatherForecast(locationId, forecastDate); // Handle error if forecast data is incomplete if (!forecast || !forecast.datum) { console.error('Invalid forecast data:', forecast); return { content: [{ type: "text", text: "Received invalid forecast data from API." }], isError: true }; } // Format the response nicely using the actual structure let formattedForecast = `Weather Forecast for date ${forecast.datum}:\n\n`; // Add general weather overview for the whole day if (forecast.ganzertag) { const dayData = forecast.ganzertag; formattedForecast += `### Daily Overview\n`; formattedForecast += `Temperature: ${dayData.uebersicht.mintemp} to ${dayData.uebersicht.maxtemp}\n`; formattedForecast += `Precipitation: ${dayData.niederschlag.menge} (Probability: ${dayData.niederschlag.wahrscheinlichkeit})\n`; formattedForecast += `Cloud coverage: ${dayData.niederschlag.wolken}\n`; formattedForecast += `Wind: ${dayData.wind.geschwindigkeit} from ${dayData.wind.richtung}\n`; formattedForecast += `Sunshine duration: ${dayData.sonne.dauer}\n\n`; } // Add time sections for detailed forecast if (forecast.abschnitte && forecast.abschnitte.length > 0) { formattedForecast += `### Hourly Forecast\n`; forecast.abschnitte.forEach(section => { formattedForecast += `\n${section.zeitvon} - ${section.zeitbis}:\n`; formattedForecast += `Temperature: ${section.uebersicht.mintemp} to ${section.uebersicht.maxtemp}\n`; formattedForecast += `Precipitation: ${section.niederschlag.menge} (Probability: ${section.niederschlag.wahrscheinlichkeit})\n`; formattedForecast += `Wind: ${section.wind.geschwindigkeit} from ${section.wind.richtung}\n`; }); } // Add general weather situation and outlook if available if (forecast.allgemeineLage) { formattedForecast += `\n### General Weather Situation\n${forecast.allgemeineLage}\n`; } if (forecast.aussichten) { formattedForecast += `\n### Outlook\n${forecast.aussichten}\n`; } return { content: [{ type: "text", text: formattedForecast }] }; } catch (error) { return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true }; } } );
- src/index.js:16-18 (helper)Utility helper to format a Date object to yyyy-MM-dd string used in API calls.function formatDate(date) { return date.toISOString().split('T')[0]; }