@aborruso/ckan-mcp-server 0.4.78 → 0.4.80

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 CHANGED
@@ -1,7 +1,18 @@
1
1
  # LOG
2
2
 
3
+ ## 2026-03-10
4
+
5
+ - fix(`worker.ts`): `sparql_query` now logs correct `server` field — was always `""` because logging code read `server_url` but SPARQL tool uses `endpoint_url`; fix: `a['server_url'] ?? a['endpoint_url'] ?? ''`
6
+
7
+ ## 2026-03-08
8
+
9
+ - fix(skill): bilingual query rule made conditional — use native language only on monolingual portals (dati.gov.it → IT, data.gov → EN); bilingual only on multilingual portals (data.europa.eu, open.canada.ca)
10
+ - fix(skill): geographic qualifiers (city/region/country) must never be OR-joined with topic terms — always use `fq` or AND; OR-joining a place name inflates results with off-topic datasets
11
+
3
12
  ## 2026-03-08
4
13
 
14
+ - feat(`package.ts`): auto-detect Solr parser mode for unknown portals via probe query `data OR dati` (2 parallel rows=0 calls); if text count > default count × 2 → use text:(...) wrapping; result cached per portal URL for session lifetime
15
+ - feat(`portal-config.ts`): add `isPortalSearchExplicitlyConfigured()` to distinguish known vs unknown portals
5
16
  - fix(`package.ts`): auto-convert `NOW` date math to ISO dates for `issued` and `modified` fields in `q` and `fq` — these are CKAN extra fields not native Solr fields, so `NOW` syntax returned 0 results on all portals tested (dati.gov.it, catalog.data.gov); ISO dates work universally
6
17
  - fix(`package.ts`): fix `content_recent` clause to use ISO date for `issued` field (same root cause)
7
18
  - docs(`tools.md`): clarify date math limitation — `NOW` only works on `metadata_modified`/`metadata_created`; `issued`/`modified` require explicit ISO dates (now auto-converted by server)
package/dist/index.js CHANGED
@@ -44,6 +44,17 @@ var portals_default = {
44
44
  dataset_view_url: "https://www.dati.gov.it/view-dataset/dataset?id={id}",
45
45
  organization_view_url: "https://www.dati.gov.it/view-dataset?organization={name}"
46
46
  },
47
+ {
48
+ id: "dati-arpae-it",
49
+ name: "dati.arpae.it",
50
+ api_url: "https://dati.arpae.it",
51
+ api_url_aliases: [
52
+ "http://dati.arpae.it"
53
+ ],
54
+ search: {
55
+ force_text_field: true
56
+ }
57
+ },
47
58
  {
48
59
  id: "anac-opendata",
49
60
  name: "dati.anticorruzione.it/opendata",
@@ -64,6 +75,9 @@ var portals_default = {
64
75
  "http://www.data.gov.uk"
65
76
  ],
66
77
  api_path: "/api/action",
78
+ search: {
79
+ force_text_field: true
80
+ },
67
81
  dataset_view_url: "https://www.data.gov.uk/dataset/{id}/{name}",
68
82
  organization_view_url: "https://www.data.gov.uk/organization/{name}"
69
83
  },
@@ -73,7 +87,10 @@ var portals_default = {
73
87
  api_url: "https://catalog.data.gov",
74
88
  api_url_aliases: [
75
89
  "http://catalog.data.gov"
76
- ]
90
+ ],
91
+ search: {
92
+ force_text_field: true
93
+ }
77
94
  },
78
95
  {
79
96
  id: "open-canada",
@@ -83,7 +100,10 @@ var portals_default = {
83
100
  "http://open.canada.ca/data",
84
101
  "https://open.canada.ca",
85
102
  "http://open.canada.ca"
86
- ]
103
+ ],
104
+ search: {
105
+ force_text_field: true
106
+ }
87
107
  },
88
108
  {
89
109
  id: "data-gov-au",
@@ -170,6 +190,10 @@ function getPortalSearchConfig(serverUrl) {
170
190
  force_text_field: portal?.search?.force_text_field ?? defaults.force_text_field ?? false
171
191
  };
172
192
  }
193
+ function isPortalSearchExplicitlyConfigured(serverUrl) {
194
+ const portal = getPortalConfig(serverUrl);
195
+ return portal?.search?.force_text_field !== void 0;
196
+ }
173
197
  function normalizePortalUrl(serverUrl) {
174
198
  return normalizeUrl(serverUrl);
175
199
  }
@@ -586,6 +610,21 @@ function resolveSearchQuery(serverUrl, query, parserOverride) {
586
610
  }
587
611
 
588
612
  // src/tools/package.ts
613
+ var _portalParserCache = /* @__PURE__ */ new Map();
614
+ async function probePortalParser(serverUrl) {
615
+ const key = serverUrl.replace(/\/$/, "").toLowerCase();
616
+ if (_portalParserCache.has(key)) return _portalParserCache.get(key);
617
+ const probe = "data OR dati";
618
+ const [defaultRes, textRes] = await Promise.allSettled([
619
+ makeCkanRequest(serverUrl, "package_search", { q: probe, rows: 0 }),
620
+ makeCkanRequest(serverUrl, "package_search", { q: `text:(${probe})`, rows: 0 })
621
+ ]);
622
+ const defaultCount = defaultRes.status === "fulfilled" ? defaultRes.value.count ?? 0 : 0;
623
+ const textCount = textRes.status === "fulfilled" ? textRes.value.count ?? 0 : 0;
624
+ const needsText = textCount > 0 && (defaultCount === 0 || textCount > defaultCount * 2);
625
+ _portalParserCache.set(key, needsText);
626
+ return needsText;
627
+ }
589
628
  var DEFAULT_RELEVANCE_WEIGHTS = {
590
629
  title: 4,
591
630
  notes: 2,
@@ -1170,10 +1209,15 @@ Typical workflow: ckan_package_search \u2192 ckan_package_show (get full metadat
1170
1209
  query = userQuery && userQuery !== "*:*" ? `(${userQuery}) AND (${recentClause})` : recentClause;
1171
1210
  if (!effectiveSort) effectiveSort = "issued desc, metadata_created desc";
1172
1211
  }
1212
+ let parserOverride = params.query_parser;
1213
+ if (!parserOverride && !isPortalSearchExplicitlyConfigured(params.server_url)) {
1214
+ const needsText = await probePortalParser(params.server_url);
1215
+ if (needsText) parserOverride = "text";
1216
+ }
1173
1217
  const { effectiveQuery } = resolveSearchQuery(
1174
1218
  params.server_url,
1175
1219
  query,
1176
- params.query_parser
1220
+ parserOverride
1177
1221
  );
1178
1222
  const { effectiveRows, effectiveStart } = resolvePageParams(params.page, params.page_size, params.start, params.rows);
1179
1223
  const apiParams = {
@@ -5033,7 +5077,7 @@ var registerAllPrompts = (server2) => {
5033
5077
  function createServer() {
5034
5078
  return new McpServer({
5035
5079
  name: "ckan-mcp-server",
5036
- version: "0.4.78"
5080
+ version: "0.4.80"
5037
5081
  });
5038
5082
  }
5039
5083
  function registerAll(server2) {