@pipeworx/mcp-datacube-sk 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  DATAcube — Statistical Office of the Slovak Republic (data.statistics.sk).
4
4
 
5
- Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1683+ live data sources.
5
+ Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1684+ live data sources.
6
6
 
7
7
  ## Tools
8
8
 
@@ -56,7 +56,7 @@ directly, instead of just this one's:
56
56
  }
57
57
  ```
58
58
 
59
- Both URLs reach the same gateway and the same 1683+ data sources. The
59
+ Both URLs reach the same gateway and the same 1684+ data sources. The
60
60
  only difference is which pack's tools are listed **directly**; `ask_pipeworx`
61
61
  reaches all of them from either one.
62
62
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipeworx/mcp-datacube-sk",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "DATAcube — Statistical Office of the Slovak Republic (data.statistics.sk).",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -26,7 +26,7 @@
26
26
  "@cloudflare/workers-types": "^4.20260405.1"
27
27
  },
28
28
  "pipeworx": {
29
- "sourceHash": "v1-6a26ec347402055b95913e0dd78ff13b920ccdf7b2c978d52ddbc5443b52af51",
30
- "sourceCommit": "56d3c46c09bb3078ffdbdbca992a93f406bcd382"
29
+ "sourceHash": "v1-1f5767dfe4a92bdc524970d0bd33d2502d4fd95a7ec3e33a948e5bfff971addc",
30
+ "sourceCommit": "a00767651388cfd017fdeac82188622721db2051"
31
31
  }
32
32
  }
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "io.github.pipeworx-io/datacube-sk",
4
4
  "title": "Datacube Sk",
5
5
  "description": "DATAcube — Statistical Office of the Slovak Republic (data.statistics.sk).",
6
- "version": "0.1.2",
6
+ "version": "0.1.3",
7
7
  "websiteUrl": "https://pipeworx.io/packs/datacube-sk",
8
8
  "repository": {
9
9
  "url": "https://github.com/pipeworx-io/mcp-datacube-sk",
package/src/index.ts CHANGED
@@ -830,17 +830,61 @@ async function getData(args: Record<string, unknown>): Promise<unknown> {
830
830
  throw new Error('selections must be a non-empty array of strings (one per dimension, in dataset_dimensions order). Use dataset_dimensions to find dimension order and valid codes.');
831
831
  }
832
832
  const path = (sel as string[]).map((s) => encodeURIComponent(s.trim())).join('/');
833
- return dcGet(`/dataset/${encodeURIComponent(cube)}/${path}?lang=${lang}`);
833
+ let out: { size?: number[]; id?: string[]; value?: unknown[] | Record<string, unknown> };
834
+ try {
835
+ out = (await dcGet(`/dataset/${encodeURIComponent(cube)}/${path}?lang=${lang}`)) as typeof out;
836
+ } catch (err) {
837
+ // DATAcube answers an unknown cube with 400 {"status_message":"Name API not
838
+ // foud: <cube>"} (sic). That threw as a Pipeworx defect (fleet #2496).
839
+ if (err instanceof DcHttpError && err.status === 400 && /not fou?n?d/i.test(err.body)) {
840
+ return {
841
+ error: 'not_found',
842
+ message: `DATAcube has no cube "${cube}". Call list_datasets({query: "..."}) to find the cube code.`,
843
+ cube,
844
+ };
845
+ }
846
+ throw err;
847
+ }
848
+ // A selection code the cube does not have is NOT an error upstream: DATAcube
849
+ // returns a normal JSON-stat dataset with that dimension's size 0 and no
850
+ // values — a plain success with nothing in it (fleet #2496). Say so.
851
+ const size = Array.isArray(out?.size) ? out.size : [];
852
+ const zeroDims = (out?.id ?? []).filter((_, i) => size[i] === 0);
853
+ const noValues = Array.isArray(out?.value) ? out.value.length === 0 : out?.value != null && Object.keys(out.value).length === 0;
854
+ if (zeroDims.length > 0 || noValues) {
855
+ return {
856
+ ...out,
857
+ empty_reason: 'no_match',
858
+ note:
859
+ `DATAcube cube "${cube}" returned no values for selections ${JSON.stringify(sel)}` +
860
+ `${zeroDims.length ? ` — nothing matched in dimension(s) ${zeroDims.join(', ')}` : ''}. ` +
861
+ `Check the codes with dataset_dimensions({cube: "${cube}"}).`,
862
+ };
863
+ }
864
+ return out;
834
865
  }
835
866
 
836
867
  async function dcGet(path: string): Promise<unknown> {
837
868
  const res = await pwFetch(`${BASE}${path}`, {
838
869
  headers: { Accept: 'application/json', 'User-Agent': UA },
839
870
  });
840
- if (!res.ok) throw new Error(`DATAcube: ${res.status} ${await res.text().then((t) => t.slice(0, 200))}`);
871
+ if (!res.ok) {
872
+ const body = await res.text().then((t) => t.slice(0, 200));
873
+ throw new DcHttpError(res.status, body, `DATAcube: ${res.status} ${body}`);
874
+ }
841
875
  return res.json();
842
876
  }
843
877
 
878
+ class DcHttpError extends Error {
879
+ readonly status: number;
880
+ readonly body: string;
881
+ constructor(status: number, body: string, message: string) {
882
+ super(message);
883
+ this.status = status;
884
+ this.body = body;
885
+ }
886
+ }
887
+
844
888
  function cubeFromHref(href: string | undefined): string | undefined {
845
889
  if (!href) return undefined;
846
890
  const m = href.match(/\/dataset\/([^/?]+)/);
package/src/server.ts CHANGED
@@ -9,7 +9,7 @@ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprot
9
9
  import pack from './index.js';
10
10
 
11
11
  const server = new Server(
12
- { name: '@pipeworx/mcp-datacube-sk', version: '0.1.2' },
12
+ { name: '@pipeworx/mcp-datacube-sk', version: '0.1.3' },
13
13
  { capabilities: { tools: {} } },
14
14
  );
15
15