
Hooks your MCP client directly into live foreign exchange data via the AllRatesToday API. Exposes four tools: fetch spot rates between any two currencies, pull historical time series at hourly to weekly granularity, batch-query multiple pairs in one call, and list all 150+ supported ISO codes. Requires an API key (free tier available) and runs over stdio with npx zero-install, so setup in Claude Desktop, Cursor, or Windsurf is a three-line JSON snippet. Rates refresh every 60 seconds and historical lookups go back one year. Reach for this when you need Claude to quote real conversion rates, analyze FX trends, or calculate multi-currency totals without hardcoded lookup tables or stale snapshots.
A Model Context Protocol server that lets Claude Code, Cursor, Claude Desktop, Windsurf, and any other MCP-compatible client fetch real-time currency rates, historical series, and multi-currency lookups from the AllRatesToday API. Rates are mid-market, with no retail spread.
English | 简体中文
After installation, your assistant can answer questions like:
This README documents the npm package @allratestoday/mcp-server (current version 0.7.6). Its source lives in AllRates-Today/mcp-server.
1d (hourly), 7d (daily), 30d (daily), 1y (weekly)get_exchange_rate, get_historical_rates, get_rates_authenticated, list_currencies, list_central_banks, get_official_rates, get_reference_rate, request_trial_key; a small surface the model uses correctly (the hosted endpoint https://allratestoday.com/api/mcp lists 11: these plus get_official_rate_history, compare_official_rates, get_publication_calendar)rate_date@modelcontextprotocol/sdk and zod; Node.js ≥ 18With a key, get_exchange_rate, get_historical_rates and get_rates_authenticated return a mid-market rate — the right number for price display and conversion. It is not the official rate a tax authority or auditor may require; for those use get_official_rates (latest published table of any of 121 central banks + 3 tax authorities, keyless), or see the AllRatesToday docs.
The key is optional. Without ALLRATES_API_KEY the server starts in keyless mode:
| Tool | Keyless | What you get |
|---|---|---|
get_exchange_rate | ✅ | An official central-bank rate: the ECB table first, else the central bank that issues the target or source currency (e.g. USD/GBP → Bank of England). Only pairs one bank publishes, or their inverses (flagged derived: true), work keyless |
list_currencies | ✅ | All 160+ supported codes |
list_central_banks | ✅ | All 121 central banks + 3 tax authorities with codes and latest publication date |
get_official_rates | ✅ | Latest official table (or one pair); a dated table needs a paid-plan key |
get_reference_rate | ✅ | Latest Daily Reference Rate table (16:00 London); a past date needs a paid-plan key |
request_trial_key | ✅ | Self-issues a 100-call, 7-day key with no account and adopts it for the session |
get_historical_rates | 🔑 | Paid-plan key (free and trial keys get 403) |
get_rates_authenticated | 🔑 | Free key for latest rates; time (a past datetime) needs a paid plan |
A free key unlocks real-time mid-market rates for 160+ currencies and multi-target lookups. The free tier is 300 requests, lifetime — it never resets. All history and dated rates — mid-market history, point-in-time lookups, dated official and reference-rate tables — need a paid plan; free and trial keys get 403 historical_requires_paid_plan (pricing).
art_live_xxxxx)ALLRATES_API_KEY in the configs belowIf the key is missing, the server prints a short keyless-mode summary on stderr and keeps running — it never exits for a missing key.
The simplest install is zero-install via npx, which is what every config below uses:
# Run without installing (recommended)
npx -y @allratestoday/mcp-server
# Or install globally
npm install -g @allratestoday/mcp-server
allratestoday-mcp
Both commands launch the stdio MCP server and wait for a client to connect — they are not meant to be run interactively from your shell; your MCP client launches them as a subprocess.
Each client reads MCP servers from a different config file. Pick yours below.
The fastest path uses the built-in CLI:
claude mcp add allratestoday -- npx -y @allratestoday/mcp-server
claude mcp env allratestoday ALLRATES_API_KEY=art_live_xxxxx
Restart Claude Code, then ask: "What's the current USD to EUR rate?"
Edit ~/.cursor/mcp.json (or .cursor/mcp.json inside your project for a project-scoped server):
{
"mcpServers": {
"allratestoday": {
"command": "npx",
"args": ["-y", "@allratestoday/mcp-server"],
"env": {
"ALLRATES_API_KEY": "art_live_xxxxx"
}
}
}
}
Restart Cursor. The eight tools should appear in the MCP tool picker.
Edit the config file (path depends on OS):
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
{
"mcpServers": {
"allratestoday": {
"command": "npx",
"args": ["-y", "@allratestoday/mcp-server"],
"env": {
"ALLRATES_API_KEY": "art_live_xxxxx"
}
}
}
}
Fully quit and reopen Claude Desktop (Cmd+Q on macOS, right-click tray icon → Exit on Windows). Closing the window alone keeps the old config loaded.
Edit ~/.codeium/windsurf/mcp_config.json with the same mcpServers block as above, then restart Windsurf.
Any MCP host that supports stdio transport works. The launch command is:
npx -y @allratestoday/mcp-server
…optionally with ALLRATES_API_KEY set in the subprocess environment. The same block, ready to copy, also lives in .mcp.json in this repo; smithery.yaml describes the same stdio launch for Smithery, and server.json is the MCP registry manifest.
npx or Node ≥ 18 (see Troubleshooting).get_exchange_rate(source: "USD", target: "EUR") and reply with a real rate. If it produces a number without a tool call, the server is not connected.| Tool | Purpose | Required input |
|---|---|---|
get_exchange_rate | Current rate for one pair | source, target |
get_historical_rates | Time series over a preset period | source, target |
get_rates_authenticated | Multiple targets in one call, optional point-in-time | source, target |
list_currencies | All supported codes, names, symbols | — |
list_central_banks | Every covered central bank / tax authority with its code | — |
get_official_rates | Official table (or one pair) a named institution published | bank |
get_reference_rate | Daily Reference Rate, one fixed mid-market table per business day (16:00 London) | — |
request_trial_key | Self-issue a 100-call, 7-day trial key, no account | — |
Only get_historical_rates and get_rates_authenticated require ALLRATES_API_KEY: a free key covers latest multi-target rates; get_historical_rates and time need a paid plan. Input schemas set additionalProperties: false — unknown fields are rejected. Full per-tool reference: mcp-server README.
get_exchange_rateCurrent mid-market rate between two currencies. Calls GET /rate with a key; keyless it calls GET /open/central-bank/{bank} (ECB first, then the bank issuing the target, then the source currency).
| Field | Type | Required | Description |
|---|---|---|---|
source | string (exactly 3 chars) | yes | ISO 4217 code, e.g. USD |
target | string (exactly 3 chars) | yes | ISO 4217 code, e.g. EUR |
{ "source": "USD", "target": "EUR" }
Response with a key:
{ "rate": 0.888889, "source": "mid-market" }
Response keyless (USD → GBP is not in the ECB table, so the Bank of England answers; derived: true because it publishes the inverse):
{
"rate": 0.7598784195,
"source": "Bank of England official rate (keyless mode)",
"bank": "boe",
"rate_date": "2026-10-14",
"derived": true,
"note": "Keyless mode: this is the Bank of England official rate published on 2026-10-14, not a live mid-market quote. For real-time rates across 160+ currencies set ALLRATES_API_KEY — free tier at https://allratestoday.com/register."
}
get_historical_ratesTime-series data points for a currency pair over a fixed period. Calls GET /historical-rates. Needs an API key on a paid plan (free and trial keys get a 403).
| Field | Type | Required | Description |
|---|---|---|---|
source | string (exactly 3 chars) | yes | Source currency code |
target | string (exactly 3 chars) | yes | Target currency code |
period | string | no (default 7d) | One of 1d, 7d, 30d, 1y |
Granularity per period:
period | Granularity |
|---|---|
1d | Hourly |
7d | Daily |
30d | Daily |
1y | Weekly |
{ "source": "USD", "target": "INR", "period": "30d" }
Response (truncated):
{
"source": "USD",
"target": "INR",
"period": "30d",
"data": [
{ "date": "2026-09-17", "rate": 96.1006, "timestamp": 1789603200000 },
{ "date": "2026-09-18", "rate": 95.8142, "timestamp": 1789689600000 },
"...",
{ "date": "2026-10-16", "rate": 94.9643, "timestamp": 1792108800000 }
]
}
get_rates_authenticatedMultiple targets in one call, with an optional historical timestamp or grouping window. Calls GET /v1/rates.
| Field | Type | Required | Description |
|---|---|---|---|
source | string (exactly 3 chars) | yes | Source currency code |
target | string | yes | One or more codes, comma-separated (EUR,GBP,JPY) |
time | string (ISO 8601 date-time) | no | Historical point in time (paid plans) |
group | string | no | One of hour, day, week, month |
{ "source": "USD", "target": "EUR,GBP,JPY" }
Response — { rates: [{ rate, source, target, time }] }:
{
"rates": [
{ "rate": 0.888889, "source": "USD", "target": "EUR", "time": "2026-10-16T12:16:01+0000" },
{ "rate": 0.749766, "source": "USD", "target": "GBP", "time": "2026-10-16T12:16:01+0000" },
{ "rate": 157.985, "source": "USD", "target": "JPY", "time": "2026-10-16T12:16:01+0000" }
]
}
list_currenciesAll supported currencies with codes, names, and symbols. Calls GET /v1/symbols, cached 24 h upstream — cheap to call for validating user input before the other tools.
Input — none.
Response (truncated):
{
"currencies": [
{ "code": "USD", "name": "US Dollar", "symbol": "$" },
{ "code": "EUR", "name": "Euro", "symbol": "€" },
{ "code": "GBP", "name": "British Pound", "symbol": "£" },
"..."
],
"count": 163
}
list_central_banksEvery official source — 121 central banks plus HMRC, the US Treasury and Swiss BAZG — with the code that get_official_rates takes as bank. Keyless. Calls GET /open/central-banks (or /v1/central-banks with a key).
{
"sources": [
{ "code": "ecb", "name": "European Central Bank", "latest": "2026-10-15", "age_days": 1, "stale": false, "cadence": "daily" },
{ "code": "fed", "name": "US Federal Reserve (H.10)", "latest": "2026-10-09", "age_days": 7, "stale": false, "cadence": "weekly" },
"..."
],
"stale_count": 3,
"checked_at": "2026-10-16T12:16:46.232Z"
}
get_official_ratesThe fixed, citable rate an institution published. Input: bank (required), optional date (YYYY-MM-DD, paid plan — a free key gets 403 Historical central bank rates require a paid plan), optional source + target for one pair. Keyless for the latest table.
{
"bank": "ecb",
"rate_date": "2026-10-15",
"source": "EUR",
"target": "USD",
"rate": 1.1208,
"rate_type": "reference",
"derived": false,
"method": "published",
"age_days": 1,
"stale": false,
"cadence": "daily",
"attribution": { "source": "Official rates published by ECB, served by AllRatesToday", "url": "https://allratestoday.com/central-bank-rates-api/ecb/", "terms": "Free to use with visible attribution linking to allratestoday.com" }
}
Every currency the AllRatesToday API serves is available through these tools — call list_currencies for the authoritative live list. Commonly used codes include:
🇺🇸 USD · 🇪🇺 EUR · 🇬🇧 GBP · 🇯🇵 JPY · 🇨🇦 CAD · 🇮🇳 INR
The source and target fields of get_exchange_rate and get_historical_rates are validated as exactly three characters, so pass ISO 4217 codes, not currency names.
| Variable | Default | Required | Purpose |
|---|---|---|---|
ALLRATES_API_KEY | — | no | Your API key, sent as a Bearer token in the Authorization header. Unset ⇒ keyless mode; the server never exits for a missing key. |
ALLRATES_BASE_URL | https://allratestoday.com/api | no | Override for a self-hosted or staging deployment. Trailing slashes are stripped. |
Set these in your MCP client's config (in the env block), not in your shell — MCP servers are launched as subprocesses with isolated environments.
Tool failures come back as an MCP tool result with isError: true. The text is AllRatesToday error (<status>): <message>.
| HTTP status | Message |
|---|---|
| 400 | The API's error field, else Bad request — possibly an unknown currency code |
| 401 | Invalid AllRatesToday API key |
| 403 | HTTP 403 — <upstream message>, e.g. Historical rates require a paid plan… for get_historical_rates or time on a free or trial key, or Historical central bank rates require a paid plan… for a dated table |
| 404 (keyless) | No keyless official source covers X/Y. Real-time rates for 160+ currencies need an API key … |
| 429 | AllRatesToday API quota exceeded |
| 5xx | HTTP <status> — <upstream message> |
Errors raised locally, before any HTTP call:
get_rates_authenticated (no time) → … needs an AllRatesToday API key. The free tier covers it — sign up at https://allratestoday.com/register …get_historical_rates, or get_rates_authenticated with time → … needs an AllRatesToday API key on a paid plan …date to get_official_rates / get_reference_rate → … needs an AllRatesToday API key on a paid plan …MCP error -32602: Tool <name> not foundBecause these arrive as text, the assistant relays them to the user — a 429 surfaces as "the API quota has been exceeded."
| Symptom | Likely cause | Fix |
|---|---|---|
| Client shows "MCP server failed to start" or a red dot | Not a missing key (0.5.0+ starts without one) — usually npx cannot reach the registry, or Node is older than 18 | Run npx -y @allratestoday/mcp-server in a shell and read stderr |
| Every call returns a 401 error | Key malformed, truncated, or revoked | Copy a fresh key from the dashboard |
| Calls return a 429 error | Quota used up — the free tier is 300 requests lifetime and never resets | Upgrade at allratestoday.com/pricing |
| Calls return a 403 error | get_historical_rates, time, or date on get_official_rates / get_reference_rate with a free or trial key | History is paid-only: omit date/time for the latest rates, or upgrade |
get_historical_rates returns a 400 error | Invalid period or unknown currency code | period must be 1d/7d/30d/1y; codes must be exactly 3 letters |
| Server starts but tools never appear | Client did not reload after the config change | Fully quit (not just close) and reopen the client |
npx runs but hangs forever | Normal — the server is waiting for an MCP client on stdio | Let your MCP client launch it |
To inspect what the server is doing, run it manually (with or without the key):
ALLRATES_API_KEY=art_live_xxxxx npx -y @allratestoday/mcp-server
No output means healthy — stdout is reserved for the MCP protocol; errors print to stderr.
Do you store my conversation or query data? No. Only your API key and the request parameters (source, target, period, time, group) are sent to allratestoday.com — never the model's conversation context.
What happens to my API key? It is only sent as a Bearer token in the Authorization header on requests to the AllRatesToday API. The server does not log it.
Why is the first call slow? Cold start of npx (the first run downloads the package) plus an upstream cache miss.
Can I run this without npm/Node? Not currently — engines requires Node ≥ 18. If a standalone binary matters to you, open an issue.
Is there a self-hosted option? Point ALLRATES_BASE_URL at your own instance.
Does it work with other clients? Any MCP-compatible host with stdio transport works, and remote-MCP clients can use the hosted endpoint https://allratestoday.com/api/mcp; the four clients above are simply the ones with documented config paths here.
The src/ in this repo is an older 0.3.x snapshot. The published package is built from AllRates-Today/mcp-server — develop there:
git clone https://github.com/AllRates-Today/mcp-server.git
cd mcp-server
npm install
npm run build
ALLRATES_API_KEY=art_live_xxxxx node dist/index.js
npm run build runs tsc; npm run dev watches and rebuilds; npm start runs the compiled server. CI (.github/workflows/ci.yml) runs npm ci && npm run build on Node 22 for every push to main and every pull request.
To test against a local AllRatesToday instance:
ALLRATES_BASE_URL=http://localhost:8080/api ALLRATES_API_KEY=test_key node dist/index.js
Project structure:
src/
├── index.ts # MCP server, tool definitions, request handlers
├── client.ts # HTTP client for the AllRatesToday API + error mapping
└── home-banks.ts # currency → issuing central bank (keyless fallback; mcp-server only)
dist/ # Compiled JS (gitignored)
server.json # MCP registry manifest
smithery.yaml # Smithery launch config
.mcp.json # Ready-to-copy client config
Issues and PRs are welcome. Before opening a PR: npm run build must succeed, exercise the change against a real API key, and update both the tool descriptions in src/index.ts and the API reference above if tool behaviour changes.
Full changelog: mcp-server README → Changelog. Recent highlights:
get_rates_authenticated with time says a paid plan is needed; history documented as paid-onlyget_exchange_rate falls back from the ECB table to the central bank issuing either currency (USD/GBP, GBP/JPY, USD/INR answer keyless), like the hosted endpoint; dated-table errors say a paid plan is neededget_reference_rate (Daily Reference Rate) and request_trial_key (self-issued 100-call trial key)list_central_banks and get_official_rates (121 central banks + 3 tax authorities)get_historical_rates/plugin marketplace add AllRates-Today/claude-code-plugin · hosted MCP endpoint https://allratestoday.com/api/mcp (keyless)POST https://allratestoday.com/api/agent/keys (JSON) → 100 calls / 7 days — and read the keyless Daily Reference Rate (16:00 London fix) at https://allratestoday.com/api/open/reference-rateMIT — see LICENSE.
ALLRATES_API_KEY*secretAPI key (art_live_xxxxx). Required for all tools. Get one free at https://allratestoday.com/register.
ALLRATES_BASE_URLOverride API base URL (default: https://allratestoday.com/api).