@cyanheads/nasa-power-mcp-server 0.1.1 → 0.3.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 +20 -16
- package/CLAUDE.md +20 -16
- package/Dockerfile +3 -3
- package/README.md +103 -47
- package/changelog/0.2.x/0.2.0.md +23 -0
- package/changelog/0.3.x/0.3.0.md +35 -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 +7 -8
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/tools/definitions/comparison-contracts.d.ts +132 -368
- package/dist/mcp-server/tools/definitions/comparison-contracts.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/comparison-contracts.js +17 -5
- 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 +180 -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-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-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 +88 -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 +30 -6
- 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 +34 -51
- 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 +86 -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 +30 -28
- 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 +40 -280
- 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 +20 -4
- package/dist/services/canvas/canvas-service.d.ts.map +1 -1
- package/dist/services/canvas/canvas-service.js +225 -64
- 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/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 +64 -1
- package/dist/services/canvas/types.d.ts.map +1 -1
- package/dist/services/canvas/types.js +7 -3
- 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.d.ts.map +1 -1
- package/dist/services/power/normalize.js +25 -9
- 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 +17 -10
- package/dist/services/power/power-service.js.map +1 -1
- package/dist/services/power/presets.d.ts +25 -0
- package/dist/services/power/presets.d.ts.map +1 -1
- package/dist/services/power/presets.js +29 -1
- package/dist/services/power/presets.js.map +1 -1
- package/dist/services/power/types.d.ts +415 -194
- package/dist/services/power/types.d.ts.map +1 -1
- package/dist/services/power/types.js +71 -9
- package/dist/services/power/types.js.map +1 -1
- package/package.json +9 -7
- package/server.json +42 -24
package/AGENTS.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** nasa-power-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.
|
|
4
|
+
**Version:** 0.3.0
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.16`
|
|
6
6
|
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/server` ^2.3.1
|
|
8
8
|
**Zod:** ^4.6.7
|
|
@@ -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.
|
|
@@ -56,11 +56,13 @@ Tool files live in `src/mcp-server/tools/definitions/`. Nine tools are registere
|
|
|
56
56
|
|
|
57
57
|
### Configuration and distribution
|
|
58
58
|
|
|
59
|
-
`src/config/server-config.ts` lazily parses the drop flag with `z.stringbool().default(false)` and exports fixed `POWER_LIMITS`. Never use `z.coerce.boolean()` for environment flags.
|
|
59
|
+
`src/config/server-config.ts` lazily parses the drop flag with `z.stringbool().default(false)`, the positive `NASA_POWER_MAX_CANVASES_PER_PROCESS` (default eight), and exports fixed `POWER_LIMITS`. Never use `z.coerce.boolean()` for environment flags.
|
|
60
60
|
|
|
61
|
-
`src/index.ts`
|
|
61
|
+
`src/index.ts` defaults DuckDB to 256 MiB engine memory, four canvases per tenant, a one-hour sliding TTL and a six-hour absolute cap while honoring validated operator overrides. Pass resolved core canvas limits to service admission and provenance retention. The service enforces the configured process cap, eight tables per canvas 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
|
+
|
|
65
|
+
`@duckdb/node-api` stays on 1.5.6: framework 0.13.16's optional peer accepts 1.x, so 2.x makes npm installs fail with `ERESOLVE`.
|
|
64
66
|
|
|
65
67
|
### Identity and lifecycle
|
|
66
68
|
|
|
@@ -77,15 +79,11 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
77
79
|
| Property | Description |
|
|
78
80
|
|:---------|:------------|
|
|
79
81
|
| `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. |
|
|
82
|
+
| `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). |
|
|
83
|
+
| `ctx.signal` | `AbortSignal` for cancellation. Producing tools replace it with the call budget's signal, so the 55-second source deadline also aborts staging. |
|
|
84
|
+
| `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`. |
|
|
85
|
+
|
|
86
|
+
Staged-table provenance is written through `core.storage` in `CanvasService`, keyed by tenant, canvas and table; no handler uses `ctx.state`.
|
|
89
87
|
|
|
90
88
|
---
|
|
91
89
|
|
|
@@ -230,11 +228,14 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
230
228
|
| `bun run format` | Auto-fix formatting (safe fixes only) |
|
|
231
229
|
| `bun run format:unsafe` | Also apply Biome's unsafe autofixes — review the diff; they can change behavior |
|
|
232
230
|
| `bun run test` | Run tests (Vitest — use `bun run test`, not `bun test`) |
|
|
231
|
+
| `bun run test:coverage` | Run tests with coverage |
|
|
232
|
+
| `bun run start` | Run the built server with the configured transport |
|
|
233
233
|
| `bun run start:stdio` | Production mode (stdio) |
|
|
234
234
|
| `bun run start:http` | Production mode (HTTP) |
|
|
235
235
|
| `bun run changelog:build` | Regenerate `CHANGELOG.md` from `changelog/*.md` |
|
|
236
236
|
| `bun run changelog:check` | Verify `CHANGELOG.md` is in sync (used by devcheck) |
|
|
237
237
|
| `bun run bundle` | Build, pack, and clean a `.mcpb` for one-click Claude Desktop install |
|
|
238
|
+
| `bun run release:github` | Create or repair the GitHub Release on the version tag and attach the `.mcpb` (run by `release-and-publish`) |
|
|
238
239
|
| `bun run publish-mcp` | Authenticate with the macOS Keychain token and publish registry metadata |
|
|
239
240
|
|
|
240
241
|
**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 +303,11 @@ import { getMyService } from '@/services/my-domain/my-service.js';
|
|
|
302
303
|
- [ ] 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
304
|
- [ ] 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
305
|
- [ ] JSDoc `@fileoverview` + `@module` on every file
|
|
305
|
-
- [ ] `ctx.log` for logging
|
|
306
|
+
- [ ] `ctx.log` for logging; persistence only through `CanvasService`
|
|
306
307
|
- [ ] Handlers throw on failure — error factories or plain `Error`, no try/catch
|
|
308
|
+
- [ ] New codes and presets are checked against the selected community/resolution dictionary; source units, fill-as-`null`, `omittedParameters` and annual-period distinctions survive normalization
|
|
309
|
+
- [ ] Producing tools present through `CanvasService.present()`: oversized data stages completely or fails with `canvas_required` / `dataset_limit`, never a truncated source prefix
|
|
310
|
+
- [ ] Workload bounds live in `POWER_LIMITS`; configurable canvas defaults and process cap match across `src/index.ts`, `.env.example`, `server.json`, `manifest.json` and both plugin manifests
|
|
307
311
|
- [ ] `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
312
|
- [ ] If wrapping external API: raw/domain/output schemas reviewed against real upstream sparsity/nullability before finalizing required vs optional fields
|
|
309
313
|
- [ ] If wrapping external API: normalization and `format()` preserve uncertainty; do not fabricate facts from missing upstream data
|
package/CLAUDE.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Developer Protocol
|
|
2
2
|
|
|
3
3
|
**Server:** nasa-power-mcp-server
|
|
4
|
-
**Version:** 0.
|
|
5
|
-
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.
|
|
4
|
+
**Version:** 0.3.0
|
|
5
|
+
**Framework:** [@cyanheads/mcp-ts-core](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) `^0.13.16`
|
|
6
6
|
**Engines:** Bun ≥1.4.0, Node ≥24.0.0
|
|
7
7
|
**MCP SDK:** `@modelcontextprotocol/server` ^2.3.1
|
|
8
8
|
**Zod:** ^4.6.7
|
|
@@ -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.
|
|
@@ -56,11 +56,13 @@ Tool files live in `src/mcp-server/tools/definitions/`. Nine tools are registere
|
|
|
56
56
|
|
|
57
57
|
### Configuration and distribution
|
|
58
58
|
|
|
59
|
-
`src/config/server-config.ts` lazily parses the drop flag with `z.stringbool().default(false)` and exports fixed `POWER_LIMITS`. Never use `z.coerce.boolean()` for environment flags.
|
|
59
|
+
`src/config/server-config.ts` lazily parses the drop flag with `z.stringbool().default(false)`, the positive `NASA_POWER_MAX_CANVASES_PER_PROCESS` (default eight), and exports fixed `POWER_LIMITS`. Never use `z.coerce.boolean()` for environment flags.
|
|
60
60
|
|
|
61
|
-
`src/index.ts`
|
|
61
|
+
`src/index.ts` defaults DuckDB to 256 MiB engine memory, four canvases per tenant, a one-hour sliding TTL and a six-hour absolute cap while honoring validated operator overrides. Pass resolved core canvas limits to service admission and provenance retention. The service enforces the configured process cap, eight tables per canvas 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
|
+
|
|
65
|
+
`@duckdb/node-api` stays on 1.5.6: framework 0.13.16's optional peer accepts 1.x, so 2.x makes npm installs fail with `ERESOLVE`.
|
|
64
66
|
|
|
65
67
|
### Identity and lifecycle
|
|
66
68
|
|
|
@@ -77,15 +79,11 @@ Handlers receive a unified `ctx` object. Key properties:
|
|
|
77
79
|
| Property | Description |
|
|
78
80
|
|:---------|:------------|
|
|
79
81
|
| `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. |
|
|
82
|
+
| `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). |
|
|
83
|
+
| `ctx.signal` | `AbortSignal` for cancellation. Producing tools replace it with the call budget's signal, so the 55-second source deadline also aborts staging. |
|
|
84
|
+
| `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`. |
|
|
85
|
+
|
|
86
|
+
Staged-table provenance is written through `core.storage` in `CanvasService`, keyed by tenant, canvas and table; no handler uses `ctx.state`.
|
|
89
87
|
|
|
90
88
|
---
|
|
91
89
|
|
|
@@ -230,11 +228,14 @@ When you complete a skill's checklist, check the boxes and add a completion time
|
|
|
230
228
|
| `bun run format` | Auto-fix formatting (safe fixes only) |
|
|
231
229
|
| `bun run format:unsafe` | Also apply Biome's unsafe autofixes — review the diff; they can change behavior |
|
|
232
230
|
| `bun run test` | Run tests (Vitest — use `bun run test`, not `bun test`) |
|
|
231
|
+
| `bun run test:coverage` | Run tests with coverage |
|
|
232
|
+
| `bun run start` | Run the built server with the configured transport |
|
|
233
233
|
| `bun run start:stdio` | Production mode (stdio) |
|
|
234
234
|
| `bun run start:http` | Production mode (HTTP) |
|
|
235
235
|
| `bun run changelog:build` | Regenerate `CHANGELOG.md` from `changelog/*.md` |
|
|
236
236
|
| `bun run changelog:check` | Verify `CHANGELOG.md` is in sync (used by devcheck) |
|
|
237
237
|
| `bun run bundle` | Build, pack, and clean a `.mcpb` for one-click Claude Desktop install |
|
|
238
|
+
| `bun run release:github` | Create or repair the GitHub Release on the version tag and attach the `.mcpb` (run by `release-and-publish`) |
|
|
238
239
|
| `bun run publish-mcp` | Authenticate with the macOS Keychain token and publish registry metadata |
|
|
239
240
|
|
|
240
241
|
**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 +303,11 @@ import { getMyService } from '@/services/my-domain/my-service.js';
|
|
|
302
303
|
- [ ] 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
304
|
- [ ] 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
305
|
- [ ] JSDoc `@fileoverview` + `@module` on every file
|
|
305
|
-
- [ ] `ctx.log` for logging
|
|
306
|
+
- [ ] `ctx.log` for logging; persistence only through `CanvasService`
|
|
306
307
|
- [ ] Handlers throw on failure — error factories or plain `Error`, no try/catch
|
|
308
|
+
- [ ] New codes and presets are checked against the selected community/resolution dictionary; source units, fill-as-`null`, `omittedParameters` and annual-period distinctions survive normalization
|
|
309
|
+
- [ ] Producing tools present through `CanvasService.present()`: oversized data stages completely or fails with `canvas_required` / `dataset_limit`, never a truncated source prefix
|
|
310
|
+
- [ ] Workload bounds live in `POWER_LIMITS`; configurable canvas defaults and process cap match across `src/index.ts`, `.env.example`, `server.json`, `manifest.json` and both plugin manifests
|
|
307
311
|
- [ ] `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
312
|
- [ ] If wrapping external API: raw/domain/output schemas reviewed against real upstream sparsity/nullability before finalizing required vs optional fields
|
|
309
313
|
- [ ] If wrapping external API: normalization and `format()` preserve uncertainty; do not fabricate facts from missing upstream data
|
package/Dockerfile
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
# output. A stage that compiles a native addon needs the target-arch toolchain
|
|
15
15
|
# and cannot cross-compile this way — drop the flag there.
|
|
16
16
|
# ==============================================================================
|
|
17
|
-
FROM --platform=$BUILDPLATFORM oven/bun:1.4.
|
|
17
|
+
FROM --platform=$BUILDPLATFORM oven/bun:1.4.4 AS build
|
|
18
18
|
|
|
19
19
|
WORKDIR /usr/src/app
|
|
20
20
|
|
|
@@ -46,7 +46,7 @@ RUN bun run build
|
|
|
46
46
|
# A clean image rather than `FROM build`: the build stage's node_modules holds
|
|
47
47
|
# devDependencies.
|
|
48
48
|
# ==============================================================================
|
|
49
|
-
FROM --platform=$BUILDPLATFORM oven/bun:1.4.
|
|
49
|
+
FROM --platform=$BUILDPLATFORM oven/bun:1.4.4 AS deps
|
|
50
50
|
|
|
51
51
|
WORKDIR /usr/src/app
|
|
52
52
|
|
|
@@ -114,7 +114,7 @@ RUN rm -rf node_modules/@socketsecurity/bun-security-scanner
|
|
|
114
114
|
# dependencies and build artifacts. Its only Bun invocations are HEALTHCHECK
|
|
115
115
|
# and CMD, which run on the real target at container start.
|
|
116
116
|
# ==============================================================================
|
|
117
|
-
FROM oven/bun:1.4.
|
|
117
|
+
FROM oven/bun:1.4.4-slim AS production
|
|
118
118
|
|
|
119
119
|
WORKDIR /usr/src/app
|
|
120
120
|
|
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
|
|
|
@@ -19,6 +19,12 @@
|
|
|
19
19
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
|
+
<div align="center">
|
|
23
|
+
|
|
24
|
+
**Public Hosted Server:** [https://nasa-power.caseyjhand.com/mcp](https://nasa-power.caseyjhand.com/mcp)
|
|
25
|
+
|
|
26
|
+
</div>
|
|
27
|
+
|
|
22
28
|
---
|
|
23
29
|
|
|
24
30
|
## Overview
|
|
@@ -45,66 +51,70 @@ Eight tools are enabled by default; `NASA_POWER_DATAFRAME_DROP_ENABLED=true` ena
|
|
|
45
51
|
|
|
46
52
|
### `nasa_power_get_timeseries` <sub>tool</sub>
|
|
47
53
|
|
|
48
|
-
- `latitude` / `longitude
|
|
49
|
-
- `community` (`RE`, `SB`, `AG`; default `RE`), `units` (`metric`, `imperial`) and `timeStandard` (`LST`, `UTC`)
|
|
50
|
-
- Returns `
|
|
54
|
+
- `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.
|
|
55
|
+
- `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.
|
|
56
|
+
- 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
57
|
|
|
52
58
|
---
|
|
53
59
|
|
|
54
60
|
### `nasa_power_get_climatology` <sub>tool</sub>
|
|
55
61
|
|
|
56
|
-
- Point coordinates
|
|
57
|
-
-
|
|
62
|
+
- Point coordinates with the same selection and corrections; optional `startYear` and `endYear` together, otherwise the source product range. No `temporalResolution` input.
|
|
63
|
+
- Small profiles remain inline; larger profiles return a bounded preview and complete `dataset` handle. Pass optional `canvas_id` to reuse an existing workspace. Without DuckDB, narrow oversized selections for inline output. `SI_EF_TILTED_SURFACE` and the distinct `SI_TILTED_AVG`, `SI_TILTED_MIN`, `SI_TILTED_MAX` groups list only their actually returned members, numeric angles and N/S orientation text included, in `expansions`. A group is omitted only when none of its members return.
|
|
58
64
|
|
|
59
65
|
---
|
|
60
66
|
|
|
61
67
|
### `nasa_power_get_region` <sub>tool</sub>
|
|
62
68
|
|
|
63
|
-
- One `parameter
|
|
64
|
-
-
|
|
69
|
+
- 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.
|
|
70
|
+
- Daily regions require date bounds and monthly regions require year bounds. Regional climatology accepts no year fields and reports the source's precomputed period; use `nasa_power_get_climatology` for a custom point year window.
|
|
71
|
+
- 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.
|
|
72
|
+
- Oversized summary envelopes return `summaryDataset` with all cross-cell summaries, exact `summaryCount` and a whole-record inline preview. Query the table in `summaryIndex` order; SQL `units: null` restores an omitted source unit. Observations and summaries register together and retain linked provenance.
|
|
65
73
|
|
|
66
74
|
---
|
|
67
75
|
|
|
68
76
|
### `nasa_power_compare_locations` <sub>tool</sub>
|
|
69
77
|
|
|
70
|
-
- 2–10 `locations`, each with coordinates and a `label` of 1–120 characters,
|
|
71
|
-
-
|
|
72
|
-
- Optional `sort`
|
|
78
|
+
- 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.
|
|
79
|
+
- 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.
|
|
80
|
+
- Optional `sort` (`parameter`, `direction` `asc` / `desc`) orders by a selected numeric parameter with known identical units. Optional `canvas_id` reuses a canvas for staging.
|
|
81
|
+
- 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
82
|
|
|
74
83
|
---
|
|
75
84
|
|
|
76
85
|
### `nasa_power_search_parameters` <sub>tool</sub>
|
|
77
86
|
|
|
78
|
-
- `community` (default `RE`), `temporalResolution` (default `daily`), optional `filter` (up to 256 characters), `offset` and `limit`
|
|
79
|
-
-
|
|
87
|
+
- `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).
|
|
88
|
+
- 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
89
|
|
|
81
90
|
---
|
|
82
91
|
|
|
83
92
|
### `nasa_power_list_reference` <sub>tool</sub>
|
|
84
93
|
|
|
85
94
|
- `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.
|
|
95
|
+
- 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
96
|
|
|
88
97
|
---
|
|
89
98
|
|
|
90
99
|
### `nasa_power_dataframe_describe` <sub>tool</sub>
|
|
91
100
|
|
|
92
101
|
- Required `canvas_id` from a producing response; optional `table` limits inspection to one table.
|
|
93
|
-
- Returns
|
|
102
|
+
- Returns canvas and table expiry, SQL columns with source units, and original scientific `provenance`. Only tables in the supplied canvas are visible.
|
|
94
103
|
|
|
95
104
|
---
|
|
96
105
|
|
|
97
106
|
### `nasa_power_dataframe_query` <sub>tool</sub>
|
|
98
107
|
|
|
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
|
|
108
|
+
- 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.
|
|
109
|
+
- 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.
|
|
110
|
+
- SQL mistakes retain bounded identifiers or conversion values with recovery guidance. Operational failures use generic messages; engine paths and native causes are excluded.
|
|
101
111
|
|
|
102
112
|
---
|
|
103
113
|
|
|
104
114
|
### `nasa_power_dataframe_drop` <sub>tool</sub>
|
|
105
115
|
|
|
106
116
|
- Required `canvas_id` and exact `table`; enabled only by `NASA_POWER_DATAFRAME_DROP_ENABLED=true`.
|
|
107
|
-
- Returns `dropped: false` for an absent table
|
|
117
|
+
- 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
118
|
|
|
109
119
|
## Features
|
|
110
120
|
|
|
@@ -115,6 +125,7 @@ POWER-specific:
|
|
|
115
125
|
- Historical gridded observations, rather than site measurements or forecasts. Meteorological coverage starts in 1981, solar in 1984 and hourly in 2001; source configuration and publication latency further constrain availability.
|
|
116
126
|
- One active upstream request, starts at least two seconds apart, bounded retries and a 55-second overall call deadline. NASA publishes no numeric request allowance. References cache for 24 hours and observations for 10 minutes.
|
|
117
127
|
- Source fill values become `null`; zero remains a measurement. Monthly annual keys and climatology `ANN` remain distinct from monthly observations. LST labels have no UTC offset.
|
|
128
|
+
- `T_ZONES` and `TM_ZONES` retain numeric climate-zone codes with `valueKind: categorical`, including in SQL column metadata. They have no arithmetic summaries or comparison sort metrics; explicit numeric sorting by either is rejected.
|
|
118
129
|
|
|
119
130
|
Agent-friendly output:
|
|
120
131
|
|
|
@@ -122,13 +133,28 @@ Agent-friendly output:
|
|
|
122
133
|
- Explicit gaps — `omittedParameters` distinguishes an absent series from fill values; arithmetic observation means and calendar-season buckets are not climate normals, annual yields or water balances.
|
|
123
134
|
- Complete datasets — inline outputs each fit 40,000 characters. Larger datasets stage all rows with a preview of at most 20 rows and a `dataset` handle; unsupported or oversized requests fail with narrowing guidance instead of returning a capped source prefix.
|
|
124
135
|
|
|
125
|
-
Staging requires DuckDB and supports at most 250,000 rows, 64 parameter columns and 32 MiB of serialized rows per dataset. Canvases are process-local capabilities: pass the returned token explicitly and route later calls to the same process. Tables expire after 30 minutes
|
|
136
|
+
Staging requires DuckDB and supports at most 250,000 rows, 64 parameter columns and 32 MiB of serialized rows per dataset. Canvases are process-local capabilities: pass the returned token explicitly and route later calls to the same process. Tables expire after 30 minutes with eight tables per canvas. Defaults are one idle hour and six absolute hours per canvas, four canvases per tenant, eight per process, and 256 MiB engine memory per canvas. Operators can size canvas capacity, memory and lifetime below; engine memory does not bound total RSS or temporary disk.
|
|
126
137
|
|
|
127
138
|
## Getting started
|
|
128
139
|
|
|
140
|
+
### Public Hosted Instance
|
|
141
|
+
|
|
142
|
+
A public instance is available at `https://nasa-power.caseyjhand.com/mcp` — no installation required. Point any MCP client at it via Streamable HTTP:
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"mcpServers": {
|
|
147
|
+
"nasa-power-mcp-server": {
|
|
148
|
+
"type": "streamable-http",
|
|
149
|
+
"url": "https://nasa-power.caseyjhand.com/mcp"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
129
155
|
### Self-Hosted / Local
|
|
130
156
|
|
|
131
|
-
Add
|
|
157
|
+
Add the following to your MCP client configuration file.
|
|
132
158
|
|
|
133
159
|
```json
|
|
134
160
|
{
|
|
@@ -172,27 +198,44 @@ Or with Docker:
|
|
|
172
198
|
}
|
|
173
199
|
```
|
|
174
200
|
|
|
175
|
-
For Streamable HTTP
|
|
201
|
+
For Streamable HTTP, set the transport and start the server:
|
|
176
202
|
|
|
177
203
|
```sh
|
|
178
204
|
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
|
|
179
|
-
# http://127.0.0.1:3010/mcp
|
|
205
|
+
# Server listens at http://127.0.0.1:3010/mcp
|
|
180
206
|
```
|
|
181
207
|
|
|
182
208
|
### Prerequisites
|
|
183
209
|
|
|
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=
|
|
210
|
+
- [Bun v1.4.0](https://bun.sh/) or higher (or Node.js v24+).
|
|
211
|
+
- 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
212
|
- 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
213
|
|
|
188
214
|
### Installation
|
|
189
215
|
|
|
216
|
+
1. **Clone the repository:**
|
|
217
|
+
|
|
190
218
|
```sh
|
|
191
219
|
git clone https://github.com/cyanheads/nasa-power-mcp-server.git
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
2. **Navigate into the directory:**
|
|
223
|
+
|
|
224
|
+
```sh
|
|
192
225
|
cd nasa-power-mcp-server
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
3. **Install dependencies:**
|
|
229
|
+
|
|
230
|
+
```sh
|
|
193
231
|
bun install
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
4. **Configure environment:**
|
|
235
|
+
|
|
236
|
+
```sh
|
|
194
237
|
cp .env.example .env
|
|
195
|
-
|
|
238
|
+
# edit .env to change transport, logging or canvas settings
|
|
196
239
|
```
|
|
197
240
|
|
|
198
241
|
## Configuration
|
|
@@ -200,38 +243,50 @@ bun run rebuild
|
|
|
200
243
|
| Variable | Description | Default |
|
|
201
244
|
|:---|:---|:---|
|
|
202
245
|
| `NASA_POWER_DATAFRAME_DROP_ENABLED` | Expose explicit staged-table removal. | `false` |
|
|
203
|
-
| `CANVAS_PROVIDER_TYPE` | `
|
|
204
|
-
| `CANVAS_DEFAULT_MEMORY_LIMIT_MB` |
|
|
205
|
-
| `CANVAS_MAX_CANVASES_PER_TENANT` |
|
|
206
|
-
| `
|
|
207
|
-
| `
|
|
246
|
+
| `CANVAS_PROVIDER_TYPE` | `duckdb` stages large results for SQL on npm/Docker; `none` keeps results inline. MCPB fixes `none`. | `duckdb` |
|
|
247
|
+
| `CANVAS_DEFAULT_MEMORY_LIMIT_MB` | Per-canvas engine memory, integer ≥64 MiB; not total RSS or temporary disk. | `256` |
|
|
248
|
+
| `CANVAS_MAX_CANVASES_PER_TENANT` | Positive tenant canvas cap; auth-none callers share one tenant. | `4` |
|
|
249
|
+
| `NASA_POWER_MAX_CANVASES_PER_PROCESS` | Positive process canvas cap, including pending and failed cleanup reservations. | `8` |
|
|
250
|
+
| `CANVAS_TTL_MS` | Positive sliding canvas lifetime in milliseconds. | `3600000` |
|
|
251
|
+
| `CANVAS_ABSOLUTE_CAP_MS` | Absolute canvas lifetime in milliseconds, at least the sliding TTL. | `21600000` |
|
|
208
252
|
| `MCP_TRANSPORT_TYPE` | `stdio` or `http`. | `stdio` |
|
|
209
253
|
| `MCP_HTTP_HOST` / `MCP_HTTP_PORT` | HTTP bind address and port. | `127.0.0.1` / `3010` |
|
|
210
254
|
| `MCP_AUTH_MODE` | `none`, `jwt` or `oauth`. | `none` |
|
|
211
255
|
| `MCP_LOG_LEVEL` | Minimum log level. | `info` |
|
|
212
|
-
| `OTEL_ENABLED` | Enable OpenTelemetry
|
|
256
|
+
| `OTEL_ENABLED` | Enable [OpenTelemetry](https://github.com/cyanheads/mcp-ts-core/tree/main/docs/telemetry). | `false` |
|
|
213
257
|
|
|
214
|
-
|
|
258
|
+
Unset, blank and whole-value placeholder settings retain these defaults. Invalid sizing fails startup. Byte budgets, table limits and producer concurrency remain fixed independently of operator canvas sizing. See [`.env.example`](./.env.example) for optional transport, authentication, storage, logging and telemetry settings.
|
|
215
259
|
|
|
216
260
|
## Running the server
|
|
217
261
|
|
|
218
262
|
### Local development
|
|
219
263
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
bun run
|
|
225
|
-
|
|
264
|
+
- **Build and run the production version**:
|
|
265
|
+
|
|
266
|
+
```sh
|
|
267
|
+
# One-time build
|
|
268
|
+
bun run rebuild
|
|
269
|
+
|
|
270
|
+
# Run the built server
|
|
271
|
+
bun run start:http
|
|
272
|
+
# or
|
|
273
|
+
bun run start:stdio
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
- **Run checks and tests**:
|
|
277
|
+
```sh
|
|
278
|
+
bun run devcheck # Lints, formats, type-checks, and more
|
|
279
|
+
bun run test # Runs the test suite
|
|
280
|
+
```
|
|
226
281
|
|
|
227
282
|
### Docker
|
|
228
283
|
|
|
229
284
|
```sh
|
|
230
285
|
docker build -t nasa-power-mcp-server .
|
|
231
|
-
docker run --rm -p 127.0.0.1:3010:3010
|
|
286
|
+
docker run --rm -p 127.0.0.1:3010:3010 nasa-power-mcp-server
|
|
232
287
|
```
|
|
233
288
|
|
|
234
|
-
The image defaults to HTTP on port 3010. For a client outside loopback, configure authentication and TLS at the deployment boundary.
|
|
289
|
+
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
290
|
|
|
236
291
|
## Project structure
|
|
237
292
|
|
|
@@ -247,12 +302,13 @@ The image defaults to HTTP on port 3010. For a client outside loopback, configur
|
|
|
247
302
|
|
|
248
303
|
## Development guide
|
|
249
304
|
|
|
250
|
-
See [`CLAUDE.md`](./CLAUDE.md)
|
|
305
|
+
See [`CLAUDE.md`](./CLAUDE.md) for development guidelines and architectural rules. The short version:
|
|
251
306
|
|
|
252
|
-
- Handlers throw, framework catches
|
|
253
|
-
-
|
|
254
|
-
-
|
|
255
|
-
-
|
|
307
|
+
- Handlers throw, framework catches — no `try/catch` in tool logic
|
|
308
|
+
- Use `ctx.log` for logging and `ctx.signal` for cancellation
|
|
309
|
+
- Register new tools in the `createApp()` array in `src/index.ts`
|
|
310
|
+
- 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
|
|
311
|
+
- `content[]` and `structuredContent` carry the same complete data
|
|
256
312
|
|
|
257
313
|
## Contributing
|
|
258
314
|
|
|
@@ -265,4 +321,4 @@ bun run test
|
|
|
265
321
|
|
|
266
322
|
## License
|
|
267
323
|
|
|
268
|
-
Apache 2.0. See [LICENSE](./LICENSE).
|
|
324
|
+
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.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "Complete regional analysis and configurable canvases"
|
|
3
|
+
breaking: true
|
|
4
|
+
security: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 0.3.0 — 2026-10-24
|
|
8
|
+
|
|
9
|
+
## Added
|
|
10
|
+
|
|
11
|
+
- **Canvas sizing** honors validated memory, tenant capacity and lifetime overrides; `NASA_POWER_MAX_CANVASES_PER_PROCESS` controls process capacity with the existing default of eight ([#19](https://github.com/cyanheads/nasa-power-mcp-server/issues/19)).
|
|
12
|
+
- **Regional summary staging** returns complete observation and summary tables with `summaryDataset`, exact `summaryCount`, ordered `summaryIndex` retrieval and linked provenance; registration failures roll back the complete new batch ([#24](https://github.com/cyanheads/nasa-power-mcp-server/issues/24)).
|
|
13
|
+
- **Point climatology** accepts optional `canvas_id` for workspace reuse and stages oversized profiles completely with bounded previews ([#23](https://github.com/cyanheads/nasa-power-mcp-server/issues/23)).
|
|
14
|
+
|
|
15
|
+
## Changed
|
|
16
|
+
|
|
17
|
+
- Regional climatology no longer accepts startYear or endYear; omit both even when they match the source period (#20). Use point climatology for custom year windows.
|
|
18
|
+
- **SQL columns named `current_schema`** now require table qualification: use `c.current_schema` rather than `current_schema` when selecting that CTE column.
|
|
19
|
+
- **Development tooling** follows the adopted framework guidance and audit classification; Bun runtime and Docker images move from 1.4.3 to 1.4.4.
|
|
20
|
+
- **Hosted access** is documented at `https://nasa-power.caseyjhand.com/mcp` and advertised in registry metadata.
|
|
21
|
+
|
|
22
|
+
## Fixed
|
|
23
|
+
|
|
24
|
+
- **Climate-zone codes** `T_ZONES` and `TM_ZONES` retain numeric values with categorical metadata and no arithmetic summaries or numeric comparison sorting; shared source units remain present independently of numeric comparability ([#21](https://github.com/cyanheads/nasa-power-mcp-server/issues/21)).
|
|
25
|
+
- **Tilted-solar aliases** `SI_TILTED_AVG`, `SI_TILTED_MIN` and `SI_TILTED_MAX` report only their returned members in `expansions` and are omitted only when no member returns ([#22](https://github.com/cyanheads/nasa-power-mcp-server/issues/22)).
|
|
26
|
+
- **Environment initialization** loads `.env` before server-specific parsing; framework error text and link rendering preserve literal source values on both response surfaces.
|
|
27
|
+
|
|
28
|
+
## Dependencies
|
|
29
|
+
|
|
30
|
+
- `@cyanheads/mcp-ts-core` ^0.13.15 → ^0.13.16.
|
|
31
|
+
- `@duckdb/node-api` ^1.5.6-r.1 → ^1.5.6-r.2.
|
|
32
|
+
- `@biomejs/biome` 2.5.15 → 2.6.2.
|
|
33
|
+
- `ignore` ^7.0.12 → ^7.0.13.
|
|
34
|
+
- `tsc-alias` ^1.9.7 → ^1.9.8.
|
|
35
|
+
- Added test dependencies `markdown-it` ^15.0.3 and `@types/markdown-it` ^14.2.0.
|
|
@@ -37,6 +37,7 @@ export declare const POWER_LIMITS: {
|
|
|
37
37
|
};
|
|
38
38
|
/** Server-specific environment configuration. */
|
|
39
39
|
export declare const ServerConfigSchema: z.ZodObject<{
|
|
40
|
+
maxCanvasesPerProcess: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
40
41
|
dataframeDropEnabled: z.ZodDefault<z.ZodCodec<z.ZodString, z.ZodBoolean>>;
|
|
41
42
|
}, z.core.$strip>;
|
|
42
43
|
/** Parsed configuration consumed by services. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA,uGAAuG;AACvG,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAG3C,4EAA4E;AAC5E,eAAO,MAAM,YAAY;aACvB,UAAU,EAAE,IAAK;aACjB,UAAU,EAAE,EAAE;aACd,WAAW,EAAE,KAAM;aACnB,UAAU,EAAE,KAAM;aAClB,SAAS,EAAE,KAAM;aACjB,QAAQ,EAAE,CAAC;aACX,kBAAkB,EAAE,EAAE;aACtB,SAAS;aACT,mBAAmB;aACnB,IAAI,EAAE,MAAO;aACb,OAAO,EAAE,EAAE;aACX,QAAQ;aACR,gBAAgB,EAAE,KAAM;aACxB,UAAU;aACV,YAAY,EAAE,GAAG;aACjB,cAAc,EAAE,QAAU;aAC1B,SAAS,EAAE,MAAO;aAClB,mBAAmB;aACnB,oBAAoB;aACpB,mBAAmB;aACnB,oBAAoB;aACpB,SAAS,EAAE,CAAC;aACZ,eAAe,EAAE,CAAC;aAClB,iBAAiB,EAAE,CAAC;aACpB,kBAAkB,EAAE,CAAC;aACrB,UAAU,EAAE,OAAS;aACrB,WAAW,EAAE,OAAS;aACtB,mBAAmB,EAAE,QAAU;aAC/B,OAAO,EAAE,KAAM;aACf,aAAa,EAAE,KAAM;aACrB,SAAS,EAAE,IAAK;aAChB,OAAO,EAAE,CAAC;CACF,CAAC;AACX,iDAAiD;AACjD,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../src/config/server-config.ts"],"names":[],"mappings":"AAAA,uGAAuG;AACvG,OAAO,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAG3C,4EAA4E;AAC5E,eAAO,MAAM,YAAY;aACvB,UAAU,EAAE,IAAK;aACjB,UAAU,EAAE,EAAE;aACd,WAAW,EAAE,KAAM;aACnB,UAAU,EAAE,KAAM;aAClB,SAAS,EAAE,KAAM;aACjB,QAAQ,EAAE,CAAC;aACX,kBAAkB,EAAE,EAAE;aACtB,SAAS;aACT,mBAAmB;aACnB,IAAI,EAAE,MAAO;aACb,OAAO,EAAE,EAAE;aACX,QAAQ;aACR,gBAAgB,EAAE,KAAM;aACxB,UAAU;aACV,YAAY,EAAE,GAAG;aACjB,cAAc,EAAE,QAAU;aAC1B,SAAS,EAAE,MAAO;aAClB,mBAAmB;aACnB,oBAAoB;aACpB,mBAAmB;aACnB,oBAAoB;aACpB,SAAS,EAAE,CAAC;aACZ,eAAe,EAAE,CAAC;aAClB,iBAAiB,EAAE,CAAC;aACpB,kBAAkB,EAAE,CAAC;aACrB,UAAU,EAAE,OAAS;aACrB,WAAW,EAAE,OAAS;aACtB,mBAAmB,EAAE,QAAU;aAC/B,OAAO,EAAE,KAAM;aACf,aAAa,EAAE,KAAM;aACrB,SAAS,EAAE,IAAK;aAChB,OAAO,EAAE,CAAC;CACF,CAAC;AACX,iDAAiD;AACjD,eAAO,MAAM,kBAAkB;;;iBAY7B,CAAC;AACH,iDAAiD;AACjD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,wEAAwE;AACxE,wBAAgB,eAAe,IAAI,YAAY,CAO9C"}
|