@cyanheads/eurostat-mcp-server 0.6.5 → 0.7.0

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.
Files changed (37) hide show
  1. package/AGENTS.md +1 -1
  2. package/CLAUDE.md +1 -1
  3. package/README.md +70 -85
  4. package/changelog/0.7.x/0.7.0.md +33 -0
  5. package/dist/mcp-server/tools/definitions/eurostat-dataframe-describe.tool.d.ts +1 -1
  6. package/dist/mcp-server/tools/definitions/eurostat-dataframe-describe.tool.js +1 -1
  7. package/dist/mcp-server/tools/definitions/eurostat-dataframe-describe.tool.js.map +1 -1
  8. package/dist/mcp-server/tools/definitions/eurostat-dataframe-query.tool.d.ts +2 -2
  9. package/dist/mcp-server/tools/definitions/eurostat-dataframe-query.tool.js +2 -2
  10. package/dist/mcp-server/tools/definitions/eurostat-dataframe-query.tool.js.map +1 -1
  11. package/dist/mcp-server/tools/definitions/eurostat-download-dataset.tool.d.ts +9 -6
  12. package/dist/mcp-server/tools/definitions/eurostat-download-dataset.tool.d.ts.map +1 -1
  13. package/dist/mcp-server/tools/definitions/eurostat-download-dataset.tool.js +61 -21
  14. package/dist/mcp-server/tools/definitions/eurostat-download-dataset.tool.js.map +1 -1
  15. package/dist/mcp-server/tools/definitions/eurostat-get-dimension-values.tool.js +1 -1
  16. package/dist/mcp-server/tools/definitions/eurostat-get-dimension-values.tool.js.map +1 -1
  17. package/dist/mcp-server/tools/definitions/eurostat-query-dataset.tool.d.ts +7 -1
  18. package/dist/mcp-server/tools/definitions/eurostat-query-dataset.tool.d.ts.map +1 -1
  19. package/dist/mcp-server/tools/definitions/eurostat-query-dataset.tool.js +129 -14
  20. package/dist/mcp-server/tools/definitions/eurostat-query-dataset.tool.js.map +1 -1
  21. package/dist/services/eurostat-bulk/eurostat-bulk-service.d.ts +3 -0
  22. package/dist/services/eurostat-bulk/eurostat-bulk-service.d.ts.map +1 -1
  23. package/dist/services/eurostat-bulk/eurostat-bulk-service.js +21 -2
  24. package/dist/services/eurostat-bulk/eurostat-bulk-service.js.map +1 -1
  25. package/dist/services/eurostat-data/eurostat-data-service.d.ts +15 -1
  26. package/dist/services/eurostat-data/eurostat-data-service.d.ts.map +1 -1
  27. package/dist/services/eurostat-data/eurostat-data-service.js +78 -3
  28. package/dist/services/eurostat-data/eurostat-data-service.js.map +1 -1
  29. package/dist/services/eurostat-data/types.d.ts +26 -0
  30. package/dist/services/eurostat-data/types.d.ts.map +1 -1
  31. package/dist/services/eurostat-data/types.js.map +1 -1
  32. package/dist/services/eurostat-periods.d.ts +68 -0
  33. package/dist/services/eurostat-periods.d.ts.map +1 -0
  34. package/dist/services/eurostat-periods.js +204 -0
  35. package/dist/services/eurostat-periods.js.map +1 -0
  36. package/package.json +2 -2
  37. package/server.json +3 -3
@@ -0,0 +1,204 @@
1
+ /**
2
+ * @fileoverview Local check of the period literals `since_period`/`until_period`
3
+ * carry, run by both data tools before any request reaches Eurostat.
4
+ * @module services/eurostat-periods
5
+ */
6
+ /**
7
+ * The accepted forms, as the tools' descriptions and recovery hints state them.
8
+ * `YYYY-A1`, the SDMX annual form, is read as well and sent as `YYYY`.
9
+ */
10
+ export const PERIOD_FORMS = 'YYYY, YYYY-MM, YYYY-MM-DD, YYYY-Qn (1–4), YYYY-Sn (1–2), YYYY-Tn (1–3), YYYY-Mnn (01–12), YYYY-Wnn (a week the year has, up to 53) or YYYY-Dnnn (a day the year has, up to 366)';
11
+ /**
12
+ * `YYYY`, `YYYY-MM`, `YYYY-MM-DD`, the annual `YYYY-A1`, or a frequency letter (in
13
+ * either case) followed by its number: `YYYY-Qn`, `YYYY-Sn`, `YYYY-Tn`, `YYYY-Mnn`,
14
+ * `YYYY-Wnn`, `YYYY-Dnnn`.
15
+ *
16
+ * Read off live probes of both endpoints: each shape here is parsed the same way by
17
+ * the Statistics API and the SDMX bulk endpoint once it is in the form {@link
18
+ * normalizePeriod} sends. The number after the letter may carry extra leading zeros
19
+ * (`2020-Q01`, `2020-W001`) — the bulk endpoint reads those, the Statistics API
20
+ * refuses them. Month and day in `YYYY-MM`/`YYYY-MM-DD` stay exactly two digits
21
+ * (both endpoints refuse `2020-1`). Frequency is deliberately not checked — both
22
+ * endpoints map a literal of another frequency (`2020-01` on annual data) onto the
23
+ * dataset's own.
24
+ */
25
+ const PERIOD_SHAPE = /^(\d{4})(?:-(\d{2})(?:-(\d{2}))?|-(A)0{0,3}1|-([QSTMWD])(\d{1,4}))?$/i;
26
+ /**
27
+ * Per frequency letter: the digits its canonical form keeps and the largest number
28
+ * any year has. Weeks and days are further bounded by the year itself.
29
+ */
30
+ const COMPONENT = {
31
+ Q: { name: 'quarter', max: 4, width: 1 },
32
+ S: { name: 'semester', max: 2, width: 1 },
33
+ T: { name: 'trimester', max: 3, width: 1 },
34
+ M: { name: 'month', max: 12, width: 2 },
35
+ W: { name: 'week', max: 53, width: 2 },
36
+ D: { name: 'day', max: 366, width: 3 },
37
+ };
38
+ const MONTH_NAMES = [
39
+ 'January',
40
+ 'February',
41
+ 'March',
42
+ 'April',
43
+ 'May',
44
+ 'June',
45
+ 'July',
46
+ 'August',
47
+ 'September',
48
+ 'October',
49
+ 'November',
50
+ 'December',
51
+ ];
52
+ /** Characters of an offending value echoed back before it is cut short. */
53
+ const ECHO_LIMIT = 40;
54
+ const isLeapYear = (year) => (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
55
+ const daysInMonth = (year, month) => month === 2 ? (isLeapYear(year) ? 29 : 28) : [4, 6, 9, 11].includes(month) ? 30 : 31;
56
+ /**
57
+ * ISO 8601 weeks in a year: 53 when the year starts on a Thursday, or on a
58
+ * Wednesday in a leap year, otherwise 52. Asking either endpoint for week 53 of
59
+ * a 52-week year silently returns data from week 1 of the next year.
60
+ */
61
+ function isoWeeksInYear(year) {
62
+ const weekday = (y) => (y + Math.floor(y / 4) - Math.floor(y / 100) + Math.floor(y / 400)) % 7;
63
+ return weekday(year) === 4 || weekday(year - 1) === 3 ? 53 : 52;
64
+ }
65
+ /** Days since 1970-01-01 (UTC). `setUTCFullYear` keeps years 0–99 literal, where `Date.UTC` would add 1900. */
66
+ function dayNumber(year, month, day) {
67
+ const date = new Date(0);
68
+ date.setUTCFullYear(year, month - 1, day);
69
+ return date.getTime() / 86_400_000;
70
+ }
71
+ /** First and last day of months `from`–`to` of `year`, as {@link dayNumber}s. */
72
+ const monthSpan = (year, from, to) => [
73
+ dayNumber(year, from, 1),
74
+ dayNumber(year, to, daysInMonth(year, to)),
75
+ ];
76
+ /** First and last day of ISO week `week`: week 1 is the one holding 4 January. */
77
+ function isoWeekSpan(year, week) {
78
+ const jan4 = dayNumber(year, 1, 4);
79
+ const mondayOffset = (((jan4 + 3) % 7) + 7) % 7; // 1970-01-01, day 0, was a Thursday
80
+ const first = jan4 - mondayOffset + 7 * (week - 1);
81
+ return [first, first + 6];
82
+ }
83
+ /** First and last day each frequency number covers. */
84
+ const FREQUENCY_SPAN = {
85
+ Q: (year, n) => monthSpan(year, 3 * n - 2, 3 * n),
86
+ S: (year, n) => monthSpan(year, 6 * n - 5, 6 * n),
87
+ T: (year, n) => monthSpan(year, 4 * n - 3, 4 * n),
88
+ M: (year, n) => monthSpan(year, n, n),
89
+ W: isoWeekSpan,
90
+ D: (year, n) => {
91
+ const day = dayNumber(year, 1, n);
92
+ return [day, day];
93
+ },
94
+ };
95
+ /**
96
+ * The period to send upstream, or why there is none.
97
+ *
98
+ * A literal already in the form both endpoints read comes back unchanged, letter
99
+ * case included. Otherwise it comes back rewritten to that form, the letter's case
100
+ * kept as sent: a frequency number with extra leading zeros is cut to its canonical
101
+ * width (`2020-Q01` → `2020-Q1`, `2020-W001` → `2020-W01`), a day of the year is
102
+ * always sent as three digits (`2026-D1` → `2026-D001`, the only width the
103
+ * Statistics API reads), and `YYYY-A1` is sent as `YYYY`, which the Statistics API
104
+ * reads and `YYYY-A1` it does not.
105
+ *
106
+ * Beyond the shape, every component must exist: month 01–12, quarter 1–4,
107
+ * semester 1–2, trimester 1–3, a week the ISO year has, a day the year has, and a
108
+ * real calendar day. Both endpoints accept some out-of-range components and
109
+ * silently roll them into a neighbouring period (`2020-13` becomes 2021-01 on the
110
+ * bulk endpoint, `2021-W53` becomes 2022-W01 on both), so an unchecked one returns
111
+ * data for a range the caller never asked for.
112
+ */
113
+ export function normalizePeriod(period) {
114
+ const match = PERIOD_SHAPE.exec(period);
115
+ if (!match)
116
+ return { problem: 'it is not one of the accepted period forms' };
117
+ const [, yearText = '', monthText, dayText, annual, letter, digits] = match;
118
+ const year = Number(yearText);
119
+ const wholeYear = () => {
120
+ const [firstDay, lastDay] = monthSpan(year, 1, 12);
121
+ return { firstDay, lastDay };
122
+ };
123
+ if (annual !== undefined)
124
+ return { period: yearText, ...wholeYear() };
125
+ if (monthText !== undefined) {
126
+ const month = Number(monthText);
127
+ if (month < 1 || month > 12)
128
+ return { problem: `month ${monthText} is outside 01–12` };
129
+ if (dayText === undefined) {
130
+ const [firstDay, lastDay] = monthSpan(year, month, month);
131
+ return { period, firstDay, lastDay };
132
+ }
133
+ const day = Number(dayText);
134
+ const last = daysInMonth(year, month);
135
+ if (day < 1 || day > last) {
136
+ return {
137
+ problem: `day ${dayText} does not exist: ${MONTH_NAMES[month - 1]} ${yearText} has ${last} days`,
138
+ };
139
+ }
140
+ const firstDay = dayNumber(year, month, day);
141
+ return { period, firstDay, lastDay: firstDay };
142
+ }
143
+ if (letter === undefined || digits === undefined)
144
+ return { period, ...wholeYear() };
145
+ const kind = letter.toUpperCase();
146
+ const n = Number(digits);
147
+ const { name, max, width } = COMPONENT[kind];
148
+ if (n < 1 || n > max)
149
+ return { problem: `${name} ${n} is outside 1–${max}` };
150
+ if (kind === 'W' && n > isoWeeksInYear(year)) {
151
+ return { problem: `week ${n} does not exist: ${yearText} has 52 ISO weeks` };
152
+ }
153
+ if (kind === 'D' && n === 366 && !isLeapYear(year)) {
154
+ return { problem: `day 366 does not exist: ${yearText} has 365 days` };
155
+ }
156
+ const number = digits.length < width && kind !== 'D' ? digits : String(n).padStart(width, '0');
157
+ const [firstDay, lastDay] = FREQUENCY_SPAN[kind](year, n);
158
+ return { period: `${yearText}-${letter}${number}`, firstDay, lastDay };
159
+ }
160
+ /**
161
+ * Check both period bounds, `since_period` first, and return them in the form to
162
+ * send upstream (and echo back). Pass the values after trimming — a blank bound is
163
+ * "no bound" and never reaches this check.
164
+ *
165
+ * With both bounds set, the range must hold at least one day: it is empty when
166
+ * `since_period`'s period starts after `until_period`'s ends. Comparing the start of
167
+ * one against the end of the other keeps a cross-frequency pair such as `2020-06`
168
+ * to `2020` valid. Neither endpoint rejects an inverted range — the Statistics API
169
+ * answers with everything outside the gap, the bulk endpoint with the whole series.
170
+ *
171
+ * Returns the first failure's caller-facing message — naming the parameter, the
172
+ * value as sent, and what is wrong with it — rather than throwing, so the calling
173
+ * tool raises it through its own typed error contract.
174
+ */
175
+ export function resolvePeriods(bounds) {
176
+ const checked = {};
177
+ for (const param of ['since_period', 'until_period']) {
178
+ const value = bounds[param];
179
+ if (value === undefined)
180
+ continue;
181
+ const result = normalizePeriod(value);
182
+ if ('problem' in result) {
183
+ const shown = value.length > ECHO_LIMIT ? `${value.slice(0, ECHO_LIMIT)}…` : value;
184
+ return {
185
+ ok: false,
186
+ message: `${param} "${shown}" is not a valid period: ${result.problem}.`,
187
+ };
188
+ }
189
+ checked[param] = result;
190
+ }
191
+ const { since_period: since, until_period: until } = checked;
192
+ if (since && until && since.firstDay > until.lastDay) {
193
+ return {
194
+ ok: false,
195
+ message: `since_period "${bounds.since_period}" starts after until_period "${bounds.until_period}" ends, so the range holds no period.`,
196
+ };
197
+ }
198
+ return {
199
+ ok: true,
200
+ ...(since && { since_period: since.period }),
201
+ ...(until && { until_period: until.period }),
202
+ };
203
+ }
204
+ //# sourceMappingURL=eurostat-periods.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eurostat-periods.js","sourceRoot":"","sources":["../../src/services/eurostat-periods.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyanheads/eurostat-mcp-server",
3
- "version": "0.6.5",
3
+ "version": "0.7.0",
4
4
  "mcpName": "io.github.cyanheads/eurostat-mcp-server",
5
5
  "description": "Search and query the Eurostat catalogue — EU economy, demography, trade, health, and NUTS regional data via MCP. STDIO or Streamable HTTP.",
6
6
  "type": "module",
@@ -95,7 +95,7 @@
95
95
  },
96
96
  "devDependencies": {
97
97
  "@biomejs/biome": "2.5.14",
98
- "@socketsecurity/bun-security-scanner": "^1.1.2",
98
+ "@socketsecurity/bun-security-scanner": "^1.1.3",
99
99
  "@types/node": "26.6.2",
100
100
  "depcheck": "^1.4.7",
101
101
  "ignore": "^7.0.9",
package/server.json CHANGED
@@ -12,14 +12,14 @@
12
12
  "url": "https://eurostat.caseyjhand.com/mcp"
13
13
  }
14
14
  ],
15
- "version": "0.6.5",
15
+ "version": "0.7.0",
16
16
  "packages": [
17
17
  {
18
18
  "registryType": "npm",
19
19
  "registryBaseUrl": "https://registry.npmjs.org",
20
20
  "identifier": "@cyanheads/eurostat-mcp-server",
21
21
  "runtimeHint": "bun",
22
- "version": "0.6.5",
22
+ "version": "0.7.0",
23
23
  "packageArguments": [
24
24
  {
25
25
  "type": "positional",
@@ -110,7 +110,7 @@
110
110
  "registryBaseUrl": "https://registry.npmjs.org",
111
111
  "identifier": "@cyanheads/eurostat-mcp-server",
112
112
  "runtimeHint": "bun",
113
- "version": "0.6.5",
113
+ "version": "0.7.0",
114
114
  "packageArguments": [
115
115
  {
116
116
  "type": "positional",