get_euro_exchange
Retrieve EUR exchange rates from ECB for 33 currencies, including USD, GBP, JPY. Supports latest or historical rates (from 1999-01-04) in JSON format with caching for efficient data access.
Instructions
Fetches EUR exchange rates against other currencies from the ECB via Frankfurter API. Returns a JSON object with: base ("EUR"), date (YYYY-MM-DD of the rate), rates (object mapping 3-letter currency codes to numeric values representing how many units of that currency equal 1 EUR), source, and retrieved_at as ISO 8601. Latest rates are cached 1 hour; historical rates are cached permanently. USAGE: Supports 33 currencies including USD, GBP, JPY, CHF, CNY, SEK, PLN, and others. Omit date for the latest available rates. Provide date in YYYY-MM-DD format for historical rates (available from 1999-01-04). These are ECB reference rates published at ~16:00 CET — not real-time mid-market rates; expect small spreads vs live quotes. Requests for weekends or ECB holidays return the previous business day's rates. Returns an error for dates before 1999-01-04 or future dates.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| currencies | No | List of 3-letter currency codes (e.g. ["USD", "GBP", "JPY"]). Omit for all available currencies. | |
| date | No | Historical date in YYYY-MM-DD format. Omit for latest rates. |
Implementation Reference
- src/tools/euro-exchange.ts:36-82 (handler)The tool handler function that executes the exchange rate lookup: builds a cache key, checks cache, fetches from Frankfurter API (ECB data), formats result with source attribution, and caches before returning.
async ({ currencies, date }) => { return withMcpMiddleware({ serverName: SERVER_NAME, toolName: 'get_euro_exchange' }, async () => { const params = { currencies, date }; const cacheKey = `get_euro_exchange:${hashParams(params as Record<string, unknown>)}`; const cached = await cacheGet<ExchangeRateResult>(cacheKey); if (cached) { return { content: [{ type: 'text' as const, text: JSON.stringify(cached, null, 2) }] }; } const endpoint = date ? `${FRANKFURTER_BASE}/${date}` : `${FRANKFURTER_BASE}/latest`; const searchParams = new URLSearchParams({ base: 'EUR' }); if (currencies?.length) { searchParams.set('to', currencies.join(',')); } const res = await fetch(`${endpoint}?${searchParams}`, { signal: AbortSignal.timeout(10_000), }); if (!res.ok) { if (res.status === 404) { return makeMcpError( `No exchange rate data found for date ${date ?? 'latest'}`, 'SOURCE_UNAVAILABLE', ); } return makeMcpError( `Frankfurter API returned ${res.status}`, 'SOURCE_UNAVAILABLE', ); } const json = (await res.json()) as { amount: number; base: string; date: string; rates: Record<string, number> }; const result: ExchangeRateResult = { base: json.base, date: json.date, rates: json.rates, source: 'European Central Bank via Frankfurter.app', retrieved_at: new Date().toISOString(), }; await cacheSet(cacheKey, result, CACHE_TTL); return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }; }); }, ); - src/tools/euro-exchange.ts:24-34 (schema)Input schema using Zod: optional 'currencies' array of 3-letter codes (uppercased) and optional 'date' string matching YYYY-MM-DD format.
{ currencies: z .array(z.string().length(3).toUpperCase()) .optional() .describe('List of 3-letter currency codes (e.g. ["USD", "GBP", "JPY"]). Omit for all available currencies.'), date: z .string() .regex(/^\d{4}-\d{2}-\d{2}$/) .optional() .describe('Historical date in YYYY-MM-DD format. Omit for latest rates.'), }, - src/tools/euro-exchange.ts:20-83 (registration)Registration function that registers the 'get_euro_exchange' tool on an McpServer instance with schema, read-only annotations, and handler.
export function registerEuroExchangeTool(server: McpServer): void { server.tool( 'get_euro_exchange', 'Fetches EUR exchange rates against other currencies from the ECB via Frankfurter API. Returns a JSON object with: `base` ("EUR"), `date` (YYYY-MM-DD of the rate), `rates` (object mapping 3-letter currency codes to numeric values representing how many units of that currency equal 1 EUR), `source`, and `retrieved_at` as ISO 8601. Latest rates are cached 1 hour; historical rates are cached permanently. USAGE: Supports 33 currencies including USD, GBP, JPY, CHF, CNY, SEK, PLN, and others. Omit `date` for the latest available rates. Provide `date` in YYYY-MM-DD format for historical rates (available from 1999-01-04). These are ECB reference rates published at ~16:00 CET — not real-time mid-market rates; expect small spreads vs live quotes. Requests for weekends or ECB holidays return the previous business day\'s rates. Returns an error for dates before 1999-01-04 or future dates.', { currencies: z .array(z.string().length(3).toUpperCase()) .optional() .describe('List of 3-letter currency codes (e.g. ["USD", "GBP", "JPY"]). Omit for all available currencies.'), date: z .string() .regex(/^\d{4}-\d{2}-\d{2}$/) .optional() .describe('Historical date in YYYY-MM-DD format. Omit for latest rates.'), }, READ_ONLY_PUBLIC_API, async ({ currencies, date }) => { return withMcpMiddleware({ serverName: SERVER_NAME, toolName: 'get_euro_exchange' }, async () => { const params = { currencies, date }; const cacheKey = `get_euro_exchange:${hashParams(params as Record<string, unknown>)}`; const cached = await cacheGet<ExchangeRateResult>(cacheKey); if (cached) { return { content: [{ type: 'text' as const, text: JSON.stringify(cached, null, 2) }] }; } const endpoint = date ? `${FRANKFURTER_BASE}/${date}` : `${FRANKFURTER_BASE}/latest`; const searchParams = new URLSearchParams({ base: 'EUR' }); if (currencies?.length) { searchParams.set('to', currencies.join(',')); } const res = await fetch(`${endpoint}?${searchParams}`, { signal: AbortSignal.timeout(10_000), }); if (!res.ok) { if (res.status === 404) { return makeMcpError( `No exchange rate data found for date ${date ?? 'latest'}`, 'SOURCE_UNAVAILABLE', ); } return makeMcpError( `Frankfurter API returned ${res.status}`, 'SOURCE_UNAVAILABLE', ); } const json = (await res.json()) as { amount: number; base: string; date: string; rates: Record<string, number> }; const result: ExchangeRateResult = { base: json.base, date: json.date, rates: json.rates, source: 'European Central Bank via Frankfurter.app', retrieved_at: new Date().toISOString(), }; await cacheSet(cacheKey, result, CACHE_TTL); return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }; }); }, ); } - src/tools/euro-exchange.ts:12-18 (helper)Type interface defining the structure of the tool's return value: base currency, date, rates map, source info, and retrieval timestamp.
interface ExchangeRateResult { base: string; date: string; rates: Record<string, number>; source: string; retrieved_at: string; }