@cyanheads/nws-weather-mcp-server 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +309 -0
- package/Dockerfile +99 -0
- package/LICENSE +190 -0
- package/README.md +249 -0
- package/dist/config/server-config.d.ts +12 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +19 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/resources/definitions/alert-types.resource.d.ts +7 -0
- package/dist/mcp-server/resources/definitions/alert-types.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/alert-types.resource.js +27 -0
- package/dist/mcp-server/resources/definitions/alert-types.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/index.d.ts +6 -0
- package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/index.js +6 -0
- package/dist/mcp-server/resources/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/find-stations.tool.d.ts +22 -0
- package/dist/mcp-server/tools/definitions/find-stations.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/find-stations.tool.js +60 -0
- package/dist/mcp-server/tools/definitions/find-stations.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-forecast.tool.d.ts +33 -0
- package/dist/mcp-server/tools/definitions/get-forecast.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-forecast.tool.js +125 -0
- package/dist/mcp-server/tools/definitions/get-forecast.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-observations.tool.d.ts +30 -0
- package/dist/mcp-server/tools/definitions/get-observations.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-observations.tool.js +177 -0
- package/dist/mcp-server/tools/definitions/get-observations.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts +10 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/index.js +10 -0
- package/dist/mcp-server/tools/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/list-alert-types.tool.d.ts +10 -0
- package/dist/mcp-server/tools/definitions/list-alert-types.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/list-alert-types.tool.js +28 -0
- package/dist/mcp-server/tools/definitions/list-alert-types.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-alerts.tool.d.ts +51 -0
- package/dist/mcp-server/tools/definitions/search-alerts.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-alerts.tool.js +242 -0
- package/dist/mcp-server/tools/definitions/search-alerts.tool.js.map +1 -0
- package/dist/mcp-server/tools/format-utils.d.ts +11 -0
- package/dist/mcp-server/tools/format-utils.d.ts.map +1 -0
- package/dist/mcp-server/tools/format-utils.js +27 -0
- package/dist/mcp-server/tools/format-utils.js.map +1 -0
- package/dist/services/nws/nws-service.d.ts +62 -0
- package/dist/services/nws/nws-service.d.ts.map +1 -0
- package/dist/services/nws/nws-service.js +372 -0
- package/dist/services/nws/nws-service.js.map +1 -0
- package/dist/services/nws/types.d.ts +96 -0
- package/dist/services/nws/types.d.ts.map +1 -0
- package/dist/services/nws/types.js +6 -0
- package/dist/services/nws/types.js.map +1 -0
- package/package.json +82 -0
- package/server.json +101 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-utils.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/tools/format-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qCAAqC;AACrC,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtC;AAED,qCAAqC;AACrC,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEtC;AAED,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWnD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared formatting utilities for tool format() functions.
|
|
3
|
+
* @module mcp-server/tools/format-utils
|
|
4
|
+
*/
|
|
5
|
+
/** Convert Celsius to Fahrenheit. */
|
|
6
|
+
export function cToF(c) {
|
|
7
|
+
return Math.round(c * 1.8 + 32);
|
|
8
|
+
}
|
|
9
|
+
/** Convert Fahrenheit to Celsius. */
|
|
10
|
+
export function fToC(f) {
|
|
11
|
+
return Math.round(((f - 32) * 5) / 9);
|
|
12
|
+
}
|
|
13
|
+
/** Format an ISO 8601 timestamp as a short human-readable string. */
|
|
14
|
+
export function formatTimestamp(iso) {
|
|
15
|
+
const d = new Date(iso);
|
|
16
|
+
if (Number.isNaN(d.getTime()))
|
|
17
|
+
return iso;
|
|
18
|
+
return d.toLocaleString('en-US', {
|
|
19
|
+
weekday: 'short',
|
|
20
|
+
month: 'short',
|
|
21
|
+
day: 'numeric',
|
|
22
|
+
hour: 'numeric',
|
|
23
|
+
minute: '2-digit',
|
|
24
|
+
timeZoneName: 'short',
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=format-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-utils.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/format-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qCAAqC;AACrC,MAAM,UAAU,IAAI,CAAC,CAAS;IAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,IAAI,CAAC,CAAS;IAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,GAAG,CAAC;IAC1C,OAAO,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE;QAC/B,OAAO,EAAE,OAAO;QAChB,KAAK,EAAE,OAAO;QACd,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,SAAS;QACjB,YAAY,EAAE,OAAO;KACtB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview NWS API client service. Handles HTTP requests, /points resolution
|
|
3
|
+
* with caching, and retry logic for transient failures.
|
|
4
|
+
* @module services/nws/nws-service
|
|
5
|
+
*/
|
|
6
|
+
import type { Context } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
import type { Alert, ForecastResponse, NwsValue, Observation } from './types.js';
|
|
8
|
+
export interface ForecastResult {
|
|
9
|
+
readonly forecast: ForecastResponse;
|
|
10
|
+
readonly location: {
|
|
11
|
+
city: string;
|
|
12
|
+
state: string;
|
|
13
|
+
office: string;
|
|
14
|
+
timeZone: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface AlertSearchResult {
|
|
18
|
+
readonly alerts: readonly Alert[];
|
|
19
|
+
}
|
|
20
|
+
export interface ObservationResult {
|
|
21
|
+
readonly observation: Observation;
|
|
22
|
+
}
|
|
23
|
+
export interface StationResult {
|
|
24
|
+
readonly bearing: string;
|
|
25
|
+
readonly county: string;
|
|
26
|
+
readonly distance: number;
|
|
27
|
+
readonly elevation: NwsValue;
|
|
28
|
+
readonly forecastZone: string;
|
|
29
|
+
readonly name: string;
|
|
30
|
+
readonly stationId: string;
|
|
31
|
+
readonly timeZone: string;
|
|
32
|
+
}
|
|
33
|
+
export interface FindStationsResult {
|
|
34
|
+
readonly stations: readonly StationResult[];
|
|
35
|
+
}
|
|
36
|
+
export declare class NwsService {
|
|
37
|
+
/** Get forecast (standard or hourly) for coordinates. */
|
|
38
|
+
getForecast(lat: number, lon: number, hourly: boolean, ctx: Context): Promise<ForecastResult>;
|
|
39
|
+
/** Search active alerts with optional filters. */
|
|
40
|
+
searchAlerts(params: {
|
|
41
|
+
area?: string | undefined;
|
|
42
|
+
point?: string | undefined;
|
|
43
|
+
zone?: string | undefined;
|
|
44
|
+
event?: string[] | undefined;
|
|
45
|
+
severity?: string[] | undefined;
|
|
46
|
+
urgency?: string[] | undefined;
|
|
47
|
+
certainty?: string[] | undefined;
|
|
48
|
+
}, ctx: Context): Promise<AlertSearchResult>;
|
|
49
|
+
/** Get latest observation, either by station ID or by resolving nearest station from coordinates. */
|
|
50
|
+
getObservation(params: {
|
|
51
|
+
latitude?: number | undefined;
|
|
52
|
+
longitude?: number | undefined;
|
|
53
|
+
stationId?: string | undefined;
|
|
54
|
+
}, ctx: Context): Promise<ObservationResult>;
|
|
55
|
+
/** Find observation stations near coordinates, sorted by proximity. */
|
|
56
|
+
findStations(lat: number, lon: number, limit: number, ctx: Context): Promise<FindStationsResult>;
|
|
57
|
+
/** List all valid alert event type names. */
|
|
58
|
+
listAlertTypes(ctx: Context): Promise<readonly string[]>;
|
|
59
|
+
}
|
|
60
|
+
export declare function initNwsService(): void;
|
|
61
|
+
export declare function getNwsService(): NwsService;
|
|
62
|
+
//# sourceMappingURL=nws-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nws-service.d.ts","sourceRoot":"","sources":["../../../src/services/nws/nws-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGtD,OAAO,KAAK,EACV,KAAK,EAEL,gBAAgB,EAChB,QAAQ,EACR,WAAW,EAGZ,MAAM,YAAY,CAAC;AA4SpB,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CACtF;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;CACnC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CAC7C;AAED,qBAAa,UAAU;IACrB,yDAAyD;IACnD,WAAW,CACf,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,cAAc,CAAC;IAkB1B,kDAAkD;IAC5C,YAAY,CAChB,MAAM,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC1B,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC7B,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAChC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC/B,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;KAClC,EACD,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,iBAAiB,CAAC;IAkB7B,qGAAqG;IAC/F,cAAc,CAClB,MAAM,EAAE;QACN,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KAChC,EACD,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,iBAAiB,CAAC;IAqD7B,uEAAuE;IACjE,YAAY,CAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,kBAAkB,CAAC;IA0B9B,6CAA6C;IACvC,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC;CAK/D;AAQD,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,wBAAgB,aAAa,IAAI,UAAU,CAG1C"}
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview NWS API client service. Handles HTTP requests, /points resolution
|
|
3
|
+
* with caching, and retry logic for transient failures.
|
|
4
|
+
* @module services/nws/nws-service
|
|
5
|
+
*/
|
|
6
|
+
import { serviceUnavailable } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { getServerConfig } from '../../config/server-config.js';
|
|
8
|
+
const BASE_URL = 'https://api.weather.gov';
|
|
9
|
+
const POINTS_CACHE_TTL = 3600; // 1 hour — grid cells rarely change
|
|
10
|
+
const MAX_RETRIES = 2;
|
|
11
|
+
const RETRY_DELAY_MS = 2000;
|
|
12
|
+
/** Extract the last path segment from an NWS API URL (e.g., zone code from zone URL). */
|
|
13
|
+
function extractZoneCode(url) {
|
|
14
|
+
const lastSlash = url.lastIndexOf('/');
|
|
15
|
+
return lastSlash >= 0 ? url.slice(lastSlash + 1) : url;
|
|
16
|
+
}
|
|
17
|
+
/** Truncate coordinate to 4 decimal places per NWS API requirement. */
|
|
18
|
+
function truncateCoord(n) {
|
|
19
|
+
return Math.trunc(n * 10000) / 10000;
|
|
20
|
+
}
|
|
21
|
+
/** Build cache key for /points resolution. */
|
|
22
|
+
function pointsCacheKey(lat, lon) {
|
|
23
|
+
return `nws/points/${truncateCoord(lat)}_${truncateCoord(lon)}`;
|
|
24
|
+
}
|
|
25
|
+
const DEFAULT_NOT_FOUND = 'NWS only covers the US. Provide coordinates within US states, territories, or adjacent marine areas.';
|
|
26
|
+
/** Try to extract a detail message from an NWS error response body. */
|
|
27
|
+
async function parseNwsErrorDetail(response) {
|
|
28
|
+
try {
|
|
29
|
+
const body = (await response.json());
|
|
30
|
+
if (typeof body.detail === 'string')
|
|
31
|
+
return body.detail;
|
|
32
|
+
if (typeof body.title === 'string')
|
|
33
|
+
return body.title;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
/* not JSON — ignore */
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
/** Fetch JSON from the NWS API with User-Agent and optional retries. */
|
|
41
|
+
async function nwsFetch(url, ctx, retries = MAX_RETRIES, notFoundMessage = DEFAULT_NOT_FOUND) {
|
|
42
|
+
const { userAgent } = getServerConfig();
|
|
43
|
+
let lastError;
|
|
44
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
45
|
+
if (attempt > 0) {
|
|
46
|
+
ctx.log.info('Retrying NWS request', { url, attempt });
|
|
47
|
+
await new Promise((r) => setTimeout(r, RETRY_DELAY_MS * attempt));
|
|
48
|
+
}
|
|
49
|
+
const response = await fetch(url, {
|
|
50
|
+
headers: {
|
|
51
|
+
'User-Agent': userAgent,
|
|
52
|
+
Accept: 'application/geo+json',
|
|
53
|
+
},
|
|
54
|
+
signal: ctx.signal,
|
|
55
|
+
});
|
|
56
|
+
if (response.ok) {
|
|
57
|
+
return (await response.json());
|
|
58
|
+
}
|
|
59
|
+
if (response.status >= 500 && attempt < retries) {
|
|
60
|
+
lastError = new Error(`NWS API returned ${response.status}`);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (response.status === 404) {
|
|
64
|
+
throw new Error(notFoundMessage);
|
|
65
|
+
}
|
|
66
|
+
if (response.status === 400) {
|
|
67
|
+
const detail = await parseNwsErrorDetail(response);
|
|
68
|
+
throw new Error(detail ?? `NWS API returned 400: Bad Request for ${url}`);
|
|
69
|
+
}
|
|
70
|
+
throw serviceUnavailable(`NWS API returned ${response.status}: ${response.statusText}`, {
|
|
71
|
+
url,
|
|
72
|
+
status: response.status,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
throw serviceUnavailable('NWS API unavailable after retries', { url }, { cause: lastError });
|
|
76
|
+
}
|
|
77
|
+
/** Resolve coordinates to NWS grid metadata, cached via ctx.state. */
|
|
78
|
+
async function resolvePoints(lat, lon, ctx) {
|
|
79
|
+
const key = pointsCacheKey(lat, lon);
|
|
80
|
+
const cached = await ctx.state.get(key);
|
|
81
|
+
if (cached) {
|
|
82
|
+
ctx.log.debug('Points cache hit', { lat, lon });
|
|
83
|
+
return cached;
|
|
84
|
+
}
|
|
85
|
+
const tLat = truncateCoord(lat);
|
|
86
|
+
const tLon = truncateCoord(lon);
|
|
87
|
+
ctx.log.info('Resolving /points', { lat: tLat, lon: tLon });
|
|
88
|
+
const data = await nwsFetch(`${BASE_URL}/points/${tLat},${tLon}`, ctx);
|
|
89
|
+
const props = data.properties;
|
|
90
|
+
const relativeLocation = props.relativeLocation
|
|
91
|
+
?.properties;
|
|
92
|
+
const forecastUrl = props.forecast;
|
|
93
|
+
const forecastHourlyUrl = props.forecastHourly;
|
|
94
|
+
const observationStationsUrl = props.observationStations;
|
|
95
|
+
if (!forecastUrl || !forecastHourlyUrl || !observationStationsUrl) {
|
|
96
|
+
throw serviceUnavailable('NWS /points response missing required URLs', {
|
|
97
|
+
lat: tLat,
|
|
98
|
+
lon: tLon,
|
|
99
|
+
forecastUrl: !!forecastUrl,
|
|
100
|
+
forecastHourlyUrl: !!forecastHourlyUrl,
|
|
101
|
+
observationStationsUrl: !!observationStationsUrl,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
const metadata = {
|
|
105
|
+
office: props.gridId,
|
|
106
|
+
gridX: props.gridX,
|
|
107
|
+
gridY: props.gridY,
|
|
108
|
+
forecastUrl,
|
|
109
|
+
forecastHourlyUrl,
|
|
110
|
+
observationStationsUrl,
|
|
111
|
+
city: relativeLocation?.city ?? '',
|
|
112
|
+
state: relativeLocation?.state ?? '',
|
|
113
|
+
timeZone: props.timeZone,
|
|
114
|
+
forecastZone: props.forecastZone,
|
|
115
|
+
county: props.county,
|
|
116
|
+
};
|
|
117
|
+
await ctx.state.set(key, metadata, { ttl: POINTS_CACHE_TTL });
|
|
118
|
+
return metadata;
|
|
119
|
+
}
|
|
120
|
+
/** Parse forecast periods from a forecast GeoJSON response. */
|
|
121
|
+
function parseForecastPeriods(data) {
|
|
122
|
+
const props = data.properties;
|
|
123
|
+
const rawPeriods = props.periods;
|
|
124
|
+
const periods = rawPeriods.map((p) => ({
|
|
125
|
+
number: p.number,
|
|
126
|
+
name: p.name,
|
|
127
|
+
startTime: p.startTime,
|
|
128
|
+
endTime: p.endTime,
|
|
129
|
+
isDaytime: p.isDaytime,
|
|
130
|
+
temperature: p.temperature,
|
|
131
|
+
temperatureUnit: p.temperatureUnit,
|
|
132
|
+
windSpeed: p.windSpeed,
|
|
133
|
+
windDirection: p.windDirection,
|
|
134
|
+
shortForecast: p.shortForecast,
|
|
135
|
+
detailedForecast: p.detailedForecast,
|
|
136
|
+
probabilityOfPrecipitation: p.probabilityOfPrecipitation ?? {
|
|
137
|
+
value: null,
|
|
138
|
+
unitCode: 'wmoUnit:percent',
|
|
139
|
+
},
|
|
140
|
+
dewpoint: p.dewpoint ?? { value: null, unitCode: 'wmoUnit:degC' },
|
|
141
|
+
relativeHumidity: p.relativeHumidity ?? {
|
|
142
|
+
value: null,
|
|
143
|
+
unitCode: 'wmoUnit:percent',
|
|
144
|
+
},
|
|
145
|
+
}));
|
|
146
|
+
return {
|
|
147
|
+
generatedAt: props.generatedAt,
|
|
148
|
+
updateTime: props.updateTime,
|
|
149
|
+
periods,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/** Parse a single alert from GeoJSON feature. */
|
|
153
|
+
function parseAlert(feature) {
|
|
154
|
+
const p = feature.properties;
|
|
155
|
+
return {
|
|
156
|
+
id: p.id,
|
|
157
|
+
event: p.event,
|
|
158
|
+
headline: p.headline ?? null,
|
|
159
|
+
description: p.description,
|
|
160
|
+
instruction: p.instruction ?? null,
|
|
161
|
+
severity: p.severity,
|
|
162
|
+
urgency: p.urgency,
|
|
163
|
+
certainty: p.certainty,
|
|
164
|
+
areaDesc: p.areaDesc,
|
|
165
|
+
onset: p.onset ?? null,
|
|
166
|
+
expires: p.expires ?? null,
|
|
167
|
+
senderName: p.senderName,
|
|
168
|
+
affectedZones: (p.affectedZones ?? []).map(extractZoneCode),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/** Parse observation from latest observation response. */
|
|
172
|
+
function parseObservation(data, stationId, stationName) {
|
|
173
|
+
const props = data.properties;
|
|
174
|
+
const nullValue = { value: null, unitCode: '' };
|
|
175
|
+
return {
|
|
176
|
+
stationId,
|
|
177
|
+
stationName,
|
|
178
|
+
timestamp: props.timestamp,
|
|
179
|
+
textDescription: props.textDescription ?? '',
|
|
180
|
+
temperature: props.temperature ?? nullValue,
|
|
181
|
+
dewpoint: props.dewpoint ?? nullValue,
|
|
182
|
+
windSpeed: props.windSpeed ?? nullValue,
|
|
183
|
+
windDirection: props.windDirection ?? nullValue,
|
|
184
|
+
windGust: props.windGust ?? nullValue,
|
|
185
|
+
barometricPressure: props.barometricPressure ?? nullValue,
|
|
186
|
+
visibility: props.visibility ?? nullValue,
|
|
187
|
+
relativeHumidity: props.relativeHumidity ?? nullValue,
|
|
188
|
+
heatIndex: props.heatIndex ?? nullValue,
|
|
189
|
+
windChill: props.windChill ?? nullValue,
|
|
190
|
+
cloudLayers: (props.cloudLayers ?? []).map((l) => ({
|
|
191
|
+
base: l.base ?? nullValue,
|
|
192
|
+
amount: l.amount ?? 'CLR',
|
|
193
|
+
})),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/** Parse station features from observation stations response. */
|
|
197
|
+
function parseStations(data) {
|
|
198
|
+
const features = (data.features ?? data.observationStations);
|
|
199
|
+
if (!Array.isArray(features))
|
|
200
|
+
return [];
|
|
201
|
+
return features.map((f) => {
|
|
202
|
+
const p = f.properties;
|
|
203
|
+
const geometry = f.geometry;
|
|
204
|
+
const coords = geometry?.coordinates ?? [0, 0];
|
|
205
|
+
return {
|
|
206
|
+
stationId: p.stationIdentifier ?? '',
|
|
207
|
+
name: p.name ?? '',
|
|
208
|
+
elevation: p.elevation ?? { value: null, unitCode: '' },
|
|
209
|
+
timeZone: p.timeZone ?? '',
|
|
210
|
+
county: extractZoneCode(p.county ?? ''),
|
|
211
|
+
forecastZone: extractZoneCode(p.forecast ?? ''),
|
|
212
|
+
coordinates: [coords[0] ?? 0, coords[1] ?? 0],
|
|
213
|
+
};
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
/** Haversine distance in kilometers between two lat/lon pairs. */
|
|
217
|
+
function haversine(lat1, lon1, lat2, lon2) {
|
|
218
|
+
const R = 6371;
|
|
219
|
+
const dLat = toRad(lat2 - lat1);
|
|
220
|
+
const dLon = toRad(lon2 - lon1);
|
|
221
|
+
const a = Math.sin(dLat / 2) ** 2 +
|
|
222
|
+
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) ** 2;
|
|
223
|
+
return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
224
|
+
}
|
|
225
|
+
function toRad(deg) {
|
|
226
|
+
return (deg * Math.PI) / 180;
|
|
227
|
+
}
|
|
228
|
+
/** Compass bearing from point 1 to point 2. */
|
|
229
|
+
function bearing(lat1, lon1, lat2, lon2) {
|
|
230
|
+
const dLon = toRad(lon2 - lon1);
|
|
231
|
+
const y = Math.sin(dLon) * Math.cos(toRad(lat2));
|
|
232
|
+
const x = Math.cos(toRad(lat1)) * Math.sin(toRad(lat2)) -
|
|
233
|
+
Math.sin(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.cos(dLon);
|
|
234
|
+
return ((Math.atan2(y, x) * 180) / Math.PI + 360) % 360;
|
|
235
|
+
}
|
|
236
|
+
/** Bearing degrees to compass direction. */
|
|
237
|
+
function bearingToCompass(deg) {
|
|
238
|
+
const dirs = [
|
|
239
|
+
'N',
|
|
240
|
+
'NNE',
|
|
241
|
+
'NE',
|
|
242
|
+
'ENE',
|
|
243
|
+
'E',
|
|
244
|
+
'ESE',
|
|
245
|
+
'SE',
|
|
246
|
+
'SSE',
|
|
247
|
+
'S',
|
|
248
|
+
'SSW',
|
|
249
|
+
'SW',
|
|
250
|
+
'WSW',
|
|
251
|
+
'W',
|
|
252
|
+
'WNW',
|
|
253
|
+
'NW',
|
|
254
|
+
'NNW',
|
|
255
|
+
];
|
|
256
|
+
return dirs[Math.round(deg / 22.5) % 16] ?? 'N';
|
|
257
|
+
}
|
|
258
|
+
export class NwsService {
|
|
259
|
+
/** Get forecast (standard or hourly) for coordinates. */
|
|
260
|
+
async getForecast(lat, lon, hourly, ctx) {
|
|
261
|
+
const points = await resolvePoints(lat, lon, ctx);
|
|
262
|
+
const url = hourly ? points.forecastHourlyUrl : points.forecastUrl;
|
|
263
|
+
ctx.log.info('Fetching forecast', { url, hourly });
|
|
264
|
+
const data = await nwsFetch(url, ctx);
|
|
265
|
+
return {
|
|
266
|
+
location: {
|
|
267
|
+
city: points.city,
|
|
268
|
+
state: points.state,
|
|
269
|
+
office: points.office,
|
|
270
|
+
timeZone: points.timeZone,
|
|
271
|
+
},
|
|
272
|
+
forecast: parseForecastPeriods(data),
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/** Search active alerts with optional filters. */
|
|
276
|
+
async searchAlerts(params, ctx) {
|
|
277
|
+
const url = new URL(`${BASE_URL}/alerts/active`);
|
|
278
|
+
if (params.area)
|
|
279
|
+
url.searchParams.set('area', params.area);
|
|
280
|
+
if (params.point)
|
|
281
|
+
url.searchParams.set('point', params.point);
|
|
282
|
+
if (params.zone)
|
|
283
|
+
url.searchParams.set('zone', params.zone);
|
|
284
|
+
if (params.event?.length)
|
|
285
|
+
url.searchParams.set('event', params.event.join(','));
|
|
286
|
+
if (params.severity?.length)
|
|
287
|
+
url.searchParams.set('severity', params.severity.join(','));
|
|
288
|
+
if (params.urgency?.length)
|
|
289
|
+
url.searchParams.set('urgency', params.urgency.join(','));
|
|
290
|
+
if (params.certainty?.length)
|
|
291
|
+
url.searchParams.set('certainty', params.certainty.join(','));
|
|
292
|
+
ctx.log.info('Searching alerts', { url: url.toString() });
|
|
293
|
+
const data = await nwsFetch(url.toString(), ctx);
|
|
294
|
+
const features = (data.features ?? []);
|
|
295
|
+
return { alerts: features.map(parseAlert) };
|
|
296
|
+
}
|
|
297
|
+
/** Get latest observation, either by station ID or by resolving nearest station from coordinates. */
|
|
298
|
+
async getObservation(params, ctx) {
|
|
299
|
+
let stationId;
|
|
300
|
+
let stationName;
|
|
301
|
+
if (params.stationId) {
|
|
302
|
+
stationId = params.stationId.toUpperCase();
|
|
303
|
+
// Fetch station metadata to get the proper name
|
|
304
|
+
const stationData = await nwsFetch(`${BASE_URL}/stations/${stationId}`, ctx, 0, `Station '${stationId}' not found. Use nws_find_stations to discover valid station IDs.`);
|
|
305
|
+
const stationProps = stationData.properties;
|
|
306
|
+
stationName = stationProps?.name ?? stationId;
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
const lat = params.latitude;
|
|
310
|
+
const lon = params.longitude;
|
|
311
|
+
const points = await resolvePoints(lat, lon, ctx);
|
|
312
|
+
ctx.log.info('Resolving nearest station', { url: points.observationStationsUrl });
|
|
313
|
+
const stationsData = await nwsFetch(points.observationStationsUrl, ctx, 0);
|
|
314
|
+
const features = (stationsData.features ?? []);
|
|
315
|
+
const first = features[0];
|
|
316
|
+
if (!first) {
|
|
317
|
+
throw new Error('No observation stations found near this location.');
|
|
318
|
+
}
|
|
319
|
+
const firstProps = first.properties;
|
|
320
|
+
stationId = firstProps.stationIdentifier;
|
|
321
|
+
stationName = firstProps.name;
|
|
322
|
+
}
|
|
323
|
+
ctx.log.info('Fetching latest observation', { stationId });
|
|
324
|
+
const data = await nwsFetch(`${BASE_URL}/stations/${stationId}/observations/latest`, ctx, MAX_RETRIES, `Station '${stationId}' not found. Use nws_find_stations to discover valid station IDs.`);
|
|
325
|
+
const observation = parseObservation(data, stationId, stationName);
|
|
326
|
+
if (!observation.timestamp) {
|
|
327
|
+
throw new Error(`Station ${stationId} has no recent observations. Try a different station — use nws_find_stations to find alternatives nearby.`);
|
|
328
|
+
}
|
|
329
|
+
return { observation };
|
|
330
|
+
}
|
|
331
|
+
/** Find observation stations near coordinates, sorted by proximity. */
|
|
332
|
+
async findStations(lat, lon, limit, ctx) {
|
|
333
|
+
const points = await resolvePoints(lat, lon, ctx);
|
|
334
|
+
ctx.log.info('Fetching stations', { url: points.observationStationsUrl });
|
|
335
|
+
const data = await nwsFetch(points.observationStationsUrl, ctx, 0);
|
|
336
|
+
const stations = parseStations(data).map((s) => {
|
|
337
|
+
const dist = haversine(lat, lon, s.coordinates[1], s.coordinates[0]);
|
|
338
|
+
const bear = bearing(lat, lon, s.coordinates[1], s.coordinates[0]);
|
|
339
|
+
return {
|
|
340
|
+
stationId: s.stationId,
|
|
341
|
+
name: s.name,
|
|
342
|
+
distance: Math.round(dist * 10) / 10,
|
|
343
|
+
bearing: bearingToCompass(bear),
|
|
344
|
+
elevation: s.elevation,
|
|
345
|
+
timeZone: s.timeZone,
|
|
346
|
+
county: s.county,
|
|
347
|
+
forecastZone: s.forecastZone,
|
|
348
|
+
};
|
|
349
|
+
});
|
|
350
|
+
stations.sort((a, b) => a.distance - b.distance);
|
|
351
|
+
return { stations: stations.slice(0, limit) };
|
|
352
|
+
}
|
|
353
|
+
/** List all valid alert event type names. */
|
|
354
|
+
async listAlertTypes(ctx) {
|
|
355
|
+
ctx.log.info('Fetching alert types');
|
|
356
|
+
const data = await nwsFetch(`${BASE_URL}/alerts/types`, ctx, 0);
|
|
357
|
+
return data.eventTypes ?? [];
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// ---------------------------------------------------------------------------
|
|
361
|
+
// Init/accessor pattern
|
|
362
|
+
// ---------------------------------------------------------------------------
|
|
363
|
+
let _service;
|
|
364
|
+
export function initNwsService() {
|
|
365
|
+
_service = new NwsService();
|
|
366
|
+
}
|
|
367
|
+
export function getNwsService() {
|
|
368
|
+
if (!_service)
|
|
369
|
+
throw new Error('NwsService not initialized — call initNwsService() in setup()');
|
|
370
|
+
return _service;
|
|
371
|
+
}
|
|
372
|
+
//# sourceMappingURL=nws-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nws-service.js","sourceRoot":"","sources":["../../../src/services/nws/nws-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Type definitions for NWS API responses.
|
|
3
|
+
* @module services/nws/types
|
|
4
|
+
*/
|
|
5
|
+
/** NWS quantity value — many observation fields use this shape. */
|
|
6
|
+
export interface NwsValue {
|
|
7
|
+
readonly unitCode: string;
|
|
8
|
+
readonly value: number | null;
|
|
9
|
+
}
|
|
10
|
+
/** Resolved grid point from /points/{lat},{lon}. */
|
|
11
|
+
export interface PointsMetadata {
|
|
12
|
+
readonly city: string;
|
|
13
|
+
readonly county: string;
|
|
14
|
+
readonly forecastHourlyUrl: string;
|
|
15
|
+
readonly forecastUrl: string;
|
|
16
|
+
readonly forecastZone: string;
|
|
17
|
+
readonly gridX: number;
|
|
18
|
+
readonly gridY: number;
|
|
19
|
+
readonly observationStationsUrl: string;
|
|
20
|
+
readonly office: string;
|
|
21
|
+
readonly state: string;
|
|
22
|
+
readonly timeZone: string;
|
|
23
|
+
}
|
|
24
|
+
/** A single forecast period (shared by standard and hourly). */
|
|
25
|
+
export interface ForecastPeriod {
|
|
26
|
+
readonly detailedForecast: string;
|
|
27
|
+
readonly dewpoint: NwsValue;
|
|
28
|
+
readonly endTime: string;
|
|
29
|
+
readonly isDaytime: boolean;
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly number: number;
|
|
32
|
+
readonly probabilityOfPrecipitation: NwsValue;
|
|
33
|
+
readonly relativeHumidity: NwsValue;
|
|
34
|
+
readonly shortForecast: string;
|
|
35
|
+
readonly startTime: string;
|
|
36
|
+
readonly temperature: number;
|
|
37
|
+
readonly temperatureUnit: string;
|
|
38
|
+
readonly windDirection: string;
|
|
39
|
+
readonly windSpeed: string;
|
|
40
|
+
}
|
|
41
|
+
/** Forecast response from /gridpoints/{wfo}/{x},{y}/forecast. */
|
|
42
|
+
export interface ForecastResponse {
|
|
43
|
+
readonly generatedAt: string;
|
|
44
|
+
readonly periods: readonly ForecastPeriod[];
|
|
45
|
+
readonly updateTime: string;
|
|
46
|
+
}
|
|
47
|
+
/** Active alert from /alerts/active. */
|
|
48
|
+
export interface Alert {
|
|
49
|
+
readonly affectedZones: readonly string[];
|
|
50
|
+
readonly areaDesc: string;
|
|
51
|
+
readonly certainty: string;
|
|
52
|
+
readonly description: string;
|
|
53
|
+
readonly event: string;
|
|
54
|
+
readonly expires: string | null;
|
|
55
|
+
readonly headline: string | null;
|
|
56
|
+
readonly id: string;
|
|
57
|
+
readonly instruction: string | null;
|
|
58
|
+
readonly onset: string | null;
|
|
59
|
+
readonly senderName: string;
|
|
60
|
+
readonly severity: string;
|
|
61
|
+
readonly urgency: string;
|
|
62
|
+
}
|
|
63
|
+
/** Latest observation from /stations/{id}/observations/latest. */
|
|
64
|
+
export interface Observation {
|
|
65
|
+
readonly barometricPressure: NwsValue;
|
|
66
|
+
readonly cloudLayers: readonly CloudLayer[];
|
|
67
|
+
readonly dewpoint: NwsValue;
|
|
68
|
+
readonly heatIndex: NwsValue;
|
|
69
|
+
readonly relativeHumidity: NwsValue;
|
|
70
|
+
readonly stationId: string;
|
|
71
|
+
readonly stationName: string;
|
|
72
|
+
readonly temperature: NwsValue;
|
|
73
|
+
readonly textDescription: string;
|
|
74
|
+
readonly timestamp: string;
|
|
75
|
+
readonly visibility: NwsValue;
|
|
76
|
+
readonly windChill: NwsValue;
|
|
77
|
+
readonly windDirection: NwsValue;
|
|
78
|
+
readonly windGust: NwsValue;
|
|
79
|
+
readonly windSpeed: NwsValue;
|
|
80
|
+
}
|
|
81
|
+
/** Cloud layer from observation data. */
|
|
82
|
+
export interface CloudLayer {
|
|
83
|
+
readonly amount: string;
|
|
84
|
+
readonly base: NwsValue;
|
|
85
|
+
}
|
|
86
|
+
/** Observation station from /points/{lat},{lon}/stations. */
|
|
87
|
+
export interface Station {
|
|
88
|
+
readonly coordinates: readonly [longitude: number, latitude: number];
|
|
89
|
+
readonly county: string;
|
|
90
|
+
readonly elevation: NwsValue;
|
|
91
|
+
readonly forecastZone: string;
|
|
92
|
+
readonly name: string;
|
|
93
|
+
readonly stationId: string;
|
|
94
|
+
readonly timeZone: string;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/services/nws/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/services/nws/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|