Get Weather History
get_weather_historyRetrieve historical weather data for any US location by ZIP code or coordinates. Get hourly observations of temperature, humidity, wind, precipitation, and pressure from NOAA ISD.
Instructions
Get historical weather data for a location and date range. Returns hourly observations including temperature, humidity, wind, precipitation, and pressure. Source: NOAA ISD. Note: This dataset is coming soon.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| zip | No | US 5-digit ZIP code | |
| lat | No | Latitude | |
| lon | No | Longitude | |
| date_from | Yes | Start date (YYYY-MM-DD). Required. | |
| date_to | Yes | End date (YYYY-MM-DD). Required. |
Implementation Reference
- src/tools/weather.ts:133-189 (handler)The async handler function for the get_weather_history tool. Validates location input (lat+lon or zip), calls the API endpoint /api/v1/weather/history, and returns weather observations with a summary count.
async ({ zip, lat, lon, date_from, date_to }) => { if (!zip && (lat === undefined || lon === undefined)) { return { content: [ { type: "text" as const, text: "Please provide either lat+lon or a ZIP code.", }, ], isError: true, }; } const res = await apiGet<WeatherResponse>("/api/v1/weather/history", { zip, lat, lon, date_from, date_to, }); if (!res.ok) { if (res.status === 404) { return { content: [ { type: "text" as const, text: "Weather dataset is not yet available. This data source is coming soon.", }, ], }; } return { content: [ { type: "text" as const, text: `API error (${res.status}): ${JSON.stringify(res.data)}`, }, ], isError: true, }; } const data = res.data; const count = Array.isArray(data.data) ? data.data.length : 1; const summary = `Retrieved ${count} weather observation(s).`; return { content: [ { type: "text" as const, text: `${summary}\n\n${JSON.stringify(data, null, 2)}`, }, ], }; }, ); - src/tools/weather.ts:115-132 (schema)Input schema for get_weather_history tool: optional zip, lat, lon, and required date_from and date_to (YYYY-MM-DD format).
{ title: "Get Weather History", description: "Get historical weather data for a location and date range. Returns hourly " + "observations including temperature, humidity, wind, precipitation, and " + "pressure. Source: NOAA ISD. Note: This dataset is coming soon.", inputSchema: { zip: z.string().optional().describe("US 5-digit ZIP code"), lat: z.number().min(-90).max(90).optional().describe("Latitude"), lon: z.number().min(-180).max(180).optional().describe("Longitude"), date_from: z .string() .describe("Start date (YYYY-MM-DD). Required."), date_to: z .string() .describe("End date (YYYY-MM-DD). Required."), }, }, - src/tools/weather.ts:113-189 (registration)Registration of the tool named 'get_weather_history' via server.registerTool() within the registerWeatherTools function.
server.registerTool( "get_weather_history", { title: "Get Weather History", description: "Get historical weather data for a location and date range. Returns hourly " + "observations including temperature, humidity, wind, precipitation, and " + "pressure. Source: NOAA ISD. Note: This dataset is coming soon.", inputSchema: { zip: z.string().optional().describe("US 5-digit ZIP code"), lat: z.number().min(-90).max(90).optional().describe("Latitude"), lon: z.number().min(-180).max(180).optional().describe("Longitude"), date_from: z .string() .describe("Start date (YYYY-MM-DD). Required."), date_to: z .string() .describe("End date (YYYY-MM-DD). Required."), }, }, async ({ zip, lat, lon, date_from, date_to }) => { if (!zip && (lat === undefined || lon === undefined)) { return { content: [ { type: "text" as const, text: "Please provide either lat+lon or a ZIP code.", }, ], isError: true, }; } const res = await apiGet<WeatherResponse>("/api/v1/weather/history", { zip, lat, lon, date_from, date_to, }); if (!res.ok) { if (res.status === 404) { return { content: [ { type: "text" as const, text: "Weather dataset is not yet available. This data source is coming soon.", }, ], }; } return { content: [ { type: "text" as const, text: `API error (${res.status}): ${JSON.stringify(res.data)}`, }, ], isError: true, }; } const data = res.data; const count = Array.isArray(data.data) ? data.data.length : 1; const summary = `Retrieved ${count} weather observation(s).`; return { content: [ { type: "text" as const, text: `${summary}\n\n${JSON.stringify(data, null, 2)}`, }, ], }; }, ); - src/index.ts:15-15 (registration)Import of registerWeatherTools from weather.ts, which is called on line 42 to register all weather tools including get_weather_history.
import { registerWeatherTools } from "./tools/weather.js"; - src/client.ts:44-76 (helper)The apiGet helper function used by the handler to make HTTP GET requests to the Verilex API.
export async function apiGet<T = unknown>( path: string, params?: Record<string, string | number | undefined>, ): Promise<ApiResponse<T>> { const url = buildUrl(path, params); const headers: Record<string, string> = { Accept: "application/json", "User-Agent": "verilex-mcp-server/0.1.0", }; // Forward x402 payment token if present in env (for paid endpoints) const paymentToken = process.env.VERILEX_PAYMENT_TOKEN; if (paymentToken) { headers["X-Payment-Token"] = paymentToken; } const res = await fetch(url, { headers }); const data = (await res.json()) as T; const stale = res.headers.get("X-Data-Stale"); const lastUpdated = res.headers.get("X-Data-Last-Updated"); const ageSeconds = res.headers.get("X-Data-Age-Seconds"); return { ok: res.ok, status: res.status, data, stale: stale === "true", lastUpdated: lastUpdated ?? undefined, ageSeconds: ageSeconds ? Number(ageSeconds) : undefined, }; }