@aborruso/ckan-mcp-server 0.4.94 → 0.4.96

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
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## 2026-03-26
4
4
 
5
+ ### v0.4.96
6
+
7
+ - Add `dati.regione.sicilia.it` (Sicily open data portal) to `portals.json` with `force_text_field: false` — CKAN 2.6.8 does not support the `text:(...)` query wrapper
8
+
9
+ ### v0.4.95
10
+
11
+ - Show `Portal Locale` (`locale_default`) in `ckan_status_show` markdown output
12
+ - Add query language hint to `ckan_package_search` description: check locale before searching
13
+ - Update skill query construction rule: dynamic locale check via `ckan_status_show` instead of hardcoded portal table
14
+
5
15
  ### v0.4.94
6
16
 
7
17
  - Add `data.gov.ua` (Ukraine open data portal) to `portals.json` with explicit `force_text_field: false` to prevent auto-detection from incorrectly wrapping Solr queries in `text:(...)`, which caused 0 results
package/dist/index.js CHANGED
@@ -152,6 +152,17 @@ var portals_default = {
152
152
  force_text_field: false
153
153
  }
154
154
  },
155
+ {
156
+ id: "dati-regione-sicilia",
157
+ name: "dati.regione.sicilia.it",
158
+ api_url: "https://dati.regione.sicilia.it",
159
+ api_url_aliases: [
160
+ "http://dati.regione.sicilia.it"
161
+ ],
162
+ search: {
163
+ force_text_field: false
164
+ }
165
+ },
155
166
  {
156
167
  id: "govdata-de",
157
168
  name: "govdata.de",
@@ -1226,7 +1237,13 @@ Examples:
1226
1237
  - Filter extras OR (correct): { fq: "extras_hvd_category:("http://data.europa.eu/bna/c_ac64a52d" OR "http://data.europa.eu/bna/c_dd313021")" }
1227
1238
  - Get facets: { facet_field: ["organization"], rows: 0 }
1228
1239
 
1229
- Typical workflow: ckan_package_search \u2192 ckan_package_show (get full metadata + resource IDs) \u2192 ckan_datastore_search (query tabular data)`,
1240
+ Query language:
1241
+ Before searching a portal, check its locale via ckan_status_show (field: "Portal Locale" / locale_default).
1242
+ Translate query terms to the portal's language \u2014 searching in English on a non-English portal returns 0 results.
1243
+ Examples: locale "it" \u2192 Italian terms; "uk_UA" \u2192 Ukrainian (Cyrillic); "fr_FR" \u2192 French.
1244
+ Exception: multilingual portals (e.g. data.europa.eu, open.canada.ca) accept EN + native terms joined with OR.
1245
+
1246
+ Typical workflow: ckan_status_show (check locale) \u2192 ckan_package_search (query in portal's language) \u2192 ckan_package_show (get full metadata + resource IDs) \u2192 ckan_datastore_search (query tabular data)`,
1230
1247
  inputSchema: z2.object({
1231
1248
  server_url: z2.string().url("Must be a valid URL").describe("Base URL of the CKAN server"),
1232
1249
  q: z2.string().optional().default("*:*").describe("Search query in Solr syntax"),
@@ -2608,6 +2625,8 @@ function formatStatusMarkdown(result, serverUrl, hvdCount) {
2608
2625
  const sparqlLine = sparql ? `**SPARQL Endpoint**: ${sparql.endpoint_url}
2609
2626
  ` : "";
2610
2627
  const hvdLine = hvdCount !== void 0 ? `**HVD Datasets**: ${hvdCount}
2628
+ ` : "";
2629
+ const localeLine = result.locale_default ? `**Portal Locale**: ${result.locale_default}
2611
2630
  ` : "";
2612
2631
  return `# CKAN Server Status
2613
2632
 
@@ -2616,7 +2635,7 @@ function formatStatusMarkdown(result, serverUrl, hvdCount) {
2616
2635
  **CKAN Version**: ${result.ckan_version || "Unknown"}
2617
2636
  **Site Title**: ${result.site_title || "N/A"}
2618
2637
  **Site URL**: ${result.site_url || "N/A"}
2619
- ` + sparqlLine + hvdLine;
2638
+ ` + localeLine + sparqlLine + hvdLine;
2620
2639
  }
2621
2640
  function registerStatusTools(server) {
2622
2641
  server.registerTool(
@@ -5140,7 +5159,7 @@ var registerAllPrompts = (server) => {
5140
5159
  function createServer() {
5141
5160
  return new McpServer({
5142
5161
  name: "ckan-mcp-server",
5143
- version: "0.4.94"
5162
+ version: "0.4.96"
5144
5163
  });
5145
5164
  }
5146
5165
  function registerAll(server) {
package/dist/worker.js CHANGED
@@ -41,7 +41,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
41
41
  `)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...r){let n=new this(e);return r.forEach(o=>n.set(o)),n}static accessor(e){let n=(this[dv]=this[dv]={accessors:{}}).accessors,o=this.prototype;function s(i){let a=_s(i);n[a]||(TA(o,i),n[a]=!0)}return y.isArray(e)?e.forEach(s):s(e),this}};so.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);y.reduceDescriptors(so.prototype,({value:t},e)=>{let r=e[0].toUpperCase()+e.slice(1);return{get:()=>t,set(n){this[r]=n}}});y.freezeMethods(so);var Te=so;function vs(t,e){let r=this||oo,n=e||r,o=Te.from(n.headers),s=n.data;return y.forEach(t,function(a){s=a.call(r,s,o.normalize(),e?e.status:void 0)}),o.normalize(),s}function bs(t){return!!(t&&t.__CANCEL__)}function fv(t,e,r){Z.call(this,t??"canceled",Z.ERR_CANCELED,e,r),this.name="CanceledError"}y.inherits(fv,Z,{__CANCEL__:!0});var Lt=fv;function ws(t,e,r){let n=r.config.validateStatus;!r.status||!n||n(r.status)?t(r):e(new Z("Request failed with status code "+r.status,[Z.ERR_BAD_REQUEST,Z.ERR_BAD_RESPONSE][Math.floor(r.status/100)-4],r.config,r.request,r))}function Ef(t){let e=/^([-+\w]{1,25})(:?\/\/|:)/.exec(t);return e&&e[1]||""}function RA(t,e){t=t||10;let r=new Array(t),n=new Array(t),o=0,s=0,i;return e=e!==void 0?e:1e3,function(c){let u=Date.now(),l=n[s];i||(i=u),r[o]=c,n[o]=u;let d=s,p=0;for(;d!==o;)p+=r[d++],d=d%t;if(o=(o+1)%t,o===s&&(s=(s+1)%t),u-i<e)return;let h=l&&u-l;return h?Math.round(p*1e3/h):void 0}}var pv=RA;function EA(t,e){let r=0,n=1e3/e,o,s,i=(u,l=Date.now())=>{r=l,o=null,s&&(clearTimeout(s),s=null),t(...u)};return[(...u)=>{let l=Date.now(),d=l-r;d>=n?i(u,l):(o=u,s||(s=setTimeout(()=>{s=null,i(o)},n-d)))},()=>o&&i(o)]}var mv=EA;var io=(t,e,r=3)=>{let n=0,o=pv(50,250);return mv(s=>{let i=s.loaded,a=s.lengthComputable?s.total:void 0,c=i-n,u=o(c),l=i<=a;n=i;let d={loaded:i,total:a,progress:a?i/a:void 0,bytes:c,rate:u||void 0,estimated:u&&a&&l?(a-i)/u:void 0,event:s,lengthComputable:a!=null,[e?"download":"upload"]:!0};t(d)},r)},Pf=(t,e)=>{let r=t!=null;return[n=>e[0]({lengthComputable:r,total:t,loaded:n}),e[1]]},Af=t=>(...e)=>y.asap(()=>t(...e));var hv=ke.hasStandardBrowserEnv?((t,e)=>r=>(r=new URL(r,ke.origin),t.protocol===r.protocol&&t.host===r.host&&(e||t.port===r.port)))(new URL(ke.origin),ke.navigator&&/(msie|trident)/i.test(ke.navigator.userAgent)):()=>!0;var gv=ke.hasStandardBrowserEnv?{write(t,e,r,n,o,s,i){if(typeof document>"u")return;let a=[`${t}=${encodeURIComponent(e)}`];y.isNumber(r)&&a.push(`expires=${new Date(r).toUTCString()}`),y.isString(n)&&a.push(`path=${n}`),y.isString(o)&&a.push(`domain=${o}`),s===!0&&a.push("secure"),y.isString(i)&&a.push(`SameSite=${i}`),document.cookie=a.join("; ")},read(t){if(typeof document>"u")return null;let e=document.cookie.match(new RegExp("(?:^|; )"+t+"=([^;]*)"));return e?decodeURIComponent(e[1]):null},remove(t){this.write(t,"",Date.now()-864e5,"/")}}:{write(){},read(){return null},remove(){}};function Of(t){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t)}function Cf(t,e){return e?t.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):t}function xs(t,e,r){let n=!Of(e);return t&&(n||r==!1)?Cf(t,e):e}var yv=t=>t instanceof Te?{...t}:t;function zt(t,e){e=e||{};let r={};function n(u,l,d,p){return y.isPlainObject(u)&&y.isPlainObject(l)?y.merge.call({caseless:p},u,l):y.isPlainObject(l)?y.merge({},l):y.isArray(l)?l.slice():l}function o(u,l,d,p){if(y.isUndefined(l)){if(!y.isUndefined(u))return n(void 0,u,d,p)}else return n(u,l,d,p)}function s(u,l){if(!y.isUndefined(l))return n(void 0,l)}function i(u,l){if(y.isUndefined(l)){if(!y.isUndefined(u))return n(void 0,u)}else return n(void 0,l)}function a(u,l,d){if(d in e)return n(u,l);if(d in t)return n(void 0,u)}let c={url:s,method:s,data:s,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:a,headers:(u,l,d)=>o(yv(u),yv(l),d,!0)};return y.forEach(Object.keys({...t,...e}),function(l){let d=c[l]||o,p=d(t[l],e[l],l);y.isUndefined(p)&&d!==a||(r[l]=p)}),r}var za=t=>{let e=zt({},t),{data:r,withXSRFToken:n,xsrfHeaderName:o,xsrfCookieName:s,headers:i,auth:a}=e;if(e.headers=i=Te.from(i),e.url=ys(xs(e.baseURL,e.url,e.allowAbsoluteUrls),t.params,t.paramsSerializer),a&&i.set("Authorization","Basic "+btoa((a.username||"")+":"+(a.password?unescape(encodeURIComponent(a.password)):""))),y.isFormData(r)){if(ke.hasStandardBrowserEnv||ke.hasStandardBrowserWebWorkerEnv)i.setContentType(void 0);else if(y.isFunction(r.getHeaders)){let c=r.getHeaders(),u=["content-type","content-length"];Object.entries(c).forEach(([l,d])=>{u.includes(l.toLowerCase())&&i.set(l,d)})}}if(ke.hasStandardBrowserEnv&&(n&&y.isFunction(n)&&(n=n(e)),n||n!==!1&&hv(e.url))){let c=o&&s&&gv.read(s);c&&i.set(o,c)}return e};var PA=typeof XMLHttpRequest<"u",_v=PA&&function(t){return new Promise(function(r,n){let o=za(t),s=o.data,i=Te.from(o.headers).normalize(),{responseType:a,onUploadProgress:c,onDownloadProgress:u}=o,l,d,p,h,f;function m(){h&&h(),f&&f(),o.cancelToken&&o.cancelToken.unsubscribe(l),o.signal&&o.signal.removeEventListener("abort",l)}let g=new XMLHttpRequest;g.open(o.method.toUpperCase(),o.url,!0),g.timeout=o.timeout;function _(){if(!g)return;let k=Te.from("getAllResponseHeaders"in g&&g.getAllResponseHeaders()),A={data:!a||a==="text"||a==="json"?g.responseText:g.response,status:g.status,statusText:g.statusText,headers:k,config:t,request:g};ws(function(pe){r(pe),m()},function(pe){n(pe),m()},A),g=null}"onloadend"in g?g.onloadend=_:g.onreadystatechange=function(){!g||g.readyState!==4||g.status===0&&!(g.responseURL&&g.responseURL.indexOf("file:")===0)||setTimeout(_)},g.onabort=function(){g&&(n(new Z("Request aborted",Z.ECONNABORTED,t,g)),g=null)},g.onerror=function(z){let A=z&&z.message?z.message:"Network Error",be=new Z(A,Z.ERR_NETWORK,t,g);be.event=z||null,n(be),g=null},g.ontimeout=function(){let z=o.timeout?"timeout of "+o.timeout+"ms exceeded":"timeout exceeded",A=o.transitional||ka;o.timeoutErrorMessage&&(z=o.timeoutErrorMessage),n(new Z(z,A.clarifyTimeoutError?Z.ETIMEDOUT:Z.ECONNABORTED,t,g)),g=null},s===void 0&&i.setContentType(null),"setRequestHeader"in g&&y.forEach(i.toJSON(),function(z,A){g.setRequestHeader(A,z)}),y.isUndefined(o.withCredentials)||(g.withCredentials=!!o.withCredentials),a&&a!=="json"&&(g.responseType=o.responseType),u&&([p,f]=io(u,!0),g.addEventListener("progress",p)),c&&g.upload&&([d,h]=io(c),g.upload.addEventListener("progress",d),g.upload.addEventListener("loadend",h)),(o.cancelToken||o.signal)&&(l=k=>{g&&(n(!k||k.type?new Lt(null,t,g):k),g.abort(),g=null)},o.cancelToken&&o.cancelToken.subscribe(l),o.signal&&(o.signal.aborted?l():o.signal.addEventListener("abort",l)));let x=Ef(o.url);if(x&&ke.protocols.indexOf(x)===-1){n(new Z("Unsupported protocol "+x+":",Z.ERR_BAD_REQUEST,t));return}g.send(s||null)})};var AA=(t,e)=>{let{length:r}=t=t?t.filter(Boolean):[];if(e||r){let n=new AbortController,o,s=function(u){if(!o){o=!0,a();let l=u instanceof Error?u:this.reason;n.abort(l instanceof Z?l:new Lt(l instanceof Error?l.message:l))}},i=e&&setTimeout(()=>{i=null,s(new Z(`timeout ${e} of ms exceeded`,Z.ETIMEDOUT))},e),a=()=>{t&&(i&&clearTimeout(i),i=null,t.forEach(u=>{u.unsubscribe?u.unsubscribe(s):u.removeEventListener("abort",s)}),t=null)};t.forEach(u=>u.addEventListener("abort",s));let{signal:c}=n;return c.unsubscribe=()=>y.asap(a),c}},vv=AA;var OA=function*(t,e){let r=t.byteLength;if(!e||r<e){yield t;return}let n=0,o;for(;n<r;)o=n+e,yield t.slice(n,o),n=o},CA=async function*(t,e){for await(let r of NA(t))yield*OA(r,e)},NA=async function*(t){if(t[Symbol.asyncIterator]){yield*t;return}let e=t.getReader();try{for(;;){let{done:r,value:n}=await e.read();if(r)break;yield n}}finally{await e.cancel()}},Nf=(t,e,r,n)=>{let o=CA(t,e),s=0,i,a=c=>{i||(i=!0,n&&n(c))};return new ReadableStream({async pull(c){try{let{done:u,value:l}=await o.next();if(u){a(),c.close();return}let d=l.byteLength;if(r){let p=s+=d;r(p)}c.enqueue(new Uint8Array(l))}catch(u){throw a(u),u}},cancel(c){return a(c),o.return()}},{highWaterMark:2})};var bv=64*1024,{isFunction:Ta}=y,IA=(({Request:t,Response:e})=>({Request:t,Response:e}))(y.global),{ReadableStream:wv,TextEncoder:xv}=y.global,kv=(t,...e)=>{try{return!!t(...e)}catch{return!1}},MA=t=>{t=y.merge.call({skipUndefined:!0},IA,t);let{fetch:e,Request:r,Response:n}=t,o=e?Ta(e):typeof fetch=="function",s=Ta(r),i=Ta(n);if(!o)return!1;let a=o&&Ta(wv),c=o&&(typeof xv=="function"?(f=>m=>f.encode(m))(new xv):async f=>new Uint8Array(await new r(f).arrayBuffer())),u=s&&a&&kv(()=>{let f=!1,m=new r(ke.origin,{body:new wv,method:"POST",get duplex(){return f=!0,"half"}}).headers.has("Content-Type");return f&&!m}),l=i&&a&&kv(()=>y.isReadableStream(new n("").body)),d={stream:l&&(f=>f.body)};o&&["text","arrayBuffer","blob","formData","stream"].forEach(f=>{!d[f]&&(d[f]=(m,g)=>{let _=m&&m[f];if(_)return _.call(m);throw new Z(`Response type '${f}' is not supported`,Z.ERR_NOT_SUPPORT,g)})});let p=async f=>{if(f==null)return 0;if(y.isBlob(f))return f.size;if(y.isSpecCompliantForm(f))return(await new r(ke.origin,{method:"POST",body:f}).arrayBuffer()).byteLength;if(y.isArrayBufferView(f)||y.isArrayBuffer(f))return f.byteLength;if(y.isURLSearchParams(f)&&(f=f+""),y.isString(f))return(await c(f)).byteLength},h=async(f,m)=>{let g=y.toFiniteNumber(f.getContentLength());return g??p(m)};return async f=>{let{url:m,method:g,data:_,signal:x,cancelToken:k,timeout:z,onDownloadProgress:A,onUploadProgress:be,responseType:pe,headers:Tt,withCredentials:nr="same-origin",fetchOptions:or}=za(f),_n=e||fetch;pe=pe?(pe+"").toLowerCase():"text";let Or=vv([x,k&&k.toAbortSignal()],z),sr=null,Ht=Or&&Or.unsubscribe&&(()=>{Or.unsubscribe()}),Xf;try{if(be&&u&&g!=="get"&&g!=="head"&&(Xf=await h(Tt,_))!==0){let ar=new r(m,{method:"POST",body:_,duplex:"half"}),vn;if(y.isFormData(_)&&(vn=ar.headers.get("content-type"))&&Tt.setContentType(vn),ar.body){let[Da,zs]=Pf(Xf,io(Af(be)));_=Nf(ar.body,bv,Da,zs)}}y.isString(nr)||(nr=nr?"include":"omit");let Rt=s&&"credentials"in r.prototype,ep={...or,signal:Or,method:g.toUpperCase(),headers:Tt.normalize().toJSON(),body:_,duplex:"half",credentials:Rt?nr:void 0};sr=s&&new r(m,ep);let ir=await(s?_n(sr,or):_n(m,ep)),tp=l&&(pe==="stream"||pe==="response");if(l&&(A||tp&&Ht)){let ar={};["status","statusText","headers"].forEach(rp=>{ar[rp]=ir[rp]});let vn=y.toFiniteNumber(ir.headers.get("content-length")),[Da,zs]=A&&Pf(vn,io(Af(A),!0))||[];ir=new n(Nf(ir.body,bv,Da,()=>{zs&&zs(),Ht&&Ht()}),ar)}pe=pe||"text";let Rb=await d[y.findKey(d,pe)||"text"](ir,f);return!tp&&Ht&&Ht(),await new Promise((ar,vn)=>{ws(ar,vn,{data:Rb,headers:Te.from(ir.headers),status:ir.status,statusText:ir.statusText,config:f,request:sr})})}catch(Rt){throw Ht&&Ht(),Rt&&Rt.name==="TypeError"&&/Load failed|fetch/i.test(Rt.message)?Object.assign(new Z("Network Error",Z.ERR_NETWORK,f,sr),{cause:Rt.cause||Rt}):Z.from(Rt,Rt&&Rt.code,f,sr)}}},jA=new Map,If=t=>{let e=t&&t.env||{},{fetch:r,Request:n,Response:o}=e,s=[n,o,r],i=s.length,a=i,c,u,l=jA;for(;a--;)c=s[a],u=l.get(c),u===void 0&&l.set(c,u=a?new Map:MA(e)),l=u;return u},oL=If();var Mf={http:wa,xhr:_v,fetch:{get:If}};y.forEach(Mf,(t,e)=>{if(t){try{Object.defineProperty(t,"name",{value:e})}catch{}Object.defineProperty(t,"adapterName",{value:e})}});var Sv=t=>`- ${t}`,DA=t=>y.isFunction(t)||t===null||t===!1;function ZA(t,e){t=y.isArray(t)?t:[t];let{length:r}=t,n,o,s={};for(let i=0;i<r;i++){n=t[i];let a;if(o=n,!DA(n)&&(o=Mf[(a=String(n)).toLowerCase()],o===void 0))throw new Z(`Unknown adapter '${a}'`);if(o&&(y.isFunction(o)||(o=o.get(e))))break;s[a||"#"+i]=o}if(!o){let i=Object.entries(s).map(([c,u])=>`adapter ${c} `+(u===!1?"is not supported by the environment":"is not available in the build")),a=r?i.length>1?`since :
42
42
  `+i.map(Sv).join(`
43
43
  `):" "+Sv(i[0]):"as no adapter specified";throw new Z("There is no suitable adapter to dispatch the request "+a,"ERR_NOT_SUPPORT")}return o}var Ra={getAdapter:ZA,adapters:Mf};function jf(t){if(t.cancelToken&&t.cancelToken.throwIfRequested(),t.signal&&t.signal.aborted)throw new Lt(null,t)}function Ea(t){return jf(t),t.headers=Te.from(t.headers),t.data=vs.call(t,t.transformRequest),["post","put","patch"].indexOf(t.method)!==-1&&t.headers.setContentType("application/x-www-form-urlencoded",!1),Ra.getAdapter(t.adapter||oo.adapter,t)(t).then(function(n){return jf(t),n.data=vs.call(t,t.transformResponse,n),n.headers=Te.from(n.headers),n},function(n){return bs(n)||(jf(t),n&&n.response&&(n.response.data=vs.call(t,t.transformResponse,n.response),n.response.headers=Te.from(n.response.headers))),Promise.reject(n)})}var Pa="1.13.2";var Aa={};["object","boolean","number","function","string","symbol"].forEach((t,e)=>{Aa[t]=function(n){return typeof n===t||"a"+(e<1?"n ":" ")+t}});var $v={};Aa.transitional=function(e,r,n){function o(s,i){return"[Axios v"+Pa+"] Transitional option '"+s+"'"+i+(n?". "+n:"")}return(s,i,a)=>{if(e===!1)throw new Z(o(i," has been removed"+(r?" in "+r:"")),Z.ERR_DEPRECATED);return r&&!$v[i]&&($v[i]=!0,console.warn(o(i," has been deprecated since v"+r+" and will be removed in the near future"))),e?e(s,i,a):!0}};Aa.spelling=function(e){return(r,n)=>(console.warn(`${n} is likely a misspelling of ${e}`),!0)};function LA(t,e,r){if(typeof t!="object")throw new Z("options must be an object",Z.ERR_BAD_OPTION_VALUE);let n=Object.keys(t),o=n.length;for(;o-- >0;){let s=n[o],i=e[s];if(i){let a=t[s],c=a===void 0||i(a,s,t);if(c!==!0)throw new Z("option "+s+" must be "+c,Z.ERR_BAD_OPTION_VALUE);continue}if(r!==!0)throw new Z("Unknown option "+s,Z.ERR_BAD_OPTION)}}var ks={assertOptions:LA,validators:Aa};var Ut=ks.validators,ao=class{constructor(e){this.defaults=e||{},this.interceptors={request:new xf,response:new xf}}async request(e,r){try{return await this._request(e,r)}catch(n){if(n instanceof Error){let o={};Error.captureStackTrace?Error.captureStackTrace(o):o=new Error;let s=o.stack?o.stack.replace(/^.+\n/,""):"";try{n.stack?s&&!String(n.stack).endsWith(s.replace(/^.+\n.+\n/,""))&&(n.stack+=`
44
- `+s):n.stack=s}catch{}}throw n}}_request(e,r){typeof e=="string"?(r=r||{},r.url=e):r=e||{},r=zt(this.defaults,r);let{transitional:n,paramsSerializer:o,headers:s}=r;n!==void 0&&ks.assertOptions(n,{silentJSONParsing:Ut.transitional(Ut.boolean),forcedJSONParsing:Ut.transitional(Ut.boolean),clarifyTimeoutError:Ut.transitional(Ut.boolean)},!1),o!=null&&(y.isFunction(o)?r.paramsSerializer={serialize:o}:ks.assertOptions(o,{encode:Ut.function,serialize:Ut.function},!0)),r.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?r.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:r.allowAbsoluteUrls=!0),ks.assertOptions(r,{baseUrl:Ut.spelling("baseURL"),withXsrfToken:Ut.spelling("withXSRFToken")},!0),r.method=(r.method||this.defaults.method||"get").toLowerCase();let i=s&&y.merge(s.common,s[r.method]);s&&y.forEach(["delete","get","head","post","put","patch","common"],f=>{delete s[f]}),r.headers=Te.concat(i,s);let a=[],c=!0;this.interceptors.request.forEach(function(m){typeof m.runWhen=="function"&&m.runWhen(r)===!1||(c=c&&m.synchronous,a.unshift(m.fulfilled,m.rejected))});let u=[];this.interceptors.response.forEach(function(m){u.push(m.fulfilled,m.rejected)});let l,d=0,p;if(!c){let f=[Ea.bind(this),void 0];for(f.unshift(...a),f.push(...u),p=f.length,l=Promise.resolve(r);d<p;)l=l.then(f[d++],f[d++]);return l}p=a.length;let h=r;for(;d<p;){let f=a[d++],m=a[d++];try{h=f(h)}catch(g){m.call(this,g);break}}try{l=Ea.call(this,h)}catch(f){return Promise.reject(f)}for(d=0,p=u.length;d<p;)l=l.then(u[d++],u[d++]);return l}getUri(e){e=zt(this.defaults,e);let r=xs(e.baseURL,e.url,e.allowAbsoluteUrls);return ys(r,e.params,e.paramsSerializer)}};y.forEach(["delete","get","head","options"],function(e){ao.prototype[e]=function(r,n){return this.request(zt(n||{},{method:e,url:r,data:(n||{}).data}))}});y.forEach(["post","put","patch"],function(e){function r(n){return function(s,i,a){return this.request(zt(a||{},{method:e,headers:n?{"Content-Type":"multipart/form-data"}:{},url:s,data:i}))}}ao.prototype[e]=r(),ao.prototype[e+"Form"]=r(!0)});var Ss=ao;var qf=class t{constructor(e){if(typeof e!="function")throw new TypeError("executor must be a function.");let r;this.promise=new Promise(function(s){r=s});let n=this;this.promise.then(o=>{if(!n._listeners)return;let s=n._listeners.length;for(;s-- >0;)n._listeners[s](o);n._listeners=null}),this.promise.then=o=>{let s,i=new Promise(a=>{n.subscribe(a),s=a}).then(o);return i.cancel=function(){n.unsubscribe(s)},i},e(function(s,i,a){n.reason||(n.reason=new Lt(s,i,a),r(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;let r=this._listeners.indexOf(e);r!==-1&&this._listeners.splice(r,1)}toAbortSignal(){let e=new AbortController,r=n=>{e.abort(n)};return this.subscribe(r),e.signal.unsubscribe=()=>this.unsubscribe(r),e.signal}static source(){let e;return{token:new t(function(o){e=o}),cancel:e}}},zv=qf;function Df(t){return function(r){return t.apply(null,r)}}function Zf(t){return y.isObject(t)&&t.isAxiosError===!0}var Lf={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(Lf).forEach(([t,e])=>{Lf[e]=t});var Tv=Lf;function Rv(t){let e=new Ss(t),r=ps(Ss.prototype.request,e);return y.extend(r,Ss.prototype,e,{allOwnKeys:!0}),y.extend(r,e,null,{allOwnKeys:!0}),r.create=function(o){return Rv(zt(t,o))},r}var $e=Rv(oo);$e.Axios=Ss;$e.CanceledError=Lt;$e.CancelToken=zv;$e.isCancel=bs;$e.VERSION=Pa;$e.toFormData=Er;$e.AxiosError=Z;$e.Cancel=$e.CanceledError;$e.all=function(e){return Promise.all(e)};$e.spread=Df;$e.isAxiosError=Zf;$e.mergeConfig=zt;$e.AxiosHeaders=Te;$e.formToJSON=t=>Sa(y.isHTMLForm(t)?new FormData(t):t);$e.getAdapter=Ra.getAdapter;$e.HttpStatusCode=Tv;$e.default=$e;var Ft=$e;var{Axios:t2,AxiosError:r2,CanceledError:n2,isCancel:o2,CancelToken:s2,VERSION:i2,all:a2,Cancel:c2,isAxiosError:u2,spread:l2,toFormData:d2,AxiosHeaders:f2,HttpStatusCode:p2,formToJSON:m2,getAdapter:h2,mergeConfig:g2}=Ft;var Pr={portals:[{id:"dati-gov-it",name:"dati.gov.it",api_url:"https://www.dati.gov.it/opendata",api_url_aliases:["https://dati.gov.it/opendata","http://www.dati.gov.it/opendata","http://dati.gov.it/opendata","https://dati.gov.it","https://www.dati.gov.it"],search:{force_text_field:!0},hvd:{category_field:"hvd_category"},sparql:{endpoint_url:"https://lod.dati.gov.it/sparql",method:"GET"},dataset_view_url:"https://www.dati.gov.it/view-dataset/dataset?id={id}",organization_view_url:"https://www.dati.gov.it/view-dataset?organization={name}"},{id:"dati-arpae-it",name:"dati.arpae.it",api_url:"https://dati.arpae.it",api_url_aliases:["http://dati.arpae.it"],search:{force_text_field:!0}},{id:"anac-opendata",name:"dati.anticorruzione.it/opendata",api_url:"https://dati.anticorruzione.it/opendata",api_url_aliases:["http://dati.anticorruzione.it/opendata","https://dati.anticorruzione.it","http://dati.anticorruzione.it"]},{id:"data-gov-uk",name:"data.gov.uk",api_url:"https://data.gov.uk",api_url_aliases:["https://www.data.gov.uk","http://data.gov.uk","http://www.data.gov.uk"],api_path:"/api/action",search:{force_text_field:!0},dataset_view_url:"https://www.data.gov.uk/dataset/{id}/{name}",organization_view_url:"https://www.data.gov.uk/organization/{name}"},{id:"catalog-data-gov",name:"catalog.data.gov",api_url:"https://catalog.data.gov",api_url_aliases:["http://catalog.data.gov"],search:{force_text_field:!0}},{id:"open-canada",name:"open.canada.ca",api_url:"https://open.canada.ca/data",api_url_aliases:["http://open.canada.ca/data","https://open.canada.ca","http://open.canada.ca"],search:{force_text_field:!0}},{id:"data-gov-au",name:"data.gov.au",api_url:"https://data.gov.au",api_url_aliases:["http://data.gov.au","https://www.data.gov.au","http://www.data.gov.au"],dataset_view_url:"https://data.gov.au/data/dataset/{name}",organization_view_url:"https://data.gov.au/data/organization/{name}"},{id:"opendata-swiss",name:"opendata.swiss",api_url:"https://ckan.opendata.swiss",api_url_aliases:["https://opendata.swiss","http://opendata.swiss","https://www.opendata.swiss","http://www.opendata.swiss"]},{id:"data-stadt-zuerich-ch",name:"data.stadt-zuerich.ch",api_url:"https://data.stadt-zuerich.ch",api_url_aliases:["http://data.stadt-zuerich.ch","https://www.data.stadt-zuerich.ch","https://ckan-prod.zurich.datopian.com"],organization_view_url:"https://ckan-prod.zurich.datopian.com/organization/{name}"},{id:"govdata-de",name:"govdata.de",api_url:"https://ckan.govdata.de",api_url_aliases:["https://www.govdata.de","https://govdata.de","https://www.govdata.de/daten","https://data.gov.de","https://www.data.gov.de"],dataset_view_url:"https://ckan.govdata.de/dataset/{name}",organization_view_url:"https://ckan.govdata.de/organization/{name}"}],defaults:{dataset_view_url:"{server_url}/dataset/{name}",organization_view_url:"{server_url}/organization/{name}",search:{force_text_field:!1}}};function mn(t){return t.replace(/\/$/,"")}function FA(t){try{return new URL(t).hostname}catch{return null}}function rr(t){let e=mn(t);return Pr.portals.find(n=>{let o=mn(n.api_url),s=(n.api_url_aliases||[]).map(mn);return o===e||s.includes(e)})||null}function Ev(t){let e=rr(t),r=Pr.defaults?.search||{};return{force_text_field:e?.search?.force_text_field??r.force_text_field??!1}}function Pv(t){return rr(t)?.search?.force_text_field!==void 0}function Uf(t){return mn(t)}function Oa(t){let e=Pr.portals.find(r=>[r.api_url,...r.api_url_aliases||[]].some(o=>FA(o)===t));return e?mn(e.api_url):null}function co(t){return rr(t)?.hvd??null}function Av(t){let e=mn(t);return Pr.portals.find(n=>n.sparql&&mn(n.sparql.endpoint_url)===e)?.sparql??null}function Ov(t){return rr(t)?.sparql??null}function hn(t){return rr(t)?.api_path||"/api/3/action"}function Ff(t){return rr(t)?.normalize==="multilingual"}var HA=(()=>{let t=null;return async()=>(t||(t=(async()=>{try{return await import("node:zlib")}catch{return null}})()),t)})();function Cv(t,e){if(!t)return;let r=e.toLowerCase();for(let[n,o]of Object.entries(t))if(n.toLowerCase()===r)return Array.isArray(o)?o.join(","):String(o)}function VA(t){if(t&&!(typeof Buffer>"u")){if(Buffer.isBuffer(t))return t;if(t instanceof ArrayBuffer)return Buffer.from(t);if(ArrayBuffer.isView(t))return Buffer.from(t.buffer,t.byteOffset,t.byteLength)}}function BA(t){if(t){if(t instanceof ArrayBuffer)return t;if(ArrayBuffer.isView(t))return t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength)}}async function KA(t,e){if(e&&typeof DecompressionStream<"u")try{let r=new DecompressionStream(e.includes("br")?"br":e.includes("deflate")?"deflate":"gzip"),n=await new Response(new Blob([t]).stream().pipeThrough(r)).arrayBuffer();return new TextDecoder("utf-8").decode(n).trim()}catch{}return new TextDecoder("utf-8").decode(t).trim()}async function Nv(t,e){if(t==null)return t;let r=BA(t);if(r&&typeof Buffer>"u"){let c=Cv(e,"content-encoding"),u=await KA(r,c);if(!u)return u;try{return JSON.parse(u)}catch{return u}}if(typeof t=="string")try{return JSON.parse(t)}catch{return t}let n=VA(t);if(!n)return t;let o=Cv(e,"content-encoding"),s=n,i=await HA();try{i&&(o?.includes("gzip")?s=i.gunzipSync(n):o?.includes("br")?s=i.brotliDecompressSync(n):o?.includes("deflate")?s=i.inflateSync(n):n.length>=2&&n[0]===31&&n[1]===139&&(s=i.gunzipSync(n)))}catch{s=n}let a=s.toString("utf-8").trim();if(!a)return a;try{return JSON.parse(a)}catch{return a}}function Hf(t){let e;try{e=new URL(t)}catch{throw new Error(`Invalid URL: ${t}`)}if(e.protocol!=="http:"&&e.protocol!=="https:")throw new Error(`Disallowed protocol "${e.protocol}". Only http and https are allowed.`);let r=e.hostname.toLowerCase();if(r==="localhost")throw new Error(`Access to "${r}" is not allowed.`);let n=r.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);if(n){let[o,s]=n.slice(1).map(Number);if(o===0||o===10||o===127||o===100&&s>=64&&s<=127||o===169&&s===254||o===172&&s>=16&&s<=31||o===192&&s===168||o===255)throw new Error("Access to private/internal IP addresses is not allowed.")}if(r.startsWith("[")){let s=r.slice(1,-1).toLowerCase();if(s==="::1"||s==="::"||s.startsWith("fc")||s.startsWith("fd")||s.startsWith("fe80")||s.startsWith("::ffff:"))throw new Error("Access to private/internal IPv6 addresses is not allowed.")}}async function F(t,e,r={}){let n=typeof process<"u"&&!!process.versions?.node;Hf(t);let o=t;try{let c=new URL(t).hostname,u=Oa(c);u&&(o=u)}catch{}let s=o.replace(/\/$/,""),i=hn(o),a=`${s}${i}/${e}`;try{let c;if(n){let u=await Ft.get(a,{params:r,timeout:3e4,responseType:"arraybuffer",headers:{Accept:"application/json, text/plain, */*","Accept-Language":"en-US,en;q=0.9,it;q=0.8","Accept-Encoding":"gzip, deflate, br",Connection:"keep-alive","Sec-CH-UA":'"Chromium";v="120", "Not?A_Brand";v="24", "Google Chrome";v="120"',"Sec-CH-UA-Mobile":"?0","Sec-CH-UA-Platform":'"Linux"',"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}});c=await Nv(u.data,u.headers)}else{let u=new URLSearchParams;for(let[g,_]of Object.entries(r))_!=null&&u.set(g,String(_));let l=u.toString()?`${a}?${u.toString()}`:a,d=new AbortController,p=setTimeout(()=>d.abort(),3e4),h;try{h=await fetch(l,{method:"GET",signal:d.signal,headers:{Accept:"application/json, text/plain, */*","Accept-Encoding":"identity","User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}})}finally{clearTimeout(p)}if(!h.ok)throw new Error(`CKAN API error (${h.status}): ${h.statusText}`);let f=await h.arrayBuffer(),m={};h.headers.forEach((g,_)=>{m[_]=g}),c=await Nv(f,m)}if(c&&c.success===!0)return c.result;throw new Error(`CKAN API returned success=false: ${JSON.stringify(c)}`)}catch(c){if(Ft.isAxiosError(c)){let u=c;if(u.response){let l=u.response.status,d=u.response.data,p=d?.error?.message||d?.error||"Unknown error";throw new Error(`CKAN API error (${l}): ${p}`)}else throw u.code==="ECONNABORTED"?new Error(`Request timeout connecting to ${t}`):u.code==="ENOTFOUND"?new Error(`Server not found: ${t}`):new Error(`Network error: ${u.message}`)}throw c}}function W(t,e=Rr){return t.length<=e?t:t.substring(0,e)+`
44
+ `+s):n.stack=s}catch{}}throw n}}_request(e,r){typeof e=="string"?(r=r||{},r.url=e):r=e||{},r=zt(this.defaults,r);let{transitional:n,paramsSerializer:o,headers:s}=r;n!==void 0&&ks.assertOptions(n,{silentJSONParsing:Ut.transitional(Ut.boolean),forcedJSONParsing:Ut.transitional(Ut.boolean),clarifyTimeoutError:Ut.transitional(Ut.boolean)},!1),o!=null&&(y.isFunction(o)?r.paramsSerializer={serialize:o}:ks.assertOptions(o,{encode:Ut.function,serialize:Ut.function},!0)),r.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?r.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:r.allowAbsoluteUrls=!0),ks.assertOptions(r,{baseUrl:Ut.spelling("baseURL"),withXsrfToken:Ut.spelling("withXSRFToken")},!0),r.method=(r.method||this.defaults.method||"get").toLowerCase();let i=s&&y.merge(s.common,s[r.method]);s&&y.forEach(["delete","get","head","post","put","patch","common"],f=>{delete s[f]}),r.headers=Te.concat(i,s);let a=[],c=!0;this.interceptors.request.forEach(function(m){typeof m.runWhen=="function"&&m.runWhen(r)===!1||(c=c&&m.synchronous,a.unshift(m.fulfilled,m.rejected))});let u=[];this.interceptors.response.forEach(function(m){u.push(m.fulfilled,m.rejected)});let l,d=0,p;if(!c){let f=[Ea.bind(this),void 0];for(f.unshift(...a),f.push(...u),p=f.length,l=Promise.resolve(r);d<p;)l=l.then(f[d++],f[d++]);return l}p=a.length;let h=r;for(;d<p;){let f=a[d++],m=a[d++];try{h=f(h)}catch(g){m.call(this,g);break}}try{l=Ea.call(this,h)}catch(f){return Promise.reject(f)}for(d=0,p=u.length;d<p;)l=l.then(u[d++],u[d++]);return l}getUri(e){e=zt(this.defaults,e);let r=xs(e.baseURL,e.url,e.allowAbsoluteUrls);return ys(r,e.params,e.paramsSerializer)}};y.forEach(["delete","get","head","options"],function(e){ao.prototype[e]=function(r,n){return this.request(zt(n||{},{method:e,url:r,data:(n||{}).data}))}});y.forEach(["post","put","patch"],function(e){function r(n){return function(s,i,a){return this.request(zt(a||{},{method:e,headers:n?{"Content-Type":"multipart/form-data"}:{},url:s,data:i}))}}ao.prototype[e]=r(),ao.prototype[e+"Form"]=r(!0)});var Ss=ao;var qf=class t{constructor(e){if(typeof e!="function")throw new TypeError("executor must be a function.");let r;this.promise=new Promise(function(s){r=s});let n=this;this.promise.then(o=>{if(!n._listeners)return;let s=n._listeners.length;for(;s-- >0;)n._listeners[s](o);n._listeners=null}),this.promise.then=o=>{let s,i=new Promise(a=>{n.subscribe(a),s=a}).then(o);return i.cancel=function(){n.unsubscribe(s)},i},e(function(s,i,a){n.reason||(n.reason=new Lt(s,i,a),r(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;let r=this._listeners.indexOf(e);r!==-1&&this._listeners.splice(r,1)}toAbortSignal(){let e=new AbortController,r=n=>{e.abort(n)};return this.subscribe(r),e.signal.unsubscribe=()=>this.unsubscribe(r),e.signal}static source(){let e;return{token:new t(function(o){e=o}),cancel:e}}},zv=qf;function Df(t){return function(r){return t.apply(null,r)}}function Zf(t){return y.isObject(t)&&t.isAxiosError===!0}var Lf={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(Lf).forEach(([t,e])=>{Lf[e]=t});var Tv=Lf;function Rv(t){let e=new Ss(t),r=ps(Ss.prototype.request,e);return y.extend(r,Ss.prototype,e,{allOwnKeys:!0}),y.extend(r,e,null,{allOwnKeys:!0}),r.create=function(o){return Rv(zt(t,o))},r}var $e=Rv(oo);$e.Axios=Ss;$e.CanceledError=Lt;$e.CancelToken=zv;$e.isCancel=bs;$e.VERSION=Pa;$e.toFormData=Er;$e.AxiosError=Z;$e.Cancel=$e.CanceledError;$e.all=function(e){return Promise.all(e)};$e.spread=Df;$e.isAxiosError=Zf;$e.mergeConfig=zt;$e.AxiosHeaders=Te;$e.formToJSON=t=>Sa(y.isHTMLForm(t)?new FormData(t):t);$e.getAdapter=Ra.getAdapter;$e.HttpStatusCode=Tv;$e.default=$e;var Ft=$e;var{Axios:t2,AxiosError:r2,CanceledError:n2,isCancel:o2,CancelToken:s2,VERSION:i2,all:a2,Cancel:c2,isAxiosError:u2,spread:l2,toFormData:d2,AxiosHeaders:f2,HttpStatusCode:p2,formToJSON:m2,getAdapter:h2,mergeConfig:g2}=Ft;var Pr={portals:[{id:"dati-gov-it",name:"dati.gov.it",api_url:"https://www.dati.gov.it/opendata",api_url_aliases:["https://dati.gov.it/opendata","http://www.dati.gov.it/opendata","http://dati.gov.it/opendata","https://dati.gov.it","https://www.dati.gov.it"],search:{force_text_field:!0},hvd:{category_field:"hvd_category"},sparql:{endpoint_url:"https://lod.dati.gov.it/sparql",method:"GET"},dataset_view_url:"https://www.dati.gov.it/view-dataset/dataset?id={id}",organization_view_url:"https://www.dati.gov.it/view-dataset?organization={name}"},{id:"dati-arpae-it",name:"dati.arpae.it",api_url:"https://dati.arpae.it",api_url_aliases:["http://dati.arpae.it"],search:{force_text_field:!0}},{id:"anac-opendata",name:"dati.anticorruzione.it/opendata",api_url:"https://dati.anticorruzione.it/opendata",api_url_aliases:["http://dati.anticorruzione.it/opendata","https://dati.anticorruzione.it","http://dati.anticorruzione.it"]},{id:"data-gov-uk",name:"data.gov.uk",api_url:"https://data.gov.uk",api_url_aliases:["https://www.data.gov.uk","http://data.gov.uk","http://www.data.gov.uk"],api_path:"/api/action",search:{force_text_field:!0},dataset_view_url:"https://www.data.gov.uk/dataset/{id}/{name}",organization_view_url:"https://www.data.gov.uk/organization/{name}"},{id:"catalog-data-gov",name:"catalog.data.gov",api_url:"https://catalog.data.gov",api_url_aliases:["http://catalog.data.gov"],search:{force_text_field:!0}},{id:"open-canada",name:"open.canada.ca",api_url:"https://open.canada.ca/data",api_url_aliases:["http://open.canada.ca/data","https://open.canada.ca","http://open.canada.ca"],search:{force_text_field:!0}},{id:"data-gov-au",name:"data.gov.au",api_url:"https://data.gov.au",api_url_aliases:["http://data.gov.au","https://www.data.gov.au","http://www.data.gov.au"],dataset_view_url:"https://data.gov.au/data/dataset/{name}",organization_view_url:"https://data.gov.au/data/organization/{name}"},{id:"opendata-swiss",name:"opendata.swiss",api_url:"https://ckan.opendata.swiss",api_url_aliases:["https://opendata.swiss","http://opendata.swiss","https://www.opendata.swiss","http://www.opendata.swiss"]},{id:"data-stadt-zuerich-ch",name:"data.stadt-zuerich.ch",api_url:"https://data.stadt-zuerich.ch",api_url_aliases:["http://data.stadt-zuerich.ch","https://www.data.stadt-zuerich.ch","https://ckan-prod.zurich.datopian.com"],organization_view_url:"https://ckan-prod.zurich.datopian.com/organization/{name}"},{id:"data-gov-ua",name:"data.gov.ua",api_url:"https://data.gov.ua",api_url_aliases:["http://data.gov.ua"],search:{force_text_field:!1}},{id:"govdata-de",name:"govdata.de",api_url:"https://ckan.govdata.de",api_url_aliases:["https://www.govdata.de","https://govdata.de","https://www.govdata.de/daten","https://data.gov.de","https://www.data.gov.de"],dataset_view_url:"https://ckan.govdata.de/dataset/{name}",organization_view_url:"https://ckan.govdata.de/organization/{name}"}],defaults:{dataset_view_url:"{server_url}/dataset/{name}",organization_view_url:"{server_url}/organization/{name}",search:{force_text_field:!1}}};function mn(t){return t.replace(/\/$/,"")}function FA(t){try{return new URL(t).hostname}catch{return null}}function rr(t){let e=mn(t);return Pr.portals.find(n=>{let o=mn(n.api_url),s=(n.api_url_aliases||[]).map(mn);return o===e||s.includes(e)})||null}function Ev(t){let e=rr(t),r=Pr.defaults?.search||{};return{force_text_field:e?.search?.force_text_field??r.force_text_field??!1}}function Pv(t){return rr(t)?.search?.force_text_field!==void 0}function Uf(t){return mn(t)}function Oa(t){let e=Pr.portals.find(r=>[r.api_url,...r.api_url_aliases||[]].some(o=>FA(o)===t));return e?mn(e.api_url):null}function co(t){return rr(t)?.hvd??null}function Av(t){let e=mn(t);return Pr.portals.find(n=>n.sparql&&mn(n.sparql.endpoint_url)===e)?.sparql??null}function Ov(t){return rr(t)?.sparql??null}function hn(t){return rr(t)?.api_path||"/api/3/action"}function Ff(t){return rr(t)?.normalize==="multilingual"}var HA=(()=>{let t=null;return async()=>(t||(t=(async()=>{try{return await import("node:zlib")}catch{return null}})()),t)})();function Cv(t,e){if(!t)return;let r=e.toLowerCase();for(let[n,o]of Object.entries(t))if(n.toLowerCase()===r)return Array.isArray(o)?o.join(","):String(o)}function VA(t){if(t&&!(typeof Buffer>"u")){if(Buffer.isBuffer(t))return t;if(t instanceof ArrayBuffer)return Buffer.from(t);if(ArrayBuffer.isView(t))return Buffer.from(t.buffer,t.byteOffset,t.byteLength)}}function BA(t){if(t){if(t instanceof ArrayBuffer)return t;if(ArrayBuffer.isView(t))return t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength)}}async function KA(t,e){if(e&&typeof DecompressionStream<"u")try{let r=new DecompressionStream(e.includes("br")?"br":e.includes("deflate")?"deflate":"gzip"),n=await new Response(new Blob([t]).stream().pipeThrough(r)).arrayBuffer();return new TextDecoder("utf-8").decode(n).trim()}catch{}return new TextDecoder("utf-8").decode(t).trim()}async function Nv(t,e){if(t==null)return t;let r=BA(t);if(r&&typeof Buffer>"u"){let c=Cv(e,"content-encoding"),u=await KA(r,c);if(!u)return u;try{return JSON.parse(u)}catch{return u}}if(typeof t=="string")try{return JSON.parse(t)}catch{return t}let n=VA(t);if(!n)return t;let o=Cv(e,"content-encoding"),s=n,i=await HA();try{i&&(o?.includes("gzip")?s=i.gunzipSync(n):o?.includes("br")?s=i.brotliDecompressSync(n):o?.includes("deflate")?s=i.inflateSync(n):n.length>=2&&n[0]===31&&n[1]===139&&(s=i.gunzipSync(n)))}catch{s=n}let a=s.toString("utf-8").trim();if(!a)return a;try{return JSON.parse(a)}catch{return a}}function Hf(t){let e;try{e=new URL(t)}catch{throw new Error(`Invalid URL: ${t}`)}if(e.protocol!=="http:"&&e.protocol!=="https:")throw new Error(`Disallowed protocol "${e.protocol}". Only http and https are allowed.`);let r=e.hostname.toLowerCase();if(r==="localhost")throw new Error(`Access to "${r}" is not allowed.`);let n=r.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);if(n){let[o,s]=n.slice(1).map(Number);if(o===0||o===10||o===127||o===100&&s>=64&&s<=127||o===169&&s===254||o===172&&s>=16&&s<=31||o===192&&s===168||o===255)throw new Error("Access to private/internal IP addresses is not allowed.")}if(r.startsWith("[")){let s=r.slice(1,-1).toLowerCase();if(s==="::1"||s==="::"||s.startsWith("fc")||s.startsWith("fd")||s.startsWith("fe80")||s.startsWith("::ffff:"))throw new Error("Access to private/internal IPv6 addresses is not allowed.")}}async function F(t,e,r={}){let n=typeof process<"u"&&!!process.versions?.node;Hf(t);let o=t;try{let c=new URL(t).hostname,u=Oa(c);u&&(o=u)}catch{}let s=o.replace(/\/$/,""),i=hn(o),a=`${s}${i}/${e}`;try{let c;if(n){let u=await Ft.get(a,{params:r,timeout:3e4,responseType:"arraybuffer",headers:{Accept:"application/json, text/plain, */*","Accept-Language":"en-US,en;q=0.9,it;q=0.8","Accept-Encoding":"gzip, deflate, br",Connection:"keep-alive","Sec-CH-UA":'"Chromium";v="120", "Not?A_Brand";v="24", "Google Chrome";v="120"',"Sec-CH-UA-Mobile":"?0","Sec-CH-UA-Platform":'"Linux"',"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}});c=await Nv(u.data,u.headers)}else{let u=new URLSearchParams;for(let[g,_]of Object.entries(r))_!=null&&u.set(g,String(_));let l=u.toString()?`${a}?${u.toString()}`:a,d=new AbortController,p=setTimeout(()=>d.abort(),3e4),h;try{h=await fetch(l,{method:"GET",signal:d.signal,headers:{Accept:"application/json, text/plain, */*","Accept-Encoding":"identity","User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}})}finally{clearTimeout(p)}if(!h.ok)throw new Error(`CKAN API error (${h.status}): ${h.statusText}`);let f=await h.arrayBuffer(),m={};h.headers.forEach((g,_)=>{m[_]=g}),c=await Nv(f,m)}if(c&&c.success===!0)return c.result;throw new Error(`CKAN API returned success=false: ${JSON.stringify(c)}`)}catch(c){if(Ft.isAxiosError(c)){let u=c;if(u.response){let l=u.response.status,d=u.response.data,p=d?.error?.message||d?.error||"Unknown error";throw new Error(`CKAN API error (${l}): ${p}`)}else throw u.code==="ECONNABORTED"?new Error(`Request timeout connecting to ${t}`):u.code==="ENOTFOUND"?new Error(`Server not found: ${t}`):new Error(`Network error: ${u.message}`)}throw c}}function W(t,e=Rr){return t.length<=e?t:t.substring(0,e)+`
45
45
 
46
46
  ... [Response truncated at ${e} characters]`}function nt(t,e=Rr){let r=JSON.stringify(t,null,2);if(r.length<=e||(r=JSON.stringify(t),r.length<=e))return r;let n=structuredClone(t),o=["results","records","resources","packages","organizations","groups","tags"];for(let s of o)if(Array.isArray(n[s])&&n[s].length>0){let i=n[s].length;for(;n[s].length>1;)if(n[s].pop(),n._truncated=!0,n._original_count=i,r=JSON.stringify(n),r.length<=e)return r}return W(JSON.stringify(n),e)}function Xe(t){try{if(!t)return"Invalid Date";let e=new Date(t);return Number.isNaN(e.getTime())?"Invalid Date":e.toISOString().slice(0,10)}catch{return"Invalid Date"}}function Iv(t){if(!t||t===0)return"0 B";let e=1024,r=["B","KB","MB","GB"],n=Math.floor(Math.log(t)/Math.log(e));return parseFloat((t/Math.pow(e,n)).toFixed(2))+" "+r[n]}function JA(){try{return typeof WorkerGlobalScope<"u"}catch{return!1}}function se(t){return JA()?t+`
47
47
 
@@ -225,7 +225,13 @@ Examples:
225
225
  - Filter extras OR (correct): { fq: "extras_hvd_category:("http://data.europa.eu/bna/c_ac64a52d" OR "http://data.europa.eu/bna/c_dd313021")" }
226
226
  - Get facets: { facet_field: ["organization"], rows: 0 }
227
227
 
228
- Typical workflow: ckan_package_search \u2192 ckan_package_show (get full metadata + resource IDs) \u2192 ckan_datastore_search (query tabular data)`,inputSchema:v.object({server_url:v.string().url("Must be a valid URL").describe("Base URL of the CKAN server"),q:v.string().optional().default("*:*").describe("Search query in Solr syntax"),fq:v.string().optional().describe(`Filter query in Solr syntax; applied after scoring, does not affect relevance. CKAN extras fields use prefix 'extras_' (e.g. extras_hvd_category). For OR on same field use field:(val1 OR val2), never field:val1 OR field:val2 (silently breaks). Examples: 'organization:comune-palermo', 'res_format:CSV', 'extras_hvd_category:("uri1" OR "uri2")'.`),rows:v.coerce.number().int().min(0).max(1e3).optional().default(10).describe("Number of results to return"),start:v.coerce.number().int().min(0).optional().default(0).describe("Offset for pagination"),sort:v.string().optional().describe("Sort field and direction (e.g., 'metadata_modified desc')"),facet_field:v.array(v.string()).optional().describe("Fields to facet on"),facet_limit:v.coerce.number().int().min(1).optional().default(50).describe("Maximum facet values per field"),page:v.coerce.number().int().min(1).optional().describe("Page number (1-based); alias for start. Overrides start if provided."),page_size:v.coerce.number().int().min(1).max(1e3).optional().default(10).describe("Results per page when using page (default: 10)"),include_drafts:v.boolean().optional().default(!1).describe("Include draft datasets"),content_recent:v.boolean().optional().default(!1).describe("Use issued date with fallback to metadata_created for recent content"),content_recent_days:v.coerce.number().int().min(1).optional().default(30).describe("Day window for content_recent (default 30)"),query_parser:v.enum(["default","text"]).optional().describe("Override search parser ('text' forces text:(...) on non-fielded queries)"),response_format:fe}).strict(),annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!0}},async e=>{try{let r=e.q,n=r,o=e.sort;if(e.content_recent){let m=e.content_recent_days??30,g=new Date;g.setUTCDate(g.getUTCDate()-m);let _=g.toISOString(),x=new Date().toISOString(),k=`(issued:[${_} TO ${x}]) OR (-issued:* AND metadata_created:[NOW-${m}DAYS TO NOW])`;n=r&&r!=="*:*"?`(${r}) AND (${k})`:k,o||(o="issued desc, metadata_created desc")}let s=e.query_parser;!s&&!Pv(e.server_url)&&await tO(e.server_url)&&(s="text");let{effectiveQuery:i}=Na(e.server_url,n,s),{effectiveRows:a,effectiveStart:c}=aO(e.page,e.page_size,e.start,e.rows),u={q:Zv(i),rows:a,start:c,include_private:e.include_drafts};e.fq&&(u.fq=Zv(e.fq)),o&&(u.sort=o),e.facet_field&&e.facet_field.length>0&&(u["facet.field"]=JSON.stringify(e.facet_field),u["facet.limit"]=e.facet_limit);let l=await F(e.server_url,"package_search",u),d=!1;if(l.count===0&&Dv(e.q)){let m=Ca(e.q),{effectiveQuery:g}=Na(e.server_url,m,e.query_parser),_=await F(e.server_url,"package_search",{...u,q:g});_.count>0&&(l=_,d=!0)}if(e.response_format==="json"){let m=uO(l,e.server_url);return{content:[{type:"text",text:nt(m)}]}}let p="";if((e.q==="*:*"||e.q===void 0)&&(a===0||e.facet_field&&e.facet_field.some(m=>["organization","tags","groups","res_format"].includes(m)))){let m=co(e.server_url);if(m)try{let g=await F(e.server_url,"package_search",{q:`${m.category_field}:*`,rows:0});g.count>0&&(p=`> **High Value Datasets (HVD)**: This portal contains **${g.count} datasets** classified as High Value Datasets under EU Regulation 2023/138.
228
+ Query language:
229
+ Before searching a portal, check its locale via ckan_status_show (field: "Portal Locale" / locale_default).
230
+ Translate query terms to the portal's language \u2014 searching in English on a non-English portal returns 0 results.
231
+ Examples: locale "it" \u2192 Italian terms; "uk_UA" \u2192 Ukrainian (Cyrillic); "fr_FR" \u2192 French.
232
+ Exception: multilingual portals (e.g. data.europa.eu, open.canada.ca) accept EN + native terms joined with OR.
233
+
234
+ Typical workflow: ckan_status_show (check locale) \u2192 ckan_package_search (query in portal's language) \u2192 ckan_package_show (get full metadata + resource IDs) \u2192 ckan_datastore_search (query tabular data)`,inputSchema:v.object({server_url:v.string().url("Must be a valid URL").describe("Base URL of the CKAN server"),q:v.string().optional().default("*:*").describe("Search query in Solr syntax"),fq:v.string().optional().describe(`Filter query in Solr syntax; applied after scoring, does not affect relevance. CKAN extras fields use prefix 'extras_' (e.g. extras_hvd_category). For OR on same field use field:(val1 OR val2), never field:val1 OR field:val2 (silently breaks). Examples: 'organization:comune-palermo', 'res_format:CSV', 'extras_hvd_category:("uri1" OR "uri2")'.`),rows:v.coerce.number().int().min(0).max(1e3).optional().default(10).describe("Number of results to return"),start:v.coerce.number().int().min(0).optional().default(0).describe("Offset for pagination"),sort:v.string().optional().describe("Sort field and direction (e.g., 'metadata_modified desc')"),facet_field:v.array(v.string()).optional().describe("Fields to facet on"),facet_limit:v.coerce.number().int().min(1).optional().default(50).describe("Maximum facet values per field"),page:v.coerce.number().int().min(1).optional().describe("Page number (1-based); alias for start. Overrides start if provided."),page_size:v.coerce.number().int().min(1).max(1e3).optional().default(10).describe("Results per page when using page (default: 10)"),include_drafts:v.boolean().optional().default(!1).describe("Include draft datasets"),content_recent:v.boolean().optional().default(!1).describe("Use issued date with fallback to metadata_created for recent content"),content_recent_days:v.coerce.number().int().min(1).optional().default(30).describe("Day window for content_recent (default 30)"),query_parser:v.enum(["default","text"]).optional().describe("Override search parser ('text' forces text:(...) on non-fielded queries)"),response_format:fe}).strict(),annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!0}},async e=>{try{let r=e.q,n=r,o=e.sort;if(e.content_recent){let m=e.content_recent_days??30,g=new Date;g.setUTCDate(g.getUTCDate()-m);let _=g.toISOString(),x=new Date().toISOString(),k=`(issued:[${_} TO ${x}]) OR (-issued:* AND metadata_created:[NOW-${m}DAYS TO NOW])`;n=r&&r!=="*:*"?`(${r}) AND (${k})`:k,o||(o="issued desc, metadata_created desc")}let s=e.query_parser;!s&&!Pv(e.server_url)&&await tO(e.server_url)&&(s="text");let{effectiveQuery:i}=Na(e.server_url,n,s),{effectiveRows:a,effectiveStart:c}=aO(e.page,e.page_size,e.start,e.rows),u={q:Zv(i),rows:a,start:c,include_private:e.include_drafts};e.fq&&(u.fq=Zv(e.fq)),o&&(u.sort=o),e.facet_field&&e.facet_field.length>0&&(u["facet.field"]=JSON.stringify(e.facet_field),u["facet.limit"]=e.facet_limit);let l=await F(e.server_url,"package_search",u),d=!1;if(l.count===0&&Dv(e.q)){let m=Ca(e.q),{effectiveQuery:g}=Na(e.server_url,m,e.query_parser),_=await F(e.server_url,"package_search",{...u,q:g});_.count>0&&(l=_,d=!0)}if(e.response_format==="json"){let m=uO(l,e.server_url);return{content:[{type:"text",text:nt(m)}]}}let p="";if((e.q==="*:*"||e.q===void 0)&&(a===0||e.facet_field&&e.facet_field.some(m=>["organization","tags","groups","res_format"].includes(m)))){let m=co(e.server_url);if(m)try{let g=await F(e.server_url,"package_search",{q:`${m.category_field}:*`,rows:0});g.count>0&&(p=`> **High Value Datasets (HVD)**: This portal contains **${g.count} datasets** classified as High Value Datasets under EU Regulation 2023/138.
229
235
 
230
236
  `)}catch{}}let f=`# CKAN Package Search Results
231
237
 
@@ -607,6 +613,7 @@ Typical workflow: ckan_package_show (get resource_id) \u2192 ckan_datastore_sear
607
613
 
608
614
  Security note: SQL queries are forwarded directly to the CKAN DataStore API. The CKAN server enforces its own access controls and read-only permissions. No local database is exposed. Queries are limited to public DataStore resources on the target portal.`,inputSchema:v.object({server_url:v.string().url().describe("Base URL of the CKAN server (e.g., https://dati.gov.it/opendata)"),sql:v.string().min(1).describe('SQL SELECT query; resource_id is the table name, must be double-quoted (e.g., SELECT * FROM "abc-123" LIMIT 10)'),response_format:fe}).strict(),annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},async e=>{try{let r=await F(e.server_url,"datastore_search_sql",{sql:e.sql});if(e.response_format==="json"){let o=Wv(r);return{content:[{type:"text",text:nt(o)}],structuredContent:o}}let n=hO(r,e.server_url,e.sql);return{content:[{type:"text",text:W(se(n))}]}}catch(r){return{content:[{type:"text",text:`Error querying DataStore SQL: ${r instanceof Error?r.message:String(r)}`}],isError:!0}}})}function gO(t,e,r){let n=Ov(e),o=n?`**SPARQL Endpoint**: ${n.endpoint_url}
609
615
  `:"",s=r!==void 0?`**HVD Datasets**: ${r}
616
+ `:"",i=t.locale_default?`**Portal Locale**: ${t.locale_default}
610
617
  `:"";return`# CKAN Server Status
611
618
 
612
619
  **Server**: ${e}
@@ -614,7 +621,7 @@ Security note: SQL queries are forwarded directly to the CKAN DataStore API. The
614
621
  **CKAN Version**: ${t.ckan_version||"Unknown"}
615
622
  **Site Title**: ${t.site_title||"N/A"}
616
623
  **Site URL**: ${t.site_url||"N/A"}
617
- `+o+s}function Qv(t){t.registerTool("ckan_status_show",{title:"Check CKAN Server Status",description:`Check if a CKAN server is available and get version information.
624
+ `+i+o+s}function Qv(t){t.registerTool("ckan_status_show",{title:"Check CKAN Server Status",description:`Check if a CKAN server is available and get version information.
618
625
 
619
626
  Useful to verify server accessibility before making other requests.
620
627
  Also shows the count of High-Value Datasets (HVD) when the portal supports it.
@@ -1086,7 +1093,7 @@ ckan_package_search({
1086
1093
  })
1087
1094
  \`\`\`
1088
1095
 
1089
- If the portal supports HVD classification, look for datasets with fields like \`hvd_category\` or \`applicable_legislation\`.`,Sb=t=>{t.registerPrompt(sC,{title:"Search High-Value Datasets (HVD)",description:"Guided prompt to find High-Value Datasets (HVD) on a CKAN portal. Automatically uses the correct filter field from portal configuration.",argsSchema:{server_url:v.string().url().describe("Base URL of the CKAN server"),rows:v.coerce.number().int().positive().default(10).describe("Max results to return")}},async({server_url:e,rows:r})=>{let n=co(e);return ht(iC(e,r,n?.category_field??null))})};var $b=t=>{vb(t),bb(t),wb(t),xb(t),kb(t),Sb(t)};function zb(){return new ga({name:"ckan-mcp-server",version:"0.4.93"})}function Tb(t){Kv(t),Jv(t),Gv(t),Qv(t),Yv(t),eb(t),ib(t),ab(t),cb(t),ub(t),lb(t),_b(t),$b(t)}var qa=class{constructor(e={}){this._started=!1,this._hasHandledRequest=!1,this._streamMapping=new Map,this._requestToStreamMapping=new Map,this._requestResponseMap=new Map,this._initialized=!1,this._enableJsonResponse=!1,this._standaloneSseStreamId="_GET_stream",this.sessionIdGenerator=e.sessionIdGenerator,this._enableJsonResponse=e.enableJsonResponse??!1,this._eventStore=e.eventStore,this._onsessioninitialized=e.onsessioninitialized,this._onsessionclosed=e.onsessionclosed,this._allowedHosts=e.allowedHosts,this._allowedOrigins=e.allowedOrigins,this._enableDnsRebindingProtection=e.enableDnsRebindingProtection??!1,this._retryInterval=e.retryInterval}async start(){if(this._started)throw new Error("Transport already started");this._started=!0}createJsonErrorResponse(e,r,n,o){let s={code:r,message:n};return o?.data!==void 0&&(s.data=o.data),new Response(JSON.stringify({jsonrpc:"2.0",error:s,id:null}),{status:e,headers:{"Content-Type":"application/json",...o?.headers}})}validateRequestHeaders(e){if(this._enableDnsRebindingProtection){if(this._allowedHosts&&this._allowedHosts.length>0){let r=e.headers.get("host");if(!r||!this._allowedHosts.includes(r)){let n=`Invalid Host header: ${r}`;return this.onerror?.(new Error(n)),this.createJsonErrorResponse(403,-32e3,n)}}if(this._allowedOrigins&&this._allowedOrigins.length>0){let r=e.headers.get("origin");if(r&&!this._allowedOrigins.includes(r)){let n=`Invalid Origin header: ${r}`;return this.onerror?.(new Error(n)),this.createJsonErrorResponse(403,-32e3,n)}}}}async handleRequest(e,r){if(!this.sessionIdGenerator&&this._hasHandledRequest)throw new Error("Stateless transport cannot be reused across requests. Create a new transport per request.");this._hasHandledRequest=!0;let n=this.validateRequestHeaders(e);if(n)return n;switch(e.method){case"POST":return this.handlePostRequest(e,r);case"GET":return this.handleGetRequest(e);case"DELETE":return this.handleDeleteRequest(e);default:return this.handleUnsupportedRequest()}}async writePrimingEvent(e,r,n,o){if(!this._eventStore||o<"2025-11-25")return;let s=await this._eventStore.storeEvent(n,{}),i=`id: ${s}
1096
+ If the portal supports HVD classification, look for datasets with fields like \`hvd_category\` or \`applicable_legislation\`.`,Sb=t=>{t.registerPrompt(sC,{title:"Search High-Value Datasets (HVD)",description:"Guided prompt to find High-Value Datasets (HVD) on a CKAN portal. Automatically uses the correct filter field from portal configuration.",argsSchema:{server_url:v.string().url().describe("Base URL of the CKAN server"),rows:v.coerce.number().int().positive().default(10).describe("Max results to return")}},async({server_url:e,rows:r})=>{let n=co(e);return ht(iC(e,r,n?.category_field??null))})};var $b=t=>{vb(t),bb(t),wb(t),xb(t),kb(t),Sb(t)};function zb(){return new ga({name:"ckan-mcp-server",version:"0.4.95"})}function Tb(t){Kv(t),Jv(t),Gv(t),Qv(t),Yv(t),eb(t),ib(t),ab(t),cb(t),ub(t),lb(t),_b(t),$b(t)}var qa=class{constructor(e={}){this._started=!1,this._hasHandledRequest=!1,this._streamMapping=new Map,this._requestToStreamMapping=new Map,this._requestResponseMap=new Map,this._initialized=!1,this._enableJsonResponse=!1,this._standaloneSseStreamId="_GET_stream",this.sessionIdGenerator=e.sessionIdGenerator,this._enableJsonResponse=e.enableJsonResponse??!1,this._eventStore=e.eventStore,this._onsessioninitialized=e.onsessioninitialized,this._onsessionclosed=e.onsessionclosed,this._allowedHosts=e.allowedHosts,this._allowedOrigins=e.allowedOrigins,this._enableDnsRebindingProtection=e.enableDnsRebindingProtection??!1,this._retryInterval=e.retryInterval}async start(){if(this._started)throw new Error("Transport already started");this._started=!0}createJsonErrorResponse(e,r,n,o){let s={code:r,message:n};return o?.data!==void 0&&(s.data=o.data),new Response(JSON.stringify({jsonrpc:"2.0",error:s,id:null}),{status:e,headers:{"Content-Type":"application/json",...o?.headers}})}validateRequestHeaders(e){if(this._enableDnsRebindingProtection){if(this._allowedHosts&&this._allowedHosts.length>0){let r=e.headers.get("host");if(!r||!this._allowedHosts.includes(r)){let n=`Invalid Host header: ${r}`;return this.onerror?.(new Error(n)),this.createJsonErrorResponse(403,-32e3,n)}}if(this._allowedOrigins&&this._allowedOrigins.length>0){let r=e.headers.get("origin");if(r&&!this._allowedOrigins.includes(r)){let n=`Invalid Origin header: ${r}`;return this.onerror?.(new Error(n)),this.createJsonErrorResponse(403,-32e3,n)}}}}async handleRequest(e,r){if(!this.sessionIdGenerator&&this._hasHandledRequest)throw new Error("Stateless transport cannot be reused across requests. Create a new transport per request.");this._hasHandledRequest=!0;let n=this.validateRequestHeaders(e);if(n)return n;switch(e.method){case"POST":return this.handlePostRequest(e,r);case"GET":return this.handleGetRequest(e);case"DELETE":return this.handleDeleteRequest(e);default:return this.handleUnsupportedRequest()}}async writePrimingEvent(e,r,n,o){if(!this._eventStore||o<"2025-11-25")return;let s=await this._eventStore.storeEvent(n,{}),i=`id: ${s}
1090
1097
  data:
1091
1098
 
1092
1099
  `;this._retryInterval!==void 0&&(i=`id: ${s}
@@ -1280,4 +1287,4 @@ data:
1280
1287
  </div>
1281
1288
  </div>
1282
1289
  </body>
1283
- </html>`,{headers:{"Content-Type":"text/html; charset=utf-8","Access-Control-Allow-Origin":"*"}});if(t.method==="GET"&&e.pathname==="/health")return new Response(JSON.stringify({status:"ok",version:"0.4.93",tools:20,resources:7,prompts:6,runtime:"cloudflare-workers"}),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}});if(e.pathname==="/mcp"){if(t.method!=="POST"&&t.method!=="OPTIONS")return new Response("Method Not Allowed",{status:405,headers:{Allow:"POST, OPTIONS","Access-Control-Allow-Origin":"*"}});if(t.method==="OPTIONS")return new Response(null,{status:204,headers:{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Accept, Authorization, Mcp-Session-Id","Access-Control-Max-Age":"86400"}});try{let r=zb();Tb(r);let n=new qa({sessionIdGenerator:void 0,enableJsonResponse:!0});await r.connect(n);let o=t.clone();try{let a=await o.json();if(a?.method==="tools/call"&&a?.params?.name){let c=a.params.name,u=a.params.arguments??{},l={tool:c,server:u.server_url??u.endpoint_url??""};u.q!==void 0&&(l.q=u.q),u.fq!==void 0&&(l.fq=u.fq),u.query!==void 0&&(l.query=u.query),u.id!==void 0&&(l.id=u.id),u.name!==void 0&&(l.name=u.name),u.pattern!==void 0&&(l.pattern=u.pattern),u.resource_id!==void 0&&(l.resource_id=u.resource_id),u.format_filter!==void 0&&(l.format_filter=u.format_filter),u.sort!==void 0&&(l.sort=u.sort),u.rows!==void 0&&(l.rows=u.rows),u.limit!==void 0&&(l.limit=u.limit),u.sql!==void 0&&(l.sql=String(u.sql).slice(0,200)),u.country!==void 0&&(l.country=u.country),u.language!==void 0&&(l.language=u.language),u.has_datastore!==void 0&&(l.has_datastore=u.has_datastore),u.min_datasets!==void 0&&(l.min_datasets=u.min_datasets),console.log(JSON.stringify(l))}}catch{}let s=await n.handleRequest(t),i=new Headers(s.headers);return i.set("Access-Control-Allow-Origin","*"),i.set("X-Service-Notice","Demo instance - 100k requests/day shared quota"),i.set("X-Recommendation","https://github.com/ondata/ckan-mcp-server#installation"),new Response(s.body,{status:s.status,statusText:s.statusText,headers:i})}catch(r){return console.error("Worker error:",r),new Response(JSON.stringify({jsonrpc:"2.0",error:{code:-32603,message:"Internal error",data:r instanceof Error?r.message:String(r)},id:null}),{status:500,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}}return new Response("Not Found",{status:404,headers:{"Access-Control-Allow-Origin":"*"}})}};export{nF as default};
1290
+ </html>`,{headers:{"Content-Type":"text/html; charset=utf-8","Access-Control-Allow-Origin":"*"}});if(t.method==="GET"&&e.pathname==="/health")return new Response(JSON.stringify({status:"ok",version:"0.4.95",tools:20,resources:7,prompts:6,runtime:"cloudflare-workers"}),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}});if(e.pathname==="/mcp"){if(t.method!=="POST"&&t.method!=="OPTIONS")return new Response("Method Not Allowed",{status:405,headers:{Allow:"POST, OPTIONS","Access-Control-Allow-Origin":"*"}});if(t.method==="OPTIONS")return new Response(null,{status:204,headers:{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, DELETE, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Accept, Authorization, Mcp-Session-Id","Access-Control-Max-Age":"86400"}});try{let r=zb();Tb(r);let n=new qa({sessionIdGenerator:void 0,enableJsonResponse:!0});await r.connect(n);let o=t.clone();try{let a=await o.json();if(a?.method==="tools/call"&&a?.params?.name){let c=a.params.name,u=a.params.arguments??{},l={tool:c,server:u.server_url??u.endpoint_url??""};u.q!==void 0&&(l.q=u.q),u.fq!==void 0&&(l.fq=u.fq),u.query!==void 0&&(l.query=u.query),u.id!==void 0&&(l.id=u.id),u.name!==void 0&&(l.name=u.name),u.pattern!==void 0&&(l.pattern=u.pattern),u.resource_id!==void 0&&(l.resource_id=u.resource_id),u.format_filter!==void 0&&(l.format_filter=u.format_filter),u.sort!==void 0&&(l.sort=u.sort),u.rows!==void 0&&(l.rows=u.rows),u.limit!==void 0&&(l.limit=u.limit),u.sql!==void 0&&(l.sql=String(u.sql).slice(0,200)),u.country!==void 0&&(l.country=u.country),u.language!==void 0&&(l.language=u.language),u.has_datastore!==void 0&&(l.has_datastore=u.has_datastore),u.min_datasets!==void 0&&(l.min_datasets=u.min_datasets),console.log(JSON.stringify(l))}}catch{}let s=await n.handleRequest(t),i=new Headers(s.headers);return i.set("Access-Control-Allow-Origin","*"),i.set("X-Service-Notice","Demo instance - 100k requests/day shared quota"),i.set("X-Recommendation","https://github.com/ondata/ckan-mcp-server#installation"),new Response(s.body,{status:s.status,statusText:s.statusText,headers:i})}catch(r){return console.error("Worker error:",r),new Response(JSON.stringify({jsonrpc:"2.0",error:{code:-32603,message:"Internal error",data:r instanceof Error?r.message:String(r)},id:null}),{status:500,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}}return new Response("Not Found",{status:404,headers:{"Access-Control-Allow-Origin":"*"}})}};export{nF as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aborruso/ckan-mcp-server",
3
- "version": "0.4.94",
3
+ "version": "0.4.96",
4
4
  "mcpName": "io.github.aborruso/ckan-mcp-server",
5
5
  "description": "MCP server for interacting with CKAN open data portals",
6
6
  "main": "dist/index.js",