get_weather
Retrieve current weather data for Dutch locations by entering city names like Amsterdam or De Bilt, which automatically convert to required grid identifiers.
Instructions
Get current weather information for a Dutch location. The location parameter accepts location names (e.g., 'Amsterdam', 'De Bilt') and automatically converts them to the required grid identifiers.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| location | Yes | Location name (e.g., 'Amsterdam', 'De Bilt') | |
| region | No | Optional region number (0-15) |
Implementation Reference
- src/index.ts:326-349 (handler)MCP tool handler for 'get_weather': resolves parameters, fetches weather data via KnmiApi, returns structured content or error.async ({ location, region }) => { try { const weatherData = await knmiApi.getWeather(location, region); return { content: [ { type: "text", text: JSON.stringify(weatherData), }, ], structuredContent: weatherData, }; } catch (error) { return { content: [ { type: "text", text: `Error fetching weather data: ${error instanceof Error ? error.message : String(error)}`, }, ], isError: true, }; } },
- src/index.ts:31-301 (schema)Zod output schema for get_weather tool response, matching KNMI API Weather structure.const weatherOutputSchema = z.object({ backgrounds: z .array( z.object({ dateTime: z .string() .describe( "Date of the background, the time from when this background is to be used", ), sky: z.enum([ "dayClear", "dayLightCloud", "dayMediumCloud", "dayHeavyCloud", "nightClear", "nightMediumCloud", "nightHeavyCloud", ]), celestial: z.enum(["sun", "moon"]).optional(), clouds: z .enum([ "dayMist", "dayLightCloud", "dayMediumCloud", "dayHeavyCloud", "dayHeavyCloudLightning", "nightMist", "nightLightCloud", "nightMediumCloud", "nightHeavyCloud", "nightHeavyCloudLightning", ]) .optional(), precipitation: z .enum([ "lightRain", "mediumRain", "heavyRain", "hail", "lightSnow", "mediumSnow", "heavySnow", ]) .optional(), }), ) .optional() .describe("The weather backgrounds to be used"), summaries: z .array( z.object({ dateTime: z .string() .describe( "Date of the summary, the time from when this summary is to be used", ), temperature: z .number() .optional() .describe("Current temperature in degrees Celsius"), }), ) .describe("Summary of the current weather conditions to be used"), alerts: z .array( z.object({ level: z .enum(["none", "potential", "yellow", "orange", "red"]) .describe("The alert level"), title: z.string().describe("The title of the alert"), description: z .string() .describe("The description of the alert"), }), ) .describe("Alerts for this location in the next 48 hours"), hourly: z .object({ forecast: z .array( z.object({ dateTime: z.string().describe("Date of the forecast"), alertLevel: z .enum([ "none", "potential", "yellow", "orange", "red", ]) .optional() .describe( "Highest alert level active for the hour", ), weatherType: z .number() .describe("Type of weather condition"), temperature: z .number() .describe("Temperature for the hour"), precipitation: z .object({ amount: z .number() .describe( "Amount of rain in millimeter per hour", ), chance: z .number() .describe("Chance of rain as a percentage"), }) .describe("Precipitation information for the hour"), wind: z .object({ source: z.enum([ "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW", "VAR", ]), speed: z .number() .describe( "The wind speed in kilometers/hour", ), gusts: z .number() .describe( "The wind gusts in kilometers/hour", ), degree: z .number() .optional() .describe( "Wind source in degrees (meteorological convention, 0 degrees represents north)", ), beaufort: z .number() .describe( "The wind speed according to the Beaufort scale", ), }) .optional() .describe("Wind information for the hour"), }), ) .describe("Entries with weather forecast"), }) .optional() .describe("Hourly forecast for the weather"), daily: z .object({ forecast: z .array( z.object({ date: z.string().describe("Date of the forecast"), alertLevels: z .array( z.enum([ "none", "potential", "yellow", "orange", "red", ]), ) .optional() .describe("All alert levels active for the day"), weatherType: z .number() .optional() .describe("Type of weather condition"), temperature: z .object({ min: z .number() .optional() .describe( "The minimum temperature in degrees Celsius", ), max: z .number() .optional() .describe( "The maximum temperature in degrees Celsius", ), }) .describe("Temperature range for the day"), precipitation: z .object({ amount: z .number() .describe( "Amount of rain in millimeter per hour", ), chance: z .number() .describe("Chance of rain as a percentage"), }) .describe("Precipitation information for the day"), }), ) .describe("Entries with weather forecast"), }) .optional() .describe("Daily forecast for the weather"), sun: z .object({ sunrise: z.string().describe("The time of sunrise"), sunset: z.string().describe("The time of sunset"), }) .optional() .describe("Sunrise and sunset times"), wind: z .object({ source: z.enum([ "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW", "VAR", ]), speed: z.number().describe("The wind speed in kilometers/hour"), gusts: z.number().describe("The wind gusts in kilometers/hour"), degree: z .number() .optional() .describe( "Wind source in degrees (meteorological convention, 0 degrees represents north)", ), beaufort: z .number() .describe("The wind speed according to the Beaufort scale"), }) .optional() .describe("Wind information for the current weather"), uvIndex: z .object({ value: z.number().describe("UV index value"), summary: z .string() .describe("A human-readable description of the UV index"), }) .optional() .describe("UV index data for the current weather"), });
- src/index.ts:303-350 (registration)Registration of the 'get_weather' tool with MCP server, including title, description, input/output schemas, and handler.server.registerTool( "get_weather", { title: "Get Weather", description: "Get current weather information for a Dutch location. The location parameter accepts location names (e.g., 'Amsterdam', 'De Bilt') and automatically converts them to the required grid identifiers.", inputSchema: { location: z .string() .describe("Location name (e.g., 'Amsterdam', 'De Bilt')"), region: z .number() .int() .min(0) .max(15) .optional() .describe("Optional region number (0-15)"), }, outputSchema: weatherOutputSchema.shape, annotations: { readOnlyHint: true, }, }, async ({ location, region }) => { try { const weatherData = await knmiApi.getWeather(location, region); return { content: [ { type: "text", text: JSON.stringify(weatherData), }, ], structuredContent: weatherData, }; } catch (error) { return { content: [ { type: "text", text: `Error fetching weather data: ${error instanceof Error ? error.message : String(error)}`, }, ], isError: true, }; } }, );
- src/lib/knmi-api.ts:221-236 (helper)KnmiApi.getWeather helper: resolves location ID, calls KNMI /weather endpoint, handles error.async getWeather(location: string, region?: number) { // Resolve location name to grid identifier const locationId = await resolveLocation(location); const { data, error } = await this.client.GET("/weather", { params: { query: { location: locationId, region }, }, }); if (error) { throw new Error( `Failed to get weather: ${(error as components["schemas"]["ErrorResponse"]).title || "Unknown error"}`, ); } return data; }