offnadir-delta-mcp 1.39.0 → 2.1.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/README.md CHANGED
@@ -16,7 +16,7 @@ satellite can actually resolve it, and produce a collection-ready plan.
16
16
  Real-time event and geospatial intelligence for OSINT, geopolitical risk, and GEOINT work —
17
17
  source-linked, geolocated, and current, not a training snapshot.
18
18
 
19
- `40` tools · MCP server version `1.39.0` · [full reference](https://offnadir-delta.com/docs/mcp)
19
+ `35` tools · MCP server version `2.1.0` · [full reference](https://offnadir-delta.com/docs/mcp)
20
20
 
21
21
  ## What it does
22
22
 
@@ -77,7 +77,7 @@ locally from a generated catalog, so registries can introspect it without creden
77
77
 
78
78
  ### First call — free
79
79
 
80
- 23 of the 40 tools cost nothing, so the first thing you run is free:
80
+ 21 of the 35 tools cost nothing, so the first thing you run is free:
81
81
 
82
82
  > Give me the latest Daily World Brief. Lead with the three most significant developments,
83
83
  > explain why each matters, and cite the supporting signals.
@@ -91,13 +91,11 @@ Then try the full signal-to-satellite workflow:
91
91
 
92
92
  ### Discover
93
93
 
94
- What is happening, where it concentrates, and what today looks like.
94
+ What is happening, what changed, and what today looks like.
95
95
 
96
96
  | Tool | What it does | Cost |
97
97
  | --- | --- | --- |
98
98
  | `query_signals` | Geolocated world events from global news media, AI-enriched with severity/GEOINT scores and collection recommendations. | 3 tok |
99
- | `query_stats` | Roll-ups over the corpus: totals plus per-category and per-day breakdown. | 1 tok |
100
- | `query_hotspots` | Where activity concentrates: density grid-binned into ranked cells with peak severity, categories and representative event_ids. | 1 tok |
101
99
  | `get_world_brief` | AI world brief: daily (prior UTC day, all plans) or weekly/monthly by plan. | free |
102
100
  | `query_developments` | What actually CHANGED about the events in an area, not which articles are new. | 3 tok |
103
101
  | `get_event_thread` | One event end to end: state plus every change in order — the "new event or update" distinction a feed cannot make. | free |
@@ -128,7 +126,6 @@ Turn reporting into a cited assessment you can audit afterwards.
128
126
  | `assess_signal` | AI remote-sensing deep-dive for one signal: what to observe, sensors, a collection window. | 5/15 tok |
129
127
  | `ask_analyst` | Ask the Delta Analyst an OSINT/GEOINT question; returns a structured brief. | 5–123 tok |
130
128
  | `get_analyst_job` | Status and result of an ask_analyst run. | free |
131
- | `query_claims` | The ledger of claims this key was given, each with its evidence class, independent source families and publishers. | free |
132
129
  | `measure_index_series` | Measure a spectral index over an area scene by scene through the Sentinel-2 archive. | 0.5 tok |
133
130
  | `detect_ships` | Count vessel-like targets in ONE Sentinel-1 SAR scene by CFAR detection — radar sees through cloud and at night. | 5 tok |
134
131
 
@@ -138,17 +135,15 @@ Stand up continuous coverage and be told only when the answer changes. Creating
138
135
 
139
136
  | Tool | What it does | Cost |
140
137
  | --- | --- | --- |
141
- | `create_standing_order` | Put an area under CONTINUOUS watch: a question plus a bbox, re-answered on a schedule, notifying only when the answer changed. | free |
138
+ | `create_standing_order` | Put an area under CONTINUOUS watch (the app’s "Watch this area"): checked weekly, notifying only when new events cross the bar. | free |
142
139
  | `list_standing_orders` | The standing orders on this key: cadence, area, last check, last actual fire, and quiet_checks — a high quiet_checks means the watch is not earning its place. | free |
143
- | `delete_standing_order` | Delete a standing order, or pause/resume with active=false/true. | free |
144
140
  | `list_monitored_areas` | Places under continuous satellite measurement: metric, latest value, change, anomaly flag, coverage. | free |
145
141
  | `get_monitored_area` | One monitored area with its full measurement history. | free |
146
142
  | `create_monitored_area` | Put a place under continuous satellite measurement — every new Sentinel-1/2 or VIIRS acquisition (or FIRMS fire detection) is measured. | free |
147
143
  | `list_watches` | The Watchlist as one list, each entry with a state bucket. | free |
148
144
  | `get_watch` | One watch end to end: target, state, latest change, measurements with recent series, standing-order questions, and for an event watch its stage, developments and thread, plus this account's notes. | free |
149
- | `get_decision_package` | Everything needed to decide what to collect next about one watch, in one object. | 5 tok |
150
145
  | `create_watch` | Add a target to the Watchlist. | free |
151
- | `update_watch` | Rename, pause, resume or close a watch. | free |
146
+ | `update_watch` | Pause, resume or close a watch. | free |
152
147
  | `delete_watch` | Delete a watch and its underlying resources — bound monitored areas with their history, and standing orders. | free |
153
148
  | `add_note` | Add a note to a watch, start a thread, or reply. | free |
154
149
  | `delete_note` | Delete one note from a watch. | free |
@@ -195,25 +190,17 @@ Two credentials are accepted on the hosted endpoint:
195
190
  Keys are shown once at creation, hashed at rest, and revocable at any time from
196
191
  [/account/api](https://offnadir-delta.com/account/api).
197
192
 
198
- ## Resources and prompts
193
+ ## Resources
199
194
 
200
195
  | Resource | Description |
201
196
  | --- | --- |
202
197
  | `brief://latest` | The most recent AI-synthesized Daily World Brief (JSON). Free. |
203
198
  | `signals://schema` | JSON Schema of the public Signal shape returned by query_signals / /api/v1/signals. |
204
199
  | `usage://current` | Remaining token balance and plan capabilities for the calling key. Free. |
205
- | `imagery://collections` | The satellite catalog collections searchable via search_imagery — Sentinel-1 C-band SAR, Sentinel-2 optical, and NISAR L-band SAR (provisional calibration). Free. |
206
200
  | `status://current` | How current the data is (ingestion/enrichment frontier), the Daily World Brief status, and an Operational/Delayed/Degraded roll-up. Free. |
207
201
  | `brief://{date}` | The Daily World Brief for a specific UTC date (YYYY-MM-DD). Free. |
208
202
  | `watch://{watch_id}` | A Watchlist entry with its current state, latest meaningful change, measurements, (for event watches) the full event thread, and the notes kept against it. The same body get_watch returns. Free. |
209
203
 
210
- | Prompt | Description |
211
- | --- | --- |
212
- | `daily-situation-briefing` | Summarize the current world situation from the Daily World Brief. |
213
- | `assess-top-signal` | Find the highest-severity recent signal in an area/category and run an RS assessment. |
214
- | `aoi-watch` | Scan an area of interest for recent escalations and recommend collection. |
215
- | `market-exposure-check` | Find recent events that could plausibly move a given market (oil, grain, shipping, ...) and explain each transmission channel. Informational only — not investment advice. |
216
-
217
204
  ## Links
218
205
 
219
206
  - [Tool reference, setup, and one-click installs](https://offnadir-delta.com/docs/mcp)
package/dist/catalog.js CHANGED
@@ -13,7 +13,7 @@
13
13
  * Actual `tools/call` / `resources/read` / `prompts/get` requests are forwarded
14
14
  * to the remote server with the caller's OFFNADIR_DELTA_API_KEY (see index.ts).
15
15
  */
16
- // Generated for Off-Nadir Delta MCP 1.39.0.
16
+ // Generated for Off-Nadir Delta MCP 2.1.0.
17
17
  export const TOOLS = [
18
18
  {
19
19
  "name": "query_signals",
@@ -30,14 +30,22 @@ export const TOOLS = [
30
30
  "maxItems": 4,
31
31
  "description": "[minLon, minLat, maxLon, maxLat] WGS84. Omit for worldwide."
32
32
  },
33
- "date": {
33
+ "startDate": {
34
34
  "type": "string",
35
- "description": "Window end date, YYYY-MM-DD (UTC). Default today. Records start 2026-09-23 (earlier: unrecorded, not quiet). Plan-bounded: meta.window_clamp."
35
+ "description": "Date range start, YYYY-MM-DD (UTC). With endDate. Records start 2026-09-23 (earlier: unrecorded, not quiet). Plan-bounded: meta.window_clamp."
36
36
  },
37
- "days": {
38
- "type": "integer",
39
- "minimum": 1,
40
- "description": "Window length in days. Default 1."
37
+ "endDate": {
38
+ "type": "string",
39
+ "description": "Date range end, YYYY-MM-DD (UTC), inclusive."
40
+ },
41
+ "recency": {
42
+ "type": "string",
43
+ "enum": [
44
+ "15m",
45
+ "1h",
46
+ "24h"
47
+ ],
48
+ "description": "Last reported within. Default 24h when no date range."
41
49
  },
42
50
  "categories": {
43
51
  "type": "array",
@@ -58,6 +66,40 @@ export const TOOLS = [
58
66
  },
59
67
  "description": "Restrict to these categories."
60
68
  },
69
+ "q": {
70
+ "type": "string",
71
+ "description": "Text search: all words; \"phrase\"; -exclude."
72
+ },
73
+ "stages": {
74
+ "type": "array",
75
+ "items": {
76
+ "type": "string",
77
+ "enum": [
78
+ "reported",
79
+ "localized",
80
+ "pinpointed"
81
+ ]
82
+ },
83
+ "description": "reported=country/province, localized=town, pinpointed=block/facility."
84
+ },
85
+ "minSeverityBand": {
86
+ "type": "integer",
87
+ "enum": [
88
+ 4,
89
+ 6,
90
+ 9
91
+ ],
92
+ "description": "severity_band >= this."
93
+ },
94
+ "minPublishers": {
95
+ "type": "integer",
96
+ "enum": [
97
+ 2,
98
+ 3,
99
+ 5
100
+ ],
101
+ "description": "At least this many publishers."
102
+ },
61
103
  "markets": {
62
104
  "type": "array",
63
105
  "items": {
@@ -76,61 +118,27 @@ export const TOOLS = [
76
118
  },
77
119
  "description": "Markets exposed via a physical/supply channel."
78
120
  },
79
- "limit": {
80
- "type": "integer",
81
- "minimum": 1,
82
- "maximum": 500,
83
- "description": "Max rows per page. Default 100."
84
- },
85
- "cursor": {
86
- "type": "string",
87
- "description": "Cursor from meta.next_cursor."
88
- },
89
- "minSeverity": {
90
- "type": "number",
91
- "minimum": 0,
92
- "maximum": 10,
93
- "description": "severity_score >= this (0-10)."
94
- },
95
- "minSeverityBand": {
96
- "type": "integer",
97
- "minimum": 1,
98
- "maximum": 10,
99
- "description": "severity_band >= this."
100
- },
101
- "escalating": {
102
- "type": "boolean",
103
- "description": "escalation_trend is \"escalating\"."
104
- },
105
- "sort": {
121
+ "placement": {
106
122
  "type": "string",
107
123
  "enum": [
108
- "severity",
109
- "recent",
110
- "sources",
111
- "geoint"
124
+ "all",
125
+ "map",
126
+ "list"
112
127
  ],
113
- "description": "Default \"severity\". \"geoint\": visible first, then geoint_score, stage."
128
+ "description": "map=a point; list=country/province only."
114
129
  },
115
- "updatedSince": {
130
+ "observable": {
116
131
  "type": "string",
117
- "description": "Refolded at/after (ISO); narrows the window."
132
+ "enum": [
133
+ "any",
134
+ "yes",
135
+ "no"
136
+ ],
137
+ "description": "A satellite could see it."
118
138
  },
119
- "createdSince": {
139
+ "linkedTo": {
120
140
  "type": "string",
121
- "description": "FIRST seen at/after (ISO)."
122
- },
123
- "stages": {
124
- "type": "array",
125
- "items": {
126
- "type": "string",
127
- "enum": [
128
- "reported",
129
- "localized",
130
- "pinpointed"
131
- ]
132
- },
133
- "description": "reported=country/province, localized=town, pinpointed=block/facility."
141
+ "description": "Events sharing a connector: facility:<entity_id>, place:<place_key>, actor:<name>. Plan-gated."
134
142
  },
135
143
  "sensors": {
136
144
  "type": "array",
@@ -146,209 +154,58 @@ export const TOOLS = [
146
154
  "none"
147
155
  ]
148
156
  },
149
- "description": "Recommended sensor is one of these."
150
- },
151
- "minGeoint": {
152
- "type": "number",
153
- "minimum": 0,
154
- "maximum": 10,
155
- "description": "geoint_score >= this (0-10)."
156
- },
157
- "plottableOnly": {
158
- "type": "boolean",
159
- "description": "Precise enough to be a point."
160
- },
161
- "observableOnly": {
162
- "type": "boolean",
163
- "description": "A satellite could see it."
164
- },
165
- "q": {
166
- "type": "string",
167
- "description": "Text search: all words; \"phrase\"; -exclude."
168
- },
169
- "reportedSince": {
170
- "type": "string",
171
- "description": "Last reported at/after (ISO)."
172
- },
173
- "minPublishers": {
174
- "type": "integer",
175
- "minimum": 1,
176
- "description": "At least this many publishers."
177
- },
178
- "unplottableOnly": {
179
- "type": "boolean",
180
- "description": "Only events that cannot be a point."
181
- },
182
- "responseFormat": {
183
- "type": "string",
184
- "enum": [
185
- "concise",
186
- "detailed"
187
- ],
188
- "description": "\"detailed\": full Signal (signals://schema)."
189
- }
190
- }
191
- },
192
- "outputSchema": {
193
- "type": "object",
194
- "properties": {
195
- "meta": {
196
- "type": "object",
197
- "description": "Query echo, token charge/balance (meta.tokens), and pagination where applicable."
198
- },
199
- "summary": {
200
- "type": "string",
201
- "description": "One-line natural-language summary of the result, ready to relay to a user."
202
- },
203
- "signals": {
204
- "type": "array",
205
- "items": {
206
- "type": "object"
207
- }
208
- }
209
- },
210
- "required": [
211
- "meta",
212
- "signals"
213
- ]
214
- },
215
- "annotations": {
216
- "readOnlyHint": false,
217
- "openWorldHint": false,
218
- "destructiveHint": true
219
- }
220
- },
221
- {
222
- "name": "query_stats",
223
- "description": "Roll-ups over the corpus: totals plus per-category and per-day breakdown. `total` counts the same events query_signals returns, so it matches its meta.total_count for the same query.",
224
- "inputSchema": {
225
- "type": "object",
226
- "properties": {
227
- "bbox": {
228
- "type": "array",
229
- "items": {
230
- "type": "number"
231
- },
232
- "minItems": 4,
233
- "maxItems": 4,
234
- "description": "[minLon, minLat, maxLon, maxLat] WGS84. Omit for worldwide."
157
+ "description": "Recommended sensor (unassessed passes)."
235
158
  },
236
- "date": {
237
- "type": "string",
238
- "description": "Window end date, YYYY-MM-DD (UTC). Defaults to today. Records start 2026-09-23 (earlier: unrecorded, not quiet). Plan-bounded: meta.window_clamp."
239
- },
240
- "days": {
241
- "type": "integer",
242
- "minimum": 1,
243
- "description": "Window length in days. Defaults to 1."
244
- },
245
- "categories": {
159
+ "collectionLevels": {
246
160
  "type": "array",
247
161
  "items": {
248
162
  "type": "string",
249
163
  "enum": [
250
- "kinetic",
251
- "armed_conflict",
252
- "maritime",
253
- "natural_disaster",
254
- "infrastructure",
255
- "aviation",
256
- "humanitarian",
257
- "protest",
258
- "diplomacy",
259
- "other"
164
+ "GSD<0.1m",
165
+ "GSD<0.5m",
166
+ "GSD<1m",
167
+ "GSD<10m",
168
+ "GSD<100m",
169
+ "Impossible"
260
170
  ]
261
171
  },
262
- "description": "Restrict to these categories. Omit for all."
263
- }
264
- }
265
- },
266
- "outputSchema": {
267
- "type": "object",
268
- "properties": {
269
- "meta": {
270
- "type": "object",
271
- "description": "Query echo, token charge/balance (meta.tokens), and pagination where applicable."
272
- },
273
- "summary": {
274
- "type": "string",
275
- "description": "One-line natural-language summary of the result, ready to relay to a user."
276
- },
277
- "stats": {
278
- "type": "object"
279
- }
280
- },
281
- "required": [
282
- "meta",
283
- "stats"
284
- ]
285
- },
286
- "annotations": {
287
- "readOnlyHint": false,
288
- "openWorldHint": false,
289
- "destructiveHint": true
290
- }
291
- },
292
- {
293
- "name": "query_hotspots",
294
- "description": "Where activity concentrates: density grid-binned into ranked cells with peak severity, categories and representative event_ids. Events too coarse to place are counted in meta.dropped_by_plottable_count, not spread over the grid.",
295
- "inputSchema": {
296
- "type": "object",
297
- "properties": {
298
- "bbox": {
299
- "type": "array",
300
- "items": {
301
- "type": "number"
302
- },
303
- "minItems": 4,
304
- "maxItems": 4,
305
- "description": "[minLon, minLat, maxLon, maxLat] WGS84. Omit for worldwide."
172
+ "description": "Resolution needed (unassessed passes)."
306
173
  },
307
- "date": {
308
- "type": "string",
309
- "description": "Window end date, YYYY-MM-DD (UTC). Defaults to today. Records start 2026-09-23 (earlier: unrecorded, not quiet). Plan-bounded: meta.window_clamp."
310
- },
311
- "days": {
312
- "type": "integer",
313
- "minimum": 1,
314
- "description": "Window length in days. Defaults to 1."
315
- },
316
- "categories": {
174
+ "escalationTrends": {
317
175
  "type": "array",
318
176
  "items": {
319
177
  "type": "string",
320
178
  "enum": [
321
- "kinetic",
322
- "armed_conflict",
323
- "maritime",
324
- "natural_disaster",
325
- "infrastructure",
326
- "aviation",
327
- "humanitarian",
328
- "protest",
329
- "diplomacy",
330
- "other"
179
+ "escalating",
180
+ "de-escalating",
181
+ "stable",
182
+ "new"
331
183
  ]
332
184
  },
333
- "description": "Restrict to these categories. Omit for all."
185
+ "description": "Trend (unassessed passes)."
334
186
  },
335
- "precision": {
336
- "type": "number",
337
- "minimum": 0.1,
338
- "maximum": 5,
339
- "description": "Grid cell size in decimal degrees. Defaults to 1."
187
+ "sort": {
188
+ "type": "string",
189
+ "enum": [
190
+ "latest",
191
+ "oldest",
192
+ "geoint"
193
+ ],
194
+ "description": "Default latest. geoint: visible first, then geoint_score, stage (plan-gated; else latest (filter_clamp))."
340
195
  },
341
- "minSeverity": {
342
- "type": "number",
343
- "minimum": 0,
344
- "maximum": 10,
345
- "description": "Keep only events with severity_score >= this."
196
+ "updatedSince": {
197
+ "type": "string",
198
+ "description": "Refolded at/after (ISO); narrows the window."
346
199
  },
347
200
  "limit": {
348
201
  "type": "integer",
349
202
  "minimum": 1,
350
203
  "maximum": 500,
351
- "description": "Max CELLS, highest first; the whole window is aggregated either way (meta.total_cell_count). Default/max 500."
204
+ "description": "Max rows per page. Default 100."
205
+ },
206
+ "cursor": {
207
+ "type": "string",
208
+ "description": "Cursor from meta.next_cursor."
352
209
  }
353
210
  }
354
211
  },
@@ -363,7 +220,7 @@ export const TOOLS = [
363
220
  "type": "string",
364
221
  "description": "One-line natural-language summary of the result, ready to relay to a user."
365
222
  },
366
- "hotspots": {
223
+ "signals": {
367
224
  "type": "array",
368
225
  "items": {
369
226
  "type": "object"
@@ -372,7 +229,7 @@ export const TOOLS = [
372
229
  },
373
230
  "required": [
374
231
  "meta",
375
- "hotspots"
232
+ "signals"
376
233
  ]
377
234
  },
378
235
  "annotations": {
@@ -503,15 +360,13 @@ export const TOOLS = [
503
360
  ],
504
361
  "description": "Catalog collection. Default sentinel-2-l2a."
505
362
  },
506
- "date": {
363
+ "startDate": {
507
364
  "type": "string",
508
- "description": "Window end date, YYYY-MM-DD (UTC). Default today."
365
+ "description": "Date range start, YYYY-MM-DD (UTC). With endDate; omit both for the last 7 days (max 30)."
509
366
  },
510
- "days": {
511
- "type": "integer",
512
- "minimum": 1,
513
- "maximum": 30,
514
- "description": "Window length in days. Default 7."
367
+ "endDate": {
368
+ "type": "string",
369
+ "description": "Date range end, YYYY-MM-DD (UTC), inclusive."
515
370
  },
516
371
  "eventDate": {
517
372
  "type": "string",
@@ -550,14 +405,6 @@ export const TOOLS = [
550
405
  "minimum": 1,
551
406
  "maximum": 100,
552
407
  "description": "Max scenes. Default 25."
553
- },
554
- "responseFormat": {
555
- "type": "string",
556
- "enum": [
557
- "concise",
558
- "detailed"
559
- ],
560
- "description": "\"detailed\" adds footprint geometry, full target_relation and SAR metadata."
561
408
  }
562
409
  },
563
410
  "required": [
@@ -1204,14 +1051,6 @@ export const TOOLS = [
1204
1051
  "idempotencyKey": {
1205
1052
  "type": "string",
1206
1053
  "description": "At-most-once key. Re-sending the SAME key returns the SAME run with no second charge, so a timeout is recoverable."
1207
- },
1208
- "response_format": {
1209
- "type": "string",
1210
- "enum": [
1211
- "full",
1212
- "compact"
1213
- ],
1214
- "description": "\"compact\" drops the prose brief, returning only the structured result."
1215
1054
  }
1216
1055
  },
1217
1056
  "required": [
@@ -1318,14 +1157,6 @@ export const TOOLS = [
1318
1157
  "job_id": {
1319
1158
  "type": "string",
1320
1159
  "description": "The job_id returned by ask_analyst."
1321
- },
1322
- "response_format": {
1323
- "type": "string",
1324
- "enum": [
1325
- "full",
1326
- "compact"
1327
- ],
1328
- "description": "\"compact\" drops the prose brief and returns only the structured result."
1329
1160
  }
1330
1161
  },
1331
1162
  "required": [
@@ -1414,79 +1245,6 @@ export const TOOLS = [
1414
1245
  "destructiveHint": false
1415
1246
  }
1416
1247
  },
1417
- {
1418
- "name": "query_claims",
1419
- "description": "The ledger of claims this key was given, each with its evidence class, independent source families and publishers. The point is the time axis: a restated assertion links to the earlier one and says which way the evidence moved.",
1420
- "inputSchema": {
1421
- "type": "object",
1422
- "properties": {
1423
- "since": {
1424
- "type": "string",
1425
- "description": "Only claims asserted on/after this date."
1426
- },
1427
- "evidence_class": {
1428
- "type": "string",
1429
- "enum": [
1430
- "CONFIRMED",
1431
- "REPORTED",
1432
- "PARTY_CLAIM",
1433
- "DISPUTED",
1434
- "ASSESSMENT",
1435
- "UNKNOWN"
1436
- ],
1437
- "description": "Restrict to one evidence class."
1438
- },
1439
- "restated_only": {
1440
- "type": "boolean",
1441
- "description": "Only claims that sit in a restatement chain."
1442
- },
1443
- "downgraded_only": {
1444
- "type": "boolean",
1445
- "description": "Only claims a later answer restated with WEAKER evidence — read these first."
1446
- },
1447
- "event_id": {
1448
- "type": "string",
1449
- "description": "Only claims about this event (the UUID from query_signals). `event_link.linked` says whether any resolved."
1450
- },
1451
- "limit": {
1452
- "type": "number",
1453
- "minimum": 1,
1454
- "maximum": 200,
1455
- "description": "How many claims to return (default 50)."
1456
- }
1457
- },
1458
- "required": []
1459
- },
1460
- "outputSchema": {
1461
- "type": "object",
1462
- "properties": {
1463
- "summary": {
1464
- "type": "string",
1465
- "description": "One-line natural-language summary of the result, ready to relay to a user."
1466
- },
1467
- "claims": {
1468
- "type": "array",
1469
- "items": {
1470
- "type": "object"
1471
- }
1472
- },
1473
- "counts": {
1474
- "type": "object"
1475
- },
1476
- "event_link": {
1477
- "type": "object"
1478
- }
1479
- },
1480
- "required": [
1481
- "claims"
1482
- ]
1483
- },
1484
- "annotations": {
1485
- "readOnlyHint": true,
1486
- "openWorldHint": false,
1487
- "destructiveHint": false
1488
- }
1489
- },
1490
1248
  {
1491
1249
  "name": "query_developments",
1492
1250
  "description": "What actually CHANGED about the events in an area, not which articles are new. Each change is labelled `world` (the event's own state moved) or `measurement` (what we can see moved). Plan-dependent values say so (`locked_by`).",
@@ -1502,14 +1260,13 @@ export const TOOLS = [
1502
1260
  "maxItems": 4,
1503
1261
  "description": "[minLon, minLat, maxLon, maxLat]. Omit for worldwide."
1504
1262
  },
1505
- "date": {
1263
+ "start_date": {
1506
1264
  "type": "string",
1507
- "description": "End of the window (YYYY-MM-DD). Defaults to today. Records start 2026-09-23 (earlier: unrecorded, not quiet). Plan-bounded: meta.window_clamp."
1265
+ "description": "Date range start (YYYY-MM-DD). With end_date; omit both for today. Records start 2026-09-23 (earlier: unrecorded, not quiet). Plan-bounded: meta.window_clamp."
1508
1266
  },
1509
- "days": {
1510
- "type": "number",
1511
- "minimum": 1,
1512
- "description": "Window length ending at `date` (default 7)."
1267
+ "end_date": {
1268
+ "type": "string",
1269
+ "description": "Date range end (YYYY-MM-DD), inclusive."
1513
1270
  },
1514
1271
  "categories": {
1515
1272
  "type": "array",
@@ -1648,7 +1405,7 @@ export const TOOLS = [
1648
1405
  },
1649
1406
  {
1650
1407
  "name": "create_standing_order",
1651
- "description": "Put an area under CONTINUOUS watch: a question plus a bbox, re-answered on a schedule, notifying only when the answer changed. **Cost is per CHANGE, not per check.**",
1408
+ "description": "Put an area under CONTINUOUS watch (the app’s \"Watch this area\"): checked weekly, notifying only when new events cross the bar. **Cost is per CHANGE, not per check.**",
1652
1409
  "inputSchema": {
1653
1410
  "type": "object",
1654
1411
  "properties": {
@@ -1661,38 +1418,10 @@ export const TOOLS = [
1661
1418
  "maxItems": 4,
1662
1419
  "description": "[west, south, east, north] WGS84. Required — a global order would fire on everything."
1663
1420
  },
1664
- "question": {
1665
- "type": "string",
1666
- "description": "Omit for \"what changed in this area, and what does it mean?\"."
1667
- },
1668
1421
  "name": {
1669
1422
  "type": "string",
1670
1423
  "description": "Label for the order (default \"Standing order\")."
1671
1424
  },
1672
- "cadence": {
1673
- "type": "string",
1674
- "enum": [
1675
- "daily",
1676
- "weekly",
1677
- "monthly"
1678
- ],
1679
- "description": "How often to CHECK (checking is free). Default weekly; faster may need a higher plan."
1680
- },
1681
- "categories": {
1682
- "type": "array",
1683
- "items": {
1684
- "type": "string"
1685
- },
1686
- "description": "Restrict the watch to these Delta categories."
1687
- },
1688
- "min_geoint_score": {
1689
- "type": "number",
1690
- "description": "Reporting bar (0-10, default 6)."
1691
- },
1692
- "min_new_events": {
1693
- "type": "number",
1694
- "description": "New qualifying events needed to trigger a run (default 1)."
1695
- },
1696
1425
  "notify_email": {
1697
1426
  "type": "boolean",
1698
1427
  "description": "Email on fire (default true); readable via list_standing_orders anyway."
@@ -1711,12 +1440,6 @@ export const TOOLS = [
1711
1440
  },
1712
1441
  "order": {
1713
1442
  "type": "object"
1714
- },
1715
- "projected_monthly_tokens_typical": {
1716
- "type": "number"
1717
- },
1718
- "projected_monthly_tokens_max": {
1719
- "type": "number"
1720
1443
  }
1721
1444
  },
1722
1445
  "required": [
@@ -1890,47 +1613,6 @@ export const TOOLS = [
1890
1613
  "destructiveHint": false
1891
1614
  }
1892
1615
  },
1893
- {
1894
- "name": "delete_standing_order",
1895
- "description": "Delete a standing order, or pause/resume with active=false/true. A paused order still counts against the plan limit.",
1896
- "inputSchema": {
1897
- "type": "object",
1898
- "properties": {
1899
- "order_id": {
1900
- "type": "string",
1901
- "description": "From create_standing_order or list_standing_orders."
1902
- },
1903
- "active": {
1904
- "type": "boolean",
1905
- "description": "Omit to DELETE. false pauses, true resumes."
1906
- }
1907
- },
1908
- "required": [
1909
- "order_id"
1910
- ]
1911
- },
1912
- "outputSchema": {
1913
- "type": "object",
1914
- "properties": {
1915
- "summary": {
1916
- "type": "string",
1917
- "description": "One-line natural-language summary of the result, ready to relay to a user."
1918
- },
1919
- "deleted": {
1920
- "type": "string"
1921
- },
1922
- "order": {
1923
- "type": "object"
1924
- }
1925
- }
1926
- },
1927
- "annotations": {
1928
- "readOnlyHint": false,
1929
- "openWorldHint": false,
1930
- "destructiveHint": true,
1931
- "idempotentHint": true
1932
- }
1933
- },
1934
1616
  {
1935
1617
  "name": "list_monitored_areas",
1936
1618
  "description": "Places under continuous satellite measurement: metric, latest value, change, anomaly flag, coverage. **coverage.window_total is null when the catalog total is UNKNOWN; null never means zero.**",
@@ -2027,6 +1709,10 @@ export const TOOLS = [
2027
1709
  "type": "string",
2028
1710
  "description": "Plain words (ships, fires, vegetation, water, burn, snow, built_up, moisture, night_lights) or index ids (ndvi, ndwi, nbr, vv, vh …). The sensor follows."
2029
1711
  },
1712
+ "satellite": {
1713
+ "type": "string",
1714
+ "description": "Pick the sensor like the app does (e.g. ship detection on NISAR_L2_GCOV_PROVISIONAL_V1). Default: the metric’s first."
1715
+ },
2030
1716
  "name": {
2031
1717
  "type": "string",
2032
1718
  "description": "Label for the area (default \"Monitored area\")."
@@ -2164,103 +1850,6 @@ export const TOOLS = [
2164
1850
  "destructiveHint": false
2165
1851
  }
2166
1852
  },
2167
- {
2168
- "name": "get_decision_package",
2169
- "description": "Everything needed to decide what to collect next about one watch, in one object. **Only `absent` asserts a negative** — `inconclusive` means imagery could not answer, `not_collected` means no valid look happened. `revision` is a content hash.",
2170
- "inputSchema": {
2171
- "type": "object",
2172
- "properties": {
2173
- "watch_id": {
2174
- "type": "string",
2175
- "description": "Id from list_watches."
2176
- }
2177
- },
2178
- "required": [
2179
- "watch_id"
2180
- ]
2181
- },
2182
- "outputSchema": {
2183
- "type": "object",
2184
- "properties": {
2185
- "summary": {
2186
- "type": "string",
2187
- "description": "One-line natural-language summary of the result, ready to relay to a user."
2188
- },
2189
- "schema_version": {
2190
- "type": "string"
2191
- },
2192
- "package_id": {
2193
- "type": "string"
2194
- },
2195
- "external_key": {
2196
- "type": "string"
2197
- },
2198
- "revision": {
2199
- "type": "string"
2200
- },
2201
- "generated_at": {
2202
- "type": "string"
2203
- },
2204
- "watch": {
2205
- "type": "object"
2206
- },
2207
- "target": {
2208
- "type": "object"
2209
- },
2210
- "current_state": {
2211
- "type": "object"
2212
- },
2213
- "claims": {
2214
- "type": "array",
2215
- "items": {
2216
- "type": "object"
2217
- }
2218
- },
2219
- "collection_options": {
2220
- "type": "object"
2221
- },
2222
- "observations": {
2223
- "type": "array",
2224
- "items": {
2225
- "type": "object"
2226
- }
2227
- },
2228
- "negative_evidence": {
2229
- "type": "array",
2230
- "items": {
2231
- "type": "object"
2232
- }
2233
- },
2234
- "assessments": {
2235
- "type": "array",
2236
- "items": {
2237
- "type": "object"
2238
- }
2239
- },
2240
- "limitations": {
2241
- "type": "array",
2242
- "items": {
2243
- "type": "string"
2244
- }
2245
- },
2246
- "note": {
2247
- "type": "string"
2248
- }
2249
- },
2250
- "required": [
2251
- "summary",
2252
- "revision",
2253
- "negative_evidence",
2254
- "limitations",
2255
- "note"
2256
- ]
2257
- },
2258
- "annotations": {
2259
- "readOnlyHint": false,
2260
- "openWorldHint": false,
2261
- "destructiveHint": true
2262
- }
2263
- },
2264
1853
  {
2265
1854
  "name": "create_watch",
2266
1855
  "description": "Add a target to the Watchlist. EVENT: the signal's event id binds the canonical event — **never watch an article URL**. AREA: a bbox. SITE: entity_id or lat+lon, and scale.",
@@ -2356,7 +1945,7 @@ export const TOOLS = [
2356
1945
  },
2357
1946
  {
2358
1947
  "name": "update_watch",
2359
- "description": "Rename, pause, resume or close a watch. **Pausing is not a display state**: monitored areas stop being measured and charged, standing orders stop checking. **Closing states how the question ended** (close_reason).",
1948
+ "description": "Pause, resume or close a watch. **Pausing is not a display state**: monitored areas stop being measured and charged, standing orders stop checking. **Closing states how the question ended** (close_reason).",
2360
1949
  "inputSchema": {
2361
1950
  "type": "object",
2362
1951
  "properties": {
@@ -2364,10 +1953,6 @@ export const TOOLS = [
2364
1953
  "type": "string",
2365
1954
  "description": "Id from list_watches."
2366
1955
  },
2367
- "name": {
2368
- "type": "string",
2369
- "description": "New label."
2370
- },
2371
1956
  "status": {
2372
1957
  "type": "string",
2373
1958
  "enum": [
@@ -2677,9 +2262,6 @@ export const TOOLS = [
2677
2262
  },
2678
2263
  "events_24h": {
2679
2264
  "type": "number"
2680
- },
2681
- "claim_count": {
2682
- "type": "number"
2683
2265
  }
2684
2266
  },
2685
2267
  "required": [
@@ -3031,9 +2613,10 @@ export const TOOLS = [
3031
2613
  "type": "string",
3032
2614
  "enum": [
3033
2615
  "sentinel-1-grd",
3034
- "sentinel-1-rtc"
2616
+ "sentinel-1-rtc",
2617
+ "NISAR_L2_GCOV_PROVISIONAL_V1"
3035
2618
  ],
3036
- "description": "Collection of the scene. NISAR detection is app-only."
2619
+ "description": "Collection of the scene (Sentinel-1, or NISAR L-band — converted first, extra tokens)."
3037
2620
  },
3038
2621
  "item_id": {
3039
2622
  "type": "string",
@@ -3120,12 +2703,6 @@ export const RESOURCES = [
3120
2703
  "description": "Remaining token balance and plan capabilities for the calling key. Free.",
3121
2704
  "mimeType": "application/json"
3122
2705
  },
3123
- {
3124
- "uri": "imagery://collections",
3125
- "name": "Imagery collections",
3126
- "description": "The satellite catalog collections searchable via search_imagery — Sentinel-1 C-band SAR, Sentinel-2 optical, and NISAR L-band SAR (provisional calibration). Free.",
3127
- "mimeType": "application/json"
3128
- },
3129
2706
  {
3130
2707
  "uri": "status://current",
3131
2708
  "name": "Data freshness & pipeline status",
@@ -3147,59 +2724,4 @@ export const RESOURCE_TEMPLATES = [
3147
2724
  "mimeType": "application/json"
3148
2725
  }
3149
2726
  ];
3150
- export const PROMPTS = [
3151
- {
3152
- "name": "daily-situation-briefing",
3153
- "description": "Summarize the current world situation from the Daily World Brief.",
3154
- "arguments": [
3155
- {
3156
- "name": "date",
3157
- "description": "UTC date YYYY-MM-DD (optional; defaults to latest).",
3158
- "required": false
3159
- }
3160
- ]
3161
- },
3162
- {
3163
- "name": "assess-top-signal",
3164
- "description": "Find the highest-severity recent signal in an area/category and run an RS assessment.",
3165
- "arguments": [
3166
- {
3167
- "name": "bbox",
3168
- "description": "Bounding box \"minLon,minLat,maxLon,maxLat\" (optional).",
3169
- "required": false
3170
- },
3171
- {
3172
- "name": "category",
3173
- "description": "Category filter (optional).",
3174
- "required": false
3175
- }
3176
- ]
3177
- },
3178
- {
3179
- "name": "aoi-watch",
3180
- "description": "Scan an area of interest for recent escalations and recommend collection.",
3181
- "arguments": [
3182
- {
3183
- "name": "bbox",
3184
- "description": "Bounding box \"minLon,minLat,maxLon,maxLat\".",
3185
- "required": true
3186
- }
3187
- ]
3188
- },
3189
- {
3190
- "name": "market-exposure-check",
3191
- "description": "Find recent events that could plausibly move a given market (oil, grain, shipping, ...) and explain each transmission channel. Informational only — not investment advice.",
3192
- "arguments": [
3193
- {
3194
- "name": "market",
3195
- "description": "Market to check: oil, natural_gas, grain, shipping, defense, metals, semiconductors, fx, equities.",
3196
- "required": true
3197
- },
3198
- {
3199
- "name": "days",
3200
- "description": "Lookback window in days (optional; default 3).",
3201
- "required": false
3202
- }
3203
- ]
3204
- }
3205
- ];
2727
+ export const PROMPTS = [];
package/dist/index.js CHANGED
@@ -10,18 +10,18 @@
10
10
  * registries only speak local stdio, or prefer a bearer key over interactive
11
11
  * OAuth. This binary gives them the same tool surface with a single env var.
12
12
  *
13
- * Introspection (initialize / tools/list / resources/list / prompts/list) is
14
- * answered from a bundled catalog and needs NO credentials, so registries can
15
- * inspect the server in a bare container. Only tools/call, resources/read and
16
- * prompts/get reach the network, and those require OFFNADIR_DELTA_API_KEY.
13
+ * Introspection (initialize / tools/list / resources/list) is answered from a
14
+ * bundled catalog and needs NO credentials, so registries can inspect the server
15
+ * in a bare container. Only tools/call and resources/read reach the network, and
16
+ * those require OFFNADIR_DELTA_API_KEY.
17
17
  */
18
18
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
19
19
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
20
20
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
21
21
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
22
- import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
23
- import { PROMPTS, RESOURCES, RESOURCE_TEMPLATES, TOOLS } from './catalog.js';
24
- const VERSION = '1.39.0';
22
+ import { CallToolRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
23
+ import { RESOURCES, RESOURCE_TEMPLATES, TOOLS } from './catalog.js';
24
+ const VERSION = '2.1.0';
25
25
  const REMOTE_URL = new URL(process.env.OFFNADIR_DELTA_MCP_URL ?? 'https://offnadir-delta.com/api/v1/mcp');
26
26
  /** Lazily-connected client to the hosted remote MCP server. */
27
27
  let remote = null;
@@ -63,12 +63,11 @@ async function getRemote() {
63
63
  throw err;
64
64
  }
65
65
  }
66
- const server = new Server({ name: 'off-nadir-delta', title: 'Off-Nadir Delta', version: VERSION }, { capabilities: { tools: {}, resources: {}, prompts: {} } });
66
+ const server = new Server({ name: 'off-nadir-delta', title: 'Off-Nadir Delta', version: VERSION }, { capabilities: { tools: {}, resources: {} } });
67
67
  // --- Introspection: answered locally, no network, no credentials. ---
68
68
  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
69
69
  server.setRequestHandler(ListResourcesRequestSchema, async () => ({ resources: RESOURCES }));
70
70
  server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({ resourceTemplates: RESOURCE_TEMPLATES }));
71
- server.setRequestHandler(ListPromptsRequestSchema, async () => ({ prompts: PROMPTS }));
72
71
  // --- Execution: forwarded to the hosted remote server with the caller's key. ---
73
72
  server.setRequestHandler(CallToolRequestSchema, async (req) => {
74
73
  const client = await getRemote();
@@ -78,10 +77,6 @@ server.setRequestHandler(ReadResourceRequestSchema, async (req) => {
78
77
  const client = await getRemote();
79
78
  return client.readResource({ uri: req.params.uri });
80
79
  });
81
- server.setRequestHandler(GetPromptRequestSchema, async (req) => {
82
- const client = await getRemote();
83
- return client.getPrompt({ name: req.params.name, arguments: req.params.arguments ?? {} });
84
- });
85
80
  async function main() {
86
81
  const transport = new StdioServerTransport();
87
82
  await server.connect(transport);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "offnadir-delta-mcp",
3
- "version": "1.39.0",
4
- "description": "Local (stdio) MCP server for Off-Nadir Delta \u2014 live, geolocated world-event intelligence, a Daily World Brief, satellite-imagery search, and an OSINT/GEOINT analyst. Forwards to the hosted server with your API key.",
3
+ "version": "2.1.0",
4
+ "description": "Local (stdio) MCP server for Off-Nadir Delta — live, geolocated world-event intelligence, a Daily World Brief, satellite-imagery search, and an OSINT/GEOINT analyst. Forwards to the hosted server with your API key.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "offnadir-delta-mcp": "dist/index.js"