@cyanheads/exchange-rates-mcp-server 0.3.2 → 0.4.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 +44 -17
- package/CLAUDE.md +44 -17
- package/README.md +90 -72
- package/changelog/0.4.x/0.4.0.md +22 -0
- package/changelog/0.4.x/0.4.1.md +27 -0
- package/changelog/template.md +9 -26
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-describe.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-describe.tool.js +2 -3
- package/dist/mcp-server/tools/definitions/fx-dataframe-describe.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-drop.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-drop.tool.js +2 -3
- package/dist/mcp-server/tools/definitions/fx-dataframe-drop.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-query.tool.d.ts +4 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-query.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-dataframe-query.tool.js +54 -22
- package/dist/mcp-server/tools/definitions/fx-dataframe-query.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-get-timeseries.tool.d.ts +2 -0
- package/dist/mcp-server/tools/definitions/fx-get-timeseries.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/fx-get-timeseries.tool.js +115 -86
- package/dist/mcp-server/tools/definitions/fx-get-timeseries.tool.js.map +1 -1
- package/dist/services/frankfurter/errors.d.ts +6 -1
- package/dist/services/frankfurter/errors.d.ts.map +1 -1
- package/dist/services/frankfurter/errors.js +6 -2
- package/dist/services/frankfurter/errors.js.map +1 -1
- package/dist/services/frankfurter/frankfurter-service.d.ts.map +1 -1
- package/dist/services/frankfurter/frankfurter-service.js +12 -4
- package/dist/services/frankfurter/frankfurter-service.js.map +1 -1
- package/dist/utils/escape-markdown-table-cell.d.ts +11 -0
- package/dist/utils/escape-markdown-table-cell.d.ts.map +1 -0
- package/dist/utils/escape-markdown-table-cell.js +19 -0
- package/dist/utils/escape-markdown-table-cell.js.map +1 -0
- package/package.json +8 -7
- package/server.json +3 -3
|
@@ -3,23 +3,32 @@
|
|
|
3
3
|
* @module mcp-server/tools/definitions/fx-get-timeseries.tool
|
|
4
4
|
*/
|
|
5
5
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
-
import { spillover } from '@cyanheads/mcp-ts-core/canvas';
|
|
6
|
+
import { CanvasIdSchema, spillover } from '@cyanheads/mcp-ts-core/canvas';
|
|
7
7
|
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
8
8
|
import { getServerConfig } from '../../../config/server-config.js';
|
|
9
9
|
import { getCanvas } from '../../../services/canvas/canvas-accessor.js';
|
|
10
10
|
import { failureOf, unsupportedCurrencyCodesOf } from '../../../services/frankfurter/errors.js';
|
|
11
11
|
import { ECB_START_DATE, getFrankfurterService, isIsoDate, } from '../../../services/frankfurter/frankfurter-service.js';
|
|
12
|
+
/**
|
|
13
|
+
* Most publication days one inline response carries — roughly two ECB years, ~21 KB
|
|
14
|
+
* serialized across both response surfaces. Rows are date-keyed, so the continuation
|
|
15
|
+
* is the next start_date rather than an offset.
|
|
16
|
+
*/
|
|
17
|
+
const INLINE_PAGE_SIZE = 500;
|
|
12
18
|
export const fxGetTimeseries = tool('fx_get_timeseries', {
|
|
13
19
|
description: 'Get historical daily exchange rates for a currency pair over a date range. ' +
|
|
14
20
|
'ECB publishes on business days only — weekends and holidays produce no entry, and no date ' +
|
|
15
21
|
'outside the requested range is ever returned, so a range covering only non-publication days ' +
|
|
16
22
|
'comes back with an empty rates map and a notice explaining why. ' +
|
|
17
23
|
'A same-currency pair returns a rate of 1 on each publication day in the range. ' +
|
|
18
|
-
|
|
19
|
-
'
|
|
20
|
-
'carries
|
|
21
|
-
'
|
|
22
|
-
'
|
|
24
|
+
`Inline results are returned as a date→rate map paged at ${INLINE_PAGE_SIZE} publication days: ` +
|
|
25
|
+
'rate_count is always the total for the requested range, and when a page is cut short the ' +
|
|
26
|
+
'response carries truncated=true and next_start_date — call again with start_date set to ' +
|
|
27
|
+
'next_start_date and the same end_date for the next page. ' +
|
|
28
|
+
'When DataCanvas is enabled (CANVAS_PROVIDER_TYPE=duckdb) long ranges (>90 days by default) spill ' +
|
|
29
|
+
'to it instead: the response carries spilled=true, a canvas_id, and a table_name — call ' +
|
|
30
|
+
'fx_dataframe_describe to inspect the staged table, then fx_dataframe_query to run SQL against it. ' +
|
|
31
|
+
'Without DataCanvas long ranges are paged inline (spilled=false) and the notice says so.',
|
|
23
32
|
annotations: {
|
|
24
33
|
readOnlyHint: true,
|
|
25
34
|
idempotentHint: true,
|
|
@@ -39,10 +48,7 @@ export const fxGetTimeseries = tool('fx_get_timeseries', {
|
|
|
39
48
|
end_date: z
|
|
40
49
|
.string()
|
|
41
50
|
.describe('ISO 8601 end date (YYYY-MM-DD). Must be >= start_date. Future dates are not supported.'),
|
|
42
|
-
canvas_id:
|
|
43
|
-
.string()
|
|
44
|
-
.optional()
|
|
45
|
-
.describe('Optional canvas ID from a prior call. Omit on the first call to start a fresh canvas; ' +
|
|
51
|
+
canvas_id: CanvasIdSchema.optional().describe('Optional canvas ID from a prior call. Omit on the first call to start a fresh canvas; ' +
|
|
46
52
|
'pass the returned canvas_id to append tables to an existing canvas.'),
|
|
47
53
|
}),
|
|
48
54
|
output: z.object({
|
|
@@ -50,20 +56,35 @@ export const fxGetTimeseries = tool('fx_get_timeseries', {
|
|
|
50
56
|
quote_currency: z.string().describe('Quote currency code.'),
|
|
51
57
|
start_date: z
|
|
52
58
|
.string()
|
|
53
|
-
.describe('First date in the
|
|
54
|
-
'requested start when that day had no ECB fix, and
|
|
59
|
+
.describe('First publication date in the requested range, and the first key in rates. Always inside ' +
|
|
60
|
+
'the requested range — later than the requested start when that day had no ECB fix, and ' +
|
|
61
|
+
'equal to it when the series is empty.'),
|
|
55
62
|
end_date: z
|
|
56
63
|
.string()
|
|
57
|
-
.describe('Last date in the
|
|
58
|
-
'requested end when that day had no ECB fix, and equal to it when the series is
|
|
64
|
+
.describe('Last publication date in the requested range. Always inside the requested range — earlier ' +
|
|
65
|
+
'than the requested end when that day had no ECB fix, and equal to it when the series is ' +
|
|
66
|
+
'empty. Later than the last key in rates when truncated is true.'),
|
|
59
67
|
rates: z
|
|
60
68
|
.record(z.string(), z.number())
|
|
61
|
-
.describe('Date → rate map
|
|
62
|
-
|
|
63
|
-
'
|
|
69
|
+
.describe('Date → rate map in date order, publication days inside the requested range only. Holds ' +
|
|
70
|
+
`every publication day when truncated is false; otherwise the first ${INLINE_PAGE_SIZE} of an ` +
|
|
71
|
+
'inline page (continue with next_start_date) or the preview of a spilled series (the full ' +
|
|
72
|
+
'series is on the canvas). Empty when the range contains no publication day at all.'),
|
|
64
73
|
rate_count: z
|
|
65
74
|
.number()
|
|
66
|
-
.describe('Total
|
|
75
|
+
.describe('Total publication days in the requested range (the start_date through end_date passed on ' +
|
|
76
|
+
'this call) — not the number of entries in rates, which is smaller when truncated is true. ' +
|
|
77
|
+
'On a continuation call it counts the days from that start_date onward.'),
|
|
78
|
+
truncated: z
|
|
79
|
+
.boolean()
|
|
80
|
+
.describe('True when rates holds only part of the series: an inline page (next_start_date continues ' +
|
|
81
|
+
'it) or a spilled preview (spilled is true). False when rates holds every publication day ' +
|
|
82
|
+
'in the requested range.'),
|
|
83
|
+
next_start_date: z
|
|
84
|
+
.string()
|
|
85
|
+
.optional()
|
|
86
|
+
.describe('Present only when an inline page was cut short: the first publication date not in rates. ' +
|
|
87
|
+
'Pass it as start_date with the same end_date to get the next page. Absent on the final page.'),
|
|
67
88
|
rate_type: z
|
|
68
89
|
.string()
|
|
69
90
|
.describe('Always "ECB reference (mid-market)" — these are reference rates, not tradeable bid/ask.'),
|
|
@@ -74,18 +95,22 @@ export const fxGetTimeseries = tool('fx_get_timeseries', {
|
|
|
74
95
|
canvas_id: z
|
|
75
96
|
.string()
|
|
76
97
|
.optional()
|
|
77
|
-
.describe('Canvas ID — present when spilled is true. Pass to
|
|
98
|
+
.describe('Canvas ID — present when spilled is true. Pass to fx_dataframe_describe to inspect the ' +
|
|
99
|
+
'staged table, then to fx_dataframe_query to run SQL.'),
|
|
78
100
|
table_name: z
|
|
79
101
|
.string()
|
|
80
102
|
.optional()
|
|
81
|
-
.describe('Canvas table name — present when spilled is true. Use in
|
|
103
|
+
.describe('Canvas table name — present when spilled is true. Use it as the FROM target in ' +
|
|
104
|
+
'fx_dataframe_query SQL; fx_dataframe_describe lists its columns.'),
|
|
82
105
|
}),
|
|
83
106
|
enrichment: {
|
|
84
107
|
notice: z
|
|
85
108
|
.string()
|
|
86
109
|
.optional()
|
|
87
|
-
.describe('Explains a result that would otherwise look broken
|
|
88
|
-
'
|
|
110
|
+
.describe('Explains a result that would otherwise look broken or incomplete: an empty series (no ' +
|
|
111
|
+
'publication day in the range); an inline page cut short (the start_date to continue ' +
|
|
112
|
+
'from, plus why a long range was not staged when DataCanvas is not configured); or a ' +
|
|
113
|
+
'spilled series (the canvas and table it was staged to, and the tools that read it).'),
|
|
89
114
|
},
|
|
90
115
|
errors: [
|
|
91
116
|
{
|
|
@@ -181,23 +206,7 @@ export const fxGetTimeseries = tool('fx_get_timeseries', {
|
|
|
181
206
|
});
|
|
182
207
|
const canvas = getCanvas();
|
|
183
208
|
const exceedsThreshold = dayCount > config.timeseriesCanvasThresholdDays;
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* An empty series and a long range that never spilled both look like failures
|
|
187
|
-
* from the outside. Say which one happened and why, on both client surfaces.
|
|
188
|
-
*/
|
|
189
|
-
if (rows.length === 0) {
|
|
190
|
-
ctx.enrich.notice(`The ECB published no ${input.base_currency.toUpperCase()}/${input.quote_currency.toUpperCase()} rate between ` +
|
|
191
|
-
`${input.start_date} and ${input.end_date}. Reference rates are published on TARGET business days ` +
|
|
192
|
-
'only, so a range covering just a weekend or a bank holiday is legitimately empty rather than ' +
|
|
193
|
-
'broken. Widen the range — a window spanning several weekdays will contain a publication day.');
|
|
194
|
-
}
|
|
195
|
-
else if (exceedsThreshold && canvas == null) {
|
|
196
|
-
ctx.enrich.notice(`This ${dayCount}-day range is past the ${config.timeseriesCanvasThresholdDays}-day spill threshold, but ` +
|
|
197
|
-
'DataCanvas is not configured on this server, so the full series is inline and spilled is false. ' +
|
|
198
|
-
'Set CANVAS_PROVIDER_TYPE=duckdb to stage long ranges for SQL instead.');
|
|
199
|
-
}
|
|
200
|
-
/** Fields every branch below returns identically — only rates/count/spill differ. */
|
|
209
|
+
/** Fields every branch below returns identically — only rates/count/paging/spill differ. */
|
|
201
210
|
const envelope = {
|
|
202
211
|
base_currency: input.base_currency.toUpperCase(),
|
|
203
212
|
quote_currency: input.quote_currency.toUpperCase(),
|
|
@@ -206,72 +215,92 @@ export const fxGetTimeseries = tool('fx_get_timeseries', {
|
|
|
206
215
|
rate_type: 'ECB reference (mid-market)',
|
|
207
216
|
source: 'ECB via Frankfurter',
|
|
208
217
|
};
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
218
|
+
if (canvas != null && exceedsThreshold) {
|
|
219
|
+
const instance = await canvas.acquire(input.canvas_id, ctx);
|
|
220
|
+
const tableName = `fx_${input.base_currency.toLowerCase()}_${input.quote_currency.toLowerCase()}`;
|
|
221
|
+
const spillResult = await spillover({
|
|
222
|
+
canvas: instance,
|
|
223
|
+
source: rows,
|
|
224
|
+
tableName,
|
|
225
|
+
previewChars: 40_000, // ~10k tokens preview
|
|
226
|
+
signal: ctx.signal,
|
|
227
|
+
});
|
|
228
|
+
ctx.log.info('Spilled to canvas', {
|
|
229
|
+
canvasId: instance.canvasId,
|
|
230
|
+
tableName,
|
|
231
|
+
rowCount: rows.length,
|
|
232
|
+
spilled: spillResult.spilled,
|
|
233
|
+
});
|
|
234
|
+
if (spillResult.spilled) {
|
|
235
|
+
const { rowCount, tableName: stagedTable } = spillResult.handle;
|
|
236
|
+
ctx.enrich.notice(`Staged ${rowCount} rows to table "${stagedTable}" on canvas ${instance.canvasId} — call ` +
|
|
237
|
+
'fx_dataframe_describe to inspect its columns, then fx_dataframe_query to run SQL over the ' +
|
|
238
|
+
'full series. rates holds only a preview.');
|
|
239
|
+
return {
|
|
240
|
+
...envelope,
|
|
241
|
+
rates: Object.fromEntries(spillResult.previewRows.map((row) => [row.date, row.rate])),
|
|
242
|
+
rate_count: rowCount,
|
|
243
|
+
truncated: true,
|
|
244
|
+
spilled: true,
|
|
245
|
+
canvas_id: instance.canvasId,
|
|
246
|
+
table_name: stagedTable,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
// Every row fit the preview budget, so nothing was staged — page it inline below.
|
|
215
250
|
}
|
|
216
|
-
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
|
|
251
|
+
const page = rows.slice(0, INLINE_PAGE_SIZE);
|
|
252
|
+
const nextRow = rows[INLINE_PAGE_SIZE];
|
|
253
|
+
/**
|
|
254
|
+
* An empty series, a page cut short, and a long range that never spilled all look
|
|
255
|
+
* incomplete or broken from the outside. Say which one happened, on both surfaces.
|
|
256
|
+
* The dataframe tools are unregistered without a canvas, so nothing here names them.
|
|
257
|
+
*/
|
|
258
|
+
const unstaged = exceedsThreshold && canvas == null
|
|
259
|
+
? `This ${dayCount}-day range is past the ${config.timeseriesCanvasThresholdDays}-day spill threshold, but ` +
|
|
260
|
+
'DataCanvas is not configured on this server, so the series is returned inline and spilled is false. ' +
|
|
261
|
+
'Set CANVAS_PROVIDER_TYPE=duckdb to stage long ranges for SQL instead.'
|
|
262
|
+
: undefined;
|
|
263
|
+
if (rows.length === 0) {
|
|
264
|
+
ctx.enrich.notice(`The ECB published no ${envelope.base_currency}/${envelope.quote_currency} rate between ` +
|
|
265
|
+
`${input.start_date} and ${input.end_date}. Reference rates are published on TARGET business days ` +
|
|
266
|
+
'only, so a range covering just a weekend or a bank holiday is legitimately empty rather than ' +
|
|
267
|
+
'broken. Widen the range — a window spanning several weekdays will contain a publication day.');
|
|
268
|
+
}
|
|
269
|
+
else if (nextRow) {
|
|
270
|
+
const pageNote = `rates holds the first ${page.length} of ${rows.length} publication days ` +
|
|
271
|
+
`(${page[0]?.date} to ${page.at(-1)?.date}). Call fx_get_timeseries again with ` +
|
|
272
|
+
`start_date=${nextRow.date} and end_date=${input.end_date} for the next page.`;
|
|
273
|
+
ctx.enrich.notice(unstaged ? `${pageNote} ${unstaged}` : pageNote);
|
|
237
274
|
}
|
|
238
|
-
if (
|
|
239
|
-
|
|
240
|
-
...envelope,
|
|
241
|
-
rates: previewRates,
|
|
242
|
-
rate_count: spillResult.handle.rowCount,
|
|
243
|
-
spilled: true,
|
|
244
|
-
canvas_id: instance.canvasId,
|
|
245
|
-
table_name: spillResult.handle.tableName,
|
|
246
|
-
};
|
|
275
|
+
else if (unstaged) {
|
|
276
|
+
ctx.enrich.notice(unstaged);
|
|
247
277
|
}
|
|
248
|
-
// Fell under budget even at canvas threshold — return inline
|
|
249
278
|
return {
|
|
250
279
|
...envelope,
|
|
251
|
-
rates:
|
|
252
|
-
rate_count:
|
|
280
|
+
rates: Object.fromEntries(page.map((row) => [row.date, row.rate])),
|
|
281
|
+
rate_count: rows.length,
|
|
282
|
+
truncated: nextRow !== undefined,
|
|
283
|
+
...(nextRow && { next_start_date: nextRow.date }),
|
|
253
284
|
spilled: false,
|
|
254
285
|
};
|
|
255
286
|
},
|
|
256
287
|
format: (result) => {
|
|
288
|
+
const rateEntries = Object.entries(result.rates).sort(([a], [b]) => a.localeCompare(b));
|
|
257
289
|
const lines = [
|
|
258
290
|
`**${result.base_currency}/${result.quote_currency} time series** — ${result.start_date} to ${result.end_date}`,
|
|
259
|
-
`*${result.rate_count} publication-day data points · ${result.rate_type} · ${result.source} · spilled: ${result.spilled}*`,
|
|
291
|
+
`*${result.rate_count} publication-day data points in range · ${result.rate_type} · ${result.source} · spilled: ${result.spilled}*`,
|
|
292
|
+
`*${rateEntries.length} shown · truncated: ${result.truncated}` +
|
|
293
|
+
(result.next_start_date ? ` · next_start_date: ${result.next_start_date}*` : '*'),
|
|
260
294
|
];
|
|
261
295
|
if (result.spilled) {
|
|
262
|
-
lines.push(`\n📊 **Result staged on DataCanvas** (large range)`, `Canvas ID: \`${result.canvas_id}\``, `Table: \`${result.table_name}\``, `
|
|
296
|
+
lines.push(`\n📊 **Result staged on DataCanvas** (large range)`, `Canvas ID: \`${result.canvas_id}\``, `Table: \`${result.table_name}\``, 'Call `fx_dataframe_describe` with this canvas_id to inspect the table columns, then ' +
|
|
297
|
+
'`fx_dataframe_query` to run SQL over the full series. Preview (first entries below):');
|
|
263
298
|
}
|
|
264
|
-
const rateEntries = Object.entries(result.rates)
|
|
265
|
-
.sort(([a], [b]) => a.localeCompare(b))
|
|
266
|
-
.slice(0, 20);
|
|
267
299
|
if (rateEntries.length > 0) {
|
|
268
300
|
lines.push('');
|
|
269
301
|
for (const [date, rate] of rateEntries) {
|
|
270
302
|
lines.push(`${date}: ${rate}`);
|
|
271
303
|
}
|
|
272
|
-
if (Object.keys(result.rates).length > 20) {
|
|
273
|
-
lines.push(`... (${Object.keys(result.rates).length - 20} more entries)`);
|
|
274
|
-
}
|
|
275
304
|
}
|
|
276
305
|
return [{ type: 'text', text: lines.join('\n') }];
|
|
277
306
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fx-get-timeseries.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-get-timeseries.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"fx-get-timeseries.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/fx-get-timeseries.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,8 +40,13 @@ export declare function unsupportedCurrency(field: string, rejected: string[], a
|
|
|
40
40
|
* The ECB published no rates for an otherwise well-formed request — most often a
|
|
41
41
|
* date that predates the requested currency's series (ILS and BRL start well after
|
|
42
42
|
* the 1999-01-04 ECB epoch).
|
|
43
|
+
*
|
|
44
|
+
* The upstream request URL is deliberately absent: `McpError.data` reaches the
|
|
45
|
+
* client as `structuredContent.error.data`, and the URL carries both the caller's
|
|
46
|
+
* inputs and the configured Frankfurter host. The calling tool re-raises with a
|
|
47
|
+
* message naming the pair and dates it asked for, which is the part a caller can act on.
|
|
43
48
|
*/
|
|
44
|
-
export declare function upstreamNoData(
|
|
49
|
+
export declare function upstreamNoData(): McpError;
|
|
45
50
|
/**
|
|
46
51
|
* Read the structured failure off a service-thrown error.
|
|
47
52
|
* Returns `undefined` for anything the service did not classify.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/services/frankfurter/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAA6B,MAAM,+BAA+B,CAAC;AAEpF;;;GAGG;AACH,QAAA,MAAM,eAAe,YACnB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,CACV,CAAC;AAEX,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,+FAA+F;IAC/F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,MAAM,EAAE,wBAAwB,CAAC;CAClC;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAMxE;AAED,mFAAmF;AACnF,MAAM,WAAW,wBAAwB;IACvC,0EAA0E;IAC1E,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,4CAA4C;IAC5C,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,MAAM,EAAE,GACjB,QAAQ,CAWV;AAED
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/services/frankfurter/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAA6B,MAAM,+BAA+B,CAAC;AAEpF;;;GAGG;AACH,QAAA,MAAM,eAAe,YACnB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,CACV,CAAC;AAEX,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,+FAA+F;IAC/F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,MAAM,EAAE,wBAAwB,CAAC;CAClC;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAMxE;AAED,mFAAmF;AACnF,MAAM,WAAW,wBAAwB;IACvC,0EAA0E;IAC1E,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,4CAA4C;IAC5C,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,MAAM,EAAE,GACjB,QAAQ,CAWV;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,IAAI,QAAQ,CAIzC;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,SAAS,CASxE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,GAAG,SAAS,CAK/F"}
|
|
@@ -45,11 +45,15 @@ export function unsupportedCurrency(field, rejected, accepted) {
|
|
|
45
45
|
* The ECB published no rates for an otherwise well-formed request — most often a
|
|
46
46
|
* date that predates the requested currency's series (ILS and BRL start well after
|
|
47
47
|
* the 1999-01-04 ECB epoch).
|
|
48
|
+
*
|
|
49
|
+
* The upstream request URL is deliberately absent: `McpError.data` reaches the
|
|
50
|
+
* client as `structuredContent.error.data`, and the URL carries both the caller's
|
|
51
|
+
* inputs and the configured Frankfurter host. The calling tool re-raises with a
|
|
52
|
+
* message naming the pair and dates it asked for, which is the part a caller can act on.
|
|
48
53
|
*/
|
|
49
|
-
export function upstreamNoData(
|
|
54
|
+
export function upstreamNoData() {
|
|
50
55
|
return notFound('The ECB published no rates for this request.', {
|
|
51
56
|
reason: 'upstream_no_data',
|
|
52
|
-
url,
|
|
53
57
|
});
|
|
54
58
|
}
|
|
55
59
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/services/frankfurter/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEpF;;;GAGG;AACH,MAAM,eAAe,GAAG;IACtB,qBAAqB;IACrB,sBAAsB;IACtB,kBAAkB;CACV,CAAC;AAYX,gEAAgE;AAChE,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,KAAa;IAC5D,OAAO,eAAe,CAAC,GAAG,KAAK,KAAK,KAAK,4CAA4C,EAAE;QACrF,KAAK;QACL,MAAM,EAAE,qBAAqB;QAC7B,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAUD;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,QAAkB,EAClB,QAAkB;IAElB,MAAM,SAAS,GACb,QAAQ,CAAC,MAAM,KAAK,CAAC;QACnB,CAAC,CAAC,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,gCAAgC;QAC1D,CAAC,CAAC,GAAG,KAAK,6CAA6C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAClF,OAAO,eAAe,CAAC,GAAG,SAAS,cAAc,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;QACvE,cAAc,EAAE,QAAQ;QACxB,KAAK;QACL,MAAM,EAAE,sBAAsB;QAC9B,cAAc,EAAE,QAAQ;KACzB,CAAC,CAAC;AACL,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/services/frankfurter/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEpF;;;GAGG;AACH,MAAM,eAAe,GAAG;IACtB,qBAAqB;IACrB,sBAAsB;IACtB,kBAAkB;CACV,CAAC;AAYX,gEAAgE;AAChE,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,KAAa;IAC5D,OAAO,eAAe,CAAC,GAAG,KAAK,KAAK,KAAK,4CAA4C,EAAE;QACrF,KAAK;QACL,MAAM,EAAE,qBAAqB;QAC7B,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAUD;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,QAAkB,EAClB,QAAkB;IAElB,MAAM,SAAS,GACb,QAAQ,CAAC,MAAM,KAAK,CAAC;QACnB,CAAC,CAAC,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,gCAAgC;QAC1D,CAAC,CAAC,GAAG,KAAK,6CAA6C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAClF,OAAO,eAAe,CAAC,GAAG,SAAS,cAAc,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;QACvE,cAAc,EAAE,QAAQ;QACxB,KAAK;QACL,MAAM,EAAE,sBAAsB;QAC9B,cAAc,EAAE,QAAQ;KACzB,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,QAAQ,CAAC,8CAA8C,EAAE;QAC9D,MAAM,EAAE,kBAAkB;KAC3B,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,IAAI,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC;QAAE,OAAO;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAyD,CAAC;IAC7E,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,EAAE,MAAM,CAAC,CAAC;IACvE,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO;IACjC,OAAO;QACL,GAAG,CAAC,OAAO,IAAI,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,KAAc;IACvD,IAAI,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC;QAAE,OAAO;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAqD,CAAC;IACzE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC;QAAE,OAAO;IACzF,OAAO,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC;AACtF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frankfurter-service.d.ts","sourceRoot":"","sources":["../../../src/services/frankfurter/frankfurter-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EACV,QAAQ,EAER,uBAAuB,EAEvB,YAAY,EAEZ,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,6EAA6E;AAC7E,QAAA,MAAM,cAAc,eAAe,CAAC;AAQpC;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIhD;AAkBD,6DAA6D;AAC7D,wBAAgB,qBAAqB,IAAI,kBAAkB,CAG1D;AAED,2CAA2C;AAC3C,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED,cAAM,kBAAkB;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,aAAa,CAAC,CAA8D;IAEpF,cAGC;IAID,wFAAwF;IAClF,cAAc,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAE1C;IAED,kFAAkF;YACpE,UAAU;IAaxB;;;;;OAKG;YACW,yBAAyB;IAcvC;;;;;;;;;;;;;;;;;;OAkBG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAgC9E;IAID;;;;;;;OAOG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA0B/F;IAID;;;;;;;;;;;;;;;OAeG;IACG,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,CAAC,CAyC3B;IAID,OAAO,CAAC,SAAS;
|
|
1
|
+
{"version":3,"file":"frankfurter-service.d.ts","sourceRoot":"","sources":["../../../src/services/frankfurter/frankfurter-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EACV,QAAQ,EAER,uBAAuB,EAEvB,YAAY,EAEZ,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,6EAA6E;AAC7E,QAAA,MAAM,cAAc,eAAe,CAAC;AAQpC;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIhD;AAkBD,6DAA6D;AAC7D,wBAAgB,qBAAqB,IAAI,kBAAkB,CAG1D;AAED,2CAA2C;AAC3C,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED,cAAM,kBAAkB;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,aAAa,CAAC,CAA8D;IAEpF,cAGC;IAID,wFAAwF;IAClF,cAAc,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAE1C;IAED,kFAAkF;YACpE,UAAU;IAaxB;;;;;OAKG;YACW,yBAAyB;IAcvC;;;;;;;;;;;;;;;;;;OAkBG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAgC9E;IAID;;;;;;;OAOG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA0B/F;IAID;;;;;;;;;;;;;;;OAeG;IACG,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,CAAC,CAyC3B;IAID,OAAO,CAAC,SAAS;CA8ClB;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -127,7 +127,7 @@ class FrankfurterService {
|
|
|
127
127
|
const raw = await this.fetchJson(url);
|
|
128
128
|
const quotedRate = raw.rates[quoted];
|
|
129
129
|
if (quotedRate === undefined)
|
|
130
|
-
throw upstreamNoData(
|
|
130
|
+
throw upstreamNoData();
|
|
131
131
|
const rate = identity ? 1 : quotedRate;
|
|
132
132
|
const dateSnapped = date !== 'latest' && raw.date !== date;
|
|
133
133
|
return {
|
|
@@ -248,7 +248,15 @@ class FrankfurterService {
|
|
|
248
248
|
});
|
|
249
249
|
}
|
|
250
250
|
catch (err) {
|
|
251
|
-
|
|
251
|
+
/**
|
|
252
|
+
* `error.data` is forwarded to the client as `structuredContent.error.data`,
|
|
253
|
+
* and the request URL carries the caller's codes and dates plus whatever host
|
|
254
|
+
* `FRANKFURTER_BASE_URL` points at — so nothing thrown here puts it on the wire.
|
|
255
|
+
* The cause keeps the underlying fetch failure reachable server-side.
|
|
256
|
+
*/
|
|
257
|
+
throw serviceUnavailable(`Frankfurter API unreachable: ${err.message}`, undefined, {
|
|
258
|
+
cause: err,
|
|
259
|
+
});
|
|
252
260
|
}
|
|
253
261
|
if (!response.ok) {
|
|
254
262
|
/**
|
|
@@ -259,8 +267,8 @@ class FrankfurterService {
|
|
|
259
267
|
* input failure is surfaced immediately instead of burning retries.
|
|
260
268
|
*/
|
|
261
269
|
if (response.status === 404)
|
|
262
|
-
throw upstreamNoData(
|
|
263
|
-
throw await httpErrorFromResponse(response, {
|
|
270
|
+
throw upstreamNoData();
|
|
271
|
+
throw await httpErrorFromResponse(response, { service: 'Frankfurter' });
|
|
264
272
|
}
|
|
265
273
|
return response.json();
|
|
266
274
|
}, { maxRetries: 2, baseDelayMs: 500 });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frankfurter-service.js","sourceRoot":"","sources":["../../../src/services/frankfurter/frankfurter-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAWrF,6EAA6E;AAC7E,MAAM,cAAc,GAAG,YAAY,CAAC;AAEpC,6FAA6F;AAC7F,MAAM,cAAc,GAAG,qBAAqB,CAAC;AAE7C,uFAAuF;AACvF,MAAM,qBAAqB,GAAG,UAAU,CAAC;AAEzC;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC;IAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC;AACxF,CAAC;AAED,8FAA8F;AAC9F,SAAS,gBAAgB,CAAC,IAAY,EAAE,KAAa;IACnD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAAE,MAAM,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACxC,CAAC;AAED,IAAI,QAAwC,CAAC;AAE7C,6DAA6D;AAC7D,MAAM,UAAU,qBAAqB;IACnC,QAAQ,KAAK,IAAI,kBAAkB,EAAE,CAAC;IACtC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,uBAAuB;IACrC,QAAQ,GAAG,SAAS,CAAC;AACvB,CAAC;AAED,MAAM,kBAAkB;IACL,OAAO,CAAS;IACjC;;;;OAIG;IACc,SAAS,CAAS;IAC3B,aAAa,CAA+D;IAEpF;QACE,IAAI,CAAC,OAAO,GAAG,eAAe,EAAE,CAAC,kBAAkB,CAAC;QACpD,IAAI,CAAC,SAAS,GAAG,6BAA6B,MAAM,CAAC,gBAAgB,EAAE,CAAC;IAC1E,CAAC;IAED,+EAA+E;IAE/E,wFAAwF;IACxF,KAAK,CAAC,cAAc;QAClB,OAAO,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC;IACxC,CAAC;IAED,kFAAkF;IAC1E,KAAK,CAAC,UAAU;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC;QAClC,IAAI,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,qBAAqB;YAAE,OAAO,MAAM,CAAC;QAEpF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAc,aAAa,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;aAC7B,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;aACvC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC;QACvF,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,yBAAyB,CAAC,KAAa,EAAE,KAAe;QACpE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3D,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACjE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,mBAAmB,CACvB,KAAK,EACL,WAAW,EACX,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CACtC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,+EAA+E;IAE/E;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,KAAa,EAAE,IAAY;QACrD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACtC,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACxC,IAAI,IAAI,KAAK,QAAQ;YAAE,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,IAAI,CAAC,yBAAyB,CAAC,eAAe,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QACpE,MAAM,IAAI,CAAC,yBAAyB,CAAC,gBAAgB,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;QAEtE,MAAM,QAAQ,GAAG,UAAU,KAAK,WAAW,CAAC;QAC5C,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QAElE,gFAAgF;QAChF,kDAAkD;QAClD,MAAM,QAAQ,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;QAChF,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1E,MAAM,GAAG,GAAG,GAAG,QAAQ,IAAI,MAAM,EAAE,CAAC;QAEpC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAA0B,GAAG,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,UAAU,KAAK,SAAS;YAAE,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"frankfurter-service.js","sourceRoot":"","sources":["../../../src/services/frankfurter/frankfurter-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Escapes a value for one cell of a GFM Markdown table.
|
|
3
|
+
* @module utils/escape-markdown-table-cell
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Renders `value` as the literal text of a single table cell: every metacharacter is
|
|
7
|
+
* backslash-escaped and each line break becomes `<br>`, so the value never leaves its
|
|
8
|
+
* row. A literal `<br>` in the data is escaped first and stays distinguishable from one.
|
|
9
|
+
*/
|
|
10
|
+
export declare function escapeMarkdownTableCell(value: string): string;
|
|
11
|
+
//# sourceMappingURL=escape-markdown-table-cell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escape-markdown-table-cell.d.ts","sourceRoot":"","sources":["../../src/utils/escape-markdown-table-cell.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7D"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Escapes a value for one cell of a GFM Markdown table.
|
|
3
|
+
* @module utils/escape-markdown-table-cell
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Markdown and HTML metacharacters that would split a table row (`|`), open a tag
|
|
7
|
+
* (`<`, `>`), or turn data into emphasis, code, links, strikethrough, or an entity.
|
|
8
|
+
* Backslash is in the set so an escape already present in the data stays literal.
|
|
9
|
+
*/
|
|
10
|
+
const METACHARACTERS = /[\\|<>*_`[\]~&]/g;
|
|
11
|
+
/**
|
|
12
|
+
* Renders `value` as the literal text of a single table cell: every metacharacter is
|
|
13
|
+
* backslash-escaped and each line break becomes `<br>`, so the value never leaves its
|
|
14
|
+
* row. A literal `<br>` in the data is escaped first and stays distinguishable from one.
|
|
15
|
+
*/
|
|
16
|
+
export function escapeMarkdownTableCell(value) {
|
|
17
|
+
return value.replace(METACHARACTERS, '\\$&').replace(/\r\n|\r|\n/g, '<br>');
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=escape-markdown-table-cell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escape-markdown-table-cell.js","sourceRoot":"","sources":["../../src/utils/escape-markdown-table-cell.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAE1C;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;AAC9E,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyanheads/exchange-rates-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"mcpName": "io.github.cyanheads/exchange-rates-mcp-server",
|
|
5
5
|
"description": "Convert currencies, get FX rates, and query historical ECB exchange rate data via MCP. STDIO or Streamable HTTP.",
|
|
6
6
|
"type": "module",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"rebuild": "bun run scripts/clean.ts && bun run scripts/build.ts",
|
|
25
25
|
"clean": "bun run scripts/clean.ts",
|
|
26
26
|
"devcheck": "bun run scripts/devcheck.ts",
|
|
27
|
+
"audit:fix": "bun audit fix",
|
|
27
28
|
"audit:refresh": "rm -f bun.lock && bun install && bun audit",
|
|
28
29
|
"tree": "bun run scripts/tree.ts",
|
|
29
30
|
"list-skills": "bun run scripts/list-skills.ts",
|
|
@@ -87,19 +88,19 @@
|
|
|
87
88
|
"access": "public"
|
|
88
89
|
},
|
|
89
90
|
"dependencies": {
|
|
90
|
-
"@cyanheads/mcp-ts-core": "0.
|
|
91
|
-
"@duckdb/node-api": "^1.5.5-r.
|
|
91
|
+
"@cyanheads/mcp-ts-core": "0.13.6",
|
|
92
|
+
"@duckdb/node-api": "^1.5.5-r.5",
|
|
92
93
|
"pino-pretty": "^13.1.3",
|
|
93
|
-
"zod": "^4.6.
|
|
94
|
+
"zod": "^4.6.5"
|
|
94
95
|
},
|
|
95
96
|
"devDependencies": {
|
|
96
|
-
"@biomejs/biome": "2.5.
|
|
97
|
+
"@biomejs/biome": "2.5.14",
|
|
97
98
|
"@socketsecurity/bun-security-scanner": "^1.1.2",
|
|
98
99
|
"@types/node": "26.5.1",
|
|
99
100
|
"depcheck": "^1.4.7",
|
|
100
101
|
"ignore": "^7.0.9",
|
|
101
|
-
"tsc-alias": "^1.9.
|
|
102
|
+
"tsc-alias": "^1.9.5",
|
|
102
103
|
"typescript": "^7.0.2",
|
|
103
|
-
"vitest": "^5.0.
|
|
104
|
+
"vitest": "^5.0.1"
|
|
104
105
|
}
|
|
105
106
|
}
|
package/server.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"url": "https://github.com/cyanheads/exchange-rates-mcp-server",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.4.1",
|
|
10
10
|
"remotes": [
|
|
11
11
|
{
|
|
12
12
|
"type": "streamable-http",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
20
20
|
"identifier": "@cyanheads/exchange-rates-mcp-server",
|
|
21
21
|
"runtimeHint": "bun",
|
|
22
|
-
"version": "0.
|
|
22
|
+
"version": "0.4.1",
|
|
23
23
|
"packageArguments": [
|
|
24
24
|
{
|
|
25
25
|
"type": "positional",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
70
70
|
"identifier": "@cyanheads/exchange-rates-mcp-server",
|
|
71
71
|
"runtimeHint": "bun",
|
|
72
|
-
"version": "0.
|
|
72
|
+
"version": "0.4.1",
|
|
73
73
|
"packageArguments": [
|
|
74
74
|
{
|
|
75
75
|
"type": "positional",
|