get_weather
Retrieve current weather data for Dutch locations by specifying names like 'Amsterdam' or 'De Bilt'. Automatically converts locations into grid identifiers for accurate results.
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)The MCP tool handler function for 'get_weather'. It invokes knmiApi.getWeather with the provided location and optional region, formats the response as MCP structured content including a JSON string, and handles errors appropriately.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:309-321 (schema)Input schema (location string, optional region number) and reference to output schema for the 'get_weather' tool registration.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,
- src/index.ts:31-301 (schema)Comprehensive Zod schema defining the structured output format for the 'get_weather' tool, including backgrounds, summaries, alerts, hourly/daily forecasts, sun times, wind, and UV index.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 the MCP server using server.registerTool, including name, metadata, schemas, and handler reference.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)Helper method in KnmiApi class that resolves the location name to a grid ID using resolveLocation and fetches weather data via the API client from the '/weather' endpoint.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; }