dk_weather_forecast
Get weather forecasts for Danish locations with hourly or daily precision using DMI and ECMWF models for up to 16 days.
Instructions
Get hourly or daily weather forecast for a location in Denmark. Uses DMI HARMONIE 2km model for the first 2.5 days, then ECMWF for up to 16 days.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| location | Yes | Danish city name, postal code, or lat,lon coordinates | |
| days | No | Forecast days (default 3, max 16) | |
| mode | No | Hourly detail or daily summary (default: daily) |
Implementation Reference
- src/servers/danish-weather.js:152-205 (handler)The dk_weather_forecast tool implementation, including schema definition and request handling logic.
server.tool( "dk_weather_forecast", "Get hourly or daily weather forecast for a location in Denmark. Uses DMI HARMONIE 2km model for the first 2.5 days, then ECMWF for up to 16 days.", { location: z.string().describe("Danish city name, postal code, or lat,lon coordinates"), days: z.number().min(1).max(16).optional().describe("Forecast days (default 3, max 16)"), mode: z.enum(["hourly", "daily"]).optional().describe("Hourly detail or daily summary (default: daily)"), }, async ({ location, days, mode }) => { try { const loc = await getLocation(location); const forecastDays = days || 3; const isHourly = mode === "hourly"; const params = { latitude: loc.lat, longitude: loc.lon, forecast_days: forecastDays }; if (isHourly) { params.hourly = "temperature_2m,apparent_temperature,precipitation,weather_code,wind_speed_10m,wind_gusts_10m,cloud_cover"; } else { params.daily = "weather_code,temperature_2m_max,temperature_2m_min,apparent_temperature_max,apparent_temperature_min,sunrise,sunset,precipitation_sum,wind_speed_10m_max,wind_gusts_10m_max,wind_direction_10m_dominant"; } const data = await openMeteoFetch(params); const lines = [`## ${loc.name} — ${forecastDays}-Day Forecast\n`]; if (isHourly) { const h = data.hourly; for (let i = 0; i < h.time.length; i++) { const t = new Date(h.time[i]); const time = t.toLocaleString("da-DK", { timeZone: "Europe/Copenhagen", weekday: "short", day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" }); const wx = WMO_CODES[h.weather_code[i]] || ""; lines.push(`**${time}:** ${h.temperature_2m[i]}°C (feels ${h.apparent_temperature[i]}°C), ${wx}, wind ${h.wind_speed_10m[i]} km/h, precip ${h.precipitation[i]} mm`); } } else { const d = data.daily; for (let i = 0; i < d.time.length; i++) { const date = new Date(d.time[i]); const day = date.toLocaleDateString("da-DK", { timeZone: "Europe/Copenhagen", weekday: "long", day: "numeric", month: "long" }); const wx = WMO_CODES[d.weather_code[i]] || ""; const sunrise = d.sunrise[i]?.split("T")[1] || ""; const sunset = d.sunset[i]?.split("T")[1] || ""; lines.push(`### ${day}`); lines.push(`${wx} | ${d.temperature_2m_min[i]}°C to ${d.temperature_2m_max[i]}°C (feels ${d.apparent_temperature_min[i]}° to ${d.apparent_temperature_max[i]}°)`); lines.push(`Wind: up to ${d.wind_speed_10m_max[i]} km/h (gusts ${d.wind_gusts_10m_max[i]} km/h) from ${d.wind_direction_10m_dominant[i]}°`); lines.push(`Precipitation: ${d.precipitation_sum[i]} mm | ☀️ ${sunrise} — ${sunset}\n`); } } lines.push(`*DMI HARMONIE 2km model via Open-Meteo*`); return { content: [{ type: "text", text: lines.join("\n") }] }; } catch (err) { return { content: [{ type: "text", text: `Error: ${err.message}` }], isError: true }; } } );