@cyanheads/eurostat-mcp-server 0.9.0 → 0.10.1
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/AGENTS.md +6 -5
- package/CLAUDE.md +6 -5
- package/Dockerfile +7 -6
- package/README.md +36 -34
- package/changelog/0.10.x/0.10.0.md +40 -0
- package/changelog/0.10.x/0.10.1.md +27 -0
- package/dist/config/server-config.d.ts +1 -0
- package/dist/config/server-config.d.ts.map +1 -1
- package/dist/config/server-config.js +9 -4
- package/dist/config/server-config.js.map +1 -1
- package/dist/index.js +26 -8
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/tools/clamp-read-limit.d.ts +11 -0
- package/dist/mcp-server/tools/clamp-read-limit.d.ts.map +1 -0
- package/dist/mcp-server/tools/clamp-read-limit.js +14 -0
- package/dist/mcp-server/tools/clamp-read-limit.js.map +1 -0
- package/dist/mcp-server/tools/definitions/eurostat-browse-themes.tool.d.ts +10 -2
- package/dist/mcp-server/tools/definitions/eurostat-browse-themes.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-browse-themes.tool.js +63 -10
- package/dist/mcp-server/tools/definitions/eurostat-browse-themes.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-dataframe-describe.tool.d.ts +0 -1
- package/dist/mcp-server/tools/definitions/eurostat-dataframe-describe.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-dataframe-describe.tool.js +14 -4
- package/dist/mcp-server/tools/definitions/eurostat-dataframe-describe.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-dataframe-query.tool.d.ts +3 -3
- package/dist/mcp-server/tools/definitions/eurostat-dataframe-query.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-dataframe-query.tool.js +113 -38
- package/dist/mcp-server/tools/definitions/eurostat-dataframe-query.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-download-dataset.tool.d.ts +101 -2
- package/dist/mcp-server/tools/definitions/eurostat-download-dataset.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-download-dataset.tool.js +60 -24
- package/dist/mcp-server/tools/definitions/eurostat-download-dataset.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-get-dataset-info.tool.d.ts +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-get-dataset-info.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-get-dataset-info.tool.js +10 -1
- package/dist/mcp-server/tools/definitions/eurostat-get-dataset-info.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-get-dimension-values.tool.d.ts +13 -6
- package/dist/mcp-server/tools/definitions/eurostat-get-dimension-values.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-get-dimension-values.tool.js +235 -53
- package/dist/mcp-server/tools/definitions/eurostat-get-dimension-values.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-query-dataset.tool.d.ts +110 -5
- package/dist/mcp-server/tools/definitions/eurostat-query-dataset.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-query-dataset.tool.js +56 -26
- package/dist/mcp-server/tools/definitions/eurostat-query-dataset.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-search-datasets.tool.d.ts +55 -2
- package/dist/mcp-server/tools/definitions/eurostat-search-datasets.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/eurostat-search-datasets.tool.js +90 -22
- package/dist/mcp-server/tools/definitions/eurostat-search-datasets.tool.js.map +1 -1
- package/dist/mcp-server/tools/value-list-paging.d.ts +49 -0
- package/dist/mcp-server/tools/value-list-paging.d.ts.map +1 -0
- package/dist/mcp-server/tools/value-list-paging.js +73 -0
- package/dist/mcp-server/tools/value-list-paging.js.map +1 -0
- package/dist/services/canvas-accessor.d.ts +11 -1
- package/dist/services/canvas-accessor.d.ts.map +1 -1
- package/dist/services/canvas-accessor.js +13 -2
- package/dist/services/canvas-accessor.js.map +1 -1
- package/dist/services/eurostat-bulk/eurostat-bulk-service.d.ts +8 -4
- package/dist/services/eurostat-bulk/eurostat-bulk-service.d.ts.map +1 -1
- package/dist/services/eurostat-bulk/eurostat-bulk-service.js +131 -46
- package/dist/services/eurostat-bulk/eurostat-bulk-service.js.map +1 -1
- package/dist/services/eurostat-bulk/types.d.ts +1 -1
- package/dist/services/eurostat-bulk/types.d.ts.map +1 -1
- package/dist/services/eurostat-catalogue/eurostat-catalogue-service.d.ts +46 -4
- package/dist/services/eurostat-catalogue/eurostat-catalogue-service.d.ts.map +1 -1
- package/dist/services/eurostat-catalogue/eurostat-catalogue-service.js +146 -36
- package/dist/services/eurostat-catalogue/eurostat-catalogue-service.js.map +1 -1
- package/dist/services/eurostat-data/eurostat-data-service.d.ts +5 -0
- package/dist/services/eurostat-data/eurostat-data-service.d.ts.map +1 -1
- package/dist/services/eurostat-data/eurostat-data-service.js +144 -28
- package/dist/services/eurostat-data/eurostat-data-service.js.map +1 -1
- package/dist/services/eurostat-filters.d.ts +13 -0
- package/dist/services/eurostat-filters.d.ts.map +1 -0
- package/dist/services/eurostat-filters.js +21 -0
- package/dist/services/eurostat-filters.js.map +1 -0
- package/dist/services/eurostat-outage.d.ts +27 -0
- package/dist/services/eurostat-outage.d.ts.map +1 -0
- package/dist/services/eurostat-outage.js +44 -0
- package/dist/services/eurostat-outage.js.map +1 -0
- package/package.json +9 -9
- package/server.json +31 -17
|
@@ -26,15 +26,23 @@ export declare const eurostatBrowseThemes: import("@cyanheads/mcp-ts-core").Tool
|
|
|
26
26
|
}, z.core.$strip>, readonly [{
|
|
27
27
|
readonly reason: "not_found";
|
|
28
28
|
readonly code: JsonRpcErrorCode.NotFound;
|
|
29
|
-
readonly when: "The provided theme_code does not exist in the TOC.";
|
|
30
|
-
readonly recovery: "Call eurostat_browse_themes without theme_code to see valid root themes, then navigate from there.";
|
|
29
|
+
readonly when: "The provided theme_code does not exist in the TOC — or is a Comext folder (ext_go_detail, prom, comext) or DS-* code while the Comext dataflow list cannot be loaded.";
|
|
30
|
+
readonly recovery: "Call eurostat_browse_themes without theme_code to see valid root themes, then navigate from there. A Comext folder missing because its list could not be loaded returns once the merge is retried, about once a minute; eurostat_get_dataset_info reads a DS-* code directly.";
|
|
31
31
|
}, {
|
|
32
32
|
readonly reason: "not_a_folder";
|
|
33
33
|
readonly code: JsonRpcErrorCode.ValidationError;
|
|
34
34
|
readonly when: "The provided theme_code identifies a dataset or table entry instead of a folder.";
|
|
35
35
|
readonly recovery: "Pass the code to eurostat_get_dataset_info to inspect it, then eurostat_query_dataset to retrieve data.";
|
|
36
|
+
}, {
|
|
37
|
+
readonly reason: "upstream_fault";
|
|
38
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
39
|
+
readonly when: "The server had no catalogue loaded yet, and Eurostat's table of contents answered HTTP 5xx or could not be reached on every retry, which the error marks retryable. Once a catalogue is loaded, a failed refresh serves that copy instead.";
|
|
40
|
+
readonly recovery: "Retry in a few minutes: the catalogue load failed on Eurostat's side and runs again on the next call.";
|
|
36
41
|
}], {
|
|
37
42
|
readonly itemCount: z.ZodNumber;
|
|
38
43
|
readonly themeCode: z.ZodOptional<z.ZodString>;
|
|
44
|
+
readonly comextListMissing: z.ZodOptional<z.ZodBoolean>;
|
|
45
|
+
readonly catalogueLoadedAt: z.ZodOptional<z.ZodString>;
|
|
46
|
+
readonly notice: z.ZodOptional<z.ZodString>;
|
|
39
47
|
}>;
|
|
40
48
|
//# sourceMappingURL=eurostat-browse-themes.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eurostat-browse-themes.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurostat-browse-themes.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAiB,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"eurostat-browse-themes.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurostat-browse-themes.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAiB,MAAM,+BAA+B,CAAC;AAIhF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiO/B,CAAC"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
6
|
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
7
|
import { getEurostatCatalogueService } from '../../../services/eurostat-catalogue/eurostat-catalogue-service.js';
|
|
8
|
+
import { outageAnswer } from '../../../services/eurostat-outage.js';
|
|
8
9
|
export const eurostatBrowseThemes = tool('eurostat_browse_themes', {
|
|
9
10
|
title: 'Browse Eurostat Theme Hierarchy',
|
|
10
11
|
description: 'Navigate the Eurostat theme tree. Without theme_code returns the top-level theme folders (Economy, Population, Transport, etc.) — the practical starting points. With a theme_code returns its immediate children: subtheme folders and datasets in that branch. Use this for structured discovery when you know the domain but not the dataset code, or to drill down from a broad topic to a specific dataset. Pair with eurostat_search_datasets for keyword-based discovery. The tree is the dissemination table of contents plus the Comext host\'s DS-* collections: detailed trade under ext_go_detail (inside ext_go, "International trade in goods") and PRODCOM under prom (inside icts, "Industry, trade and services"). A collection on neither, such as the legacy PRODCOM DS-056120, is not disseminated and appears nowhere in the tree.',
|
|
@@ -61,13 +62,25 @@ export const eurostatBrowseThemes = tool('eurostat_browse_themes', {
|
|
|
61
62
|
enrichment: {
|
|
62
63
|
itemCount: z.number().describe('Number of items returned in this level.'),
|
|
63
64
|
themeCode: z.string().optional().describe('Folder code that was browsed, or omitted for root.'),
|
|
65
|
+
comextListMissing: z
|
|
66
|
+
.boolean()
|
|
67
|
+
.optional()
|
|
68
|
+
.describe('True on a browse of ext_go or icts when the Comext dataflow list could not be loaded, so the DS-* collection folder filed there is not listed. Omitted otherwise.'),
|
|
69
|
+
catalogueLoadedAt: z
|
|
70
|
+
.string()
|
|
71
|
+
.optional()
|
|
72
|
+
.describe('When the catalogue that answered was loaded (ISO 8601). Present only when a refresh failed and that older copy is still in service; omitted otherwise.'),
|
|
73
|
+
notice: z
|
|
74
|
+
.string()
|
|
75
|
+
.optional()
|
|
76
|
+
.describe('Names each part of the catalogue this listing is missing — the Comext collections, or updates since a refresh failed — and what to do about it. Omitted when the whole catalogue answered.'),
|
|
64
77
|
},
|
|
65
78
|
errors: [
|
|
66
79
|
{
|
|
67
80
|
reason: 'not_found',
|
|
68
81
|
code: JsonRpcErrorCode.NotFound,
|
|
69
|
-
when: 'The provided theme_code does not exist in the TOC.',
|
|
70
|
-
recovery: 'Call eurostat_browse_themes without theme_code to see valid root themes, then navigate from there.',
|
|
82
|
+
when: 'The provided theme_code does not exist in the TOC — or is a Comext folder (ext_go_detail, prom, comext) or DS-* code while the Comext dataflow list cannot be loaded.',
|
|
83
|
+
recovery: 'Call eurostat_browse_themes without theme_code to see valid root themes, then navigate from there. A Comext folder missing because its list could not be loaded returns once the merge is retried, about once a minute; eurostat_get_dataset_info reads a DS-* code directly.',
|
|
71
84
|
},
|
|
72
85
|
{
|
|
73
86
|
reason: 'not_a_folder',
|
|
@@ -75,6 +88,12 @@ export const eurostatBrowseThemes = tool('eurostat_browse_themes', {
|
|
|
75
88
|
when: 'The provided theme_code identifies a dataset or table entry instead of a folder.',
|
|
76
89
|
recovery: 'Pass the code to eurostat_get_dataset_info to inspect it, then eurostat_query_dataset to retrieve data.',
|
|
77
90
|
},
|
|
91
|
+
{
|
|
92
|
+
reason: 'upstream_fault',
|
|
93
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
94
|
+
when: "The server had no catalogue loaded yet, and Eurostat's table of contents answered HTTP 5xx or could not be reached on every retry, which the error marks retryable. Once a catalogue is loaded, a failed refresh serves that copy instead.",
|
|
95
|
+
recovery: "Retry in a few minutes: the catalogue load failed on Eurostat's side and runs again on the next call.",
|
|
96
|
+
},
|
|
78
97
|
],
|
|
79
98
|
async handler(input, ctx) {
|
|
80
99
|
const svc = getEurostatCatalogueService();
|
|
@@ -86,10 +105,20 @@ export const eurostatBrowseThemes = tool('eurostat_browse_themes', {
|
|
|
86
105
|
catch (err) {
|
|
87
106
|
const data = err.data;
|
|
88
107
|
if (data?.reason === 'not_found') {
|
|
108
|
+
const stale = data.catalogueLoadedAt
|
|
109
|
+
? `The catalogue could not be refreshed, so this lookup ran against the copy loaded at ${data.catalogueLoadedAt}; folders Eurostat added since then are not in it.`
|
|
110
|
+
: undefined;
|
|
111
|
+
const hint = data.comextListMissing
|
|
112
|
+
? [
|
|
113
|
+
`The Comext dataflow list merge is retried about once a minute: browse "${themeCode}" again after that. eurostat_get_dataset_info reads a DS-* code directly.`,
|
|
114
|
+
stale,
|
|
115
|
+
]
|
|
116
|
+
: [
|
|
117
|
+
stale,
|
|
118
|
+
'Call eurostat_browse_themes without theme_code to see valid root themes, then navigate from there.',
|
|
119
|
+
];
|
|
89
120
|
throw ctx.fail('not_found', err.message, {
|
|
90
|
-
recovery: {
|
|
91
|
-
hint: 'Call eurostat_browse_themes without theme_code to see valid root themes, then navigate from there.',
|
|
92
|
-
},
|
|
121
|
+
recovery: { hint: hint.filter(Boolean).join(' ') },
|
|
93
122
|
});
|
|
94
123
|
}
|
|
95
124
|
if (data?.reason === 'not_a_folder') {
|
|
@@ -101,16 +130,40 @@ export const eurostatBrowseThemes = tool('eurostat_browse_themes', {
|
|
|
101
130
|
},
|
|
102
131
|
});
|
|
103
132
|
}
|
|
133
|
+
if (data?.reason === 'upstream_fault' && data.retryable === true) {
|
|
134
|
+
throw ctx.fail('upstream_fault', err.message, {
|
|
135
|
+
retryable: true,
|
|
136
|
+
recovery: {
|
|
137
|
+
hint: `Eurostat's table of contents ${outageAnswer(data.status)} on every attempt, so there is no catalogue to browse yet — an upstream outage, not a fault in the request. The load runs again on the next call, so retry in a few minutes.`,
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
}
|
|
104
141
|
throw err;
|
|
105
142
|
}
|
|
106
|
-
|
|
107
|
-
ctx.
|
|
108
|
-
|
|
143
|
+
const { comextListMissing, catalogueLoadedAt, ...listing } = browsed;
|
|
144
|
+
ctx.log.info('Theme browse complete', { themeCode, itemCount: listing.items.length });
|
|
145
|
+
ctx.enrich({
|
|
146
|
+
itemCount: listing.items.length,
|
|
147
|
+
...(themeCode && { themeCode }),
|
|
148
|
+
...(comextListMissing && { comextListMissing }),
|
|
149
|
+
...(catalogueLoadedAt && { catalogueLoadedAt }),
|
|
150
|
+
});
|
|
151
|
+
// `notice` is last-wins, so every sentence is collected here and written once.
|
|
152
|
+
const notices = [];
|
|
153
|
+
if (comextListMissing) {
|
|
154
|
+
notices.push('The Comext dataflow list could not be loaded, so the DS-* collections filed in this folder are not listed; the merge is retried about once a minute. eurostat_get_dataset_info reads a DS-* code directly.');
|
|
155
|
+
}
|
|
156
|
+
if (catalogueLoadedAt) {
|
|
157
|
+
notices.push(`The catalogue could not be refreshed, so this listing comes from the copy loaded at ${catalogueLoadedAt}; folders and datasets Eurostat added or changed since then are not reflected.`);
|
|
158
|
+
}
|
|
159
|
+
if (notices.length > 0)
|
|
160
|
+
ctx.enrich.notice(notices.join(' '));
|
|
161
|
+
const nextStep = listing.items.length === 0
|
|
109
162
|
? undefined
|
|
110
|
-
:
|
|
163
|
+
: listing.items.some((i) => i.type !== 'folder')
|
|
111
164
|
? `Pass a dataset/table code to eurostat_get_dataset_info to inspect dimensions. Pass a folder code back to theme_code to drill deeper.`
|
|
112
165
|
: `Pass a folder code back to theme_code to drill into sub-themes.`;
|
|
113
|
-
return { ...
|
|
166
|
+
return { ...listing, ...(nextStep && { nextStep }) };
|
|
114
167
|
},
|
|
115
168
|
format: (result) => {
|
|
116
169
|
const lines = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eurostat-browse-themes.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurostat-browse-themes.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAiB,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,2BAA2B,EAAE,MAAM,6DAA6D,CAAC;
|
|
1
|
+
{"version":3,"file":"eurostat-browse-themes.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurostat-browse-themes.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAiB,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,2BAA2B,EAAE,MAAM,6DAA6D,CAAC;AAC1G,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC,wBAAwB,EAAE;IACjE,KAAK,EAAE,iCAAiC;IACxC,WAAW,EACT,yzBAAyzB;IAC3zB,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;IAC9E,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,2FAA2F,CAC5F;KACJ,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,KAAK,EAAE,CAAC;aACL,KAAK,CACJ,CAAC;aACE,MAAM,CAAC;YACN,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,QAAQ,CACP,0GAA0G,CAC3G;YACH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YAClD,IAAI,EAAE,CAAC;iBACJ,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;iBACpC,QAAQ,CACP,+EAA+E,CAChF;YACH,WAAW,EAAE,CAAC;iBACX,OAAO,EAAE;iBACT,QAAQ,CACP,8EAA8E,CAC/E;YACH,SAAS,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,iFAAiF,CAClF;YACH,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,qEAAqE,CAAC;YAClF,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,2EAA2E,CAC5E;SACJ,CAAC;aACD,QAAQ,CAAC,0CAA0C,CAAC,CACxD;aACA,QAAQ,CACP,0FAA0F,CAC3F;QACH,UAAU,EAAE,CAAC;aACV,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,QAAQ,CACP,8HAA8H,CAC/H;QACH,eAAe,EAAE,CAAC;aACf,KAAK,CACJ,CAAC;aACE,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,QAAQ,CAAC,uEAAuE,CAAC,CACrF;aACA,QAAQ,EAAE;aACV,QAAQ,CACP,8cAA8c,CAC/c;QACH,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,+FAA+F,CAChG;KACJ,CAAC;IACF,UAAU,EAAE;QACV,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;QACzE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;QAC/F,iBAAiB,EAAE,CAAC;aACjB,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CACP,mKAAmK,CACpK;QACH,iBAAiB,EAAE,CAAC;aACjB,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,wJAAwJ,CACzJ;QACH,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,4LAA4L,CAC7L;KACJ;IAED,MAAM,EAAE;QACN;YACE,MAAM,EAAE,WAAW;YACnB,IAAI,EAAE,gBAAgB,CAAC,QAAQ;YAC/B,IAAI,EAAE,uKAAuK;YAC7K,QAAQ,EACN,+QAA+Q;SAClR;QACD;YACE,MAAM,EAAE,cAAc;YACtB,IAAI,EAAE,gBAAgB,CAAC,eAAe;YACtC,IAAI,EAAE,kFAAkF;YACxF,QAAQ,EACN,yGAAyG;SAC5G;QACD;YACE,MAAM,EAAE,gBAAgB;YACxB,IAAI,EAAE,gBAAgB,CAAC,kBAAkB;YACzC,IAAI,EAAE,4OAA4O;YAClP,QAAQ,EACN,uGAAuG;SAC1G;KACF;IAED,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;QACtB,MAAM,GAAG,GAAG,2BAA2B,EAAE,CAAC;QAC1C,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;QACxD,IAAI,OAA+C,CAAC;QACpD,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,GAAI,GAAgB,CAAC,IAAI,CAAC;YACpC,IAAI,IAAI,EAAE,MAAM,KAAK,WAAW,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB;oBAClC,CAAC,CAAC,uFAAuF,IAAI,CAAC,iBAAiB,oDAAoD;oBACnK,CAAC,CAAC,SAAS,CAAC;gBACd,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB;oBACjC,CAAC,CAAC;wBACE,0EAA0E,SAAS,2EAA2E;wBAC9J,KAAK;qBACN;oBACH,CAAC,CAAC;wBACE,KAAK;wBACL,oGAAoG;qBACrG,CAAC;gBACN,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,EAAG,GAAa,CAAC,OAAO,EAAE;oBAClD,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;iBACnD,CAAC,CAAC;YACL,CAAC;YACD,IAAI,IAAI,EAAE,MAAM,KAAK,cAAc,EAAE,CAAC;gBACpC,MAAM,GAAG,CAAC,IAAI,CAAC,cAAc,EAAG,GAAa,CAAC,OAAO,EAAE;oBACrD,SAAS;oBACT,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,QAAQ,EAAE;wBACR,IAAI,EAAE,SAAS,SAAS,yHAAyH;qBAClJ;iBACF,CAAC,CAAC;YACL,CAAC;YACD,IAAI,IAAI,EAAE,MAAM,KAAK,gBAAgB,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;gBACjE,MAAM,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAG,GAAa,CAAC,OAAO,EAAE;oBACvD,SAAS,EAAE,IAAI;oBACf,QAAQ,EAAE;wBACR,IAAI,EAAE,gCAAgC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,8KAA8K;qBAC9O;iBACF,CAAC,CAAC;YACL,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC;QACrE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACtF,GAAG,CAAC,MAAM,CAAC;YACT,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM;YAC/B,GAAG,CAAC,SAAS,IAAI,EAAE,SAAS,EAAE,CAAC;YAC/B,GAAG,CAAC,iBAAiB,IAAI,EAAE,iBAAiB,EAAE,CAAC;YAC/C,GAAG,CAAC,iBAAiB,IAAI,EAAE,iBAAiB,EAAE,CAAC;SAChD,CAAC,CAAC;QACH,+EAA+E;QAC/E,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,iBAAiB,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CACV,4MAA4M,CAC7M,CAAC;QACJ,CAAC;QACD,IAAI,iBAAiB,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CACV,uFAAuF,iBAAiB,gFAAgF,CACzL,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7D,MAAM,QAAQ,GACZ,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YACxB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;gBAC9C,CAAC,CAAC,sIAAsI;gBACxI,CAAC,CAAC,iEAAiE,CAAC;QAC1E,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;IAED,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;QACjB,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,aAAa,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,MAAM,QAAQ,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACvF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YAClD,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,MAAM,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;YACxC,KAAK,CAAC,IAAI,CACR,eAAe,IAAI,CAAC,IAAI,gBAAgB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAC9G,CAAC;YACF,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACnC,KAAK,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,SAAS,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;YAChF,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI;gBACvB,KAAK,CAAC,IAAI,CAAC,uBAAuB,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,MAAM,CAAC,eAAe,IAAI,MAAM,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChE,KAAK,CAAC,IAAI,CACR,gDAAgD,MAAM,CAAC,eAAe,CAAC,MAAM,gBAAgB,MAAM,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,sEAAsE,CACpR,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,oBAAoB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -34,7 +34,6 @@ export declare const eurostatDataframeDescribe: import("@cyanheads/mcp-ts-core")
|
|
|
34
34
|
readonly code: JsonRpcErrorCode.NotFound;
|
|
35
35
|
readonly when: "The canvas_id is unknown or its lifetime has elapsed.";
|
|
36
36
|
readonly recovery: "Re-run eurostat_query_dataset or eurostat_download_dataset without canvas_id and use the canvasId it returns; eurostat_get_dimension_values stages onto that canvas but never starts one.";
|
|
37
|
-
readonly thrownBy: "service";
|
|
38
37
|
}], {
|
|
39
38
|
readonly notice: z.ZodOptional<z.ZodString>;
|
|
40
39
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eurostat-dataframe-describe.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurostat-dataframe-describe.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,yBAAyB
|
|
1
|
+
{"version":3,"file":"eurostat-dataframe-describe.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurostat-dataframe-describe.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8IpC,CAAC"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
6
|
import { CanvasIdSchema } from '@cyanheads/mcp-ts-core/canvas';
|
|
7
7
|
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
8
|
-
import { acquireCanvas, getCanvas } from '../../../services/canvas-accessor.js';
|
|
8
|
+
import { acquireCanvas, getCanvas, isCanvasFailure } from '../../../services/canvas-accessor.js';
|
|
9
9
|
export const eurostatDataframeDescribe = tool('eurostat_dataframe_describe', {
|
|
10
10
|
title: 'Describe Eurostat Dataframes',
|
|
11
11
|
description: 'List the tables staged on a Eurostat dataframe canvas, with their row counts and column names and types. Call this before eurostat_dataframe_query to learn the table and column names to write SQL against. The canvas_id comes from a eurostat_query_dataset or eurostat_download_dataset response that reported a staged table. Three tools stage tables, and they write different columns, so read the columns reported here rather than assuming. The two observation stagers keep every column flat: eurostat_query_dataset gives each dimension a code column named after the dimension (e.g. "geo") plus a label companion (e.g. "geo_label"); eurostat_download_dataset gives code columns only — the bulk endpoint carries no labels — plus a "time" column. Both write the same five measure columns — obs_value, obs_flag, obs_flag_label, conf_status, conf_status_label — carrying the same codes for the same observation, so their tables join on dimension codes and time and compare like with like. A table staged from a DS-* dataset (Comext detailed trade, PRODCOM) adds obs_value_text, holding a value Eurostat published as text, such as a PRODCOM quantity unit. eurostat_get_dimension_values, given a canvas_id, stages one dimension\'s value list as two columns, code and label, which labels a download\'s code column through a join (e.g. d.geo = g.code).',
|
|
@@ -62,7 +62,6 @@ export const eurostatDataframeDescribe = tool('eurostat_dataframe_describe', {
|
|
|
62
62
|
code: JsonRpcErrorCode.NotFound,
|
|
63
63
|
when: 'The canvas_id is unknown or its lifetime has elapsed.',
|
|
64
64
|
recovery: 'Re-run eurostat_query_dataset or eurostat_download_dataset without canvas_id and use the canvasId it returns; eurostat_get_dimension_values stages onto that canvas but never starts one.',
|
|
65
|
-
thrownBy: 'service',
|
|
66
65
|
},
|
|
67
66
|
],
|
|
68
67
|
async handler(input, ctx) {
|
|
@@ -70,8 +69,19 @@ export const eurostatDataframeDescribe = tool('eurostat_dataframe_describe', {
|
|
|
70
69
|
if (!canvas) {
|
|
71
70
|
throw ctx.fail('canvas_disabled');
|
|
72
71
|
}
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Re-thrown so the declared recovery replaces the canvas service's generic one. A
|
|
74
|
+
* canvas can also expire between the acquire and the describe, so both calls go
|
|
75
|
+
* through the same mapping.
|
|
76
|
+
*/
|
|
77
|
+
const asDeclared = (err) => {
|
|
78
|
+
if (isCanvasFailure(err, 'canvas_not_found')) {
|
|
79
|
+
throw ctx.fail('canvas_not_found', err.message, { canvasId: input.canvas_id }, { cause: err });
|
|
80
|
+
}
|
|
81
|
+
throw err;
|
|
82
|
+
};
|
|
83
|
+
const instance = await acquireCanvas(canvas, input.canvas_id, ctx).catch(asDeclared);
|
|
84
|
+
const tables = await instance.describe().catch(asDeclared);
|
|
75
85
|
ctx.log.info('Described canvas', { canvasId: instance.canvasId, tableCount: tables.length });
|
|
76
86
|
if (tables.length === 0) {
|
|
77
87
|
ctx.enrich.notice(`Canvas ${instance.canvasId} holds no tables. Staged tables expire on their own schedule — re-run the tool that staged the data to stage it again: eurostat_query_dataset, eurostat_download_dataset, or eurostat_get_dimension_values with this canvas_id.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eurostat-dataframe-describe.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurostat-dataframe-describe.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"eurostat-dataframe-describe.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurostat-dataframe-describe.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,12 +25,12 @@ export declare const eurostatDataframeQuery: import("@cyanheads/mcp-ts-core").To
|
|
|
25
25
|
readonly code: JsonRpcErrorCode.NotFound;
|
|
26
26
|
readonly when: "The canvas_id is unknown or its lifetime has elapsed.";
|
|
27
27
|
readonly recovery: "Re-run eurostat_query_dataset or eurostat_download_dataset without canvas_id and use the canvasId it returns; eurostat_get_dimension_values stages onto that canvas but never starts one.";
|
|
28
|
-
readonly thrownBy: "service";
|
|
29
28
|
}, {
|
|
30
29
|
readonly reason: "missing_table";
|
|
31
30
|
readonly code: JsonRpcErrorCode.NotFound;
|
|
32
31
|
readonly when: "The SQL names a table that is not staged on this canvas, or that has expired.";
|
|
33
32
|
readonly recovery: "Call eurostat_dataframe_describe for the staged table names, or re-run the tool that staged them (eurostat_query_dataset, eurostat_download_dataset, or eurostat_get_dimension_values with canvas_id).";
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
}], {
|
|
34
|
+
readonly notice: z.ZodOptional<z.ZodString>;
|
|
35
|
+
}>;
|
|
36
36
|
//# sourceMappingURL=eurostat-dataframe-query.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eurostat-dataframe-query.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurostat-dataframe-query.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"eurostat-dataframe-query.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurostat-dataframe-query.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAEjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAkDjE,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4JjC,CAAC"}
|
|
@@ -6,10 +6,41 @@
|
|
|
6
6
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
7
7
|
import { CanvasIdSchema } from '@cyanheads/mcp-ts-core/canvas';
|
|
8
8
|
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
9
|
-
import {
|
|
9
|
+
import { fitPage, INLINE_BUDGET_BYTES, utf8Bytes, } from '../value-list-paging.js';
|
|
10
|
+
import { acquireCanvas, getCanvas, isCanvasFailure } from '../../../services/canvas-accessor.js';
|
|
11
|
+
const QueryOutputSchema = z.object({
|
|
12
|
+
canvasId: z.string().describe('Canvas identifier the query ran against.'),
|
|
13
|
+
columns: z.array(z.string()).describe('Column names in projection order.'),
|
|
14
|
+
rows: z
|
|
15
|
+
.array(z.record(z.string(), z.unknown()))
|
|
16
|
+
.describe('Complete result rows, keyed by column name, bounded by the canvas row limit and 64,000 bytes per serialized surface. Nested cells render as JSON; 64-bit integers arrive as strings so they survive intact. Cast to DOUBLE in SQL if a number is wanted.'),
|
|
17
|
+
rowCount: z
|
|
18
|
+
.number()
|
|
19
|
+
.describe('Complete rows returned after the canvas row limit and the 64,000-byte budget per serialized response surface. Advance SQL OFFSET by this actual count.'),
|
|
20
|
+
truncated: z
|
|
21
|
+
.boolean()
|
|
22
|
+
.describe('True when the canvas row limit or the 64,000-byte budget per serialized response surface omitted rows. At least one complete row is retained even if oversized. Follow notice for SQL paging.'),
|
|
23
|
+
});
|
|
24
|
+
/** JSON cells preserve nested values, string quoting and escaped line breaks. */
|
|
25
|
+
function renderRow(columns, row) {
|
|
26
|
+
return columns.map((column) => `${column}=${JSON.stringify(row[column])}`).join(' | ');
|
|
27
|
+
}
|
|
28
|
+
/** Shared by the formatter and the serialized response budget. */
|
|
29
|
+
function renderText(result) {
|
|
30
|
+
return [
|
|
31
|
+
`# Query result (canvas \`${result.canvasId}\`)`,
|
|
32
|
+
`**Rows:** ${result.rowCount} | **Truncated:** ${result.truncated}`,
|
|
33
|
+
`**Columns:** ${result.columns.join(', ')}\n`,
|
|
34
|
+
...result.rows.map((row) => renderRow(result.columns, row)),
|
|
35
|
+
].join('\n');
|
|
36
|
+
}
|
|
37
|
+
/** Paging depends on a fixed deterministic SELECT over unchanged staged tables. */
|
|
38
|
+
function cutNotice(rows) {
|
|
39
|
+
return `Returned ${rows.toLocaleString('en-US')} complete rows; the canvas row limit or the 64,000-byte budget per serialized response surface cut this result. Page with the same deterministic SELECT and a total ORDER BY (add tie-breakers for tied keys), using LIMIT/OFFSET and advancing OFFSET by the actual returned rowCount, not the requested LIMIT. If the first page had no ORDER BY, restart sorted at OFFSET 0. Volatile expressions and changing or expired tables do not support stable paging.`;
|
|
40
|
+
}
|
|
10
41
|
export const eurostatDataframeQuery = tool('eurostat_dataframe_query', {
|
|
11
42
|
title: 'Query Eurostat Dataframes',
|
|
12
|
-
description: 'Run a read-only SQL SELECT against tables staged on a Eurostat dataframe canvas — the way to reach observations past the 5,000-row inline cap of eurostat_query_dataset and past the inline preview of a eurostat_download_dataset bulk download, and to aggregate, group, or join across staged tables without re-fetching from Eurostat. Call eurostat_dataframe_describe first for the table and column names, which differ between the tools that stage them. Only a single SELECT statement runs: statement chaining, non-SELECT verbs, and functions that read files or external data are rejected. Columns are flat — every dimension is a code column named after the dimension, the measure is obs_value, the observation flag is obs_flag / obs_flag_label and the confidentiality marker is conf_status / conf_status_label; a "_label" companion per dimension exists only on tables eurostat_query_dataset staged. Both observation stagers write the same five measure columns with the same codes, so join their tables on dimension codes and time and compare obs_flag or conf_status across them directly; a DS-* table also carries obs_value_text, a value published as text (e.g. a PRODCOM unit "KG"). A value list eurostat_get_dimension_values staged has two columns, code and label: join it to the code column of a download (e.g. JOIN df_x g ON d.geo = g.code) to label that table.',
|
|
43
|
+
description: 'Run a read-only SQL SELECT against tables staged on a Eurostat dataframe canvas — the way to reach observations past the 5,000-row inline cap of eurostat_query_dataset and past the inline preview of a eurostat_download_dataset bulk download, and to aggregate, group, or join across staged tables without re-fetching from Eurostat. Call eurostat_dataframe_describe first for the table and column names, which differ between the tools that stage them. Only a single SELECT statement runs: statement chaining, non-SELECT verbs, and functions that read files or external data are rejected. Columns are flat — every dimension is a code column named after the dimension, the measure is obs_value, the observation flag is obs_flag / obs_flag_label and the confidentiality marker is conf_status / conf_status_label; a "_label" companion per dimension exists only on tables eurostat_query_dataset staged. Both observation stagers write the same five measure columns with the same codes, so join their tables on dimension codes and time and compare obs_flag or conf_status across them directly; a DS-* table also carries obs_value_text, a value published as text (e.g. a PRODCOM unit "KG"). A value list eurostat_get_dimension_values staged has two columns, code and label: join it to the code column of a download (e.g. JOIN df_x g ON d.geo = g.code) to label that table. Returns complete rows within the canvas row limit and 64,000 bytes per serialized response surface, retaining at least one complete row even if oversized. Nested cells render as JSON. A cut sets truncated and adds a notice: page the same deterministic SELECT over unchanged tables with a total ORDER BY and LIMIT/OFFSET, advancing by actual rowCount; restart an unordered first page sorted at offset zero. Tied keys need tie-breakers; volatile SQL and changing or expired tables cannot provide stable paging.',
|
|
13
44
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },
|
|
14
45
|
input: z.object({
|
|
15
46
|
canvas_id: CanvasIdSchema.describe('Canvas identifier returned as canvasId by eurostat_query_dataset, eurostat_download_dataset, or eurostat_get_dimension_values. Identifies the workspace holding the staged tables.'),
|
|
@@ -18,19 +49,13 @@ export const eurostatDataframeQuery = tool('eurostat_dataframe_query', {
|
|
|
18
49
|
.min(1)
|
|
19
50
|
.describe("A single read-only SELECT statement. Reference tables by the names eurostat_dataframe_describe reports. Example: SELECT geo, geo_label, AVG(obs_value) AS mean FROM df_a1b2c3d4 WHERE time >= '2020' GROUP BY geo, geo_label ORDER BY mean DESC."),
|
|
20
51
|
}),
|
|
21
|
-
output:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
.
|
|
26
|
-
.describe('
|
|
27
|
-
|
|
28
|
-
.number()
|
|
29
|
-
.describe('Rows materialized into this response. Equals the full result size unless truncated is true.'),
|
|
30
|
-
truncated: z
|
|
31
|
-
.boolean()
|
|
32
|
-
.describe('True when the result exceeded the canvas row limit and was cut short. Add a LIMIT, an aggregate, or a narrower WHERE clause to see the rest.'),
|
|
33
|
-
}),
|
|
52
|
+
output: QueryOutputSchema,
|
|
53
|
+
enrichment: {
|
|
54
|
+
notice: z
|
|
55
|
+
.string()
|
|
56
|
+
.optional()
|
|
57
|
+
.describe('Whole-row cut disclosure and deterministic SQL paging guidance. Omitted when no rows were omitted.'),
|
|
58
|
+
},
|
|
34
59
|
errors: [
|
|
35
60
|
{
|
|
36
61
|
reason: 'canvas_disabled',
|
|
@@ -44,14 +69,12 @@ export const eurostatDataframeQuery = tool('eurostat_dataframe_query', {
|
|
|
44
69
|
code: JsonRpcErrorCode.NotFound,
|
|
45
70
|
when: 'The canvas_id is unknown or its lifetime has elapsed.',
|
|
46
71
|
recovery: 'Re-run eurostat_query_dataset or eurostat_download_dataset without canvas_id and use the canvasId it returns; eurostat_get_dimension_values stages onto that canvas but never starts one.',
|
|
47
|
-
thrownBy: 'service',
|
|
48
72
|
},
|
|
49
73
|
{
|
|
50
74
|
reason: 'missing_table',
|
|
51
75
|
code: JsonRpcErrorCode.NotFound,
|
|
52
76
|
when: 'The SQL names a table that is not staged on this canvas, or that has expired.',
|
|
53
77
|
recovery: 'Call eurostat_dataframe_describe for the staged table names, or re-run the tool that staged them (eurostat_query_dataset, eurostat_download_dataset, or eurostat_get_dimension_values with canvas_id).',
|
|
54
|
-
thrownBy: 'service',
|
|
55
78
|
},
|
|
56
79
|
],
|
|
57
80
|
async handler(input, ctx) {
|
|
@@ -59,7 +82,21 @@ export const eurostatDataframeQuery = tool('eurostat_dataframe_query', {
|
|
|
59
82
|
if (!canvas) {
|
|
60
83
|
throw ctx.fail('canvas_disabled');
|
|
61
84
|
}
|
|
62
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Both are re-thrown so the declared recovery replaces the canvas service's
|
|
87
|
+
* generic one. A canvas can also expire between the acquire and the query,
|
|
88
|
+
* so both calls go through the same mapping.
|
|
89
|
+
*/
|
|
90
|
+
const asDeclared = (err) => {
|
|
91
|
+
if (isCanvasFailure(err, 'canvas_not_found')) {
|
|
92
|
+
throw ctx.fail('canvas_not_found', err.message, { canvasId: input.canvas_id }, { cause: err });
|
|
93
|
+
}
|
|
94
|
+
if (isCanvasFailure(err, 'missing_table')) {
|
|
95
|
+
throw ctx.fail('missing_table', err.message, { tableName: err.data?.tableName }, { cause: err });
|
|
96
|
+
}
|
|
97
|
+
throw err;
|
|
98
|
+
};
|
|
99
|
+
const instance = await acquireCanvas(canvas, input.canvas_id, ctx).catch(asDeclared);
|
|
63
100
|
/**
|
|
64
101
|
* The SQL is not sanitized here on purpose. The canvas gate rejects
|
|
65
102
|
* anything that is not a single SELECT — statement count, statement type,
|
|
@@ -68,31 +105,69 @@ export const eurostatDataframeQuery = tool('eurostat_dataframe_query', {
|
|
|
68
105
|
* second, weaker string filter in front of it would only shadow those
|
|
69
106
|
* reasons with a vaguer message.
|
|
70
107
|
*/
|
|
71
|
-
const result = await instance.query(input.sql, { signal: ctx.signal });
|
|
72
|
-
|
|
73
|
-
canvasId: instance.canvasId,
|
|
74
|
-
rowCount: result.rowCount,
|
|
75
|
-
truncated: result.truncated === true,
|
|
76
|
-
});
|
|
77
|
-
return {
|
|
108
|
+
const result = await instance.query(input.sql, { signal: ctx.signal }).catch(asDeclared);
|
|
109
|
+
const page = (count) => ({
|
|
78
110
|
canvasId: instance.canvasId,
|
|
79
111
|
columns: result.columns,
|
|
80
|
-
rows: result.rows,
|
|
81
|
-
rowCount:
|
|
112
|
+
rows: result.rows.slice(0, count),
|
|
113
|
+
rowCount: count,
|
|
114
|
+
truncated: result.truncated === true || count < result.rows.length,
|
|
115
|
+
});
|
|
116
|
+
const measure = (count) => {
|
|
117
|
+
const output = page(count);
|
|
118
|
+
const notice = output.truncated ? cutNotice(count) : undefined;
|
|
119
|
+
const content = [
|
|
120
|
+
{ type: 'text', text: renderText(output) },
|
|
121
|
+
...(notice ? [{ type: 'text', text: `\n\n> ${notice}` }] : []),
|
|
122
|
+
];
|
|
123
|
+
return {
|
|
124
|
+
structured: utf8Bytes(JSON.stringify({ ...output, ...(notice && { notice }) })),
|
|
125
|
+
text: utf8Bytes(JSON.stringify(content)),
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
const costs = [];
|
|
129
|
+
const costOf = (index) => {
|
|
130
|
+
const cached = costs[index];
|
|
131
|
+
if (cached)
|
|
132
|
+
return cached;
|
|
133
|
+
const row = result.rows[index];
|
|
134
|
+
const cost = {
|
|
135
|
+
structured: utf8Bytes(JSON.stringify(row)) + 1,
|
|
136
|
+
text: utf8Bytes(JSON.stringify(`\n${renderRow(result.columns, row)}`)) - 2,
|
|
137
|
+
};
|
|
138
|
+
costs[index] = cost;
|
|
139
|
+
return cost;
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* A full result has no cut notice, so it can fit when a partial prefix plus
|
|
143
|
+
* that notice cannot. Test that case with additive row costs, stopping at
|
|
144
|
+
* the budget instead of serializing an arbitrarily large full result.
|
|
145
|
+
*/
|
|
146
|
+
const empty = {
|
|
147
|
+
...page(0),
|
|
148
|
+
rowCount: result.rows.length,
|
|
82
149
|
truncated: result.truncated === true,
|
|
83
150
|
};
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
for (const row of result.rows) {
|
|
93
|
-
lines.push(result.columns.map((col) => `${col}=${row[col] === null ? 'NULL' : row[col]}`).join(' | '));
|
|
151
|
+
let structured = utf8Bytes(JSON.stringify(empty));
|
|
152
|
+
let text = utf8Bytes(JSON.stringify([{ type: 'text', text: renderText(empty) }]));
|
|
153
|
+
let fullFits = !empty.truncated;
|
|
154
|
+
for (let index = 0; fullFits && index < result.rows.length; index++) {
|
|
155
|
+
const cost = costOf(index);
|
|
156
|
+
structured += cost.structured - (index === 0 ? 1 : 0);
|
|
157
|
+
text += cost.text;
|
|
158
|
+
fullFits = structured <= INLINE_BUDGET_BYTES && text <= INLINE_BUDGET_BYTES;
|
|
94
159
|
}
|
|
95
|
-
|
|
160
|
+
const count = fullFits ? result.rows.length : fitPage(result.rows.length, measure, costOf);
|
|
161
|
+
const output = page(count);
|
|
162
|
+
if (output.truncated)
|
|
163
|
+
ctx.enrich.notice(cutNotice(count));
|
|
164
|
+
ctx.log.info('Canvas query complete', {
|
|
165
|
+
canvasId: instance.canvasId,
|
|
166
|
+
rowCount: output.rowCount,
|
|
167
|
+
truncated: output.truncated,
|
|
168
|
+
});
|
|
169
|
+
return output;
|
|
96
170
|
},
|
|
171
|
+
format: (result) => [{ type: 'text', text: renderText(result) }],
|
|
97
172
|
});
|
|
98
173
|
//# sourceMappingURL=eurostat-dataframe-query.tool.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eurostat-dataframe-query.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurostat-dataframe-query.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"eurostat-dataframe-query.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/eurostat-dataframe-query.tool.ts"],"names":[],"mappings":"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"}
|