@dangahagan/weather-mcp 1.27.1 → 1.28.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/README.md +12 -6
- package/dist/config/displayThresholds.d.ts +31 -0
- package/dist/config/displayThresholds.d.ts.map +1 -1
- package/dist/config/displayThresholds.js +31 -0
- package/dist/config/displayThresholds.js.map +1 -1
- package/dist/config/tools.d.ts +10 -0
- package/dist/config/tools.d.ts.map +1 -1
- package/dist/config/tools.js +13 -0
- package/dist/config/tools.js.map +1 -1
- package/dist/handlers/criticalAlertBanner.d.ts +84 -0
- package/dist/handlers/criticalAlertBanner.d.ts.map +1 -0
- package/dist/handlers/criticalAlertBanner.js +172 -0
- package/dist/handlers/criticalAlertBanner.js.map +1 -0
- package/dist/handlers/currentConditionsHandler.d.ts +1 -1
- package/dist/handlers/currentConditionsHandler.d.ts.map +1 -1
- package/dist/handlers/currentConditionsHandler.js +64 -37
- package/dist/handlers/currentConditionsHandler.js.map +1 -1
- package/dist/handlers/forecastHandler.d.ts +1 -1
- package/dist/handlers/forecastHandler.d.ts.map +1 -1
- package/dist/handlers/forecastHandler.js +68 -43
- package/dist/handlers/forecastHandler.js.map +1 -1
- package/dist/handlers/weatherSummaryHandler.d.ts +1 -1
- package/dist/handlers/weatherSummaryHandler.d.ts.map +1 -1
- package/dist/handlers/weatherSummaryHandler.js +30 -2
- package/dist/handlers/weatherSummaryHandler.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +42 -35
- package/dist/index.js.map +1 -1
- package/dist/utils/criticalAlert.d.ts +86 -0
- package/dist/utils/criticalAlert.d.ts.map +1 -0
- package/dist/utils/criticalAlert.js +252 -0
- package/dist/utils/criticalAlert.js.map +1 -0
- package/dist/utils/locationResolver.d.ts +32 -0
- package/dist/utils/locationResolver.d.ts.map +1 -1
- package/dist/utils/locationResolver.js +33 -0
- package/dist/utils/locationResolver.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@dangahagan/weather-mcp)
|
|
4
4
|
[](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.dgahagan/weather-mcp)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
|
-
[](./docs/testing/TEST_SUITE_README.md)
|
|
7
7
|
[](https://nodejs.org)
|
|
8
8
|
|
|
9
9
|
**Give your AI assistant real weather data — 17 tools, zero API keys, zero signup, zero cost.**
|
|
@@ -58,7 +58,7 @@ Choose this one if you want:
|
|
|
58
58
|
|
|
59
59
|
- **Genuinely free** — every data source is a free public API. No trial that expires, no credit card, no rate-limited "free tier" bait.
|
|
60
60
|
- **No API keys** — install to first forecast in under a minute. Nothing to configure, nothing to leak into a repo. ([Three optional keys](#optional-api-keys) add extras if you want them; the default configuration needs none.)
|
|
61
|
-
- **Fully open source** — MIT licensed, readable TypeScript, 3,
|
|
61
|
+
- **Fully open source** — MIT licensed, readable TypeScript, 3,292 tests. Audit it, fork it, fix it.
|
|
62
62
|
- **Privacy-respecting** — your queries go directly from your machine to public weather APIs. No middleman server, no telemetry.
|
|
63
63
|
- **Breadth** — 17 tools covering weather, safety hazards (lightning, floods, wildfires), marine conditions, air quality, and historical data back to 1940. Most weather MCPs stop at forecasts.
|
|
64
64
|
|
|
@@ -70,11 +70,11 @@ All 17 tools, documented in detail in **[docs/TOOLS.md](./docs/TOOLS.md)**:
|
|
|
70
70
|
|
|
71
71
|
| Tool | What it does | Coverage |
|
|
72
72
|
|------|-------------|----------|
|
|
73
|
-
| `get_forecast` | Daily/hourly forecasts up to 16 days by coordinates, saved location, or city name (NOAA publishes 7 days daily and ~6.5 days hourly in the US, and says so when you ask for more; `source="openmeteo"` reaches the full range); sunrise/sunset, UV, precipitation probability, optional climate-normals comparison, optional moon phase & twilight almanac, optional five-model agreement comparison | 🌍 Global |
|
|
74
|
-
| `get_current_conditions` | Current weather: temperature, wind, humidity, pressure; NOAA station observations in the US (plus heat index/wind chill, snow depth, optional NOAA fire-weather indices), Open-Meteo model data elsewhere (with an optional computed Fosberg fire-weather index), or real airport station observations worldwide with `source="metar"`. Always states the observation's age, and automatically falls back to a fresher nearby station when the nearest one has gone dark. In extreme conditions automatically adds frostbite time-to-onset (computed wind chill) or heat-stress context (estimated WBGT) | 🌍 Global |
|
|
73
|
+
| `get_forecast` | Daily/hourly forecasts up to 16 days by coordinates, saved location, or city name (NOAA publishes 7 days daily and ~6.5 days hourly in the US, and says so when you ask for more; `source="openmeteo"` reaches the full range); sunrise/sunset, UV, precipitation probability, optional climate-normals comparison, optional moon phase & twilight almanac, optional five-model agreement comparison When the National Weather Service has a life-threatening alert active for a US point, its warning is surfaced at the top of the response before the report — absence of the banner is not an all-clear, so call `get_alerts` for the authoritative answer | 🌍 Global |
|
|
74
|
+
| `get_current_conditions` | Current weather: temperature, wind, humidity, pressure; NOAA station observations in the US (plus heat index/wind chill, snow depth, optional NOAA fire-weather indices), Open-Meteo model data elsewhere (with an optional computed Fosberg fire-weather index), or real airport station observations worldwide with `source="metar"`. Always states the observation's age, and automatically falls back to a fresher nearby station when the nearest one has gone dark. In extreme conditions automatically adds frostbite time-to-onset (computed wind chill) or heat-stress context (estimated WBGT) When the National Weather Service has a life-threatening alert active for a US point, its warning is surfaced at the top of the response before the report — absence of the banner is not an all-clear, so call `get_alerts` for the authoritative answer | 🌍 Global |
|
|
75
75
|
| `get_alerts` | Active watches, warnings, and advisories sorted by severity; official national warnings for the US (NOAA), Canada (ECCC), 38 European countries (MeteoAlarm), India (NDMA SACHET), the Philippines (PAGASA), Indonesia (BMKG), and Japan (JMA) | 🇺🇸 🇨🇦 🇪🇺 🇮🇳 🇵🇭 🇮🇩 🇯🇵 |
|
|
76
76
|
| `get_historical_weather` | Hourly/daily observations from 1940 to present | 🌍 Global |
|
|
77
|
-
| `get_weather_summary` | One-call overview combining current conditions, forecast, and alerts (optionally air quality and lightning) | 🌍 Global |
|
|
77
|
+
| `get_weather_summary` | One-call overview combining current conditions, forecast, and alerts (optionally air quality and lightning); a life-threatening US alert is surfaced once above the whole summary, not once per section | 🌍 Global |
|
|
78
78
|
| `search_location` | Geocode place names to coordinates ("Paris" → 48.85, 2.35) | 🌍 Global |
|
|
79
79
|
| `get_air_quality` | AQI (US/European scales), pollutants, UV index, health guidance; current pollen levels for European locations (or worldwide with an optional key); optional day-grouped forecast up to 7 days with per-day peak AQI and UV | 🌍 Global |
|
|
80
80
|
| `get_marine_conditions` | Wave height, swell, ocean currents, sea state on WMO Code Table 3700 (Douglas sea scale) with a severity marker and legend — includes Great Lakes and major US bays; forecast up to 16 days | 🌍 Global |
|
|
@@ -226,6 +226,12 @@ Control which tools are exposed to reduce context overhead:
|
|
|
226
226
|
| `full` | everything — standard + marine, imagery, lightning, rivers, wildfire (same as `all`) |
|
|
227
227
|
| `all` | all 17 tools |
|
|
228
228
|
|
|
229
|
+
**Context cost.** Every MCP client puts the `tools/list` result into model context on
|
|
230
|
+
every turn, so the preset you choose is a standing cost on every request. Measured on
|
|
231
|
+
the built server: `basic` **12,987 bytes** (~3.2k tokens), `standard` **20,961** (~5.2k),
|
|
232
|
+
`full`/`all` **30,836** (~7.7k). It scales with the number of **tools**, not the number of
|
|
233
|
+
data sources — adding Japan and India as alert authorities added zero tools and zero bytes.
|
|
234
|
+
|
|
229
235
|
```bash
|
|
230
236
|
ENABLED_TOOLS=all # Use a preset
|
|
231
237
|
ENABLED_TOOLS=forecast,current,alerts,aqi # Specific tools only
|
|
@@ -380,7 +386,7 @@ Being honest about what free public data can and can't do:
|
|
|
380
386
|
```bash
|
|
381
387
|
npm run build # Compile TypeScript
|
|
382
388
|
npm run dev # Run in development mode
|
|
383
|
-
npm test # Run all 3,
|
|
389
|
+
npm test # Run all 3,292 tests
|
|
384
390
|
npm run test:coverage # Coverage report
|
|
385
391
|
npm run audit # Dependency vulnerability scan
|
|
386
392
|
```
|
|
@@ -107,6 +107,37 @@ export declare const DisplayThresholds: {
|
|
|
107
107
|
/** Compute/render WBGT only when air temp (°F) is at or above showHeatIndex and rounded WBGT (°F) is at or above this */
|
|
108
108
|
readonly showWbgtF: 80;
|
|
109
109
|
};
|
|
110
|
+
/**
|
|
111
|
+
* Life-threatening alert banner gate
|
|
112
|
+
*/
|
|
113
|
+
readonly criticalAlert: {
|
|
114
|
+
/**
|
|
115
|
+
* Display gates only. The predicate that reads them lives in
|
|
116
|
+
* `src/utils/criticalAlert.ts`, which owns the *shape* of the rule — the
|
|
117
|
+
* three-axis leg is an `and`, the response leg stands alone, and the two
|
|
118
|
+
* are `or`ed. Widening a list here loosens the gate; it cannot change that
|
|
119
|
+
* shape.
|
|
120
|
+
*
|
|
121
|
+
* These are membership lists rather than a rank because CAP's severity,
|
|
122
|
+
* urgency and certainty are unordered enums as far as this repo is
|
|
123
|
+
* concerned: `CAP_SEVERITY_ORDER` in `alertsHandler.ts` is a sort rank for
|
|
124
|
+
* display, and reusing it here would tie a safety gate to a presentation
|
|
125
|
+
* decision.
|
|
126
|
+
*
|
|
127
|
+
* Calibrated against the live national feed — see the Verification section
|
|
128
|
+
* of the design plan for the histogram the current values were read from.
|
|
129
|
+
* Tuning is a config change here, deliberately, so re-calibration never
|
|
130
|
+
* needs a code review of the predicate.
|
|
131
|
+
*/
|
|
132
|
+
/** CAP `severity` values that can reach the gate's three-axis leg */
|
|
133
|
+
readonly severities: readonly string[];
|
|
134
|
+
/** CAP `urgency` values that can reach the gate's three-axis leg */
|
|
135
|
+
readonly urgencies: readonly string[];
|
|
136
|
+
/** CAP `certainty` values that can reach the gate's three-axis leg */
|
|
137
|
+
readonly certainties: readonly string[];
|
|
138
|
+
/** CAP `response` values that fire the gate on their own, whatever the severity */
|
|
139
|
+
readonly responses: readonly string[];
|
|
140
|
+
};
|
|
110
141
|
};
|
|
111
142
|
/**
|
|
112
143
|
* API-related constants
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"displayThresholds.d.ts","sourceRoot":"","sources":["../../src/config/displayThresholds.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,iBAAiB;IAC5B;;OAEG;aACH,WAAW;QACT,2DAA2D;iBAC3D,aAAa,EAAE,EAAE;QACjB,2DAA2D;iBAC3D,aAAa,EAAE,EAAE;QACjB;;;;;;WAMG;iBACH,YAAY;qBACV,CAAC,EAAE,CAAC;qBACJ,CAAC,EAAE,CAAC;;;IAIR;;OAEG;aACH,IAAI;QACF,4FAA4F;iBAC5F,qBAAqB,EAAE,GAAG;;IAG5B;;OAEG;aACH,UAAU;QACR,gBAAgB;iBAChB,QAAQ,EAAE,IAAI;QACd,UAAU;iBACV,GAAG,EAAE,CAAG;QACR,mBAAmB;iBACnB,QAAQ,EAAE,CAAG;QACb,uBAAuB;iBACvB,KAAK,EAAE,EAAI;;IAGb;;OAEG;aACH,iBAAiB;QACf;;;;WAIG;iBACH,mBAAmB,EAAE,GAAG;QACxB;;;;WAIG;iBACH,sBAAsB,EAAE,GAAG;QAC3B;;;WAGG;iBACH,kBAAkB,EAAE,CAAC;;IAGvB;;OAEG;aACH,aAAa;QACX,4CAA4C;iBAC5C,KAAK,EAAE,GAAG;QACV,+CAA+C;iBAC/C,QAAQ,EAAE,GAAG;QACb,4CAA4C;iBAC5C,KAAK,EAAE,GAAG;QACV;;;;;;;;;WASG;iBACH,UAAU;qBACR,IAAI,EAAE,KAAK;qBACX,EAAE,EAAE,IAAI;;;IAIZ;;OAEG;aACH,aAAa;QACX;;;;;;WAMG;QACH,mFAAmF;iBACnF,yBAAyB,EAAE,CAAC,EAAE;QAC9B,yHAAyH;iBACzH,SAAS,EAAE,EAAE;;
|
|
1
|
+
{"version":3,"file":"displayThresholds.d.ts","sourceRoot":"","sources":["../../src/config/displayThresholds.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,iBAAiB;IAC5B;;OAEG;aACH,WAAW;QACT,2DAA2D;iBAC3D,aAAa,EAAE,EAAE;QACjB,2DAA2D;iBAC3D,aAAa,EAAE,EAAE;QACjB;;;;;;WAMG;iBACH,YAAY;qBACV,CAAC,EAAE,CAAC;qBACJ,CAAC,EAAE,CAAC;;;IAIR;;OAEG;aACH,IAAI;QACF,4FAA4F;iBAC5F,qBAAqB,EAAE,GAAG;;IAG5B;;OAEG;aACH,UAAU;QACR,gBAAgB;iBAChB,QAAQ,EAAE,IAAI;QACd,UAAU;iBACV,GAAG,EAAE,CAAG;QACR,mBAAmB;iBACnB,QAAQ,EAAE,CAAG;QACb,uBAAuB;iBACvB,KAAK,EAAE,EAAI;;IAGb;;OAEG;aACH,iBAAiB;QACf;;;;WAIG;iBACH,mBAAmB,EAAE,GAAG;QACxB;;;;WAIG;iBACH,sBAAsB,EAAE,GAAG;QAC3B;;;WAGG;iBACH,kBAAkB,EAAE,CAAC;;IAGvB;;OAEG;aACH,aAAa;QACX,4CAA4C;iBAC5C,KAAK,EAAE,GAAG;QACV,+CAA+C;iBAC/C,QAAQ,EAAE,GAAG;QACb,4CAA4C;iBAC5C,KAAK,EAAE,GAAG;QACV;;;;;;;;;WASG;iBACH,UAAU;qBACR,IAAI,EAAE,KAAK;qBACX,EAAE,EAAE,IAAI;;;IAIZ;;OAEG;aACH,aAAa;QACX;;;;;;WAMG;QACH,mFAAmF;iBACnF,yBAAyB,EAAE,CAAC,EAAE;QAC9B,yHAAyH;iBACzH,SAAS,EAAE,EAAE;;IAGf;;OAEG;aACH,aAAa;QACX;;;;;;;;;;;;;;;;;WAiBG;QACH,qEAAqE;iBACrE,UAAU,EAAiB,SAAS,MAAM,EAAE;QAC5C,oEAAoE;iBACpE,SAAS,EAAmB,SAAS,MAAM,EAAE;QAC7C,sEAAsE;iBACtE,WAAW,EAA4B,SAAS,MAAM,EAAE;QACxD,mFAAmF;iBACnF,SAAS,EAAkB,SAAS,MAAM,EAAE;;CAEtC,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,YAAY;IACvB;;;OAGG;aACH,2BAA2B,EAAE,CAAC;IAE9B;;OAEG;aACH,uBAAuB,EAAE,EAAE;CACnB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe;IAC1B;;OAEG;aACH,mBAAmB,EAAE,CAAC;IAEtB;;OAEG;aACH,eAAe,EAAE,EAAE;IAEnB;;OAEG;aACH,sBAAsB,EAAE,GAAG;IAE3B;;;;;OAKG;aACH,kBAAkB,EAAE,GAAG;CACf,CAAC"}
|
|
@@ -107,6 +107,37 @@ export const DisplayThresholds = {
|
|
|
107
107
|
/** Compute/render WBGT only when air temp (°F) is at or above showHeatIndex and rounded WBGT (°F) is at or above this */
|
|
108
108
|
showWbgtF: 80,
|
|
109
109
|
},
|
|
110
|
+
/**
|
|
111
|
+
* Life-threatening alert banner gate
|
|
112
|
+
*/
|
|
113
|
+
criticalAlert: {
|
|
114
|
+
/**
|
|
115
|
+
* Display gates only. The predicate that reads them lives in
|
|
116
|
+
* `src/utils/criticalAlert.ts`, which owns the *shape* of the rule — the
|
|
117
|
+
* three-axis leg is an `and`, the response leg stands alone, and the two
|
|
118
|
+
* are `or`ed. Widening a list here loosens the gate; it cannot change that
|
|
119
|
+
* shape.
|
|
120
|
+
*
|
|
121
|
+
* These are membership lists rather than a rank because CAP's severity,
|
|
122
|
+
* urgency and certainty are unordered enums as far as this repo is
|
|
123
|
+
* concerned: `CAP_SEVERITY_ORDER` in `alertsHandler.ts` is a sort rank for
|
|
124
|
+
* display, and reusing it here would tie a safety gate to a presentation
|
|
125
|
+
* decision.
|
|
126
|
+
*
|
|
127
|
+
* Calibrated against the live national feed — see the Verification section
|
|
128
|
+
* of the design plan for the histogram the current values were read from.
|
|
129
|
+
* Tuning is a config change here, deliberately, so re-calibration never
|
|
130
|
+
* needs a code review of the predicate.
|
|
131
|
+
*/
|
|
132
|
+
/** CAP `severity` values that can reach the gate's three-axis leg */
|
|
133
|
+
severities: ['Extreme'],
|
|
134
|
+
/** CAP `urgency` values that can reach the gate's three-axis leg */
|
|
135
|
+
urgencies: ['Immediate'],
|
|
136
|
+
/** CAP `certainty` values that can reach the gate's three-axis leg */
|
|
137
|
+
certainties: ['Observed', 'Likely'],
|
|
138
|
+
/** CAP `response` values that fire the gate on their own, whatever the severity */
|
|
139
|
+
responses: ['Evacuate'],
|
|
140
|
+
},
|
|
110
141
|
};
|
|
111
142
|
/**
|
|
112
143
|
* API-related constants
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"displayThresholds.js","sourceRoot":"","sources":["../../src/config/displayThresholds.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B;;OAEG;IACH,WAAW,EAAE;QACX,2DAA2D;QAC3D,aAAa,EAAE,EAAE;QACjB,2DAA2D;QAC3D,aAAa,EAAE,EAAE;QACjB;;;;;;WAMG;QACH,YAAY,EAAE;YACZ,CAAC,EAAE,CAAC;YACJ,CAAC,EAAE,CAAC;SACL;KACF;IAED;;OAEG;IACH,IAAI,EAAE;QACJ,4FAA4F;QAC5F,qBAAqB,EAAE,GAAG;KAC3B;IAED;;OAEG;IACH,UAAU,EAAE;QACV,gBAAgB;QAChB,QAAQ,EAAE,IAAI;QACd,UAAU;QACV,GAAG,EAAE,GAAG;QACR,mBAAmB;QACnB,QAAQ,EAAE,GAAG;QACb,uBAAuB;QACvB,KAAK,EAAE,IAAI;KACZ;IAED;;OAEG;IACH,iBAAiB,EAAE;QACjB;;;;WAIG;QACH,mBAAmB,EAAE,GAAG;QACxB;;;;WAIG;QACH,sBAAsB,EAAE,GAAG;QAC3B;;;WAGG;QACH,kBAAkB,EAAE,CAAC;KACtB;IAED;;OAEG;IACH,aAAa,EAAE;QACb,4CAA4C;QAC5C,KAAK,EAAE,GAAG;QACV,+CAA+C;QAC/C,QAAQ,EAAE,GAAG;QACb,4CAA4C;QAC5C,KAAK,EAAE,GAAG;QACV;;;;;;;;;WASG;QACH,UAAU,EAAE;YACV,IAAI,EAAE,KAAK;YACX,EAAE,EAAE,IAAI;SACT;KACF;IAED;;OAEG;IACH,aAAa,EAAE;QACb;;;;;;WAMG;QACH,mFAAmF;QACnF,yBAAyB,EAAE,CAAC,EAAE;QAC9B,yHAAyH;QACzH,SAAS,EAAE,EAAE;KACd;CACO,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B;;;OAGG;IACH,2BAA2B,EAAE,CAAC;IAE9B;;OAEG;IACH,uBAAuB,EAAE,EAAE;CACnB,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B;;OAEG;IACH,mBAAmB,EAAE,CAAC;IAEtB;;OAEG;IACH,eAAe,EAAE,EAAE;IAEnB;;OAEG;IACH,sBAAsB,EAAE,GAAG,EAAE,0BAA0B;IAEvD;;;;;OAKG;IACH,kBAAkB,EAAE,GAAG;CACf,CAAC"}
|
|
1
|
+
{"version":3,"file":"displayThresholds.js","sourceRoot":"","sources":["../../src/config/displayThresholds.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B;;OAEG;IACH,WAAW,EAAE;QACX,2DAA2D;QAC3D,aAAa,EAAE,EAAE;QACjB,2DAA2D;QAC3D,aAAa,EAAE,EAAE;QACjB;;;;;;WAMG;QACH,YAAY,EAAE;YACZ,CAAC,EAAE,CAAC;YACJ,CAAC,EAAE,CAAC;SACL;KACF;IAED;;OAEG;IACH,IAAI,EAAE;QACJ,4FAA4F;QAC5F,qBAAqB,EAAE,GAAG;KAC3B;IAED;;OAEG;IACH,UAAU,EAAE;QACV,gBAAgB;QAChB,QAAQ,EAAE,IAAI;QACd,UAAU;QACV,GAAG,EAAE,GAAG;QACR,mBAAmB;QACnB,QAAQ,EAAE,GAAG;QACb,uBAAuB;QACvB,KAAK,EAAE,IAAI;KACZ;IAED;;OAEG;IACH,iBAAiB,EAAE;QACjB;;;;WAIG;QACH,mBAAmB,EAAE,GAAG;QACxB;;;;WAIG;QACH,sBAAsB,EAAE,GAAG;QAC3B;;;WAGG;QACH,kBAAkB,EAAE,CAAC;KACtB;IAED;;OAEG;IACH,aAAa,EAAE;QACb,4CAA4C;QAC5C,KAAK,EAAE,GAAG;QACV,+CAA+C;QAC/C,QAAQ,EAAE,GAAG;QACb,4CAA4C;QAC5C,KAAK,EAAE,GAAG;QACV;;;;;;;;;WASG;QACH,UAAU,EAAE;YACV,IAAI,EAAE,KAAK;YACX,EAAE,EAAE,IAAI;SACT;KACF;IAED;;OAEG;IACH,aAAa,EAAE;QACb;;;;;;WAMG;QACH,mFAAmF;QACnF,yBAAyB,EAAE,CAAC,EAAE;QAC9B,yHAAyH;QACzH,SAAS,EAAE,EAAE;KACd;IAED;;OAEG;IACH,aAAa,EAAE;QACb;;;;;;;;;;;;;;;;;WAiBG;QACH,qEAAqE;QACrE,UAAU,EAAE,CAAC,SAAS,CAAsB;QAC5C,oEAAoE;QACpE,SAAS,EAAE,CAAC,WAAW,CAAsB;QAC7C,sEAAsE;QACtE,WAAW,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAsB;QACxD,mFAAmF;QACnF,SAAS,EAAE,CAAC,UAAU,CAAsB;KAC7C;CACO,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B;;;OAGG;IACH,2BAA2B,EAAE,CAAC;IAE9B;;OAEG;IACH,uBAAuB,EAAE,EAAE;CACnB,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B;;OAEG;IACH,mBAAmB,EAAE,CAAC;IAEtB;;OAEG;IACH,eAAe,EAAE,EAAE;IAEnB;;OAEG;IACH,sBAAsB,EAAE,GAAG,EAAE,0BAA0B;IAEvD;;;;;OAKG;IACH,kBAAkB,EAAE,GAAG;CACf,CAAC"}
|
package/dist/config/tools.d.ts
CHANGED
|
@@ -41,5 +41,15 @@ declare class ToolConfig {
|
|
|
41
41
|
export declare const toolConfig: ToolConfig;
|
|
42
42
|
export declare const PRESETS: Record<string, ("check_service_status" | "get_air_quality" | "get_alerts" | "get_current_conditions" | "get_forecast" | "get_historical_weather" | "get_lightning_activity" | "get_marine_conditions" | "get_river_conditions" | "get_saved_location" | "get_weather_imagery" | "get_weather_summary" | "get_wildfire_info" | "list_saved_locations" | "remove_saved_location" | "save_location" | "search_location")[]>;
|
|
43
43
|
export declare const ALIASES: Record<string, "check_service_status" | "get_air_quality" | "get_alerts" | "get_current_conditions" | "get_forecast" | "get_historical_weather" | "get_lightning_activity" | "get_marine_conditions" | "get_river_conditions" | "get_saved_location" | "get_weather_imagery" | "get_weather_summary" | "get_wildfire_info" | "list_saved_locations" | "remove_saved_location" | "save_location" | "search_location">;
|
|
44
|
+
/**
|
|
45
|
+
* Ceiling on the JSON size of the `tools/list` result, per preset, in bytes.
|
|
46
|
+
* Every MCP client puts this payload into model context on every turn, so it is
|
|
47
|
+
* a standing context cost. Each value is the measured payload rounded up to the
|
|
48
|
+
* next 1,000 bytes, so growth past it is a deliberate edit of this file rather
|
|
49
|
+
* than a description that quietly grew. Measured 2026-09-08 in UTF-8 bytes
|
|
50
|
+
* (Buffer.byteLength, not String.length — the descriptions carry em-dashes, and
|
|
51
|
+
* a code-unit count under-reports): basic 12,987, full 30,836.
|
|
52
|
+
*/
|
|
53
|
+
export declare const TOOLS_LIST_BYTE_BUDGET: Record<'basic' | 'full', number>;
|
|
44
54
|
export {};
|
|
45
55
|
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/config/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;GAEG;AAKH,eAAO,MAAM,UAAU,YACrB,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,mBAAmB,EACnB,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,CACf,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;AAmOjD;;GAEG;AACH,cAAM,UAAU;IACd,OAAO,CAAC,YAAY,CAAgB;IAEpC,cASC;IAED;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAEjC;IAED;;OAEG;IACH,eAAe,IAAI,QAAQ,EAAE,CAE5B;IAED;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAE9C;IAED;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAE5C;CACF;AAGD,eAAO,MAAM,UAAU,YAAmB,CAAC;AAG3C,eAAO,MAAM,OAAO,0ZAAe,CAAC;AACpC,eAAO,MAAM,OAAO,sZAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/config/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;GAEG;AAKH,eAAO,MAAM,UAAU,YACrB,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,mBAAmB,EACnB,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,CACf,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;AAmOjD;;GAEG;AACH,cAAM,UAAU;IACd,OAAO,CAAC,YAAY,CAAgB;IAEpC,cASC;IAED;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAEjC;IAED;;OAEG;IACH,eAAe,IAAI,QAAQ,EAAE,CAE5B;IAED;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAE9C;IAED;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAE5C;CACF;AAGD,eAAO,MAAM,UAAU,YAAmB,CAAC;AAG3C,eAAO,MAAM,OAAO,0ZAAe,CAAC;AACpC,eAAO,MAAM,OAAO,sZAAe,CAAC;AAEpC;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,EAAE,MAAM,CAGnE,CAAC"}
|
package/dist/config/tools.js
CHANGED
|
@@ -294,4 +294,17 @@ export const toolConfig = new ToolConfig();
|
|
|
294
294
|
// Export preset definitions for documentation
|
|
295
295
|
export const PRESETS = TOOL_PRESETS;
|
|
296
296
|
export const ALIASES = TOOL_ALIASES;
|
|
297
|
+
/**
|
|
298
|
+
* Ceiling on the JSON size of the `tools/list` result, per preset, in bytes.
|
|
299
|
+
* Every MCP client puts this payload into model context on every turn, so it is
|
|
300
|
+
* a standing context cost. Each value is the measured payload rounded up to the
|
|
301
|
+
* next 1,000 bytes, so growth past it is a deliberate edit of this file rather
|
|
302
|
+
* than a description that quietly grew. Measured 2026-09-08 in UTF-8 bytes
|
|
303
|
+
* (Buffer.byteLength, not String.length — the descriptions carry em-dashes, and
|
|
304
|
+
* a code-unit count under-reports): basic 12,987, full 30,836.
|
|
305
|
+
*/
|
|
306
|
+
export const TOOLS_LIST_BYTE_BUDGET = {
|
|
307
|
+
basic: 13000,
|
|
308
|
+
full: 31000,
|
|
309
|
+
};
|
|
297
310
|
//# sourceMappingURL=tools.js.map
|
package/dist/config/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/config/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;GAEG;AACH,6EAA6E;AAC7E,4EAA4E;AAC5E,4EAA4E;AAC5E,4CAA4C;AAC5C,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,cAAc;IACd,wBAAwB;IACxB,YAAY;IACZ,wBAAwB;IACxB,qBAAqB;IACrB,sBAAsB;IACtB,iBAAiB;IACjB,iBAAiB;IACjB,uBAAuB;IACvB,qBAAqB;IACrB,wBAAwB;IACxB,sBAAsB;IACtB,mBAAmB;IACnB,eAAe;IACf,sBAAsB;IACtB,oBAAoB;IACpB,uBAAuB;CACf,CAAC;AAIX;;GAEG;AACH,MAAM,YAAY,GAA+B;IAC/C,8EAA8E;IAC9E,8EAA8E;IAC9E,uEAAuE;IACvE,8EAA8E;IAC9E,+DAA+D;IAC/D,KAAK,EAAE;QACL,qBAAqB;QACrB,cAAc;QACd,wBAAwB;QACxB,YAAY;QACZ,iBAAiB;QACjB,sBAAsB;KACvB;IAED,mEAAmE;IACnE,QAAQ,EAAE;QACR,qBAAqB;QACrB,cAAc;QACd,wBAAwB;QACxB,YAAY;QACZ,wBAAwB;QACxB,iBAAiB;QACjB,iBAAiB;QACjB,sBAAsB;QACtB,eAAe;QACf,sBAAsB;QACtB,oBAAoB;QACpB,uBAAuB;KACxB;IAED,uEAAuE;IACvE,IAAI,EAAE;QACJ,qBAAqB;QACrB,cAAc;QACd,wBAAwB;QACxB,YAAY;QACZ,wBAAwB;QACxB,iBAAiB;QACjB,uBAAuB;QACvB,qBAAqB;QACrB,wBAAwB;QACxB,sBAAsB;QACtB,mBAAmB;QACnB,iBAAiB;QACjB,sBAAsB;QACtB,eAAe;QACf,sBAAsB;QACtB,oBAAoB;QACpB,uBAAuB;KACxB;IAED,gDAAgD;IAChD,GAAG,EAAE;QACH,qBAAqB;QACrB,cAAc;QACd,wBAAwB;QACxB,YAAY;QACZ,wBAAwB;QACxB,sBAAsB;QACtB,iBAAiB;QACjB,iBAAiB;QACjB,uBAAuB;QACvB,qBAAqB;QACrB,wBAAwB;QACxB,sBAAsB;QACtB,mBAAmB;QACnB,eAAe;QACf,sBAAsB;QACtB,oBAAoB;QACpB,uBAAuB;KACxB;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,YAAY,GAA6B;IAC7C,UAAU,EAAE,cAAc;IAC1B,SAAS,EAAE,wBAAwB;IACnC,YAAY,EAAE,wBAAwB;IACtC,QAAQ,EAAE,YAAY;IACtB,UAAU,EAAE,YAAY;IACxB,YAAY,EAAE,wBAAwB;IACtC,SAAS,EAAE,wBAAwB;IACnC,SAAS,EAAE,qBAAqB;IAChC,iBAAiB,EAAE,qBAAqB;IACxC,UAAU,EAAE,qBAAqB;IACjC,QAAQ,EAAE,sBAAsB;IAChC,UAAU,EAAE,iBAAiB;IAC7B,QAAQ,EAAE,iBAAiB;IAC3B,aAAa,EAAE,iBAAiB;IAChC,KAAK,EAAE,iBAAiB;IACxB,QAAQ,EAAE,uBAAuB;IACjC,OAAO,EAAE,uBAAuB;IAChC,OAAO,EAAE,uBAAuB;IAChC,SAAS,EAAE,qBAAqB;IAChC,OAAO,EAAE,qBAAqB;IAC9B,WAAW,EAAE,qBAAqB;IAClC,WAAW,EAAE,wBAAwB;IACrC,SAAS,EAAE,wBAAwB;IACnC,cAAc,EAAE,wBAAwB;IACxC,OAAO,EAAE,sBAAsB;IAC/B,QAAQ,EAAE,sBAAsB;IAChC,OAAO,EAAE,sBAAsB;IAC/B,YAAY,EAAE,sBAAsB;IACpC,UAAU,EAAE,mBAAmB;IAC/B,WAAW,EAAE,mBAAmB;IAChC,MAAM,EAAE,mBAAmB;IAC3B,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,mBAAmB;CAC7B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,SAAS,iBAAiB,CAAC,QAA4B;IACrD,6CAA6C;IAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnF,IAAI,YAAY,GAAG,IAAI,GAAG,EAAY,CAAC;IACvC,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,2BAA2B;QAC3B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC/C,IAAI,YAAY,EAAE,CAAC;gBACjB,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,yBAAyB,QAAQ,GAAG,CAAC,CAAC;YACrD,CAAC;YACD,SAAS;QACX,CAAC;QAED,0BAA0B;QAC1B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC/C,IAAI,YAAY,EAAE,CAAC;gBACjB,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,4BAA4B,QAAQ,GAAG,CAAC,CAAC;YACxD,CAAC;YACD,SAAS;QACX,CAAC;QAED,iBAAiB;QACjB,IAAI,IAAI,IAAI,YAAY,EAAE,CAAC;YACzB,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,oCAAoC;gBACpC,YAAY,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC3C,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,yCAAyC;gBACzC,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;YACD,SAAS;QACX,CAAC;QAED,0BAA0B;QAC1B,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,0CAA0C;gBAC1C,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;gBACvC,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,4BAA4B,IAAI,GAAG,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAEtC,yCAAyC;IACzC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,OAAO,UAAsB,CAAC;IAChC,CAAC;IAED,gBAAgB;IAChB,IAAI,UAAU,IAAI,YAAY,EAAE,CAAC;QAC/B,OAAO,YAAY,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAQ,UAAgC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU;IACN,YAAY,CAAgB;IAEpC;QACE,IAAI,CAAC,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAEjE,kCAAkC;QAClC,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,+BAA+B,IAAI,CAAC,YAAY,CAAC,IAAI,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,IAAc;QACtB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,UAAU;QACf,OAAO,EAAE,GAAG,YAAY,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,UAAU;QACf,OAAO,EAAE,GAAG,YAAY,EAAE,CAAC;IAC7B,CAAC;CACF;AAED,4BAA4B;AAC5B,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;AAE3C,8CAA8C;AAC9C,MAAM,CAAC,MAAM,OAAO,GAAG,YAAY,CAAC;AACpC,MAAM,CAAC,MAAM,OAAO,GAAG,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/config/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place that fetches for the life-threatening alert banner.
|
|
3
|
+
*
|
|
4
|
+
* `get_forecast`, `get_current_conditions` and `get_weather_summary` all call
|
|
5
|
+
* `resolveCriticalAlertBanner` rather than each doing their own fetch-gate-format
|
|
6
|
+
* sequence, so the **failure posture exists once**. Three copies of a safety
|
|
7
|
+
* failure posture is how one copy drifts, and the copy that drifts is the one
|
|
8
|
+
* that renders a fabricated all-clear.
|
|
9
|
+
*
|
|
10
|
+
* The posture itself is D1 of the design plan: **silent omit**, one
|
|
11
|
+
* `logger.warn`, and no retries. That is only safe because the banner is a
|
|
12
|
+
* positive assertion — its absence claims nothing. `get_alerts` still serves
|
|
13
|
+
* the same data under full contract rules, where a failure propagates. Nothing
|
|
14
|
+
* in a tool description, schema or doc may ever say these three tools "check
|
|
15
|
+
* for alerts", or absence silently becomes an implied all-clear.
|
|
16
|
+
*
|
|
17
|
+
* The gate, the selection and the copy all live in `src/utils/criticalAlert.ts`,
|
|
18
|
+
* which is pure and zero-I/O. This module is the glue between that and the
|
|
19
|
+
* service, and holds no display logic of its own.
|
|
20
|
+
*/
|
|
21
|
+
import { NOAAService } from '../services/noaa.js';
|
|
22
|
+
import type { ResolvedLocation } from '../utils/locationResolver.js';
|
|
23
|
+
/**
|
|
24
|
+
* The banner for this point, or `''` — which is every path but one.
|
|
25
|
+
*
|
|
26
|
+
* In order:
|
|
27
|
+
*
|
|
28
|
+
* 1. **US pre-filter.** `country_code` when the resolution path knew one,
|
|
29
|
+
* `isInUS` otherwise. NOAA is the only upstream in v1 (D2), so a non-US
|
|
30
|
+
* point returns without making any request at all.
|
|
31
|
+
* 2. **One fetch, no retries.** `getAlerts` caches on its own point-keyed
|
|
32
|
+
* alerts entry with the five-minute alerts TTL (`src/services/noaa.ts`), so a
|
|
33
|
+
* banner fetch and a real `get_alerts` call within five minutes share one
|
|
34
|
+
* request. This module deliberately builds no key and declares no TTL of its
|
|
35
|
+
* own — that is what keeps risk floor F5 untripped, and the acceptance check
|
|
36
|
+
* for it is a grep of this file for either construct.
|
|
37
|
+
* 3. **Any failure is silent.** One `logger.warn` and `''`. Never a
|
|
38
|
+
* "could not check alerts" note: repeated benign warnings during an upstream
|
|
39
|
+
* outage train readers to ignore the banner slot, which is worse than
|
|
40
|
+
* nothing at all.
|
|
41
|
+
* 4. **All-or-nothing.** With no critical alert this emits nothing — no header,
|
|
42
|
+
* no rule, no "no critical alerts" line.
|
|
43
|
+
*
|
|
44
|
+
* **G2 is not tripped by the pre-filter.** `isInUS` is a bounding box, but
|
|
45
|
+
* nothing about the box is rendered: a false negative omits a
|
|
46
|
+
* positive-assertion-only element and claims nothing, and a false positive (a
|
|
47
|
+
* point just over the Canadian border) costs one request that returns no alerts
|
|
48
|
+
* and therefore no banner.
|
|
49
|
+
*
|
|
50
|
+
* @param noaaService The NOAA client; its `getAlerts` is the only method called
|
|
51
|
+
* @param resolved The already-resolved location, carrying `country_code` when known
|
|
52
|
+
* @param timezone IANA zone the banner's expiry is rendered in
|
|
53
|
+
* @returns The formatted banner, or `''`
|
|
54
|
+
*/
|
|
55
|
+
export declare function resolveCriticalAlertBanner(noaaService: NOAAService, resolved: ResolvedLocation, timezone?: string): Promise<string>;
|
|
56
|
+
/**
|
|
57
|
+
* Carry an already-resolved banner on an error about to be thrown.
|
|
58
|
+
*
|
|
59
|
+
* `get_forecast` and `get_current_conditions` resolve the banner concurrently
|
|
60
|
+
* with the weather body. When the body fails, the warning is the half the
|
|
61
|
+
* caller most needs, so it travels with the error to the one place that renders
|
|
62
|
+
* errors (`src/index.ts`) instead of being dropped. This keeps error formatting
|
|
63
|
+
* and error logging at that single site rather than duplicating either here.
|
|
64
|
+
*
|
|
65
|
+
* An empty banner attaches nothing at all, so a failure with no critical alert
|
|
66
|
+
* — every non-US point, and every US point with nothing life-threatening
|
|
67
|
+
* active — is byte-identical to what it was before.
|
|
68
|
+
*
|
|
69
|
+
* @param error The error being thrown; returned unchanged for `throw` chaining
|
|
70
|
+
* @param banner The resolved banner, or `''`
|
|
71
|
+
* @returns The same error
|
|
72
|
+
*/
|
|
73
|
+
export declare function carryCriticalAlertBannerOnError(error: unknown, banner: string): unknown;
|
|
74
|
+
/**
|
|
75
|
+
* The banner carried by an error, or `''`.
|
|
76
|
+
*
|
|
77
|
+
* Read once, by the dispatch's error path. Returning `''` for every error that
|
|
78
|
+
* carries nothing is what keeps the existing error output unchanged.
|
|
79
|
+
*
|
|
80
|
+
* @param error The caught error
|
|
81
|
+
* @returns The carried banner, or `''`
|
|
82
|
+
*/
|
|
83
|
+
export declare function criticalAlertBannerFromError(error: unknown): string;
|
|
84
|
+
//# sourceMappingURL=criticalAlertBanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"criticalAlertBanner.d.ts","sourceRoot":"","sources":["../../src/handlers/criticalAlertBanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AA4BrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,0BAA0B,CAC9C,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAqDjB;AAYD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAKvF;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQnE"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place that fetches for the life-threatening alert banner.
|
|
3
|
+
*
|
|
4
|
+
* `get_forecast`, `get_current_conditions` and `get_weather_summary` all call
|
|
5
|
+
* `resolveCriticalAlertBanner` rather than each doing their own fetch-gate-format
|
|
6
|
+
* sequence, so the **failure posture exists once**. Three copies of a safety
|
|
7
|
+
* failure posture is how one copy drifts, and the copy that drifts is the one
|
|
8
|
+
* that renders a fabricated all-clear.
|
|
9
|
+
*
|
|
10
|
+
* The posture itself is D1 of the design plan: **silent omit**, one
|
|
11
|
+
* `logger.warn`, and no retries. That is only safe because the banner is a
|
|
12
|
+
* positive assertion — its absence claims nothing. `get_alerts` still serves
|
|
13
|
+
* the same data under full contract rules, where a failure propagates. Nothing
|
|
14
|
+
* in a tool description, schema or doc may ever say these three tools "check
|
|
15
|
+
* for alerts", or absence silently becomes an implied all-clear.
|
|
16
|
+
*
|
|
17
|
+
* The gate, the selection and the copy all live in `src/utils/criticalAlert.ts`,
|
|
18
|
+
* which is pure and zero-I/O. This module is the glue between that and the
|
|
19
|
+
* service, and holds no display logic of its own.
|
|
20
|
+
*/
|
|
21
|
+
import { isInUS } from '../utils/geography.js';
|
|
22
|
+
import { logger } from '../utils/logger.js';
|
|
23
|
+
import { formatCriticalAlertBanner, selectCriticalAlert, } from '../utils/criticalAlert.js';
|
|
24
|
+
/**
|
|
25
|
+
* The HTTP status an error carries, or `undefined`.
|
|
26
|
+
*
|
|
27
|
+
* Reads the two shapes this path can see — an `ApiError` subclass's
|
|
28
|
+
* `statusCode`, and an axios error's `response.status` — and nothing else. A
|
|
29
|
+
* bare number is the whole of what is logged: no message, no config, no URL.
|
|
30
|
+
*/
|
|
31
|
+
function httpStatusOf(error) {
|
|
32
|
+
if (typeof error !== 'object' || error === null) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
const record = error;
|
|
36
|
+
if (typeof record.statusCode === 'number') {
|
|
37
|
+
return record.statusCode;
|
|
38
|
+
}
|
|
39
|
+
if (typeof record.response?.status === 'number') {
|
|
40
|
+
return record.response.status;
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The banner for this point, or `''` — which is every path but one.
|
|
46
|
+
*
|
|
47
|
+
* In order:
|
|
48
|
+
*
|
|
49
|
+
* 1. **US pre-filter.** `country_code` when the resolution path knew one,
|
|
50
|
+
* `isInUS` otherwise. NOAA is the only upstream in v1 (D2), so a non-US
|
|
51
|
+
* point returns without making any request at all.
|
|
52
|
+
* 2. **One fetch, no retries.** `getAlerts` caches on its own point-keyed
|
|
53
|
+
* alerts entry with the five-minute alerts TTL (`src/services/noaa.ts`), so a
|
|
54
|
+
* banner fetch and a real `get_alerts` call within five minutes share one
|
|
55
|
+
* request. This module deliberately builds no key and declares no TTL of its
|
|
56
|
+
* own — that is what keeps risk floor F5 untripped, and the acceptance check
|
|
57
|
+
* for it is a grep of this file for either construct.
|
|
58
|
+
* 3. **Any failure is silent.** One `logger.warn` and `''`. Never a
|
|
59
|
+
* "could not check alerts" note: repeated benign warnings during an upstream
|
|
60
|
+
* outage train readers to ignore the banner slot, which is worse than
|
|
61
|
+
* nothing at all.
|
|
62
|
+
* 4. **All-or-nothing.** With no critical alert this emits nothing — no header,
|
|
63
|
+
* no rule, no "no critical alerts" line.
|
|
64
|
+
*
|
|
65
|
+
* **G2 is not tripped by the pre-filter.** `isInUS` is a bounding box, but
|
|
66
|
+
* nothing about the box is rendered: a false negative omits a
|
|
67
|
+
* positive-assertion-only element and claims nothing, and a false positive (a
|
|
68
|
+
* point just over the Canadian border) costs one request that returns no alerts
|
|
69
|
+
* and therefore no banner.
|
|
70
|
+
*
|
|
71
|
+
* @param noaaService The NOAA client; its `getAlerts` is the only method called
|
|
72
|
+
* @param resolved The already-resolved location, carrying `country_code` when known
|
|
73
|
+
* @param timezone IANA zone the banner's expiry is rendered in
|
|
74
|
+
* @returns The formatted banner, or `''`
|
|
75
|
+
*/
|
|
76
|
+
export async function resolveCriticalAlertBanner(noaaService, resolved, timezone) {
|
|
77
|
+
const { latitude, longitude } = resolved;
|
|
78
|
+
// country_code first, isInUS second. A saved or geocoded location already
|
|
79
|
+
// knows its country, so the common case costs no geography at all. Casing
|
|
80
|
+
// follows the upstream source (saved locations store "US", geocoders vary),
|
|
81
|
+
// hence the case-insensitive compare.
|
|
82
|
+
const countryCode = resolved.country_code;
|
|
83
|
+
const isUS = typeof countryCode === 'string' && countryCode.length > 0
|
|
84
|
+
? countryCode.toLowerCase() === 'us'
|
|
85
|
+
: isInUS(latitude, longitude);
|
|
86
|
+
if (!isUS) {
|
|
87
|
+
return '';
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
const alerts = await noaaService.getAlerts(latitude, longitude, true);
|
|
91
|
+
const features = Array.isArray(alerts?.features) ? alerts.features : [];
|
|
92
|
+
if (features.length === 0) {
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
// `properties` is required on the documented shape but a third-party
|
|
96
|
+
// response may omit it, so the map tolerates a feature without one rather
|
|
97
|
+
// than throwing inside a garnish path.
|
|
98
|
+
const candidates = features.map((feature) => (feature?.properties ?? {}));
|
|
99
|
+
return formatCriticalAlertBanner(selectCriticalAlert(candidates), features.length, timezone);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
// Exactly one warn, carrying no URL and no raw axios error. The banner is
|
|
103
|
+
// garnish (D1): this must add no latency and must never rethrow, because
|
|
104
|
+
// the forecast the caller actually asked for still has to render.
|
|
105
|
+
//
|
|
106
|
+
// The impl plan's contract is "no URL and no raw axios error", and
|
|
107
|
+
// `error.message` was carrying exactly that — "Request failed with status
|
|
108
|
+
// code 503" is the axios message, and an axios message is one upstream
|
|
109
|
+
// change away from carrying the request URL with it. What is logged is
|
|
110
|
+
// therefore the error's *type* and its status, the shape this project
|
|
111
|
+
// already uses for key-bearing services, which is what a reader of these
|
|
112
|
+
// logs actually needs to tell a 404 from an outage.
|
|
113
|
+
logger.warn('Critical-alert banner lookup failed; omitting the banner', {
|
|
114
|
+
service: 'NOAA',
|
|
115
|
+
securityEvent: true,
|
|
116
|
+
errorType: error instanceof Error ? error.constructor.name : 'Unknown',
|
|
117
|
+
status: httpStatusOf(error),
|
|
118
|
+
});
|
|
119
|
+
return '';
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* The banner a failed weather request is carrying, if any.
|
|
124
|
+
*
|
|
125
|
+
* A `Symbol.for` key rather than a named property: it cannot collide with any
|
|
126
|
+
* field on an `ApiError` subclass, it does not appear in `JSON.stringify`, and
|
|
127
|
+
* it survives being rethrown unchanged through the handlers' existing
|
|
128
|
+
* fallback `catch` blocks.
|
|
129
|
+
*/
|
|
130
|
+
const CRITICAL_ALERT_BANNER = Symbol.for('weather-mcp.critical-alert-banner');
|
|
131
|
+
/**
|
|
132
|
+
* Carry an already-resolved banner on an error about to be thrown.
|
|
133
|
+
*
|
|
134
|
+
* `get_forecast` and `get_current_conditions` resolve the banner concurrently
|
|
135
|
+
* with the weather body. When the body fails, the warning is the half the
|
|
136
|
+
* caller most needs, so it travels with the error to the one place that renders
|
|
137
|
+
* errors (`src/index.ts`) instead of being dropped. This keeps error formatting
|
|
138
|
+
* and error logging at that single site rather than duplicating either here.
|
|
139
|
+
*
|
|
140
|
+
* An empty banner attaches nothing at all, so a failure with no critical alert
|
|
141
|
+
* — every non-US point, and every US point with nothing life-threatening
|
|
142
|
+
* active — is byte-identical to what it was before.
|
|
143
|
+
*
|
|
144
|
+
* @param error The error being thrown; returned unchanged for `throw` chaining
|
|
145
|
+
* @param banner The resolved banner, or `''`
|
|
146
|
+
* @returns The same error
|
|
147
|
+
*/
|
|
148
|
+
export function carryCriticalAlertBannerOnError(error, banner) {
|
|
149
|
+
if (banner && typeof error === 'object' && error !== null) {
|
|
150
|
+
error[CRITICAL_ALERT_BANNER] = banner;
|
|
151
|
+
}
|
|
152
|
+
return error;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* The banner carried by an error, or `''`.
|
|
156
|
+
*
|
|
157
|
+
* Read once, by the dispatch's error path. Returning `''` for every error that
|
|
158
|
+
* carries nothing is what keeps the existing error output unchanged.
|
|
159
|
+
*
|
|
160
|
+
* @param error The caught error
|
|
161
|
+
* @returns The carried banner, or `''`
|
|
162
|
+
*/
|
|
163
|
+
export function criticalAlertBannerFromError(error) {
|
|
164
|
+
if (typeof error === 'object' && error !== null) {
|
|
165
|
+
const banner = error[CRITICAL_ALERT_BANNER];
|
|
166
|
+
if (typeof banner === 'string') {
|
|
167
|
+
return banner;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return '';
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=criticalAlertBanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"criticalAlertBanner.js","sourceRoot":"","sources":["../../src/handlers/criticalAlertBanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ import { AcisService } from '../services/acis.js';
|
|
|
8
8
|
import { AviationWeatherService } from '../services/aviationWeather.js';
|
|
9
9
|
import { LocationStore } from '../services/locationStore.js';
|
|
10
10
|
import { GeocodingService } from '../services/geocoding.js';
|
|
11
|
-
export declare function handleGetCurrentConditions(args: unknown, noaaService: NOAAService, openMeteoService: OpenMeteoService, nceiService: NCEIService, locationStore: LocationStore, geocodingService: GeocodingService, acisService?: AcisService, aviationWeatherService?: AviationWeatherService): Promise<{
|
|
11
|
+
export declare function handleGetCurrentConditions(args: unknown, noaaService: NOAAService, openMeteoService: OpenMeteoService, nceiService: NCEIService, locationStore: LocationStore, geocodingService: GeocodingService, acisService?: AcisService, aviationWeatherService?: AviationWeatherService, criticalAlertBanner?: boolean): Promise<{
|
|
12
12
|
content: Array<{
|
|
13
13
|
type: string;
|
|
14
14
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"currentConditionsHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/currentConditionsHandler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"currentConditionsHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/currentConditionsHandler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AA8G5D,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,OAAO,EACb,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,EAAE,WAAW,EACxB,aAAa,EAAE,aAAa,EAC5B,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,CAAC,EAAE,WAAW,EACzB,sBAAsB,CAAC,EAAE,sBAAsB,EAC/C,mBAAmB,CAAC,EAAE,OAAO,GAC5B,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAiJ7D"}
|