@dangahagan/weather-mcp 1.20.0 → 1.22.0

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.
Files changed (50) hide show
  1. package/README.md +48 -9
  2. package/dist/config/api.d.ts +28 -0
  3. package/dist/config/api.d.ts.map +1 -1
  4. package/dist/config/api.js +30 -0
  5. package/dist/config/api.js.map +1 -1
  6. package/dist/config/cache.d.ts +2 -0
  7. package/dist/config/cache.d.ts.map +1 -1
  8. package/dist/config/cache.js +9 -0
  9. package/dist/config/cache.js.map +1 -1
  10. package/dist/handlers/airQualityHandler.d.ts +2 -1
  11. package/dist/handlers/airQualityHandler.d.ts.map +1 -1
  12. package/dist/handlers/airQualityHandler.js +124 -11
  13. package/dist/handlers/airQualityHandler.js.map +1 -1
  14. package/dist/handlers/currentConditionsHandler.js +16 -40
  15. package/dist/handlers/currentConditionsHandler.js.map +1 -1
  16. package/dist/handlers/forecastHandler.d.ts.map +1 -1
  17. package/dist/handlers/forecastHandler.js +586 -45
  18. package/dist/handlers/forecastHandler.js.map +1 -1
  19. package/dist/handlers/weatherSummaryHandler.d.ts.map +1 -1
  20. package/dist/handlers/weatherSummaryHandler.js +7 -0
  21. package/dist/handlers/weatherSummaryHandler.js.map +1 -1
  22. package/dist/index.js +20 -3
  23. package/dist/index.js.map +1 -1
  24. package/dist/services/googlePollen.d.ts +72 -0
  25. package/dist/services/googlePollen.d.ts.map +1 -0
  26. package/dist/services/googlePollen.js +249 -0
  27. package/dist/services/googlePollen.js.map +1 -0
  28. package/dist/services/openmeteo.d.ts +151 -8
  29. package/dist/services/openmeteo.d.ts.map +1 -1
  30. package/dist/services/openmeteo.js +374 -54
  31. package/dist/services/openmeteo.js.map +1 -1
  32. package/dist/types/googlePollen.d.ts +67 -0
  33. package/dist/types/googlePollen.d.ts.map +1 -0
  34. package/dist/types/googlePollen.js +16 -0
  35. package/dist/types/googlePollen.js.map +1 -0
  36. package/dist/types/openmeteo.d.ts +63 -0
  37. package/dist/types/openmeteo.d.ts.map +1 -1
  38. package/dist/utils/ensembleSpread.d.ts +201 -0
  39. package/dist/utils/ensembleSpread.d.ts.map +1 -0
  40. package/dist/utils/ensembleSpread.js +312 -0
  41. package/dist/utils/ensembleSpread.js.map +1 -0
  42. package/dist/utils/modelComparison.d.ts +195 -0
  43. package/dist/utils/modelComparison.d.ts.map +1 -0
  44. package/dist/utils/modelComparison.js +364 -0
  45. package/dist/utils/modelComparison.js.map +1 -0
  46. package/dist/utils/normals.d.ts +69 -18
  47. package/dist/utils/normals.d.ts.map +1 -1
  48. package/dist/utils/normals.js +147 -67
  49. package/dist/utils/normals.js.map +1 -1
  50. package/package.json +4 -4
package/README.md CHANGED
@@ -3,12 +3,12 @@
3
3
  [![npm version](https://badge.fury.io/js/@dangahagan%2Fweather-mcp.svg)](https://www.npmjs.com/package/@dangahagan/weather-mcp)
4
4
  [![MCP Registry](https://img.shields.io/badge/MCP-Registry-blue)](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.dgahagan/weather-mcp)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
- [![Tests](https://img.shields.io/badge/tests-1%2C961%20passing-brightgreen)](./docs/testing/TEST_SUITE_README.md)
6
+ [![Tests](https://img.shields.io/badge/tests-2%2C204%20passing-brightgreen)](./docs/testing/TEST_SUITE_README.md)
7
7
  [![Node](https://img.shields.io/badge/node-%3E%3D18-339933?logo=node.js&logoColor=white)](https://nodejs.org)
8
8
 
9
9
  **Give your AI assistant real weather data — 17 tools, zero API keys, zero signup, zero cost.**
10
10
 
11
- Weather MCP is a [Model Context Protocol](https://modelcontextprotocol.io) server that connects AI assistants (Claude, Cursor, Cline, Zed, and any other MCP client) to live weather data: forecasts, current conditions, alerts, air quality, marine conditions, lightning, radar, rivers, wildfires, and 85+ years of historical weather. It's built entirely on free public data sources — NOAA, Open-Meteo, USGS, NIFC, NASA FIRMS, RainViewer, and Blitzortung.org — so there is nothing to sign up for and no key to paste in.
11
+ Weather MCP is a [Model Context Protocol](https://modelcontextprotocol.io) server that connects AI assistants (Claude, Cursor, Cline, Zed, and any other MCP client) to live weather data: forecasts, current conditions, alerts, air quality, marine conditions, lightning, radar, rivers, wildfires, and 85+ years of historical weather. It's built entirely on free public data sources — NOAA, Open-Meteo, USGS, NIFC, NASA FIRMS, RainViewer, and Blitzortung.org — so there is nothing to sign up for and no key to paste in. (A few optional keys unlock extras — see [Optional API keys](#optional-api-keys) — but no tool ever requires one.)
12
12
 
13
13
  ```bash
14
14
  claude mcp add weather -- npx -y @dangahagan/weather-mcp@latest
@@ -49,8 +49,8 @@ There are excellent commercial weather MCPs backed by paid APIs and full-time te
49
49
  Choose this one if you want:
50
50
 
51
51
  - **Genuinely free** — every data source is a free public API. No trial that expires, no credit card, no rate-limited "free tier" bait.
52
- - **No API keys** — install to first forecast in under a minute. Nothing to configure, nothing to leak into a repo.
53
- - **Fully open source** — MIT licensed, readable TypeScript, 1,961 tests. Audit it, fork it, fix it.
52
+ - **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.)
53
+ - **Fully open source** — MIT licensed, readable TypeScript, 2,204 tests. Audit it, fork it, fix it.
54
54
  - **Privacy-respecting** — your queries go directly from your machine to public weather APIs. No middleman server, no telemetry.
55
55
  - **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.
56
56
 
@@ -62,13 +62,13 @@ All 17 tools, documented in detail in **[docs/TOOLS.md](./docs/TOOLS.md)**:
62
62
 
63
63
  | Tool | What it does | Coverage |
64
64
  |------|-------------|----------|
65
- | `get_forecast` | Daily/hourly forecasts up to 16 days by coordinates, saved location, or city name; sunrise/sunset, UV, precipitation probability, optional climate-normals comparison, optional moon phase & twilight almanac | 🌍 Global |
65
+ | `get_forecast` | Daily/hourly forecasts up to 16 days by coordinates, saved location, or city name; sunrise/sunset, UV, precipitation probability, optional climate-normals comparison, optional moon phase & twilight almanac, optional five-model agreement comparison | 🌍 Global |
66
66
  | `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 | 🌍 Global |
67
67
  | `get_alerts` | Active watches, warnings, and advisories sorted by severity; official national warnings for the US (NOAA), Canada (ECCC), and 38 European countries (MeteoAlarm) | 🇺🇸 🇨🇦 🇪🇺 |
68
68
  | `get_historical_weather` | Hourly/daily observations from 1940 to present | 🌍 Global |
69
69
  | `get_weather_summary` | One-call overview combining current conditions, forecast, and alerts (optionally air quality and lightning) | 🌍 Global |
70
70
  | `search_location` | Geocode place names to coordinates ("Paris" → 48.85, 2.35) | 🌍 Global |
71
- | `get_air_quality` | AQI (US/European scales), pollutants, UV index, health guidance; current pollen levels for European locations; optional day-grouped forecast up to 7 days with per-day peak AQI and UV | 🌍 Global |
71
+ | `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 |
72
72
  | `get_marine_conditions` | Wave height, swell, ocean currents, Douglas Sea Scale — includes Great Lakes and major US bays; forecast up to 16 days | 🌍 Global |
73
73
  | `get_weather_imagery` | Precipitation radar (static or 2-hour animated loops) + GOES satellite imagery; `composite: true` returns a finished radar map over a base map as an image | 🌍 Global |
74
74
  | `get_lightning_activity` | Real-time strike detection with 4-level proximity safety assessment | 🌍 Global |
@@ -91,6 +91,8 @@ All 17 tools, documented in detail in **[docs/TOOLS.md](./docs/TOOLS.md)**:
91
91
  - **Smart source selection** — US queries use NOAA (detailed, includes forecaster narratives); everywhere else uses Open-Meteo. You never pick; it just works.
92
92
  - **International weather alerts** — `get_alerts` routes by country: NOAA in the US, Environment and Climate Change Canada alerts in Canada, and the official national warnings of 38 European countries via EUMETNET MeteoAlarm — shown unmodified, with the issuing service credited. Border cities like Toronto get the right country's alerts, not the nearest bounding box's.
93
93
  - **Real observations worldwide** — ask for what a station is *actually reporting* and `get_current_conditions` will read the nearest airport's METAR (`source="metar"`): a genuine instrument reading anywhere on earth, with the station, its distance, and the observation age always stated. Outside the US this is the difference between a measurement and a model estimate.
94
+ - **Model agreement** — ask *"how confident is this forecast?"* and `compare_models=true` compares five global models (GFS, ECMWF, ICON, GEM, UKMO) in one request, summarizing where they agree and where they split rather than dumping five forecasts. Spread across models is a proxy for uncertainty, not a guarantee — a tight spread can still be wrong, and the output says so.
95
+ - **Ensemble spread** — the sibling question: *"how confident is the model itself?"* `ensemble_spread=true` summarizes ECMWF ENS's 50 perturbed members — per-day High/Moderate/Low confidence, interquartile temperature bands, and how many members produce rain — instead of one deterministic forecast. Member fractions are raw model output, **not calibrated probabilities**: a confident ensemble can still be wrong, and the output says so. Mutually exclusive with `compare_models`; the two answer different questions.
94
96
  - **Saved locations** — save "home", "work", or "cabin" once, then ask *"what's the weather at home?"* Locations persist in `~/.weather-mcp/locations.json` and can be tagged with activities ("boating", "skiing") so the AI highlights what matters to you.
95
97
  - **Climate context** — optional 30-year climate normals show how today compares: *"10°F warmer than normal for this date."* For US locations the normals also carry the record high/low for the date and the year it was set: *"is this a record high?"*
96
98
  - **Astronomy almanac** — opt-in moon phase, illumination, moonrise/moonset, civil/nautical/astronomical twilight, and next full/new moon dates on daily forecasts (`include_astronomy`). Computed locally — accurate to the arcminute, works at the poles, costs zero API calls: *"when does it get fully dark?"*
@@ -164,7 +166,7 @@ npm run build
164
166
 
165
167
  Then point your MCP client at `node /absolute/path/to/weather-mcp/dist/index.js`.
166
168
 
167
- Requires Node.js 18+. No API keys, tokens, or accounts needed.
169
+ Requires Node.js 18+. No API keys, tokens, or accounts needed — see [Optional API keys](#optional-api-keys) for the three that add optional extras.
168
170
 
169
171
  ### Works with
170
172
 
@@ -251,10 +253,45 @@ Supported on `get_forecast`, `get_current_conditions`, and `get_historical_weath
251
253
  | `API_TIMEOUT_MS` | `30000` | Upstream API timeout (5000–120000) |
252
254
  | `WEATHER_LIGHTNING_PREWARM` | `true` | Subscribe saved locations' geohashes at startup so `get_lightning_activity` has coverage before the first query. Set `false` to skip this and avoid the persistent MQTT connection at startup. No effect when the lightning tool is disabled. |
253
255
  | `LOG_LEVEL` | `1` | 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR (logs go to stderr) |
254
- | `NCEI_API_TOKEN` | — | Optional [free NCEI token](https://www.ncdc.noaa.gov/cdo-web/token) for official NOAA climate normals (US); falls back to Open-Meteo automatically |
256
+ | `NCEI_API_TOKEN` | — | Optional [free NCEI token](https://www.ncdc.noaa.gov/cdo-web/token) for official NOAA climate normals (US); falls back to Open-Meteo automatically. See [Optional API keys](#optional-api-keys) |
257
+ | `FIRMS_MAP_KEY` | — | Optional [free FIRMS key](https://firms.modaps.eosdis.nasa.gov/api/map_key/) for targeted wildfire queries and up to 5 days of detection history. See [Optional API keys](#optional-api-keys) |
258
+ | `GOOGLE_POLLEN_API_KEY` | — | Optional key for pollen outside Europe (incl. the US). **Requires a Google Cloud billing account** — free tier is 5,000 lookups/month. See [Optional API keys](#optional-api-keys) and [the setup guide](./docs/GOOGLE_POLLEN_KEY_SETUP.md) |
255
259
 
256
260
  For caching architecture details, see [.github/CACHING.md](./.github/CACHING.md).
257
261
 
262
+ ## Optional API keys
263
+
264
+ **The default is the product.** Every one of the 17 tools works with zero keys,
265
+ zero signup, and zero cost — that is the configuration this project is built
266
+ around and the one most people should use. If that's you, you can skip this
267
+ section entirely.
268
+
269
+ Three optional keys each unlock one extra. Without them the corresponding tool
270
+ still works; it just returns the keyless answer.
271
+
272
+ | Variable | What it costs | What it adds | Without it |
273
+ |----------|---------------|--------------|------------|
274
+ | [`NCEI_API_TOKEN`](https://www.ncdc.noaa.gov/cdo-web/token) | Free registration (email) | Official NOAA station climate normals for US locations | Normals are computed from the Open-Meteo reanalysis archive — global, and the path virtually every user is already on |
275
+ | [`FIRMS_MAP_KEY`](https://firms.modaps.eosdis.nasa.gov/api/map_key/) | Free registration (email) | Targeted wildfire bbox queries with 1–5 days of detection history | Keyless 24-hour regional detection files — `get_wildfire_info` still works globally |
276
+ | `GOOGLE_POLLEN_API_KEY` | **Free tier, but requires a Google Cloud billing account (credit card on file)** — 5,000 lookups/month free, ~$10/1,000 after. [Setup guide](./docs/GOOGLE_POLLEN_KEY_SETUP.md) | Grass/tree/weed Universal Pollen Index outside Europe, including the US (65+ countries) | European pollen via CAMS still works keyless; elsewhere no pollen section renders |
277
+
278
+ The NCEI and FIRMS keys are true free registrations. **The Google Pollen key is
279
+ not** — it has a free usage tier, but Google requires a billing account with a
280
+ payment method to issue it at all. That's why it isn't described as simply
281
+ "free" anywhere in these docs, and why it stays strictly optional.
282
+
283
+ ### Standing key policy
284
+
285
+ So the "genuinely free" promise above stays meaningful, this project holds to
286
+ three rules:
287
+
288
+ 1. **Optional keys must always have a usable free tier.** A key that only makes
289
+ sense once you're paying doesn't belong here.
290
+ 2. **No tool will ever *require* a key.** Every feature has a keyless path, even
291
+ if that path is "this data isn't available for your region".
292
+ 3. **Features that would require a *paid* key are out of scope** unless there's
293
+ significant user demand for that specific service.
294
+
258
295
  ## Coverage & Limitations
259
296
 
260
297
  Being honest about what free public data can and can't do:
@@ -269,6 +306,7 @@ Being honest about what free public data can and can't do:
269
306
  | River conditions | ✅ (GloFAS modeled discharge) | Gauge observations + official flood stages via NWPS |
270
307
  | Wildfires | ✅ (FIRMS satellite detections) | Named incidents with acreage + containment via NIFC |
271
308
  | Fire weather | ✅ (computed Fosberg index + dryness context) | NOAA-published Haines, grassland, red-flag indices |
309
+ | Pollen | 🇪🇺 Europe keyless (CAMS, grains/m³); elsewhere needs an optional key | Universal Pollen Index with `GOOGLE_POLLEN_API_KEY` |
272
310
 
273
311
  - European alerts are matched at **country level** — the keyless MeteoAlarm feeds carry no region polygons, so warnings for a large country may not affect the requested point; the output says so. Canadian alerts use a real bbox query with polygon-backed features.
274
312
  - International current conditions default to **model-interpolated** values at the exact coordinates. `source="metar"` returns a **real instrument reading** instead — but from the nearest airport, which may be tens of km away and up to an hour old. The output always names the station, its distance and bearing, and the observation age, so the tradeoff is visible rather than assumed. METAR coverage follows airports, so remote land and open ocean have real gaps.
@@ -276,6 +314,7 @@ Being honest about what free public data can and can't do:
276
314
  - Non-US wildfire results are **satellite heat detections, not managed incidents** — no fire names, sizes, or containment percentages exist in the data, detections can include industrial heat sources or agricultural burns, and a clear result is not an all-clear (cloud cover hides fires; small or new fires evade detection). The output frames all of this explicitly. Keyless data covers the last 24 hours; an optional free [`FIRMS_MAP_KEY`](https://firms.modaps.eosdis.nasa.gov/api/map_key/) unlocks targeted queries and up to 5 days of detection history (`day_range`).
277
315
  - Non-US fire weather is a **Fosberg Fire Weather Index computed by this server** from current model values, not an agency-published rating — US locations get NOAA's own Haines/grassland/red-flag indices instead. The output says which it is and defers to national fire authorities; its category bands are a project heuristic.
278
316
  - Non-US river discharge is **modeled**, not observed, and has no official flood-stage thresholds — levels are shown relative to recent history and the forecast ensemble. The ~5km model grid means the reported channel may be a few km from the requested point; the output says so when it is.
317
+ - Pollen is **Europe-only without a key**: it rides the CAMS European model on the air-quality endpoint, which returns real grains/m³ in Europe and nothing anywhere else. An optional [`GOOGLE_POLLEN_API_KEY`](#optional-api-keys) fills the gap for 65+ countries including the US, as a grass/tree/weed Universal Pollen Index (0–5) rather than per-species counts. Europe keeps the richer keyless data and never contacts Google.
279
318
  - Marine data has limited coastal accuracy and is **not suitable for navigation**.
280
319
  - Lightning coverage varies by region (community-operated detector network).
281
320
  - Open-Meteo's fair-use limit is 10,000 requests/day; the built-in cache makes this hard to hit in normal use.
@@ -285,7 +324,7 @@ Being honest about what free public data can and can't do:
285
324
  ```bash
286
325
  npm run build # Compile TypeScript
287
326
  npm run dev # Run in development mode
288
- npm test # Run all 1,961 tests
327
+ npm test # Run all 2,204 tests
289
328
  npm run test:coverage # Coverage report
290
329
  npm run audit # Dependency vulnerability scan
291
330
  ```
@@ -49,4 +49,32 @@ export declare const FIRMS_MAP_KEY: string | undefined;
49
49
  * Check if FIRMS API key is available (key configured)
50
50
  */
51
51
  export declare function isFIRMSKeyAvailable(): boolean;
52
+ /**
53
+ * Google Pollen API key
54
+ *
55
+ * OPTIONAL: Create a key in the Google Cloud console
56
+ * (https://console.cloud.google.com/). Unlike the NCEI and FIRMS keys above,
57
+ * this one is **not a free registration**: it has a free usage tier, but
58
+ * **requires a Google Cloud billing account** (credit card on file).
59
+ *
60
+ * Benefits of providing a key:
61
+ * - Global pollen data for 65+ countries including the US
62
+ * - Grass/Tree/Weed Universal Pollen Index (UPI 0–5)
63
+ *
64
+ * If not provided:
65
+ * - European pollen via CAMS model continues to work
66
+ * - Pollen outside Europe is unavailable
67
+ * - No setup required
68
+ *
69
+ * Rate limits with key:
70
+ * - 5,000 lookups per month (free tier)
71
+ * - ~$10 per 1,000 lookups after free tier
72
+ *
73
+ * Setup guide: docs/GOOGLE_POLLEN_KEY_SETUP.md
74
+ */
75
+ export declare const GOOGLE_POLLEN_API_KEY: string | undefined;
76
+ /**
77
+ * Check if Google Pollen API key is available (key configured)
78
+ */
79
+ export declare function isGooglePollenKeyAvailable(): boolean;
52
80
  //# sourceMappingURL=api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/config/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,cAAc,oBAA6B,CAAC;AAEzD;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,oBAA4B,CAAC;AAEvD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/config/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,cAAc,oBAA6B,CAAC;AAEzD;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,oBAA4B,CAAC;AAEvD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,qBAAqB,oBAAoC,CAAC;AAEvE;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD"}
@@ -53,4 +53,34 @@ export const FIRMS_MAP_KEY = process.env.FIRMS_MAP_KEY;
53
53
  export function isFIRMSKeyAvailable() {
54
54
  return !!FIRMS_MAP_KEY && FIRMS_MAP_KEY.trim().length > 0;
55
55
  }
56
+ /**
57
+ * Google Pollen API key
58
+ *
59
+ * OPTIONAL: Create a key in the Google Cloud console
60
+ * (https://console.cloud.google.com/). Unlike the NCEI and FIRMS keys above,
61
+ * this one is **not a free registration**: it has a free usage tier, but
62
+ * **requires a Google Cloud billing account** (credit card on file).
63
+ *
64
+ * Benefits of providing a key:
65
+ * - Global pollen data for 65+ countries including the US
66
+ * - Grass/Tree/Weed Universal Pollen Index (UPI 0–5)
67
+ *
68
+ * If not provided:
69
+ * - European pollen via CAMS model continues to work
70
+ * - Pollen outside Europe is unavailable
71
+ * - No setup required
72
+ *
73
+ * Rate limits with key:
74
+ * - 5,000 lookups per month (free tier)
75
+ * - ~$10 per 1,000 lookups after free tier
76
+ *
77
+ * Setup guide: docs/GOOGLE_POLLEN_KEY_SETUP.md
78
+ */
79
+ export const GOOGLE_POLLEN_API_KEY = process.env.GOOGLE_POLLEN_API_KEY;
80
+ /**
81
+ * Check if Google Pollen API key is available (key configured)
82
+ */
83
+ export function isGooglePollenKeyAvailable() {
84
+ return !!GOOGLE_POLLEN_API_KEY && GOOGLE_POLLEN_API_KEY.trim().length > 0;
85
+ }
56
86
  //# sourceMappingURL=api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/config/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;AAEzD;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,CAAC,cAAc,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;AAEvD;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,CAAC,CAAC,aAAa,IAAI,aAAa,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC5D,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/config/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;AAEzD;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,CAAC,cAAc,IAAI,cAAc,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;AAEvD;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,CAAC,CAAC,aAAa,IAAI,aAAa,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;AAEvE;;GAEG;AACH,MAAM,UAAU,0BAA0B;IACxC,OAAO,CAAC,CAAC,qBAAqB,IAAI,qBAAqB,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC5E,CAAC"}
@@ -20,8 +20,10 @@ export declare const CacheConfig: {
20
20
  readonly alerts: number;
21
21
  readonly recentHistorical: number;
22
22
  readonly historicalData: number;
23
+ readonly normals: number;
23
24
  readonly serviceStatus: number;
24
25
  readonly floodDischarge: number;
26
+ readonly googlePollen: number;
25
27
  readonly records: number;
26
28
  readonly recordsStation: number;
27
29
  readonly metarObservations: number;
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/config/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAkDH,eAAO,MAAM,WAAW;aAEtB,OAAO;aAIP,OAAO;aAIP,YAAY;aAGZ,GAAG;iBAGD,eAAe;iBAIf,SAAS;iBAIT,QAAQ;iBAIR,QAAQ;iBAIR,iBAAiB;iBAIjB,MAAM;iBAIN,gBAAgB;iBAIhB,cAAc;iBAId,aAAa;iBAMb,cAAc;iBAMd,OAAO;iBAIP,cAAc;iBAMd,iBAAiB;iBAQjB,YAAY;iBAQZ,cAAc;iBAKd,cAAc;iBAKd,cAAc;iBAKd,iBAAiB;;CAEX,CAAC;AAEX;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAYrE"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/config/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAkDH,eAAO,MAAM,WAAW;aAEtB,OAAO;aAIP,OAAO;aAIP,YAAY;aAGZ,GAAG;iBAGD,eAAe;iBAIf,SAAS;iBAIT,QAAQ;iBAIR,QAAQ;iBAIR,iBAAiB;iBAIjB,MAAM;iBAIN,gBAAgB;iBAIhB,cAAc;iBAKd,OAAO;iBAIP,aAAa;iBAMb,cAAc;iBAMd,YAAY;iBAMZ,OAAO;iBAIP,cAAc;iBAMd,iBAAiB;iBAQjB,YAAY;iBAQZ,cAAc;iBAKd,cAAc;iBAKd,cAAc;iBAKd,iBAAiB;;CAEX,CAAC;AAEX;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAYrE"}
@@ -85,6 +85,10 @@ export const CacheConfig = {
85
85
  // Historical data (> 1 day old from current time)
86
86
  // Historical data beyond 1 day is finalized and won't change
87
87
  historicalData: Infinity,
88
+ // Climate normals (1991–2020 baseline)
89
+ // Climate normals are static reference data that never change; the cached
90
+ // value is one full-year 366-slot table per location
91
+ normals: Infinity,
88
92
  // Service health check status
89
93
  // Check freshness periodically
90
94
  serviceStatus: 5 * MINUTE,
@@ -93,6 +97,11 @@ export const CacheConfig = {
93
97
  // the 9-point channel-snapping probe (a single lookup fans out to 9
94
98
  // grid cells in one request, so caching keeps repeat queries cheap).
95
99
  floodDischarge: 6 * HOUR,
100
+ // Google Pollen API (optional global pollen fallback)
101
+ // Pollen models update ~daily; 6h matches the daily-model posture and
102
+ // shields the 5,000/month free-tier quota once the 1h air-quality cache
103
+ // expires. In-memory only — nothing is persisted per Google Maps Platform ToS.
104
+ googlePollen: 6 * HOUR,
96
105
  // US daily temperature records (RCC ACIS) — the full 366-slot per-station
97
106
  // table. ACIS publishes no rate limits or ToS, so be a good citizen and
98
107
  // cache hard: a record changes at most when it is broken, so a stale
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/config/cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/config/cache.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,8 @@
4
4
  import { OpenMeteoService } from '../services/openmeteo.js';
5
5
  import { LocationStore } from '../services/locationStore.js';
6
6
  import { GeocodingService } from '../services/geocoding.js';
7
- export declare function handleGetAirQuality(args: unknown, openMeteoService: OpenMeteoService, locationStore: LocationStore, geocodingService: GeocodingService): Promise<{
7
+ import type { GooglePollenService } from '../services/googlePollen.js';
8
+ export declare function handleGetAirQuality(args: unknown, openMeteoService: OpenMeteoService, locationStore: LocationStore, geocodingService: GeocodingService, googlePollenService?: GooglePollenService): Promise<{
8
9
  content: Array<{
9
10
  type: string;
10
11
  text: string;
@@ -1 +1 @@
1
- {"version":3,"file":"airQualityHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/airQualityHandler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAyB5D,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,OAAO,EACb,gBAAgB,EAAE,gBAAgB,EAClC,aAAa,EAAE,aAAa,EAC5B,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAiC7D"}
1
+ {"version":3,"file":"airQualityHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/airQualityHandler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAgB5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAqCvE,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,OAAO,EACb,gBAAgB,EAAE,gBAAgB,EAClC,aAAa,EAAE,aAAa,EAC5B,gBAAgB,EAAE,gBAAgB,EAClC,mBAAmB,CAAC,EAAE,mBAAmB,GACxC,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CA8E7D"}
@@ -4,9 +4,28 @@
4
4
  import { resolveLocationAsync, prependLocationLine } from '../utils/locationResolver.js';
5
5
  import { validateOptionalBoolean, validatePositiveInteger } from '../utils/validation.js';
6
6
  import { getUSAQICategory, getEuropeanAQICategory, getUVIndexCategory, getPollutantInfo, formatPollutantConcentration, shouldUseUSAQI } from '../utils/airQuality.js';
7
+ import { GooglePollenKeyRejectedError } from '../services/googlePollen.js';
8
+ import { logger } from '../utils/logger.js';
7
9
  const DEFAULT_FORECAST_DAYS = 5;
8
10
  const MAX_FORECAST_DAYS = 7; // Open-Meteo air quality API limit (168 hours)
9
- export async function handleGetAirQuality(args, openMeteoService, locationStore, geocodingService) {
11
+ /**
12
+ * The six CAMS European-model pollen species, filtered to those carrying a
13
+ * real number. Non-European points return HTTP 200 with every species null,
14
+ * so an empty result is the "no CAMS coverage here" signal — shared by the
15
+ * render block and the Google-fallback trigger so the two can never drift
16
+ * (design plan D1).
17
+ */
18
+ function finiteCamsPollen(current) {
19
+ return [
20
+ { label: 'Alder', value: current.alder_pollen },
21
+ { label: 'Birch', value: current.birch_pollen },
22
+ { label: 'Grass', value: current.grass_pollen },
23
+ { label: 'Mugwort', value: current.mugwort_pollen },
24
+ { label: 'Olive', value: current.olive_pollen },
25
+ { label: 'Ragweed', value: current.ragweed_pollen }
26
+ ].filter(species => typeof species.value === 'number' && Number.isFinite(species.value));
27
+ }
28
+ export async function handleGetAirQuality(args, openMeteoService, locationStore, geocodingService, googlePollenService) {
10
29
  // Resolve location from coordinates, a saved location name, or a geocoded city name
11
30
  const resolved = await resolveLocationAsync(args, locationStore, geocodingService);
12
31
  const { latitude, longitude } = resolved;
@@ -17,8 +36,44 @@ export async function handleGetAirQuality(args, openMeteoService, locationStore,
17
36
  : validatePositiveInteger(rawForecastDays, 'forecast_days', 1, MAX_FORECAST_DAYS);
18
37
  // Get air quality data
19
38
  const airQualityData = await openMeteoService.getAirQuality(latitude, longitude, forecast, forecastDays);
39
+ // Optional keyed global pollen fallback (design plan D1/D6). Fires only
40
+ // when a key is configured AND the CAMS European model returned nothing
41
+ // for this point — Europe keeps the richer keyless grains/m³ data and
42
+ // never contacts Google. Sequential by necessity: the trigger needs the
43
+ // CAMS answer first.
44
+ //
45
+ // The Google data is garnish, not contract: the whole fetch sits in one
46
+ // try/catch and the air-quality call never fails because of it.
47
+ let googlePollen;
48
+ let googleKeyRejected = false;
49
+ if (googlePollenService &&
50
+ googlePollenService.isKeyAvailable() &&
51
+ airQualityData.current &&
52
+ finiteCamsPollen(airQualityData.current).length === 0) {
53
+ try {
54
+ googlePollen = await googlePollenService.getCurrentPollen(latitude, longitude);
55
+ if (!googlePollen) {
56
+ // Expected outside Google's 65+ covered countries — not a fault.
57
+ logger.info('Google Pollen returned no data for this location');
58
+ }
59
+ }
60
+ catch (error) {
61
+ if (error instanceof GooglePollenKeyRejectedError) {
62
+ googleKeyRejected = true;
63
+ logger.warn('Google Pollen API key was rejected', {
64
+ service: 'GooglePollen',
65
+ securityEvent: true
66
+ });
67
+ }
68
+ else {
69
+ logger.warn('Google Pollen fallback failed; rendering no pollen section', {
70
+ service: 'GooglePollen'
71
+ });
72
+ }
73
+ }
74
+ }
20
75
  // Format the air quality data for display
21
- const output = formatAirQuality(airQualityData, latitude, longitude, forecast);
76
+ const output = formatAirQuality(airQualityData, latitude, longitude, forecast, googlePollen, googleKeyRejected);
22
77
  return prependLocationLine({
23
78
  content: [
24
79
  {
@@ -31,7 +86,7 @@ export async function handleGetAirQuality(args, openMeteoService, locationStore,
31
86
  /**
32
87
  * Format air quality data as markdown
33
88
  */
34
- function formatAirQuality(data, latitude, longitude, includeForecast) {
89
+ function formatAirQuality(data, latitude, longitude, includeForecast, googlePollen, googleKeyRejected) {
35
90
  let output = `# Air Quality Report\n\n`;
36
91
  output += `**Location:** ${latitude.toFixed(4)}, ${longitude.toFixed(4)}\n`;
37
92
  output += `**Timezone:** ${data.timezone}\n`;
@@ -122,14 +177,7 @@ function formatAirQuality(data, latitude, longitude, includeForecast) {
122
177
  // every species null, so the section renders only when at least one species
123
178
  // carries a real value — never trust the 200 alone. In-season zeros are
124
179
  // meaningful ("none detected") and do render.
125
- const pollenSpecies = [
126
- { label: 'Alder', value: current.alder_pollen },
127
- { label: 'Birch', value: current.birch_pollen },
128
- { label: 'Grass', value: current.grass_pollen },
129
- { label: 'Mugwort', value: current.mugwort_pollen },
130
- { label: 'Olive', value: current.olive_pollen },
131
- { label: 'Ragweed', value: current.ragweed_pollen }
132
- ].filter(species => typeof species.value === 'number' && Number.isFinite(species.value));
180
+ const pollenSpecies = finiteCamsPollen(current);
133
181
  if (pollenSpecies.length > 0) {
134
182
  output += `## 🌾 Pollen\n\n`;
135
183
  for (const species of pollenSpecies) {
@@ -138,6 +186,19 @@ function formatAirQuality(data, latitude, longitude, includeForecast) {
138
186
  }
139
187
  output += `\n*Pollen from the CAMS European forecast — available for European locations only.*\n\n`;
140
188
  }
189
+ else {
190
+ // No CAMS coverage here. Fall back to the optional keyed Google Pollen
191
+ // section, or — if the configured key was rejected — a single
192
+ // misconfiguration note (design plan D5/D6). Otherwise nothing renders,
193
+ // exactly as before.
194
+ const googleSection = formatGooglePollen(googlePollen);
195
+ if (googleSection) {
196
+ output += googleSection;
197
+ }
198
+ else if (googleKeyRejected) {
199
+ output += `*Note: GOOGLE_POLLEN_API_KEY was rejected; global pollen data is unavailable.*\n\n`;
200
+ }
201
+ }
141
202
  // Show secondary AQI for reference
142
203
  if (useUSAQI && current.european_aqi !== undefined) {
143
204
  output += `*European AQI: ${Math.round(current.european_aqi)} (${getEuropeanAQICategory(current.european_aqi).level})*\n\n`;
@@ -153,6 +214,58 @@ function formatAirQuality(data, latitude, longitude, includeForecast) {
153
214
  }
154
215
  return output;
155
216
  }
217
+ /**
218
+ * Render the Google Pollen day-1 section that fills the CAMS slot outside
219
+ * Europe (design plan D5). Returns an empty string when there is nothing
220
+ * worth showing, so the caller can fall through to the key-rejected note.
221
+ *
222
+ * Only types whose `indexInfo.value` is a finite number render: Google omits
223
+ * `indexInfo` entirely for out-of-season types (upstream (c)), while a zero
224
+ * UPI that *does* carry `indexInfo` is meaningful ("none detected") and
225
+ * renders — mirroring the CAMS olive-0 rule.
226
+ *
227
+ * The attribution sentence is **mandatory and exact** — the Google Pollen
228
+ * API policies require the string "Source: Includes pollen data from Google"
229
+ * on or next to the data (upstream (d)). Do not reword it.
230
+ */
231
+ function formatGooglePollen(daily) {
232
+ if (!daily) {
233
+ return '';
234
+ }
235
+ const types = (daily.pollenTypeInfo ?? []).filter(type => typeof type.indexInfo?.value === 'number' && Number.isFinite(type.indexInfo.value));
236
+ if (types.length === 0) {
237
+ return '';
238
+ }
239
+ let section = `## 🌾 Pollen\n\n`;
240
+ for (const type of types) {
241
+ // Google sends "Grass"/"Tree"/"Weed" as displayName; fall back to the
242
+ // enum code (GRASS) title-cased if a response ever omits it.
243
+ const label = type.displayName ?? titleCase(type.code ?? 'Pollen');
244
+ const category = type.indexInfo?.category;
245
+ const seasonSuffix = type.inSeason === true ? ' — in season' : '';
246
+ section += `**${label}:** ${type.indexInfo?.value}`;
247
+ section += category ? ` (${category})` : '';
248
+ section += `${seasonSuffix}\n`;
249
+ }
250
+ const inSeasonPlants = (daily.plantInfo ?? [])
251
+ .filter(plant => plant.inSeason === true && plant.displayName)
252
+ .map(plant => {
253
+ const category = plant.indexInfo?.category;
254
+ return category ? `${plant.displayName} (${category})` : `${plant.displayName}`;
255
+ });
256
+ if (inSeasonPlants.length > 0) {
257
+ section += `\nIn season: ${inSeasonPlants.join(', ')}\n`;
258
+ }
259
+ section += `\n*Universal Pollen Index (0–5) for today. Source: Includes pollen data from Google.*\n\n`;
260
+ return section;
261
+ }
262
+ /**
263
+ * "GRASS" -> "Grass". Only used as a defensive fallback when a pollen type
264
+ * arrives without a displayName.
265
+ */
266
+ function titleCase(value) {
267
+ return value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();
268
+ }
156
269
  /**
157
270
  * Format the hourly AQI forecast grouped by local calendar day, with 6-hour
158
271
  * period ranges inside each day. Hours before the current observation time
@@ -1 +1 @@
1
- {"version":3,"file":"airQualityHandler.js","sourceRoot":"","sources":["../../src/handlers/airQualityHandler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"airQualityHandler.js","sourceRoot":"","sources":["../../src/handlers/airQualityHandler.ts"],"names":[],"mappings":"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"}