offnadir-delta-mcp 1.26.0 → 1.28.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 +3 -2
- package/dist/catalog.js +96 -5
- package/dist/index.js +11 -2
- package/package.json +1 -1
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
|
-
`
|
|
19
|
+
`41` tools · MCP server version `1.28.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
|
|
80
|
+
23 of the 41 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.
|
|
@@ -116,6 +116,7 @@ Whether a satellite can resolve it, which one, and when it next passes.
|
|
|
116
116
|
| `rank_imaging_priority` | WHERE — and with what class (and therefore cost) of satellite — is observation most worthwhile right now? | 1 tok |
|
|
117
117
|
| `survey_observable_events` | Which events in a window can a given in-app sensor actually RESOLVE? | 1 tok |
|
|
118
118
|
| `predict_satellite_passes` | WHEN can this place next be imaged, and by WHAT — the timing half of collection planning. | 2 tok |
|
|
119
|
+
| `test_hypotheses` | Given competing statements, return the observation that would REFUTE the most of them — and, in the same answer, the observations that would refute none of them however convincing they look. | 3 tok |
|
|
119
120
|
| `lookup_elevation` | Measure terrain height from the Copernicus DEM GLO-30 — a point (lat + lon), an area (bbox), or a drawn polygon, for which the statistics are computed over the samples INSIDE the ring rather than its bounding box. | free |
|
|
120
121
|
| `analyze_terrain` | Compute FROM the terrain rather than reading heights out of it (that is lookup_elevation). | free |
|
|
121
122
|
|
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.
|
|
16
|
+
// Generated for Off-Nadir Delta MCP 1.28.0.
|
|
17
17
|
export const TOOLS = [
|
|
18
18
|
{
|
|
19
19
|
"name": "query_signals",
|
|
@@ -815,10 +815,11 @@ export const TOOLS = [
|
|
|
815
815
|
"synspective",
|
|
816
816
|
"iqps",
|
|
817
817
|
"radarsat-2",
|
|
818
|
-
"cosmo-skymed"
|
|
818
|
+
"cosmo-skymed",
|
|
819
|
+
"nisar"
|
|
819
820
|
]
|
|
820
821
|
},
|
|
821
|
-
"description": "Families to consider. Omit for all
|
|
822
|
+
"description": "Families to consider. Omit for all thirteen. Use this to compare \"free systematic only\" (Sentinel, Landsat, NISAR) against \"what could I task\"."
|
|
822
823
|
},
|
|
823
824
|
"max_passes": {
|
|
824
825
|
"type": "number",
|
|
@@ -1189,7 +1190,7 @@ export const TOOLS = [
|
|
|
1189
1190
|
},
|
|
1190
1191
|
"event_id": {
|
|
1191
1192
|
"type": "number",
|
|
1192
|
-
"description": "Only claims about this event (global event id).
|
|
1193
|
+
"description": "Only claims about this event (global event id). Two deterministic anchors are tried: the claim’s own recorded event, and the registry facilities the event is linked to. Neither is a guess — when neither resolves, nothing is returned and `event_link.linked` says so."
|
|
1193
1194
|
},
|
|
1194
1195
|
"limit": {
|
|
1195
1196
|
"type": "number",
|
|
@@ -1230,6 +1231,93 @@ export const TOOLS = [
|
|
|
1230
1231
|
"destructiveHint": false
|
|
1231
1232
|
}
|
|
1232
1233
|
},
|
|
1234
|
+
{
|
|
1235
|
+
"name": "test_hypotheses",
|
|
1236
|
+
"description": "Given competing statements, return the observation that would REFUTE the most of them — and, in the same answer, the observations that would refute none of them however convincing they look. Each statement is decomposed into the observables it requires (vessel presence, berth occupancy, burn extent, ground deformation, a running total…), and the observables are scored by how many statements their ABSENCE would eliminate. Read the direction carefully, because it only runs one way: an observable that is absent refutes every statement requiring it; an observable that is PRESENT refutes nothing, since a statement that does not require it is not predicting its absence. Four verdicts come back: `actionable` (Delta serves it today), `procurable` (real, but bought or fetched elsewhere — `how_to_obtain` says where), `not_observable` (no overhead collection settles it; a record or a transponder might), and `no_diagnostic_value` (every statement requires it, so measuring it cannot separate them). Pass `hypotheses` for a comparison you define, or `event_id` to test the claims you were already given about that event. Answering \"nothing you can collect would change this\" is a supported outcome, not a failure.",
|
|
1237
|
+
"inputSchema": {
|
|
1238
|
+
"type": "object",
|
|
1239
|
+
"properties": {
|
|
1240
|
+
"hypotheses": {
|
|
1241
|
+
"type": "array",
|
|
1242
|
+
"items": {
|
|
1243
|
+
"type": "string"
|
|
1244
|
+
},
|
|
1245
|
+
"minItems": 2,
|
|
1246
|
+
"maxItems": 8,
|
|
1247
|
+
"description": "Two to eight competing statements, one assertion each (up to 500 characters). Omit when using event_id."
|
|
1248
|
+
},
|
|
1249
|
+
"mode": {
|
|
1250
|
+
"type": "string",
|
|
1251
|
+
"enum": [
|
|
1252
|
+
"competing",
|
|
1253
|
+
"joint"
|
|
1254
|
+
],
|
|
1255
|
+
"description": "`competing` (default): the statements are mutually exclusive, so the goal is to separate them and an observable required by all of them has no diagnostic value. `joint`: they are held together, so the goal is to falsify the most at once and an observable required by all of them is the best one. Ignored with event_id, which is always joint."
|
|
1256
|
+
},
|
|
1257
|
+
"event_id": {
|
|
1258
|
+
"type": "number",
|
|
1259
|
+
"description": "Use the standing claims you were given about this event (global event id) as the statements. Restated claims are excluded — only what currently stands is tested."
|
|
1260
|
+
}
|
|
1261
|
+
},
|
|
1262
|
+
"required": []
|
|
1263
|
+
},
|
|
1264
|
+
"outputSchema": {
|
|
1265
|
+
"type": "object",
|
|
1266
|
+
"properties": {
|
|
1267
|
+
"summary": {
|
|
1268
|
+
"type": "string",
|
|
1269
|
+
"description": "One-line natural-language summary of the result, ready to relay to a user."
|
|
1270
|
+
},
|
|
1271
|
+
"meta": {
|
|
1272
|
+
"type": "object",
|
|
1273
|
+
"description": "Query echo, token charge/balance (meta.tokens), and pagination where applicable."
|
|
1274
|
+
},
|
|
1275
|
+
"hypotheses": {
|
|
1276
|
+
"type": "array",
|
|
1277
|
+
"items": {
|
|
1278
|
+
"type": "object"
|
|
1279
|
+
}
|
|
1280
|
+
},
|
|
1281
|
+
"best": {
|
|
1282
|
+
"type": "object"
|
|
1283
|
+
},
|
|
1284
|
+
"discriminators": {
|
|
1285
|
+
"type": "array",
|
|
1286
|
+
"items": {
|
|
1287
|
+
"type": "object"
|
|
1288
|
+
}
|
|
1289
|
+
},
|
|
1290
|
+
"no_diagnostic_value": {
|
|
1291
|
+
"type": "array",
|
|
1292
|
+
"items": {
|
|
1293
|
+
"type": "object"
|
|
1294
|
+
}
|
|
1295
|
+
},
|
|
1296
|
+
"undecomposable": {
|
|
1297
|
+
"type": "array",
|
|
1298
|
+
"items": {
|
|
1299
|
+
"type": "string"
|
|
1300
|
+
}
|
|
1301
|
+
},
|
|
1302
|
+
"no_discriminator_reason": {
|
|
1303
|
+
"type": "string"
|
|
1304
|
+
},
|
|
1305
|
+
"note": {
|
|
1306
|
+
"type": "string"
|
|
1307
|
+
}
|
|
1308
|
+
},
|
|
1309
|
+
"required": [
|
|
1310
|
+
"summary",
|
|
1311
|
+
"discriminators",
|
|
1312
|
+
"note"
|
|
1313
|
+
]
|
|
1314
|
+
},
|
|
1315
|
+
"annotations": {
|
|
1316
|
+
"readOnlyHint": false,
|
|
1317
|
+
"openWorldHint": false,
|
|
1318
|
+
"destructiveHint": true
|
|
1319
|
+
}
|
|
1320
|
+
},
|
|
1233
1321
|
{
|
|
1234
1322
|
"name": "query_developments",
|
|
1235
1323
|
"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.",
|
|
@@ -2216,7 +2304,7 @@ export const TOOLS = [
|
|
|
2216
2304
|
},
|
|
2217
2305
|
{
|
|
2218
2306
|
"name": "get_entity",
|
|
2219
|
-
"description": "What has happened at one place. Returns the registry record plus every event linked to it, each carrying HOW it was linked — `alias_exact_location` means a report named this facility, `geo_proximity` means a report was geolocated within range of it and the distance is given. Read the basis before treating a link as established: proximity is an association, not a statement that the event happened at this facility. Also returns how many Analyst claims mention it. Costs 1 token per lookup.",
|
|
2307
|
+
"description": "What has happened at one place. Returns the registry record plus every event linked to it, each carrying HOW it was linked — `alias_exact_location` means a report named this facility, `geo_proximity` means a report was geolocated within range of it and the distance is given. Read the basis before treating a link as established: proximity is an association, not a statement that the event happened at this facility. Also returns how many Analyst claims mention it, and an OBSERVABILITY profile: the events linked here are decomposed into the observables that would have tested them, counted, and marked with whether Delta serves each one or where it could be obtained instead. That profile is derived from what actually happened at this place — it is not a general claim about places of this type, and a place with no linked events returns no profile rather than a guess. Costs 1 token per lookup.",
|
|
2220
2308
|
"inputSchema": {
|
|
2221
2309
|
"type": "object",
|
|
2222
2310
|
"properties": {
|
|
@@ -2253,6 +2341,9 @@ export const TOOLS = [
|
|
|
2253
2341
|
},
|
|
2254
2342
|
"claim_count": {
|
|
2255
2343
|
"type": "number"
|
|
2344
|
+
},
|
|
2345
|
+
"observability": {
|
|
2346
|
+
"type": "object"
|
|
2256
2347
|
}
|
|
2257
2348
|
},
|
|
2258
2349
|
"required": [
|
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.
|
|
24
|
+
const VERSION = '1.28.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;
|
|
@@ -38,7 +38,16 @@ async function getRemote() {
|
|
|
38
38
|
}
|
|
39
39
|
connecting = (async () => {
|
|
40
40
|
const transport = new StreamableHTTPClientTransport(REMOTE_URL, {
|
|
41
|
-
requestInit: {
|
|
41
|
+
requestInit: {
|
|
42
|
+
headers: {
|
|
43
|
+
Authorization: `Bearer ${apiKey}`,
|
|
44
|
+
// Identify the proxy in the server's request log. Without it every call through this
|
|
45
|
+
// package arrives as a bare `node` and cannot be told apart from any other Node client,
|
|
46
|
+
// so "how much traffic comes through npm" has no answer. Same shape as the Python SDK
|
|
47
|
+
// (`offnadir-delta-python/x.y.z`), which the server already parses.
|
|
48
|
+
'User-Agent': `offnadir-delta-mcp/${VERSION}`,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
42
51
|
});
|
|
43
52
|
const client = new Client({ name: 'offnadir-delta-mcp-proxy', version: VERSION }, { capabilities: {} });
|
|
44
53
|
await client.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "offnadir-delta-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.28.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": {
|