Most currency tools give you a number with no date on it. That is fine for curiosity and useless for an invoice, because the question an accountant asks is not "what is the rate" but "which rate did you use, and on what date". The MCP Currency Converter reads the European Central Bank's published euro foreign exchange reference rates, states the rate date in every answer, and needs no API key, no account and no rate limit, because the ECB publishes the files openly.
claude mcp add currency -- npx -y @theluckystrike/mcp-currency
Cursor and Claude Desktop take the same server as a config block:
{
"mcpServers": {
"currency": {
"command": "npx",
"args": ["-y", "@theluckystrike/mcp-currency"]
}
}
}
The npm publish of the package is pending, so until it lands use the .mcpb bundle from
the latest release or a clone and build. Exact config paths per client are on the
setup pages.
Three reasons, in the order they matter. It is the series tax authorities and accountants already
accept, so a converted invoice line is defensible. It is keyless: the two files,
eurofxref-daily.xml and eurofxref-hist.xml, are public downloads, so there is
no signup, no quota and no key to rotate out of a config file. And it is small enough to cache, so the
server keeps answering on a plane: the daily file is refreshed only when the local copy is more than 6
hours old, the history file after 24 hours.
The cost is honesty about what these rates are. They are reference rates published once a day, around 16:00 CET, for accounting and reporting. They are not dealing rates. The number your bank actually charges you will differ, and the server says so rather than implying you can trade on it.
The ECB publishes on TARGET business days only. There is no rate for a Saturday, a Sunday, 1 January, Good Friday, Easter Monday, 1 May, 25 December or 26 December. That is not a small gap. Counting the published history file directly: the series runs from 1999-01-04 to 2026-09-02, which is 10,104 calendar days, and it holds 7,084 dates. 29.9% of all calendar dates in the series carry no rate at all. Taking single years, 2025 has 255 published dates out of 365 and 2024 has 256 out of 366, both 30.1% missing.
So a tool that looks up a date and returns nothing fails on nearly one date in three, and a tool that quietly returns the next rate it can find is inventing a number your client can check. This server applies the convention every bank uses: the last rate published on or before the date you asked for, the nearest previous business day, and the answer names the date it landed on and why. Ask for a rate on a Sunday and you get Friday's rate, labelled as Friday's rate.
rate_on { pair: "USD/PLN", date: "2026-08-30" } # a Saturday
-> rule: nearest previous business day
-> rate date 2026-08-28, stated in the answer
The ECB quotes everything against the euro, so a USD/PLN rate is a cross rate. The ratio is formed at full precision, rounded once to 6 decimals, and that rounded rate is the number the result is computed from. The consequence is the one that matters in a document: the rate printed in the answer reproduces the amount printed in the answer. Results are rounded to the target currency's own ISO 4217 minor units, so JPY comes back whole and BHD to three places.
This is the reason the server exists rather than a conversion widget. The
expense tracker can fold a set of expenses in several currencies into
one invoice currency, but expense_to_invoice will not fetch or invent a rate: you have to
hand it an fx_rates object. fx_rates_for returns exactly that object, plus the
rate date. Three calls, no rate typed by a human:
expense_to_invoice { project: "Nova", from, to }
-> which currencies are actually present: EUR, GBP
fx_rates_for { target: "USD", currencies: ["EUR", "GBP"] }
-> { "EUR": 1.0812, "GBP": 1.2717 }, rate date 2026-09-02
expense_to_invoice { project: "Nova", target_currency: "USD", fx_rates: { ... } }
-> one currency, every converted line annotated
invoice_create { currency: "USD", items: [ ... ] }
The prompt convert_invoice_lines walks that whole chain in one step. Put the returned
invoice_note, which reads "Converted at ECB reference rates of 2026-09-02", on the document,
and the client can verify every line against a public file.
Free covers the latest rates, convert, convert_many,
fx_rates_for and history windows up to 90 days, unlimited, in all of the 30 or more
currencies the ECB quotes. Pro ($19 once) opens any date and any window back to 1999-01-04. A refused
window returns the reason and the exact narrower call to make; it never truncates a table silently.
Product page: MCP Currency Converter. Side by side with the alternatives:
currency comparison.
No. The ECB publishes eurofxref-daily.xml and eurofxref-hist.xml as open files, so there is no signup, no key and no quota. The only network request the server makes is to www.ecb.europa.eu, and only when the local cache is older than 6 hours for the daily file or 24 hours for the history.
The last rate published on or before that date, which is the nearest previous business day convention banks use, and the answer states which date it landed on. This matters more than it sounds: 29.9% of the calendar dates in the ECB series carry no rate of their own.
Yes, and that is what they are for. They are the published reference rates used for accounting and reporting. They are not dealing rates, so your bank's rate will differ. Put the returned invoice_note with the rate date on the document so the client can check it.
Call expense_to_invoice to see which currencies are present, fx_rates_for to get the fx_rates object for your target currency, then expense_to_invoice again with target_currency and that object. The expense tracker never fetches a rate itself, by design, so nothing is invented.
After the first download, yes. Both ECB files are cached under ~/.local/share/mcp-servers/currency/ and every answer is served from that copy until it ages out. Set ECB_BASE_URL to a mirror if outbound access is restricted.