weather_forecast
Get hourly weather forecasts for Swedish locations using SMHI data. Specify a city or coordinates to receive detailed meteorological predictions for up to 72 hours ahead.
Instructions
Get hourly weather forecast for a location in Sweden using SMHI.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| location | Yes | Swedish city name or lat,lon coordinates | |
| hours | No | Hours ahead (default 24, max 72) |
Implementation Reference
- src/index.js:148-170 (handler)Main handler function for weather_forecast tool that processes location and hours parameters, fetches forecast data from SMHI API, formats hourly forecast entries with temperature, conditions, wind, and precipitation data
async ({ location, hours }) => { try { const loc = await getLocation(location); const data = await fetchForecast(loc.lat, loc.lon); const maxHours = hours || 24; const now = Date.now(); const cutoff = now + maxHours * 3600000; const lines = [`## ${loc.name} — ${maxHours}h Forecast\n`]; for (const entry of data.timeSeries) { const t = new Date(entry.validTime); if (t.getTime() > cutoff) break; if (t.getTime() < now - 3600000) continue; const time = t.toLocaleString("sv-SE", { timeZone: "Europe/Stockholm", weekday: "short", day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" }); const p = entry.parameters; const precip = getParam(p, "pmean"); lines.push(`**${time}:** ${getParam(p, "t")}°C, ${WSYMB2[getParam(p, "Wsymb2")] || ""}, wind ${getParam(p, "ws")} m/s${precip > 0 ? `, ${precip} mm/h` : ""}`); } lines.push(`\n*SMHI Open Data*`); return { content: [{ type: "text", text: lines.join("\n") }] }; } catch (err) { return { content: [{ type: "text", text: `Error: ${err.message}` }], isError: true }; } } - src/index.js:141-171 (registration)Tool registration with MCP server defining the weather_forecast tool name, description, input schema with location string and optional hours number, and the handler function
server.tool( "weather_forecast", "Get hourly weather forecast for a location in Sweden using SMHI.", { location: z.string().describe("Swedish city name or lat,lon coordinates"), hours: z.number().min(1).max(72).optional().describe("Hours ahead (default 24, max 72)"), }, async ({ location, hours }) => { try { const loc = await getLocation(location); const data = await fetchForecast(loc.lat, loc.lon); const maxHours = hours || 24; const now = Date.now(); const cutoff = now + maxHours * 3600000; const lines = [`## ${loc.name} — ${maxHours}h Forecast\n`]; for (const entry of data.timeSeries) { const t = new Date(entry.validTime); if (t.getTime() > cutoff) break; if (t.getTime() < now - 3600000) continue; const time = t.toLocaleString("sv-SE", { timeZone: "Europe/Stockholm", weekday: "short", day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" }); const p = entry.parameters; const precip = getParam(p, "pmean"); lines.push(`**${time}:** ${getParam(p, "t")}°C, ${WSYMB2[getParam(p, "Wsymb2")] || ""}, wind ${getParam(p, "ws")} m/s${precip > 0 ? `, ${precip} mm/h` : ""}`); } lines.push(`\n*SMHI Open Data*`); return { content: [{ type: "text", text: lines.join("\n") }] }; } catch (err) { return { content: [{ type: "text", text: `Error: ${err.message}` }], isError: true }; } } ); - src/index.js:144-147 (schema)Input validation schema using zod for weather_forecast tool parameters, defining location as required string and hours as optional number between 1-72
{ location: z.string().describe("Swedish city name or lat,lon coordinates"), hours: z.number().min(1).max(72).optional().describe("Hours ahead (default 24, max 72)"), }, - src/index.js:97-102 (helper)Helper function that fetches weather forecast data from SMHI API for given latitude and longitude coordinates, returning JSON data
async function fetchForecast(lat, lon) { const url = `${BASE_URL}/lon/${lon.toFixed(6)}/lat/${lat.toFixed(6)}/data.json`; const res = await fetch(url, { headers: { "User-Agent": USER_AGENT } }); if (!res.ok) throw new Error(`SMHI API error (${res.status}): ${await res.text()}`); return res.json(); } - src/index.js:84-90 (helper)Helper function that resolves location input by first checking against known Swedish cities, then geocoding if needed, throwing error if location cannot be found in Sweden
async function getLocation(input) { const loc = resolveLocation(input); if (loc) return loc; const geo = await geocode(input); if (geo) return geo; throw new Error(`Could not find location "${input}" in Sweden. Try a city name or lat,lon coordinates.`); }