@cyanheads/nasa-power-mcp-server 0.1.1 → 0.2.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 +15 -13
- package/CLAUDE.md +15 -13
- package/README.md +72 -43
- package/changelog/0.2.x/0.2.0.md +23 -0
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/tools/definitions/comparison-contracts.d.ts +125 -366
- package/dist/mcp-server/tools/definitions/comparison-contracts.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/comparison-contracts.js +14 -4
- 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 +175 -300
- package/dist/mcp-server/tools/definitions/nasa-power-compare-locations.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-compare-locations.tool.js +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-compare-locations.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-dataframe-drop.tool.js +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-dataframe-drop.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-dataframe-query.tool.d.ts +3 -1
- package/dist/mcp-server/tools/definitions/nasa-power-dataframe-query.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-dataframe-query.tool.js +7 -2
- package/dist/mcp-server/tools/definitions/nasa-power-dataframe-query.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-get-climatology.tool.d.ts +73 -162
- 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 +10 -4
- 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 +10 -47
- 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-timeseries.tool.d.ts +84 -136
- 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 +26 -24
- package/dist/mcp-server/tools/definitions/nasa-power-list-reference.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-search-parameters.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/nasa-power-search-parameters.tool.js +17 -8
- package/dist/mcp-server/tools/definitions/nasa-power-search-parameters.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/point-contracts.d.ts +38 -280
- package/dist/mcp-server/tools/definitions/point-contracts.d.ts.map +1 -1
- package/dist/services/canvas/canvas-service.d.ts +13 -3
- package/dist/services/canvas/canvas-service.d.ts.map +1 -1
- package/dist/services/canvas/canvas-service.js +198 -63
- package/dist/services/canvas/canvas-service.js.map +1 -1
- package/dist/services/canvas/errors.d.ts.map +1 -1
- package/dist/services/canvas/errors.js +20 -8
- package/dist/services/canvas/errors.js.map +1 -1
- package/dist/services/canvas/types.d.ts +54 -1
- package/dist/services/canvas/types.d.ts.map +1 -1
- package/dist/services/canvas/types.js +6 -1
- package/dist/services/canvas/types.js.map +1 -1
- package/dist/services/power/errors.js +1 -1
- package/dist/services/power/errors.js.map +1 -1
- package/dist/services/power/normalize.js +2 -2
- 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 +8 -7
- package/dist/services/power/power-service.js.map +1 -1
- package/dist/services/power/presets.d.ts +23 -0
- package/dist/services/power/presets.d.ts.map +1 -1
- package/dist/services/power/presets.js +27 -1
- package/dist/services/power/presets.js.map +1 -1
- package/dist/services/power/types.d.ts +410 -191
- package/dist/services/power/types.d.ts.map +1 -1
- package/dist/services/power/types.js +59 -5
- package/dist/services/power/types.js.map +1 -1
- package/package.json +1 -1
- package/server.json +8 -8
package/AGENTS.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** nasa-power-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
4
|
+
**Version:** 0.2.0
|
|
5
5
|
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.15`
|
|
6
6
|
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/server` ^2.3.1
|
|
@@ -34,7 +34,7 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
34
34
|
|
|
35
35
|
- **Logic throws, framework catches.** Tool/resource handlers are pure — throw on failure, no `try/catch`. Plain `Error` is fine; the framework catches, classifies, and formats. Use error factories (`notFound()`, `validationError()`, etc.) when the error code matters.
|
|
36
36
|
- **Use `ctx.log`** for request-scoped logging. No `console` calls.
|
|
37
|
-
- **
|
|
37
|
+
- **Keep persistence in `CanvasService`** through its injected `core.storage`; tool handlers do not access storage directly.
|
|
38
38
|
- **Need input the caller didn't supply?** `return ctx.requestInput(...)` and read `ctx.inputs` when the handler is re-entered. Never `await` for user input mid-handler.
|
|
39
39
|
- **Secrets in env vars only** — never hardcoded.
|
|
40
40
|
- **Cut noise.** Add only what earns its place: no speculative generality, no guards for states the framework already prevents (Zod-validated params, classified errors), no abstraction until a third caller proves it, no option nothing sets.
|
|
@@ -60,7 +60,7 @@ Tool files live in `src/mcp-server/tools/definitions/`. Nine tools are registere
|
|
|
60
60
|
|
|
61
61
|
`src/index.ts` fixes DuckDB to 256 MiB engine memory, four canvases per tenant, a one-hour sliding TTL and a six-hour absolute cap. The service further enforces eight tables per canvas, eight canvases per process and a 30-minute table TTL. Engine memory is not total RSS or temporary-disk capacity.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
`src/index.ts` also defaults `CANVAS_PROVIDER_TYPE` to `duckdb` once `parseConfig()` has loaded `.env`, so npm and Docker installs, which install the native dependency normally on supported platforms, stage by default; `none` disables staging. The portable MCPB fixes `CANVAS_PROVIDER_TYPE=none` because its bundle strips DuckDB's native bindings. Keep those option sets distinct.
|
|
64
64
|
|
|
65
65
|
### Identity and lifecycle
|
|
66
66
|
|
|
@@ -77,15 +77,11 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
77
77
|
| Property | Description |
|
|
78
78
|
|:---------|:------------|
|
|
79
79
|
| `ctx.log` | Request-scoped logger — `.debug()`, `.info()`, `.notice()`, `.warning()`, `.error()`. Auto-correlates requestId, traceId, tenantId. Dual-sink: Pino **and** `notifications/message` to the client, so treat it as client-visible. |
|
|
80
|
-
| `ctx.
|
|
81
|
-
| `ctx.
|
|
82
|
-
| `ctx.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
| `ctx.content` | Non-text content blocks — `.image(data, mimeType)`, `.audio(data, mimeType)`, or `ctx.content(block)` for a raw block. Prepended to `content[]` after `format()`; never enters `structuredContent`. |
|
|
86
|
-
| `ctx.signal` | `AbortSignal` for cancellation. |
|
|
87
|
-
| `ctx.requestId` | Request ID — the one every log record of the call carries and its error envelope returns as `data.requestId`. |
|
|
88
|
-
| `ctx.tenantId` | Tenant ID from JWT; `'default'` for stdio or HTTP with auth off. |
|
|
80
|
+
| `ctx.enrich` | Success-path agent context — `nasa_power_search_parameters` calls `.notice()` on an empty match. Reaches `structuredContent` and `content[]`; lands only when the definition declares an `enrichment` block (no-op otherwise). |
|
|
81
|
+
| `ctx.signal` | `AbortSignal` for cancellation. Producing tools replace it with the call budget's signal, so the 55-second source deadline also aborts staging. |
|
|
82
|
+
| `ctx.tenantId` | Tenant ID from JWT; `'default'` for stdio or HTTP with auth off. Canvas records are owned per tenant, and a token presented by another tenant is `canvas_not_found`. |
|
|
83
|
+
|
|
84
|
+
Staged-table provenance is written through `core.storage` in `CanvasService`, keyed by tenant, canvas and table; no handler uses `ctx.state`.
|
|
89
85
|
|
|
90
86
|
---
|
|
91
87
|
|
|
@@ -230,11 +226,14 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
230
226
|
| `bun run format` | Auto-fix formatting (safe fixes only) |
|
|
231
227
|
| `bun run format:unsafe` | Also apply Biome's unsafe autofixes — review the diff; they can change behavior |
|
|
232
228
|
| `bun run test` | Run tests (Vitest — use `bun run test`, not `bun test`) |
|
|
229
|
+
| `bun run test:coverage` | Run tests with coverage |
|
|
230
|
+
| `bun run start` | Run the built server with the configured transport |
|
|
233
231
|
| `bun run start:stdio` | Production mode (stdio) |
|
|
234
232
|
| `bun run start:http` | Production mode (HTTP) |
|
|
235
233
|
| `bun run changelog:build` | Regenerate `CHANGELOG.md` from `changelog/*.md` |
|
|
236
234
|
| `bun run changelog:check` | Verify `CHANGELOG.md` is in sync (used by devcheck) |
|
|
237
235
|
| `bun run bundle` | Build, pack, and clean a `.mcpb` for one-click Claude Desktop install |
|
|
236
|
+
| `bun run release:github` | Create or repair the GitHub Release on the version tag and attach the `.mcpb` (run by `release-and-publish`) |
|
|
238
237
|
| `bun run publish-mcp` | Authenticate with the macOS Keychain token and publish registry metadata |
|
|
239
238
|
|
|
240
239
|
**CI is one file.** `.github/workflows/codeql.yml` (scaffolded) is the only GitHub Actions workflow: CodeQL is GitHub-owned end to end, and the file runs only while the repo's CodeQL *default setup* is turned off. Verification — `devcheck`, tests, the release gates — runs locally; don't add a workflow that re-runs it.
|
|
@@ -302,8 +301,11 @@ import { getMyService } from '@/services/my-domain/my-service.js';
|
|
|
302
301
|
- [ ] Zod schemas: all fields have `.describe()`, only JSON-Schema-serializable types (no `z.custom()`, `z.date()`, `z.transform()`, `z.bigint()`, `z.symbol()`, `z.void()`, `z.map()`, `z.set()`, `z.function()`, `z.nan()`)
|
|
303
302
|
- [ ] Optional nested objects: handler guards for empty inner values from form-based clients (`if (input.obj?.field && ...)`, not just `if (input.obj)`). When regex/length constraints matter, use `z.union([z.literal(''), z.string().regex(...).describe(...)])` — literal variants are exempt from `describe-on-fields`.
|
|
304
303
|
- [ ] JSDoc `@fileoverview` + `@module` on every file
|
|
305
|
-
- [ ] `ctx.log` for logging
|
|
304
|
+
- [ ] `ctx.log` for logging; persistence only through `CanvasService`
|
|
306
305
|
- [ ] Handlers throw on failure — error factories or plain `Error`, no try/catch
|
|
306
|
+
- [ ] New codes and presets are checked against the selected community/resolution dictionary; source units, fill-as-`null`, `omittedParameters` and annual-period distinctions survive normalization
|
|
307
|
+
- [ ] Producing tools present through `CanvasService.present()`: oversized data stages completely or fails with `canvas_required` / `dataset_limit`, never a truncated source prefix
|
|
308
|
+
- [ ] Workload bounds live in `POWER_LIMITS`; the four fixed canvas settings match across `src/index.ts`, `.env.example`, `server.json`, `manifest.json` and both plugin manifests
|
|
307
309
|
- [ ] `format()` renders all data the LLM needs — different clients forward different surfaces (Claude Code → `structuredContent`, Claude Desktop → `content[]`); both must carry the same data
|
|
308
310
|
- [ ] If wrapping external API: raw/domain/output schemas reviewed against real upstream sparsity/nullability before finalizing required vs optional fields
|
|
309
311
|
- [ ] If wrapping external API: normalization and `format()` preserve uncertainty; do not fabricate facts from missing upstream data
|
package/CLAUDE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** nasa-power-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
4
|
+
**Version:** 0.2.0
|
|
5
5
|
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.15`
|
|
6
6
|
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/server` ^2.3.1
|
|
@@ -34,7 +34,7 @@ Tailor suggestions to what's actually missing or stale — don't recite the full
|
|
|
34
34
|
|
|
35
35
|
- **Logic throws, framework catches.** Tool/resource handlers are pure — throw on failure, no `try/catch`. Plain `Error` is fine; the framework catches, classifies, and formats. Use error factories (`notFound()`, `validationError()`, etc.) when the error code matters.
|
|
36
36
|
- **Use `ctx.log`** for request-scoped logging. No `console` calls.
|
|
37
|
-
- **
|
|
37
|
+
- **Keep persistence in `CanvasService`** through its injected `core.storage`; tool handlers do not access storage directly.
|
|
38
38
|
- **Need input the caller didn't supply?** `return ctx.requestInput(...)` and read `ctx.inputs` when the handler is re-entered. Never `await` for user input mid-handler.
|
|
39
39
|
- **Secrets in env vars only** — never hardcoded.
|
|
40
40
|
- **Cut noise.** Add only what earns its place: no speculative generality, no guards for states the framework already prevents (Zod-validated params, classified errors), no abstraction until a third caller proves it, no option nothing sets.
|
|
@@ -60,7 +60,7 @@ Tool files live in `src/mcp-server/tools/definitions/`. Nine tools are registere
|
|
|
60
60
|
|
|
61
61
|
`src/index.ts` fixes DuckDB to 256 MiB engine memory, four canvases per tenant, a one-hour sliding TTL and a six-hour absolute cap. The service further enforces eight tables per canvas, eight canvases per process and a 30-minute table TTL. Engine memory is not total RSS or temporary-disk capacity.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
`src/index.ts` also defaults `CANVAS_PROVIDER_TYPE` to `duckdb` once `parseConfig()` has loaded `.env`, so npm and Docker installs, which install the native dependency normally on supported platforms, stage by default; `none` disables staging. The portable MCPB fixes `CANVAS_PROVIDER_TYPE=none` because its bundle strips DuckDB's native bindings. Keep those option sets distinct.
|
|
64
64
|
|
|
65
65
|
### Identity and lifecycle
|
|
66
66
|
|
|
@@ -77,15 +77,11 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
77
77
|
| Property | Description |
|
|
78
78
|
|:---------|:------------|
|
|
79
79
|
| `ctx.log` | Request-scoped logger — `.debug()`, `.info()`, `.notice()`, `.warning()`, `.error()`. Auto-correlates requestId, traceId, tenantId. Dual-sink: Pino **and** `notifications/message` to the client, so treat it as client-visible. |
|
|
80
|
-
| `ctx.
|
|
81
|
-
| `ctx.
|
|
82
|
-
| `ctx.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
| `ctx.content` | Non-text content blocks — `.image(data, mimeType)`, `.audio(data, mimeType)`, or `ctx.content(block)` for a raw block. Prepended to `content[]` after `format()`; never enters `structuredContent`. |
|
|
86
|
-
| `ctx.signal` | `AbortSignal` for cancellation. |
|
|
87
|
-
| `ctx.requestId` | Request ID — the one every log record of the call carries and its error envelope returns as `data.requestId`. |
|
|
88
|
-
| `ctx.tenantId` | Tenant ID from JWT; `'default'` for stdio or HTTP with auth off. |
|
|
80
|
+
| `ctx.enrich` | Success-path agent context — `nasa_power_search_parameters` calls `.notice()` on an empty match. Reaches `structuredContent` and `content[]`; lands only when the definition declares an `enrichment` block (no-op otherwise). |
|
|
81
|
+
| `ctx.signal` | `AbortSignal` for cancellation. Producing tools replace it with the call budget's signal, so the 55-second source deadline also aborts staging. |
|
|
82
|
+
| `ctx.tenantId` | Tenant ID from JWT; `'default'` for stdio or HTTP with auth off. Canvas records are owned per tenant, and a token presented by another tenant is `canvas_not_found`. |
|
|
83
|
+
|
|
84
|
+
Staged-table provenance is written through `core.storage` in `CanvasService`, keyed by tenant, canvas and table; no handler uses `ctx.state`.
|
|
89
85
|
|
|
90
86
|
---
|
|
91
87
|
|
|
@@ -230,11 +226,14 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
230
226
|
| `bun run format` | Auto-fix formatting (safe fixes only) |
|
|
231
227
|
| `bun run format:unsafe` | Also apply Biome's unsafe autofixes — review the diff; they can change behavior |
|
|
232
228
|
| `bun run test` | Run tests (Vitest — use `bun run test`, not `bun test`) |
|
|
229
|
+
| `bun run test:coverage` | Run tests with coverage |
|
|
230
|
+
| `bun run start` | Run the built server with the configured transport |
|
|
233
231
|
| `bun run start:stdio` | Production mode (stdio) |
|
|
234
232
|
| `bun run start:http` | Production mode (HTTP) |
|
|
235
233
|
| `bun run changelog:build` | Regenerate `CHANGELOG.md` from `changelog/*.md` |
|
|
236
234
|
| `bun run changelog:check` | Verify `CHANGELOG.md` is in sync (used by devcheck) |
|
|
237
235
|
| `bun run bundle` | Build, pack, and clean a `.mcpb` for one-click Claude Desktop install |
|
|
236
|
+
| `bun run release:github` | Create or repair the GitHub Release on the version tag and attach the `.mcpb` (run by `release-and-publish`) |
|
|
238
237
|
| `bun run publish-mcp` | Authenticate with the macOS Keychain token and publish registry metadata |
|
|
239
238
|
|
|
240
239
|
**CI is one file.** `.github/workflows/codeql.yml` (scaffolded) is the only GitHub Actions workflow: CodeQL is GitHub-owned end to end, and the file runs only while the repo's CodeQL *default setup* is turned off. Verification — `devcheck`, tests, the release gates — runs locally; don't add a workflow that re-runs it.
|
|
@@ -302,8 +301,11 @@ import { getMyService } from '@/services/my-domain/my-service.js';
|
|
|
302
301
|
- [ ] Zod schemas: all fields have `.describe()`, only JSON-Schema-serializable types (no `z.custom()`, `z.date()`, `z.transform()`, `z.bigint()`, `z.symbol()`, `z.void()`, `z.map()`, `z.set()`, `z.function()`, `z.nan()`)
|
|
303
302
|
- [ ] Optional nested objects: handler guards for empty inner values from form-based clients (`if (input.obj?.field && ...)`, not just `if (input.obj)`). When regex/length constraints matter, use `z.union([z.literal(''), z.string().regex(...).describe(...)])` — literal variants are exempt from `describe-on-fields`.
|
|
304
303
|
- [ ] JSDoc `@fileoverview` + `@module` on every file
|
|
305
|
-
- [ ] `ctx.log` for logging
|
|
304
|
+
- [ ] `ctx.log` for logging; persistence only through `CanvasService`
|
|
306
305
|
- [ ] Handlers throw on failure — error factories or plain `Error`, no try/catch
|
|
306
|
+
- [ ] New codes and presets are checked against the selected community/resolution dictionary; source units, fill-as-`null`, `omittedParameters` and annual-period distinctions survive normalization
|
|
307
|
+
- [ ] Producing tools present through `CanvasService.present()`: oversized data stages completely or fails with `canvas_required` / `dataset_limit`, never a truncated source prefix
|
|
308
|
+
- [ ] Workload bounds live in `POWER_LIMITS`; the four fixed canvas settings match across `src/index.ts`, `.env.example`, `server.json`, `manifest.json` and both plugin manifests
|
|
307
309
|
- [ ] `format()` renders all data the LLM needs — different clients forward different surfaces (Claude Code → `structuredContent`, Claude Desktop → `content[]`); both must carry the same data
|
|
308
310
|
- [ ] If wrapping external API: raw/domain/output schemas reviewed against real upstream sparsity/nullability before finalizing required vs optional fields
|
|
309
311
|
- [ ] If wrapping external API: normalization and `format()` preserve uncertainty; do not fabricate facts from missing upstream data
|
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<h1>@cyanheads/nasa-power-mcp-server</h1>
|
|
3
3
|
<p><b>Query NASA POWER solar, wind, building, and agroclimatology data via MCP. STDIO or Streamable HTTP.</b>
|
|
4
|
-
<div>9 Tools
|
|
4
|
+
<div>9 Tools</div>
|
|
5
5
|
</p>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/nasa-power-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/nasa-power-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
@@ -45,66 +45,68 @@ Eight tools are enabled by default; `NASA_POWER_DATAFRAME_DROP_ENABLED=true` ena
|
|
|
45
45
|
|
|
46
46
|
### `nasa_power_get_timeseries` <sub>tool</sub>
|
|
47
47
|
|
|
48
|
-
- `latitude` / `longitude
|
|
49
|
-
- `community` (`RE`, `SB`, `AG`; default `RE`), `units` (`metric`, `imperial`) and `timeStandard` (`LST`, `UTC`)
|
|
50
|
-
- Returns `
|
|
48
|
+
- `latitude` / `longitude` and `temporalResolution`: `hourly` and `daily` take an inclusive `startDate` / `endDate`, `monthly` takes `startYear` / `endYear`. `selection` is a named `preset` (default `solar_pv`) or explicit `parameters`, at most 15 effective codes hourly and 20 otherwise, corrections included.
|
|
49
|
+
- `community` (`RE`, `SB`, `AG`; default `RE`), `units` (`metric`, `imperial`) and `timeStandard` (`LST`, `UTC`). Optional `siteElevation` adds `PSC`; paired `windElevation` (10–300 meters) and `windSurface` add `WSC`. Use `nasa_power_list_reference` topic `wind_surfaces` for all 17 canonical NASA aliases, including `airportgrass`, `airportice` and `vegtype_1`; vegetation underscores are retained.
|
|
50
|
+
- Returns `metadata`, `parameters`, `expansions`, `omittedParameters`, `summaries`, `rows`, an exact `rowCount` and `dataset` (null unless staged). Optional `canvas_id` reuses a canvas when staging is needed.
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
54
|
### `nasa_power_get_climatology` <sub>tool</sub>
|
|
55
55
|
|
|
56
|
-
- Point coordinates
|
|
57
|
-
-
|
|
56
|
+
- Point coordinates with the same selection and corrections; optional `startYear` and `endYear` together, otherwise the source product range. No `temporalResolution` input.
|
|
57
|
+
- Always inline, with no `canvas_id`; a profile over the 40,000-character budget fails `dataset_limit`. The `SI_EF_TILTED_SURFACE` alias lists its returned members, numeric angles and N/S orientation text included, in `expansions`.
|
|
58
58
|
|
|
59
59
|
---
|
|
60
60
|
|
|
61
61
|
### `nasa_power_get_region` <sub>tool</sub>
|
|
62
62
|
|
|
63
|
-
- One `parameter
|
|
64
|
-
- Returns cell-tagged
|
|
63
|
+
- One `parameter` over ordered `latitudeMin` / `latitudeMax` and `longitudeMin` / `longitudeMax`, each axis spanning 2–10 degrees (`invalid_region` otherwise); split antimeridian regions into separate calls. `temporalResolution` is `daily`, `monthly` or `climatology`; point corrections are unsupported.
|
|
64
|
+
- Returns cell-tagged `rows`, `cellCount` and per-period `summaries` with equal-weight cell `min` / `mean` / `max`, not area-weighted. Optional `canvas_id` reuses a canvas for staging.
|
|
65
65
|
|
|
66
66
|
---
|
|
67
67
|
|
|
68
68
|
### `nasa_power_compare_locations` <sub>tool</sub>
|
|
69
69
|
|
|
70
|
-
- 2–10 `locations`, each with coordinates and a `label` of 1–120 characters,
|
|
71
|
-
-
|
|
72
|
-
- Optional `sort`
|
|
70
|
+
- 2–10 `locations`, each with coordinates and a `label` of 1–120 characters, sharing one selection, corrections and window. `temporalResolution` defaults to `climatology`; `hourly`, `daily` and `monthly` also work.
|
|
71
|
+
- Returns successful `locations` with per-site provenance, location-tagged `rows`, annual and calendar-season `summaries`, and `failed` entries with `partial: true` when some sites fail; all-site failure returns `all_locations_failed`. `possibleSharedGridCell` flags sites that may share a grid cell.
|
|
72
|
+
- Optional `sort` (`parameter`, `direction` `asc` / `desc`) orders by a selected numeric parameter with known identical units. Optional `canvas_id` reuses a canvas for staging.
|
|
73
|
+
- When summaries exceed the response budget, `summaryDatasets.buckets` and `summaryDatasets.locations` point to complete SQL tables; inline summaries become whole-record previews and each location includes `summaryCount`. Query in `summaryIndex` order; the location-summary table includes `locationId`. SQL `units: null` represents an omitted source unit, not a known unit.
|
|
73
74
|
|
|
74
75
|
---
|
|
75
76
|
|
|
76
77
|
### `nasa_power_search_parameters` <sub>tool</sub>
|
|
77
78
|
|
|
78
|
-
- `community` (default `RE`), `temporalResolution` (default `daily`), optional `filter` (up to 256 characters), `offset` and `limit`
|
|
79
|
-
-
|
|
79
|
+
- `community` (default `RE`), `temporalResolution` (default `daily`), optional `filter` (up to 256 characters), `offset` and positive integer `limit` (default 20, effective cap 100 with a notice when capped).
|
|
80
|
+
- Every case-insensitive `filter` token must match a code, name or definition across the complete dictionary before sorted pagination; a blank filter browses it. `entries`, `total`, `hasMore` and `truncated` describe the page.
|
|
80
81
|
|
|
81
82
|
---
|
|
82
83
|
|
|
83
84
|
### `nasa_power_list_reference` <sub>tool</sub>
|
|
84
85
|
|
|
85
86
|
- `topic`: `presets` (default), `communities`, `coverage`, `missing_data`, `wind_surfaces` or `dataframes`.
|
|
86
|
-
- Returns typed `entries`, `guidance`, `documentationUrls` and `verifiedOn`. Presets are `solar_pv`, `wind_turbine`, `building_hvac`, `agroclimatology` and `water_balance`; `building_hvac` is unavailable hourly.
|
|
87
|
+
- Returns typed `entries`, `guidance`, `documentationUrls` and `verifiedOn`. Presets are `solar_pv`, `wind_turbine`, `building_hvac`, `agroclimatology` and `water_balance`; `building_hvac` is unavailable hourly. `agroclimatology` adds `T2M_MAX` and `T2M_MIN` outside hourly resolution; monthly/climatology extremes remain source aggregates, without reconstructed daily records or calculated growing degree days.
|
|
87
88
|
|
|
88
89
|
---
|
|
89
90
|
|
|
90
91
|
### `nasa_power_dataframe_describe` <sub>tool</sub>
|
|
91
92
|
|
|
92
93
|
- Required `canvas_id` from a producing response; optional `table` limits inspection to one table.
|
|
93
|
-
- Returns
|
|
94
|
+
- Returns canvas and table expiry, SQL columns with source units, and original scientific `provenance`. Only tables in the supplied canvas are visible.
|
|
94
95
|
|
|
95
96
|
---
|
|
96
97
|
|
|
97
98
|
### `nasa_power_dataframe_query` <sub>tool</sub>
|
|
98
99
|
|
|
99
|
-
- Required `canvas_id` and one read-only SELECT in `sql` (up to 16,384 characters); `rowLimit`
|
|
100
|
-
- Returns `columns`, `rows`, `rowCount`, `shownCount`, `truncated` and `countSemantics` (`exact` or `materialized_prefix`). SQL has a 10-second deadline; the
|
|
100
|
+
- Required `canvas_id` and one read-only SELECT in `sql` (up to 16,384 characters); positive integer `rowLimit` defaults to 100 and is capped at 1,000, with an effective-cap notice for larger requests. Files, writes and system catalogs are denied.
|
|
101
|
+
- Returns `columns`, `rows`, `rowCount`, `shownCount`, `truncated` and `countSemantics` (`exact` or `materialized_prefix`). SQL has a 10-second deadline; the structured and rendered outputs each must fit 40,000 characters.
|
|
102
|
+
- SQL mistakes retain bounded identifiers or conversion values with recovery guidance. Operational failures use generic messages; engine paths and native causes are excluded.
|
|
101
103
|
|
|
102
104
|
---
|
|
103
105
|
|
|
104
106
|
### `nasa_power_dataframe_drop` <sub>tool</sub>
|
|
105
107
|
|
|
106
108
|
- Required `canvas_id` and exact `table`; enabled only by `NASA_POWER_DATAFRAME_DROP_ENABLED=true`.
|
|
107
|
-
- Returns `dropped: false` for an absent table
|
|
109
|
+
- Returns `dropped: false` for an absent table while other tables keep the canvas alive. Removing the final table also retires its canvas and frees its slot; subsequent describe, query or drop calls return `canvas_not_found`.
|
|
108
110
|
|
|
109
111
|
## Features
|
|
110
112
|
|
|
@@ -126,9 +128,7 @@ Staging requires DuckDB and supports at most 250,000 rows, 64 parameter columns
|
|
|
126
128
|
|
|
127
129
|
## Getting started
|
|
128
130
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
Add this to your MCP client configuration:
|
|
131
|
+
Add the following to your MCP client configuration file.
|
|
132
132
|
|
|
133
133
|
```json
|
|
134
134
|
{
|
|
@@ -172,27 +172,44 @@ Or with Docker:
|
|
|
172
172
|
}
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
-
For Streamable HTTP
|
|
175
|
+
For Streamable HTTP, set the transport and start the server:
|
|
176
176
|
|
|
177
177
|
```sh
|
|
178
178
|
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
|
|
179
|
-
# http://127.0.0.1:3010/mcp
|
|
179
|
+
# Server listens at http://127.0.0.1:3010/mcp
|
|
180
180
|
```
|
|
181
181
|
|
|
182
182
|
### Prerequisites
|
|
183
183
|
|
|
184
|
-
- [Bun v1.4.0](https://bun.sh/) or higher
|
|
185
|
-
- npm and Docker install native DuckDB dependencies normally on supported platforms. Set `CANVAS_PROVIDER_TYPE=
|
|
184
|
+
- [Bun v1.4.0](https://bun.sh/) or higher (or Node.js v24+).
|
|
185
|
+
- npm and Docker install native DuckDB dependencies normally on supported platforms, and staging and SQL are on by default. Set `CANVAS_PROVIDER_TYPE=none` to keep every result inline.
|
|
186
186
|
- The portable Claude Desktop MCPB bundle fixes `CANVAS_PROVIDER_TYPE=none` and supports inline results. Narrow an oversized request or use npm/Docker for analytics.
|
|
187
187
|
|
|
188
188
|
### Installation
|
|
189
189
|
|
|
190
|
+
1. **Clone the repository:**
|
|
191
|
+
|
|
190
192
|
```sh
|
|
191
193
|
git clone https://github.com/cyanheads/nasa-power-mcp-server.git
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
2. **Navigate into the directory:**
|
|
197
|
+
|
|
198
|
+
```sh
|
|
192
199
|
cd nasa-power-mcp-server
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
3. **Install dependencies:**
|
|
203
|
+
|
|
204
|
+
```sh
|
|
193
205
|
bun install
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
4. **Configure environment:**
|
|
209
|
+
|
|
210
|
+
```sh
|
|
194
211
|
cp .env.example .env
|
|
195
|
-
|
|
212
|
+
# edit .env to change transport, logging or canvas settings
|
|
196
213
|
```
|
|
197
214
|
|
|
198
215
|
## Configuration
|
|
@@ -200,7 +217,7 @@ bun run rebuild
|
|
|
200
217
|
| Variable | Description | Default |
|
|
201
218
|
|:---|:---|:---|
|
|
202
219
|
| `NASA_POWER_DATAFRAME_DROP_ENABLED` | Expose explicit staged-table removal. | `false` |
|
|
203
|
-
| `CANVAS_PROVIDER_TYPE` | `
|
|
220
|
+
| `CANVAS_PROVIDER_TYPE` | `duckdb` stages large results for SQL on npm/Docker; `none` keeps results inline. MCPB fixes `none`. | `duckdb` |
|
|
204
221
|
| `CANVAS_DEFAULT_MEMORY_LIMIT_MB` | Fixed engine memory limit; not total RSS or temporary disk. | `256` |
|
|
205
222
|
| `CANVAS_MAX_CANVASES_PER_TENANT` | Fixed tenant canvas cap. | `4` |
|
|
206
223
|
| `CANVAS_TTL_MS` | Fixed sliding canvas lifetime. | `3600000` |
|
|
@@ -209,7 +226,7 @@ bun run rebuild
|
|
|
209
226
|
| `MCP_HTTP_HOST` / `MCP_HTTP_PORT` | HTTP bind address and port. | `127.0.0.1` / `3010` |
|
|
210
227
|
| `MCP_AUTH_MODE` | `none`, `jwt` or `oauth`. | `none` |
|
|
211
228
|
| `MCP_LOG_LEVEL` | Minimum log level. | `info` |
|
|
212
|
-
| `OTEL_ENABLED` | Enable OpenTelemetry
|
|
229
|
+
| `OTEL_ENABLED` | Enable [OpenTelemetry](https://github.com/cyanheads/mcp-ts-core/tree/main/docs/telemetry). | `false` |
|
|
213
230
|
|
|
214
231
|
DuckDB startup rejects changes to the four fixed canvas settings. See [`.env.example`](./.env.example) for optional transport, authentication, storage, logging and telemetry settings.
|
|
215
232
|
|
|
@@ -217,21 +234,32 @@ DuckDB startup rejects changes to the four fixed canvas settings. See [`.env.exa
|
|
|
217
234
|
|
|
218
235
|
### Local development
|
|
219
236
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
bun run
|
|
225
|
-
|
|
237
|
+
- **Build and run the production version**:
|
|
238
|
+
|
|
239
|
+
```sh
|
|
240
|
+
# One-time build
|
|
241
|
+
bun run rebuild
|
|
242
|
+
|
|
243
|
+
# Run the built server
|
|
244
|
+
bun run start:http
|
|
245
|
+
# or
|
|
246
|
+
bun run start:stdio
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
- **Run checks and tests**:
|
|
250
|
+
```sh
|
|
251
|
+
bun run devcheck # Lints, formats, type-checks, and more
|
|
252
|
+
bun run test # Runs the test suite
|
|
253
|
+
```
|
|
226
254
|
|
|
227
255
|
### Docker
|
|
228
256
|
|
|
229
257
|
```sh
|
|
230
258
|
docker build -t nasa-power-mcp-server .
|
|
231
|
-
docker run --rm -p 127.0.0.1:3010:3010
|
|
259
|
+
docker run --rm -p 127.0.0.1:3010:3010 nasa-power-mcp-server
|
|
232
260
|
```
|
|
233
261
|
|
|
234
|
-
The image defaults to HTTP on port 3010. For a client outside loopback, configure authentication and TLS at the deployment boundary.
|
|
262
|
+
The image defaults to HTTP on port 3010 in stateless session mode and logs to `/var/log/nasa-power-mcp-server`. OpenTelemetry peer dependencies are installed by default; build with `--build-arg OTEL_ENABLED=false` to omit them. For a client outside loopback, configure authentication and TLS at the deployment boundary.
|
|
235
263
|
|
|
236
264
|
## Project structure
|
|
237
265
|
|
|
@@ -247,12 +275,13 @@ The image defaults to HTTP on port 3010. For a client outside loopback, configur
|
|
|
247
275
|
|
|
248
276
|
## Development guide
|
|
249
277
|
|
|
250
|
-
See [`CLAUDE.md`](./CLAUDE.md)
|
|
278
|
+
See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rules. The short version:
|
|
251
279
|
|
|
252
|
-
- Handlers throw, framework catches
|
|
253
|
-
-
|
|
254
|
-
-
|
|
255
|
-
-
|
|
280
|
+
- Handlers throw, framework catches — no `try/catch` in tool logic
|
|
281
|
+
- Use `ctx.log` for logging and `ctx.signal` for cancellation
|
|
282
|
+
- Register new tools in the `createApp()` array in `src/index.ts`
|
|
283
|
+
- Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields, and preserve source units and annual-period distinctions
|
|
284
|
+
- `content[]` and `structuredContent` carry the same complete data
|
|
256
285
|
|
|
257
286
|
## Contributing
|
|
258
287
|
|
|
@@ -265,4 +294,4 @@ bun run test
|
|
|
265
294
|
|
|
266
295
|
## License
|
|
267
296
|
|
|
268
|
-
Apache 2.0. See [LICENSE](./LICENSE).
|
|
297
|
+
This project is licensed under the Apache 2.0 License. See the [LICENSE](./LICENSE) file for details.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Complete NASA POWER comparisons with bounded analytical outputs."
|
|
3
|
+
breaking: true
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.2.0 — 2026-10-20
|
|
8
|
+
|
|
9
|
+
## Changed
|
|
10
|
+
|
|
11
|
+
- **Canvas lifecycle:** Dropping the last table now retires its canvas; subsequent describe, query, and drop calls with that token return `canvas_not_found`. ([#10](https://github.com/cyanheads/nasa-power-mcp-server/issues/10))
|
|
12
|
+
- **DuckDB** is enabled by default for npm and Docker; set `CANVAS_PROVIDER_TYPE=none` to disable staging. The portable MCPB remains inline-only.
|
|
13
|
+
- **Normalized request output schemas** share typed fields while preserving every request echo, including per-location provenance. ([#13](https://github.com/cyanheads/nasa-power-mcp-server/issues/13))
|
|
14
|
+
- **Output limits** above 100 dictionary entries or 1,000 SQL rows use the effective cap with a notice; explicit parameter codes deduplicate after normalization and date schemas advertise their Gregorian shape. ([#14](https://github.com/cyanheads/nasa-power-mcp-server/issues/14))
|
|
15
|
+
- **`agroclimatology`** adds `T2M_MAX` and `T2M_MIN` outside hourly resolution; reference entries show exact expansions and retain source-period semantics. ([#16](https://github.com/cyanheads/nasa-power-mcp-server/issues/16))
|
|
16
|
+
|
|
17
|
+
## Fixed
|
|
18
|
+
|
|
19
|
+
- **Location comparisons** stage complete observations, bucket summaries and per-location summaries together, returning bounded previews and ordered SQL handles with exact counts. Failed registrations roll back the entire batch. ([#9](https://github.com/cyanheads/nasa-power-mcp-server/issues/9))
|
|
20
|
+
- **Wind corrections** use all 17 canonical NASA surface aliases, preserving vegetation underscores and documented airport-ice aliases. ([#8](https://github.com/cyanheads/nasa-power-mcp-server/issues/8))
|
|
21
|
+
- **SQL diagnostics** retain bounded caller-correctable identifiers and conversion values with recovery guidance, excluding engine paths, stacks and native causes. Operational errors retain safe classifications. ([#12](https://github.com/cyanheads/nasa-power-mcp-server/issues/12))
|
|
22
|
+
- **Upstream 429 errors** report `retryable: true` to callers while preserving fail-fast handling, cooldown and `Retry-After`. ([#15](https://github.com/cyanheads/nasa-power-mcp-server/issues/15))
|
|
23
|
+
- **Documentation** aligns tool usage, native distribution defaults and canvas persistence guidance.
|
package/dist/index.js
CHANGED
|
@@ -17,8 +17,13 @@ import { listReferenceTool } from './mcp-server/tools/definitions/nasa-power-lis
|
|
|
17
17
|
import { searchParametersTool } from './mcp-server/tools/definitions/nasa-power-search-parameters.tool.js';
|
|
18
18
|
import { initCanvasService } from './services/canvas/index.js';
|
|
19
19
|
import { initPowerService } from './services/power/index.js';
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* DataCanvas defaults to DuckDB (`CANVAS_PROVIDER_TYPE=none` disables it), and the
|
|
22
|
+
* native settings must match the bounded workload contract. Applied after
|
|
23
|
+
* `parseConfig()` loads `.env`, so a value set there still wins.
|
|
24
|
+
*/
|
|
21
25
|
const canvasDefaults = {
|
|
26
|
+
CANVAS_PROVIDER_TYPE: 'duckdb',
|
|
22
27
|
CANVAS_DEFAULT_MEMORY_LIMIT_MB: '256',
|
|
23
28
|
CANVAS_MAX_CANVASES_PER_TENANT: String(POWER_LIMITS.canvasesPerTenant),
|
|
24
29
|
CANVAS_TTL_MS: String(POWER_LIMITS.canvasTtlMs),
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qEAAqE,CAAC;AAC3G,OAAO,EAAE,qBAAqB,EAAE,MAAM,sEAAsE,CAAC;AAC7G,OAAO,EAAE,iBAAiB,EAAE,MAAM,kEAAkE,CAAC;AACrG,OAAO,EAAE,kBAAkB,EAAE,MAAM,mEAAmE,CAAC;AACvG,OAAO,EAAE,kBAAkB,EAAE,MAAM,mEAAmE,CAAC;AACvG,OAAO,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAC;AAC7F,OAAO,EAAE,iBAAiB,EAAE,MAAM,kEAAkE,CAAC;AACrG,OAAO,EAAE,iBAAiB,EAAE,MAAM,kEAAkE,CAAC;AACrG,OAAO,EAAE,oBAAoB,EAAE,MAAM,qEAAqE,CAAC;AAC3G,OAAO,EAAsB,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,gBAAgB,EAAqB,MAAM,2BAA2B,CAAC;AAEhF
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|