@cyanheads/nasa-power-mcp-server 0.2.0 → 0.4.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.
- package/AGENTS.md +26 -11
- package/CLAUDE.md +26 -11
- package/Dockerfile +9 -3
- package/README.md +50 -79
- package/changelog/0.3.x/0.3.0.md +35 -0
- package/changelog/0.4.x/0.4.0.md +36 -0
- package/dist/config/server-config.d.ts +1 -0
- package/dist/config/server-config.d.ts.map +1 -1
- package/dist/config/server-config.js +11 -1
- package/dist/config/server-config.js.map +1 -1
- package/dist/index.js +3 -8
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/tools/definitions/comparison-contracts.d.ts +7 -2
- package/dist/mcp-server/tools/definitions/comparison-contracts.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/comparison-contracts.js +3 -1
- package/dist/mcp-server/tools/definitions/comparison-contracts.js.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-compare-locations.tool.d.ts +5 -0
- package/dist/mcp-server/tools/definitions/nasa-power-compare-locations.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-dataframe-describe.tool.d.ts +1 -0
- package/dist/mcp-server/tools/definitions/nasa-power-dataframe-describe.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-get-climatology.tool.d.ts +15 -0
- package/dist/mcp-server/tools/definitions/nasa-power-get-climatology.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-get-climatology.tool.js +21 -3
- package/dist/mcp-server/tools/definitions/nasa-power-get-climatology.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-get-region.tool.d.ts +24 -4
- package/dist/mcp-server/tools/definitions/nasa-power-get-region.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-get-region.tool.js +9 -3
- package/dist/mcp-server/tools/definitions/nasa-power-get-region.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-get-timeseries.tool.d.ts +2 -0
- package/dist/mcp-server/tools/definitions/nasa-power-get-timeseries.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-list-reference.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-list-reference.tool.js +5 -5
- package/dist/mcp-server/tools/definitions/nasa-power-list-reference.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/point-contracts.d.ts +2 -0
- package/dist/mcp-server/tools/definitions/point-contracts.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/point-contracts.js +1 -5
- package/dist/mcp-server/tools/definitions/point-contracts.js.map +1 -1
- package/dist/services/canvas/canvas-service.d.ts +9 -3
- package/dist/services/canvas/canvas-service.d.ts.map +1 -1
- package/dist/services/canvas/canvas-service.js +58 -32
- package/dist/services/canvas/canvas-service.js.map +1 -1
- package/dist/services/canvas/format.d.ts +0 -1
- package/dist/services/canvas/format.d.ts.map +1 -1
- package/dist/services/canvas/format.js +3 -3
- package/dist/services/canvas/format.js.map +1 -1
- package/dist/services/canvas/types.d.ts +11 -1
- package/dist/services/canvas/types.d.ts.map +1 -1
- package/dist/services/canvas/types.js +2 -3
- package/dist/services/canvas/types.js.map +1 -1
- package/dist/services/power/normalize.d.ts.map +1 -1
- package/dist/services/power/normalize.js +24 -8
- package/dist/services/power/normalize.js.map +1 -1
- package/dist/services/power/power-service.d.ts.map +1 -1
- package/dist/services/power/power-service.js +9 -3
- package/dist/services/power/power-service.js.map +1 -1
- package/dist/services/power/presets.d.ts +2 -0
- package/dist/services/power/presets.d.ts.map +1 -1
- package/dist/services/power/presets.js +2 -0
- package/dist/services/power/presets.js.map +1 -1
- package/dist/services/power/types.d.ts +5 -3
- package/dist/services/power/types.d.ts.map +1 -1
- package/dist/services/power/types.js +12 -4
- package/dist/services/power/types.js.map +1 -1
- package/package.json +11 -8
- package/server.json +37 -19
- package/skills/nasa-power-guide/SKILL.md +73 -0
package/server.json
CHANGED
|
@@ -6,14 +6,20 @@
|
|
|
6
6
|
"url": "https://github.com/cyanheads/nasa-power-mcp-server",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.4.0",
|
|
10
|
+
"remotes": [
|
|
11
|
+
{
|
|
12
|
+
"type": "streamable-http",
|
|
13
|
+
"url": "https://nasa-power.caseyjhand.com/mcp"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
10
16
|
"packages": [
|
|
11
17
|
{
|
|
12
18
|
"registryType": "npm",
|
|
13
19
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
14
20
|
"identifier": "@cyanheads/nasa-power-mcp-server",
|
|
15
21
|
"runtimeHint": "npx",
|
|
16
|
-
"version": "0.
|
|
22
|
+
"version": "0.4.0",
|
|
17
23
|
"environmentVariables": [
|
|
18
24
|
{
|
|
19
25
|
"name": "CANVAS_PROVIDER_TYPE",
|
|
@@ -24,27 +30,33 @@
|
|
|
24
30
|
},
|
|
25
31
|
{
|
|
26
32
|
"name": "CANVAS_DEFAULT_MEMORY_LIMIT_MB",
|
|
27
|
-
"description": "
|
|
33
|
+
"description": "Per-canvas engine memory in MiB (integer >=64), not total RSS or temporary disk.",
|
|
28
34
|
"format": "string",
|
|
29
|
-
"
|
|
35
|
+
"default": "256"
|
|
30
36
|
},
|
|
31
37
|
{
|
|
32
38
|
"name": "CANVAS_MAX_CANVASES_PER_TENANT",
|
|
33
|
-
"description": "
|
|
39
|
+
"description": "Positive tenant canvas limit; auth-none callers share one tenant.",
|
|
34
40
|
"format": "string",
|
|
35
|
-
"
|
|
41
|
+
"default": "4"
|
|
36
42
|
},
|
|
37
43
|
{
|
|
38
44
|
"name": "CANVAS_TTL_MS",
|
|
39
|
-
"description": "
|
|
45
|
+
"description": "Positive sliding canvas lifetime in milliseconds.",
|
|
40
46
|
"format": "string",
|
|
41
|
-
"
|
|
47
|
+
"default": "3600000"
|
|
42
48
|
},
|
|
43
49
|
{
|
|
44
50
|
"name": "CANVAS_ABSOLUTE_CAP_MS",
|
|
45
|
-
"description": "
|
|
51
|
+
"description": "Absolute canvas lifetime in milliseconds, at least the sliding TTL.",
|
|
52
|
+
"format": "string",
|
|
53
|
+
"default": "21600000"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "NASA_POWER_MAX_CANVASES_PER_PROCESS",
|
|
57
|
+
"description": "Positive process canvas cap including pending and cleanup reservations.",
|
|
46
58
|
"format": "string",
|
|
47
|
-
"
|
|
59
|
+
"default": "8"
|
|
48
60
|
},
|
|
49
61
|
{
|
|
50
62
|
"name": "NASA_POWER_DATAFRAME_DROP_ENABLED",
|
|
@@ -70,7 +82,7 @@
|
|
|
70
82
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
71
83
|
"identifier": "@cyanheads/nasa-power-mcp-server",
|
|
72
84
|
"runtimeHint": "npx",
|
|
73
|
-
"version": "0.
|
|
85
|
+
"version": "0.4.0",
|
|
74
86
|
"environmentVariables": [
|
|
75
87
|
{
|
|
76
88
|
"name": "CANVAS_PROVIDER_TYPE",
|
|
@@ -81,27 +93,27 @@
|
|
|
81
93
|
},
|
|
82
94
|
{
|
|
83
95
|
"name": "CANVAS_DEFAULT_MEMORY_LIMIT_MB",
|
|
84
|
-
"description": "
|
|
96
|
+
"description": "Per-canvas engine memory in MiB (integer >=64), not total RSS or temporary disk.",
|
|
85
97
|
"format": "string",
|
|
86
|
-
"
|
|
98
|
+
"default": "256"
|
|
87
99
|
},
|
|
88
100
|
{
|
|
89
101
|
"name": "CANVAS_MAX_CANVASES_PER_TENANT",
|
|
90
|
-
"description": "
|
|
102
|
+
"description": "Positive tenant canvas limit; auth-none callers share one tenant.",
|
|
91
103
|
"format": "string",
|
|
92
|
-
"
|
|
104
|
+
"default": "4"
|
|
93
105
|
},
|
|
94
106
|
{
|
|
95
107
|
"name": "CANVAS_TTL_MS",
|
|
96
|
-
"description": "
|
|
108
|
+
"description": "Positive sliding canvas lifetime in milliseconds.",
|
|
97
109
|
"format": "string",
|
|
98
|
-
"
|
|
110
|
+
"default": "3600000"
|
|
99
111
|
},
|
|
100
112
|
{
|
|
101
113
|
"name": "CANVAS_ABSOLUTE_CAP_MS",
|
|
102
|
-
"description": "
|
|
114
|
+
"description": "Absolute canvas lifetime in milliseconds, at least the sliding TTL.",
|
|
103
115
|
"format": "string",
|
|
104
|
-
"
|
|
116
|
+
"default": "21600000"
|
|
105
117
|
},
|
|
106
118
|
{
|
|
107
119
|
"name": "NASA_POWER_DATAFRAME_DROP_ENABLED",
|
|
@@ -110,6 +122,12 @@
|
|
|
110
122
|
"default": "false",
|
|
111
123
|
"isRequired": false
|
|
112
124
|
},
|
|
125
|
+
{
|
|
126
|
+
"name": "NASA_POWER_MAX_CANVASES_PER_PROCESS",
|
|
127
|
+
"description": "Positive process canvas cap including pending and cleanup reservations.",
|
|
128
|
+
"format": "string",
|
|
129
|
+
"default": "8"
|
|
130
|
+
},
|
|
113
131
|
{
|
|
114
132
|
"name": "MCP_TRANSPORT_TYPE",
|
|
115
133
|
"description": "Selects the HTTP transport.",
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nasa-power-guide
|
|
3
|
+
description: Plan nasa_power_* calls for NASA POWER solar, wind, temperature, precipitation, and degree-day history. Covers which tool answers a typical-month versus a dated question, one data call at a time, grid-cell size, data freshness, rate versus total units, degree days, and SQL over staged tables. Use before solar sizing, wind screening, site comparison, regional, or agroclimate work with these tools.
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: cyanheads
|
|
7
|
+
version: "1.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Scope
|
|
11
|
+
|
|
12
|
+
NASA POWER serves historical gridded estimates (reanalysis and satellite products), keyless. It does not serve forecasts or station measurements, and its newest days are not available yet (see the freshness gate below). The data tools take latitude and longitude only, so geocode a place name before calling.
|
|
13
|
+
|
|
14
|
+
Values describe grid cells, not the exact point:
|
|
15
|
+
|
|
16
|
+
| Family | Cell size |
|
|
17
|
+
|:--|:--|
|
|
18
|
+
| Meteorology (temperature, humidity, wind, precipitation, degree days) | 0.5° latitude × 0.625° longitude |
|
|
19
|
+
| Solar irradiance | 1° × 1° |
|
|
20
|
+
|
|
21
|
+
Sites that fall in the same cell return identical values. The `returnedCoordinates` in metadata echo the request; they are not the cell center.
|
|
22
|
+
|
|
23
|
+
## Identifiers
|
|
24
|
+
|
|
25
|
+
- **Parameter codes** come from `nasa_power_search_parameters` for one community and temporalResolution pair. A code valid at daily can be missing at hourly: degree days, `T2M_MAX` and `T2M_MIN` have no hourly form. Filter with plain words, for example `degree days` or `wind 50`.
|
|
26
|
+
- **Preset names and the `SI_EF_TILTED_SURFACE` alias** (climatology only) come from `nasa_power_list_reference` topic `presets`.
|
|
27
|
+
- **`canvas_id` and table names** come from the handles on a producing response: `dataset` for observations, `summaryDataset` for regional summaries, `summaryDatasets.buckets` and `summaryDatasets.locations` for comparison summaries.
|
|
28
|
+
- **`locationId`, `label` and `cellId`** are row columns. `locationId` follows input position (`location_1` …), and `cellId` numbers the cells in a regional result.
|
|
29
|
+
|
|
30
|
+
## Gates
|
|
31
|
+
|
|
32
|
+
1. **One data call at a time.** `nasa_power_get_timeseries`, `nasa_power_get_climatology`, `nasa_power_get_region` and `nasa_power_compare_locations` share one admission budget. While one is running, another call is refused immediately with `canvas_capacity_exhausted`, however small it is. Its recovery text about canvases does not apply here: wait for the running call to return, then retry. For several sites, use one `nasa_power_compare_locations` call (up to 10 sites) instead of parallel point calls.
|
|
33
|
+
2. **Check freshness before you conclude.** The latest days of a window come back as nulls until NASA releases them, and solar can lag meteorology. Read `summaries[].lastValidDate` for each parameter. Never report trailing nulls as zero, as calm, or as "no sun".
|
|
34
|
+
3. **Same cell, not a tie.** When `nasa_power_compare_locations` returns `possibleSharedGridCell`, the listed sites sit in one cell. Report them as indistinguishable, not as equal results.
|
|
35
|
+
4. **Rate or total.** Check what a value measures before summing or comparing:
|
|
36
|
+
- `PRECTOTCORR` is mm/day at every resolution. Monthly values, `YYYY13` and climatology months and `ANN` are mean daily rates, so multiply by the number of days for a total.
|
|
37
|
+
- Solar units follow the community: `RE` returns kW-hr/m^2/day and `AG` returns MJ/m^2/day for the same code.
|
|
38
|
+
- Degree-day codes (`GDD*`, `HDD*`, `CDD*`) are totals for their period: per day, per month, and per year for `ANN` and `YYYY13`.
|
|
39
|
+
- Temperature, humidity and wind annual records are means.
|
|
40
|
+
5. **Degree days come from NASA.** Growing degree days are source codes `GDD4_4`, `GDD7_2`, `GDD10`, `GDD13_3` and `GDD15_6` (base °C), alongside `HDD*` and `CDD*`. Request them; don't rebuild them from `T2M`. The dictionary also lists `GDD*` at monthly and climatology, but NASA's monthly and climatology endpoints fail on them with HTTP 500. Request `GDD*` at daily and sum the days.
|
|
41
|
+
6. **Annual rows sit inside monthly data.** Monthly results add one annual record per year (`periodKind` `annual`, `month` null, key `YYYY13`), and climatology adds `ANN`. Exclude these rows before averaging or ranking months.
|
|
42
|
+
7. **A regional box spans at least 2° on each axis.** For a smaller area, use a point call. The box returns one parameter per call, so make sequential calls for several parameters (gate 1).
|
|
43
|
+
8. **Summaries are coarse.** `summaries` aggregate each period kind over the whole window. Comparison buckets are calendar-season means (DJF, MAM, JJA, SON, annual): they don't accumulate and don't follow a growing season. For any other grouping or any sum, compute it from the inline rows or with SQL.
|
|
44
|
+
|
|
45
|
+
## Workflows
|
|
46
|
+
|
|
47
|
+
### Picking the call
|
|
48
|
+
|
|
49
|
+
| Question | Call |
|
|
50
|
+
|:--|:--|
|
|
51
|
+
| Typical month or year: PV sizing, the calmest month, annual heating load | `nasa_power_get_climatology`. The default period is stated in `metadata.range`. Pass `startYear` with `endYear` for a custom multi-year window, which returns `JAN`…`DEC` plus `ANN` in one small response. |
|
|
52
|
+
| Specific dates, day-level distributions, seasonal accumulations | `nasa_power_get_timeseries` at daily (or hourly from 2001) |
|
|
53
|
+
| The same question at 2–10 sites | `nasa_power_compare_locations` |
|
|
54
|
+
| A spatial pattern | `nasa_power_get_region` |
|
|
55
|
+
|
|
56
|
+
**PV sizing:** call climatology with community `RE` and `SI_EF_TILTED_SURFACE` (add `ALLSKY_SFC_SW_DWN` for the horizontal baseline). Irradiance arrives in kW-hr/m^2/day, which equals peak sun hours, for horizontal, latitude, latitude ±15°, vertical and optimal tilts. `SI_TILTED_AVG_OPTIMAL_ANG` is the optimal tilt in degrees, and `SI_TILTED_AVG_OPTIMAL_ANG_ORT` is facing text such as `S`.
|
|
57
|
+
|
|
58
|
+
**Season totals at several farms** (growing degree days, rainfall): run `nasa_power_compare_locations` at daily for the season's dates, then `SUM` per `label` in SQL. Bucket means don't give totals. A daily `PRECTOTCORR` value is that day's total in mm, so the daily values add up directly.
|
|
59
|
+
|
|
60
|
+
### Staged tables and SQL
|
|
61
|
+
|
|
62
|
+
Staging is automatic. A data call stages only when the complete response would not fit inline. Smaller results come back inline with `dataset: null`, even when you pass `canvas_id`, and you compute from those rows directly.
|
|
63
|
+
|
|
64
|
+
Results too large to return inline are staged as a DataCanvas table, and the response carries a `canvas_id`. Call `nasa_power_dataframe_describe` with it for the staged table and column names before writing SQL, then `nasa_power_dataframe_query` with a read-only query. Pass the same `canvas_id` back to stage further results beside the first; each table expires at the `expiresAt` on its handle.
|
|
65
|
+
|
|
66
|
+
- **Dialect.** DuckDB. Reference tables by the exact `power_…` name from the handle.
|
|
67
|
+
- **Observation columns.** `periodKey`, `periodKind`, `date`, `year`, `month`, `hour`, `latitude`, `longitude`, `elevation`, then one column per returned parameter code. Comparison tables add `locationId` and `label`; regional tables add `cellId`.
|
|
68
|
+
- **Dates.** `date` is VARCHAR (`YYYY-MM-DD` on daily and monthly rows, null on annual and climatology rows), so use `CAST(date AS DATE)` before date functions.
|
|
69
|
+
- **Nulls.** Missing values are NULL, and `AVG` and `SUM` skip them. Compare `count(column)` with the number of days you expected before trusting a total.
|
|
70
|
+
- **Integer results.** Integer-typed results such as `COUNT` come back as strings. Wrap them in `CAST(… AS INTEGER)` when you need a number; aggregates over measured parameters are numeric.
|
|
71
|
+
- **Shared canvas.** Reuse one `canvas_id` across the data calls in a task. The tables then share a canvas and can be joined in one SELECT, and you don't spend the limited canvas capacity on a fresh canvas per call.
|
|
72
|
+
- **Expiry.** Tables expire. After `canvas_not_found` or `missing_table`, rerun the producing call without the old `canvas_id` (a stale token fails again) to stage the data in a fresh canvas.
|
|
73
|
+
- **Row limit.** `rowLimit` defaults to 100 rows. Aggregate in SQL rather than paging raw rows.
|