@aborruso/ckan-mcp-server 0.4.132 → 0.4.133
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/LOG.md +20 -1
- package/dist/index.js +28 -14
- package/package.json +1 -1
package/LOG.md
CHANGED
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
# LOG
|
|
2
2
|
|
|
3
|
+
## 2026-10-28
|
|
4
|
+
|
|
5
|
+
### v0.4.133
|
|
6
|
+
|
|
7
|
+
Ships #568. For callers: `ckan_find_portals` works again on the hosted Worker (it failed on every call since at least 2026-09-05); `ckan_status_show` on a site that is not a CKAN API now says so and points at `ckan_find_portals`, instead of telling the caller to call `ckan_status_show`; `open.toronto.ca` works as a server URL in every tool (routed to its CKAN host). Tests 616 passed. Smoke 16/17: same MQA outage as v0.4.132 (per-dataset `/api/mqa/cache/*/{id}` still not answering, `/global` 0.2 s), tagged with `SKIP_RELEASE_GATE=1` on the user's decision.
|
|
8
|
+
|
|
9
|
+
### Telemetry errors: find_portals fixed on Workers, error messages logged, non-CKAN hints
|
|
10
|
+
|
|
11
|
+
From the error analysis of `worker_events_flat.jsonl` (app errors are logged only since 2026-09-05: 754 of 3,752 calls, 537 of them invalid input from scanners).
|
|
12
|
+
|
|
13
|
+
- `ckan_find_portals` failed on every Worker call (96/96 since 2026-09-05): it was the only tool calling axios directly, and axios's fetch adapter breaks on Workers ("The 'cache' field on 'RequestInitializerDict' is not implemented"). Now uses `safeFetch`, like MQA; SSRF checks on redirects come with it. Checked with `wrangler dev`: 945 portals, about 5 s (the datashades.info list is 22 MB).
|
|
14
|
+
- The worker log line of a failed call now has `error_message` (first 200 chars, one line) and `error_kind` (`validation`, `not_allowed`, `timeout`, `upstream_http`, `unreachable`, `other`, `src/utils/error-telemetry.ts`); the archiver carries both into the flat file. The find_portals failure stayed hidden for weeks because the log only said `error`.
|
|
15
|
+
- `ckan_status_show` on a site that is not the CKAN API (47% failure on real URLs: open.toronto.ca, open.ottawa.ca, data.europa.eu/data, ...) told the caller to call `ckan_status_show`. It now says the site may not run CKAN or keep the API on another host, and points at `ckan_find_portals`. `open.toronto.ca` is routed to its CKAN host `ckan0.cf.opendata.inter.prod-toronto.ca` via `portals.json`.
|
|
16
|
+
- Tests 615 passed (+14, each new test fails without its fix), Python tests 5.
|
|
17
|
+
|
|
3
18
|
## 2026-10-27
|
|
4
19
|
|
|
20
|
+
### Archiver: empty result lists for zero-result searches
|
|
21
|
+
|
|
22
|
+
Manual archiver run on a scratchpad copy (7 live events): search fields reach `worker_events_flat.jsonl`, but a zero-result search came in with `result_ids`/`result_names` null, since the Observability API drops empty arrays from `source`. `flatten()` now restores `[]` whenever `result_count` is present, so "0 results" stays distinct from "not a search". Rechecked on a fresh copy: `zzqxkwvnonesiste` → `result_count` 0, lists `[]`. Tests in `tests/python/test_worker_telemetry_archiver.py` (stdlib `unittest`: zero count with omitted lists, non-empty lists, non-search event, field set); the zero-count case fails on the previous `flatten()`. They run in `update-telemetry.yml` before each archiver run (Greptile review).
|
|
23
|
+
|
|
5
24
|
### v0.4.132
|
|
6
25
|
|
|
7
|
-
Ships #565: worker telemetry logs returned search results. Tests 601 passed. Smoke 16/17: the MQA case times out because data.europa.eu `/api/mqa/cache/datasets/{id}` (and its successor `/resources/{id}`) hang for every dataset id tried, while `/global`, `/countries`, `/catalogues/dati-gov-it` answer in 0.2 s; released anyway on the user's decision. The official spec (`openapi.yaml` 6.0.1-SNAPSHOT) marks `/datasets/{id}` deprecated, alias of `/resources/{id}`: switching is a separate change.
|
|
26
|
+
Ships #565: worker telemetry logs returned search results. Tests 601 passed. Smoke 16/17: the MQA case times out because data.europa.eu `/api/mqa/cache/datasets/{id}` (and its successor `/resources/{id}`) hang for every dataset id tried, while `/global`, `/countries`, `/catalogues/dati-gov-it` answer in 0.2 s; released anyway on the user's decision. Live on npm (provenance), the MCP Registry (`isLatest`), the Worker (`/health` 0.4.132) and the GitHub release (DXT + skill attached). Observability API checked read-only: `result_ids` arrives as a list and `flatten()` maps it. The official spec (`openapi.yaml` 6.0.1-SNAPSHOT) marks `/datasets/{id}` deprecated, alias of `/resources/{id}`: switching is a separate change.
|
|
8
27
|
|
|
9
28
|
### Worker telemetry: returned search results
|
|
10
29
|
|
package/dist/index.js
CHANGED
|
@@ -96,6 +96,16 @@ var portals_default = {
|
|
|
96
96
|
"http://open.canada.ca"
|
|
97
97
|
]
|
|
98
98
|
},
|
|
99
|
+
{
|
|
100
|
+
id: "open-toronto",
|
|
101
|
+
name: "open.toronto.ca",
|
|
102
|
+
api_url: "https://ckan0.cf.opendata.inter.prod-toronto.ca",
|
|
103
|
+
api_url_aliases: [
|
|
104
|
+
"https://open.toronto.ca",
|
|
105
|
+
"http://open.toronto.ca"
|
|
106
|
+
],
|
|
107
|
+
dataset_view_url: "https://open.toronto.ca/dataset/{name}/"
|
|
108
|
+
},
|
|
99
109
|
{
|
|
100
110
|
id: "data-gov-au",
|
|
101
111
|
name: "data.gov.au",
|
|
@@ -3648,14 +3658,15 @@ Typical workflow: ckan_status_show (verify server is up) \u2192 ckan_package_sea
|
|
|
3648
3658
|
structuredContent: cappedStructured(result)
|
|
3649
3659
|
};
|
|
3650
3660
|
} catch (error) {
|
|
3651
|
-
const migrated = error instanceof CkanApiError && error.serverUrl && getPortalMigration(error.serverUrl);
|
|
3652
|
-
|
|
3661
|
+
const migrated = (error instanceof CkanApiError || error instanceof CkanTransportError) && error.serverUrl && getPortalMigration(error.serverUrl);
|
|
3662
|
+
if (migrated) {
|
|
3663
|
+
return { content: [{ type: "text", text: formatCkanError(error, "ckan_status_show") }], isError: true };
|
|
3664
|
+
}
|
|
3665
|
+
const detail = error instanceof CkanApiError || error instanceof CkanTransportError ? `${error.message}
|
|
3666
|
+
\u2192 No CKAN API answered at this address. The site may be up but not run CKAN, or keep its CKAN API on another host. Use \`ckan_find_portals\` to look up the portal's CKAN API URL; retry later only if this address usually works.` : formatCkanError(error, "ckan_status_show");
|
|
3653
3667
|
return {
|
|
3654
|
-
content: [{
|
|
3655
|
-
|
|
3656
|
-
text: migrated ? detail : `Server appears to be offline or not a valid CKAN instance:
|
|
3657
|
-
${detail}`
|
|
3658
|
-
}],
|
|
3668
|
+
content: [{ type: "text", text: `Server appears to be offline or not a valid CKAN instance:
|
|
3669
|
+
${detail}` }],
|
|
3659
3670
|
isError: true
|
|
3660
3671
|
};
|
|
3661
3672
|
}
|
|
@@ -5407,14 +5418,17 @@ ${error instanceof Error ? error.message : String(error)}`;
|
|
|
5407
5418
|
|
|
5408
5419
|
// src/tools/portal-discovery.ts
|
|
5409
5420
|
import { z as z11 } from "zod";
|
|
5410
|
-
import axios2 from "axios";
|
|
5411
5421
|
var DATASHADES_URL = "https://datashades.info/api/portal/list";
|
|
5412
5422
|
async function fetchPortals() {
|
|
5413
|
-
const resp = await
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
});
|
|
5417
|
-
|
|
5423
|
+
const resp = await safeFetch(DATASHADES_URL, {
|
|
5424
|
+
headers: { "User-Agent": "CKAN-MCP-Server/1.0" },
|
|
5425
|
+
signal: AbortSignal.timeout(15e3)
|
|
5426
|
+
}, { httpsOnly: true });
|
|
5427
|
+
if (!resp.ok) {
|
|
5428
|
+
throw new Error(`datashades.info returned ${resp.status} ${resp.statusText}`);
|
|
5429
|
+
}
|
|
5430
|
+
const data = await resp.json();
|
|
5431
|
+
return data.portals;
|
|
5418
5432
|
}
|
|
5419
5433
|
function deduplicateByHostname(portals) {
|
|
5420
5434
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -6142,7 +6156,7 @@ var registerAllPrompts = (server) => {
|
|
|
6142
6156
|
function createServer() {
|
|
6143
6157
|
return new McpServer({
|
|
6144
6158
|
name: "ckan-mcp-server",
|
|
6145
|
-
version: "0.4.
|
|
6159
|
+
version: "0.4.133"
|
|
6146
6160
|
});
|
|
6147
6161
|
}
|
|
6148
6162
|
function registerAll(server) {
|