offnadir-delta-mcp 1.12.2 → 1.19.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
- `25` tools · MCP server version `1.12.2` · [full reference](https://offnadir-delta.com/docs/mcp)
19
+ `30` tools · MCP server version `1.19.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
- 12 of the 25 tools cost nothing, so the first thing you run is free:
80
+ 16 of the 30 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.
@@ -99,6 +99,8 @@ What is happening, where it concentrates, and what today looks like.
99
99
  | `query_stats` | Aggregate statistics over the signal corpus — total event count plus per-category and per-day breakdown (trend) for a bounding box and date window. | 1 tok |
100
100
  | `query_hotspots` | Geographic hotspots — signal density grid-binned into cells, ranked by event count, each with peak severity, the categories present, and up to 5 representative event_ids (trace a cell back to its signals). | 1 tok |
101
101
  | `get_world_brief` | Fetch the Daily World Brief — an AI-synthesized OSINT/GEOINT digest of the previous UTC day's worldwide event signals (headline, executive summary, top developments with why-it-matters and what-to-watch, per-theme roll-up, ranked signals). | free |
102
+ | `query_developments` | What actually CHANGED about the events in an area — not which articles are new. | 3 tok |
103
+ | `get_event_thread` | The full history of ONE event: its current state, and every change in the order it happened. | free |
102
104
 
103
105
  ### Plan
104
106
 
@@ -141,6 +143,16 @@ Stand up continuous coverage and be told only when the answer changes. Creating
141
143
  | `get_monitored_area` | Fetch one monitored area with its full measurement history — every acquisition that was measured, its value, and whether it was flagged anomalous. | free |
142
144
  | `create_monitored_area` | Put a place under continuous satellite measurement: pick an area and what to count, and every new Sentinel-1 / Sentinel-2 / VIIRS acquisition over it is measured automatically from then on. | free |
143
145
 
146
+ ### Workspace
147
+
148
+ The map assets you own — saved layer sets and your own uploaded data.
149
+
150
+ | Tool | What it does | Cost |
151
+ | --- | --- | --- |
152
+ | `list_layer_sets` | List the layer sets saved on this account — the named map configurations a user builds in the app, each with how many layers it holds, its tags, when it was last changed and when it was last opened. | free |
153
+ | `get_layer_set` | Read one saved layer set by id: its name, description, layer count, size, tags and timestamps. | free |
154
+ | `list_uploaded_layers` | List the data this account uploaded to the map — name, format, size and when it was added — plus the formats the uploader actually accepts. | free |
155
+
144
156
  ### Account
145
157
 
146
158
  Pre-flight your token balance before a metered call.
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.12.2.
16
+ // Generated for Off-Nadir Delta MCP 1.19.0.
17
17
  export const TOOLS = [
18
18
  {
19
19
  "name": "query_signals",
@@ -1218,6 +1218,158 @@ export const TOOLS = [
1218
1218
  "destructiveHint": false
1219
1219
  }
1220
1220
  },
1221
+ {
1222
+ "name": "query_developments",
1223
+ "description": "What actually CHANGED about the events in an area — not which articles are new. Polling query_signals and diffing the ids finds new REPORTING: a 2025 attack re-reported in 2026 with a fresh attribution is indistinguishable from a fresh attack. This returns changes as changes, each with what it was and what it became. Two kinds, labelled: `world` = the event's own state moved (a death toll revised, a perpetrator named, a report disputed); `measurement` = what WE can now see moved (a location resolved, post-event imagery arrived, a SAR before/after pair became ready). This is the right source for \"what is new since last time\" and for a standing watch. By default only changes worth a person's attention are returned — set notable_only=false for the full ledger, including changes deliberately judged too minor to notify on.",
1224
+ "inputSchema": {
1225
+ "type": "object",
1226
+ "properties": {
1227
+ "bbox": {
1228
+ "type": "array",
1229
+ "items": {
1230
+ "type": "number"
1231
+ },
1232
+ "minItems": 4,
1233
+ "maxItems": 4,
1234
+ "description": "[minLon, minLat, maxLon, maxLat]. Omit for worldwide."
1235
+ },
1236
+ "date": {
1237
+ "type": "string",
1238
+ "description": "End of the window (YYYY-MM-DD). Defaults to today."
1239
+ },
1240
+ "days": {
1241
+ "type": "number",
1242
+ "minimum": 1,
1243
+ "maximum": 30,
1244
+ "description": "Window length ending at `date` (default 7)."
1245
+ },
1246
+ "categories": {
1247
+ "type": "array",
1248
+ "items": {
1249
+ "type": "string"
1250
+ },
1251
+ "description": "Restrict to these signal categories."
1252
+ },
1253
+ "development_types": {
1254
+ "type": "array",
1255
+ "items": {
1256
+ "type": "string",
1257
+ "enum": [
1258
+ "new_event",
1259
+ "baseline",
1260
+ "occurrence_time_established",
1261
+ "casualty_count_first_reported",
1262
+ "casualty_count_raised",
1263
+ "casualty_count_corrected",
1264
+ "casualties_disputed",
1265
+ "attribution_stated",
1266
+ "attribution_changed",
1267
+ "attribution_disputed",
1268
+ "corroboration_increased",
1269
+ "severity_escalated",
1270
+ "location_resolved",
1271
+ "observability_established",
1272
+ "collection_ready",
1273
+ "imagery_available",
1274
+ "sar_pair_ready",
1275
+ "observed",
1276
+ "confirmed",
1277
+ "reporting_disputed",
1278
+ "retracted"
1279
+ ]
1280
+ },
1281
+ "description": "Restrict to these kinds of change. An unknown value is an error, never an empty result."
1282
+ },
1283
+ "notable_only": {
1284
+ "type": "boolean",
1285
+ "description": "Default true. False returns every recorded change, including minor ones."
1286
+ },
1287
+ "limit": {
1288
+ "type": "number",
1289
+ "minimum": 1,
1290
+ "maximum": 200,
1291
+ "description": "How many developments to return (default 50)."
1292
+ }
1293
+ },
1294
+ "required": []
1295
+ },
1296
+ "outputSchema": {
1297
+ "type": "object",
1298
+ "properties": {
1299
+ "summary": {
1300
+ "type": "string",
1301
+ "description": "One-line natural-language summary of the result, ready to relay to a user."
1302
+ },
1303
+ "meta": {
1304
+ "type": "object",
1305
+ "description": "Query echo, token charge/balance (meta.tokens), and pagination where applicable."
1306
+ },
1307
+ "developments": {
1308
+ "type": "array",
1309
+ "items": {
1310
+ "type": "object"
1311
+ }
1312
+ }
1313
+ },
1314
+ "required": [
1315
+ "developments"
1316
+ ]
1317
+ },
1318
+ "annotations": {
1319
+ "readOnlyHint": false,
1320
+ "openWorldHint": false,
1321
+ "destructiveHint": true
1322
+ }
1323
+ },
1324
+ {
1325
+ "name": "get_event_thread",
1326
+ "description": "The full history of ONE event: its current state, and every change in the order it happened. Answers \"is this a new event or an update to an old one\" — the distinction a news feed cannot make. Returns the canonical event (where, when it HAPPENED as distinct from when it was reported, casualties, attribution and how that attribution is grounded), a timeline of developments, and every source article behind it. `occurred_at_basis` says whether the occurrence time was stated, absent, or never measured — those are three different things. `history_incomplete` marks an event that already existed when tracking began. Free of token charges: the discovery call that found the event was already metered.",
1327
+ "inputSchema": {
1328
+ "type": "object",
1329
+ "properties": {
1330
+ "event_id": {
1331
+ "type": "number",
1332
+ "description": "Any signal id belonging to the event; the whole canonical event is returned."
1333
+ }
1334
+ },
1335
+ "required": [
1336
+ "event_id"
1337
+ ]
1338
+ },
1339
+ "outputSchema": {
1340
+ "type": "object",
1341
+ "properties": {
1342
+ "summary": {
1343
+ "type": "string",
1344
+ "description": "One-line natural-language summary of the result, ready to relay to a user."
1345
+ },
1346
+ "canonical_event": {
1347
+ "type": "object"
1348
+ },
1349
+ "timeline": {
1350
+ "type": "array",
1351
+ "items": {
1352
+ "type": "object"
1353
+ }
1354
+ },
1355
+ "sources": {
1356
+ "type": "array",
1357
+ "items": {
1358
+ "type": "object"
1359
+ }
1360
+ }
1361
+ },
1362
+ "required": [
1363
+ "canonical_event",
1364
+ "timeline"
1365
+ ]
1366
+ },
1367
+ "annotations": {
1368
+ "readOnlyHint": true,
1369
+ "openWorldHint": false,
1370
+ "destructiveHint": false
1371
+ }
1372
+ },
1221
1373
  {
1222
1374
  "name": "create_standing_order",
1223
1375
  "description": "Put an area under CONTINUOUS watch: save a question plus a bounding box and Delta re-answers it on a schedule, notifying only when the answer actually changed. Creating one is FREE. Each time it fires it runs ask_analyst and is metered like any Analyst question, so the cost is per CHANGE, not per check: a deterministic pass over the corpus decides whether anything new crossed the reporting bar, and quiet periods never invoke the model or charge anything. Returns projected_monthly_tokens_typical (the observed median cost per run × this cadence) and projected_monthly_tokens_max (the true ceiling: every check fires AND every run reaches the per-question cap), so the cost is visible before committing. Cadence and how many orders you may hold are set by your plan; the error says which limit you hit. Use it when the question is \"tell me when this changes\" rather than \"what is happening right now\".",
@@ -1301,6 +1453,132 @@ export const TOOLS = [
1301
1453
  "destructiveHint": false
1302
1454
  }
1303
1455
  },
1456
+ {
1457
+ "name": "list_layer_sets",
1458
+ "description": "List the layer sets saved on this account — the named map configurations a user builds in the app, each with how many layers it holds, its tags, when it was last changed and when it was last opened. Use it to answer \"what have I saved\" and to tell an idle configuration from a working one. The layer tree itself is not returned: it is an internal format, and opening it is the map’s job. Free of token charges.",
1459
+ "inputSchema": {
1460
+ "type": "object",
1461
+ "properties": {
1462
+ "limit": {
1463
+ "type": "integer",
1464
+ "minimum": 1,
1465
+ "maximum": 100,
1466
+ "description": "Max layer sets to return (default 50)."
1467
+ }
1468
+ },
1469
+ "required": []
1470
+ },
1471
+ "outputSchema": {
1472
+ "type": "object",
1473
+ "properties": {
1474
+ "summary": {
1475
+ "type": "string",
1476
+ "description": "One-line natural-language summary of the result, ready to relay to a user."
1477
+ },
1478
+ "layer_sets": {
1479
+ "type": "array",
1480
+ "items": {
1481
+ "type": "object"
1482
+ }
1483
+ },
1484
+ "total": {
1485
+ "type": "integer"
1486
+ }
1487
+ },
1488
+ "required": [
1489
+ "layer_sets"
1490
+ ]
1491
+ },
1492
+ "annotations": {
1493
+ "readOnlyHint": true,
1494
+ "openWorldHint": false,
1495
+ "destructiveHint": false
1496
+ }
1497
+ },
1498
+ {
1499
+ "name": "get_layer_set",
1500
+ "description": "Read one saved layer set by id: its name, description, layer count, size, tags and timestamps. The serialized layer tree is deliberately not exposed (contents:\"not_exposed\") — it is an internal representation, not a public contract. Free of token charges.",
1501
+ "inputSchema": {
1502
+ "type": "object",
1503
+ "properties": {
1504
+ "layer_set_id": {
1505
+ "type": "string",
1506
+ "description": "The layer set id."
1507
+ }
1508
+ },
1509
+ "required": [
1510
+ "layer_set_id"
1511
+ ]
1512
+ },
1513
+ "outputSchema": {
1514
+ "type": "object",
1515
+ "properties": {
1516
+ "summary": {
1517
+ "type": "string",
1518
+ "description": "One-line natural-language summary of the result, ready to relay to a user."
1519
+ },
1520
+ "layer_set": {
1521
+ "type": "object"
1522
+ }
1523
+ },
1524
+ "required": [
1525
+ "layer_set"
1526
+ ]
1527
+ },
1528
+ "annotations": {
1529
+ "readOnlyHint": true,
1530
+ "openWorldHint": false,
1531
+ "destructiveHint": false
1532
+ }
1533
+ },
1534
+ {
1535
+ "name": "list_uploaded_layers",
1536
+ "description": "List the data this account uploaded to the map — name, format, size and when it was added — plus the formats the uploader actually accepts. Uploading itself happens in the app (it is a file transfer, not a JSON call), so use this to see what is already there and to answer format questions correctly: GeoJSON and GeoTIFF are accepted, a shapefile or KML is not. Free of token charges.",
1537
+ "inputSchema": {
1538
+ "type": "object",
1539
+ "properties": {
1540
+ "limit": {
1541
+ "type": "integer",
1542
+ "minimum": 1,
1543
+ "maximum": 100,
1544
+ "description": "Max uploads to return (default 50)."
1545
+ }
1546
+ },
1547
+ "required": []
1548
+ },
1549
+ "outputSchema": {
1550
+ "type": "object",
1551
+ "properties": {
1552
+ "summary": {
1553
+ "type": "string",
1554
+ "description": "One-line natural-language summary of the result, ready to relay to a user."
1555
+ },
1556
+ "uploads": {
1557
+ "type": "array",
1558
+ "items": {
1559
+ "type": "object"
1560
+ }
1561
+ },
1562
+ "total": {
1563
+ "type": "integer"
1564
+ },
1565
+ "accepted_formats": {
1566
+ "type": "array",
1567
+ "items": {
1568
+ "type": "string"
1569
+ }
1570
+ }
1571
+ },
1572
+ "required": [
1573
+ "uploads"
1574
+ ]
1575
+ },
1576
+ "annotations": {
1577
+ "readOnlyHint": true,
1578
+ "openWorldHint": false,
1579
+ "destructiveHint": false
1580
+ }
1581
+ },
1304
1582
  {
1305
1583
  "name": "list_standing_orders",
1306
1584
  "description": "List the standing orders on this key, with each one’s cadence, watched area, when it last checked, when it last actually fired, and how many consecutive checks found nothing (quiet_checks — a high number means the watch is not earning its place). Also returns how many orders the plan allows and how many remain. Free of token charges.",
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
21
21
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
22
22
  import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
23
23
  import { PROMPTS, RESOURCES, RESOURCE_TEMPLATES, TOOLS } from './catalog.js';
24
- const VERSION = '1.12.2';
24
+ const VERSION = '1.19.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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "offnadir-delta-mcp",
3
- "version": "1.12.2",
3
+ "version": "1.19.0",
4
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.",
5
5
  "type": "module",
6
6
  "bin": {