@allratestoday/mcp-server 0.7.3 β 0.7.5
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/README.md +75 -46
- package/dist/client.d.ts +10 -3
- package/dist/client.js +55 -25
- package/dist/home-banks.d.ts +4 -0
- package/dist/home-banks.js +123 -0
- package/dist/index.js +14 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,17 +21,17 @@ After installation, your assistant can answer questions like:
|
|
|
21
21
|
|
|
22
22
|
## π Why this server?
|
|
23
23
|
|
|
24
|
-
- π‘ **Live mid-market rates** β
|
|
24
|
+
- π‘ **Live mid-market rates** β 160+ ISO 4217 currencies, refreshed every ~60 seconds
|
|
25
25
|
- π **Historical series built in** β `1d` / `7d` / `30d` / `1y` windows with sensible granularity per period
|
|
26
26
|
- π§° **Eight focused tools** β `get_exchange_rate`, `get_historical_rates`, `get_rates_authenticated`, `list_currencies`, `list_central_banks`, `get_official_rates`, `get_reference_rate`, `request_trial_key`; small surface, easy for the model to use correctly
|
|
27
27
|
- π **Works everywhere MCP does** β stdio transport, MCP 1.x; Claude Code, Cursor, Claude Desktop, Windsurf, or any generic host
|
|
28
|
-
- π **Works with no API key** β installs and answers out of the box from
|
|
28
|
+
- π **Works with no API key** β installs and answers out of the box from open official central-bank tables (ECB first, else the bank that issues one of the two currencies); a free key unlocks real-time rates for 160+ currencies
|
|
29
29
|
- π‘οΈ **Honest about what it returned** β every keyless answer says which rate it is and when it was published; API errors map to clear, actionable messages
|
|
30
30
|
- π **Nothing leaks** β only the request parameters and your API key ever reach allratestoday.com; never conversation context
|
|
31
31
|
|
|
32
32
|
## βοΈ Mid-market vs official central-bank rates
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
With a key, `get_exchange_rate`, `get_historical_rates` and `get_rates_authenticated` return a **mid-market rate**, refreshed every ~60 seconds β the right number for price display, conversion, and anything that should track the market. It is *not* the official rate a tax authority or auditor may require. For those, call **`get_official_rates`**: the latest table published by any of 121 central banks and 3 tax authorities (ECB, Fed, HMRC, US Treasury, Swiss BAZG, β¦), fixed once published and carrying the institution's own `rate_date`, no key needed. `list_central_banks` gives the codes. Dated official tables (a past `date`) need an API key on a **paid plan** β a free key gets `403 Historical central bank rates require a paid plan`; mid-market history (`get_historical_rates`) works on the free key. See the [central bank REST API](https://allratestoday.com/docs/#central-bank) and [per-bank npm SDKs](https://allratestoday.com/central-bank-rates-api/). The two can diverge by several percent, so pick by use case, not convenience.
|
|
35
35
|
|
|
36
36
|
## π Keyless mode β what works with no setup
|
|
37
37
|
|
|
@@ -39,23 +39,25 @@ Install it with no configuration at all and it starts, connects, and answers:
|
|
|
39
39
|
|
|
40
40
|
| Tool | Keyless | What you get |
|
|
41
41
|
|---|---|---|
|
|
42
|
-
| `get_exchange_rate` | β
|
|
|
42
|
+
| `get_exchange_rate` | β
| An **official central-bank rate**: the ECB reference table first, else the central bank that issues the target or source currency (USD/GBP β Bank of England, USD/INR β Reserve Bank of India). The response carries `bank`, `rate_date`, `derived` and a note saying so, so the assistant never passes it off as a live quote. Only pairs one bank publishes, or their inverses (flagged `derived: true`), work keyless; other crosses are refused with a pointer to the key. |
|
|
43
43
|
| `list_currencies` | β
| All 160+ supported ISO 4217 codes. |
|
|
44
44
|
| `list_central_banks` | β
| Codes, names and latest publication date of all 121 central banks + 3 tax authorities. |
|
|
45
|
-
| `get_official_rates` | β
| Latest **official table** (or one pair) published by any of them. A dated table needs
|
|
46
|
-
| `get_reference_rate` | β
| The **Daily Reference Rate**: one never-revised table per business day, fixed at 16:00 London. A past date needs
|
|
45
|
+
| `get_official_rates` | β
| Latest **official table** (or one pair) published by any of them. A dated table needs a paid-plan key. |
|
|
46
|
+
| `get_reference_rate` | β
| The **Daily Reference Rate**: one never-revised table per business day, fixed at 16:00 London. A past date needs a paid-plan key. |
|
|
47
47
|
| `request_trial_key` | β
| Self-issues a 100-call, 7-day key with no account and adopts it for the session. |
|
|
48
|
-
| `get_historical_rates` | π | Returns one sentence explaining how to get a
|
|
48
|
+
| `get_historical_rates` | π | Returns one sentence explaining how to get a key. Needs a paid plan. |
|
|
49
49
|
| `get_rates_authenticated` | π | Same. |
|
|
50
50
|
|
|
51
|
-
The keyless path reads the open, edge-cached `/api/open/central-bank/
|
|
52
|
-
|
|
51
|
+
The keyless path reads the open, edge-cached `/api/open/central-bank/{bank}`
|
|
52
|
+
endpoints β no upstream cost, no rate limit to trip over, nothing to sign up for.
|
|
53
53
|
|
|
54
54
|
## π Get your API key (free)
|
|
55
55
|
|
|
56
|
-
A key unlocks **real-time mid-market rates across 160+ currencies
|
|
57
|
-
|
|
58
|
-
development and
|
|
56
|
+
A key unlocks **real-time mid-market rates across 160+ currencies** and
|
|
57
|
+
multi-target lookups. The free tier (300 requests, lifetime β it does not reset
|
|
58
|
+
monthly) is enough for development and trying it out β **no credit card required**.
|
|
59
|
+
Historical series, point-in-time lookups and dated official and reference-rate
|
|
60
|
+
tables need a paid plan from β¬4.99/month.
|
|
59
61
|
|
|
60
62
|
1. Register at [allratestoday.com/register](https://allratestoday.com/register) β 30 seconds
|
|
61
63
|
2. Verify your email
|
|
@@ -82,7 +84,7 @@ Everything below still applies for other MCP clients.
|
|
|
82
84
|
|
|
83
85
|
## βοΈ Hosted endpoint β nothing to install
|
|
84
86
|
|
|
85
|
-
The same tools also run as a hosted **Streamable HTTP** MCP server
|
|
87
|
+
The same tools also run as a hosted **Streamable HTTP** MCP server, which lists **11 tools**: the 8 of this stdio package plus `get_official_rate_history`, `compare_official_rates` and `get_publication_calendar` from the sibling central-bank server. Paste the URL into any client that supports remote MCP β Claude.ai and Claude Desktop connectors, ChatGPT, Cursor, VS Code, Codex, Gemini CLI:
|
|
86
88
|
|
|
87
89
|
```
|
|
88
90
|
https://allratestoday.com/api/mcp
|
|
@@ -144,7 +146,7 @@ Edit `~/.cursor/mcp.json` (or `.cursor/mcp.json` inside your project for project
|
|
|
144
146
|
}
|
|
145
147
|
```
|
|
146
148
|
|
|
147
|
-
Restart Cursor. The
|
|
149
|
+
Restart Cursor. The eight tools should appear in the MCP tool picker.
|
|
148
150
|
|
|
149
151
|
### Claude Desktop
|
|
150
152
|
|
|
@@ -190,8 +192,8 @@ npx -y @allratestoday/mcp-server
|
|
|
190
192
|
|
|
191
193
|
After configuring your client, test in this order:
|
|
192
194
|
|
|
193
|
-
1. **Server starts** β open the client.
|
|
194
|
-
2. **Tools are listed** β most clients have a "tools" or "MCP" panel showing the
|
|
195
|
+
1. **Server starts** β open the client. The server starts with or without a key (no key β keyless mode), so a red dot or "failed to connect" means the client could not launch it β usually `npx` or Node β₯18 (see Troubleshooting below). A wrong key does not stop it starting; calls then return `Invalid AllRatesToday API key`.
|
|
196
|
+
2. **Tools are listed** β most clients have a "tools" or "MCP" panel showing the eight tools.
|
|
195
197
|
3. **A live call returns a number** β ask: *"What's the current USD to EUR rate?"* The assistant should call `get_exchange_rate(source: "USD", target: "EUR")` and reply with a real rate. If it fabricates a number without a tool call, the server isn't connected.
|
|
196
198
|
|
|
197
199
|
## π Tools reference
|
|
@@ -205,7 +207,7 @@ After configuring your client, test in this order:
|
|
|
205
207
|
- [`get_reference_rate`](#get_reference_rate) β the Daily Reference Rate, one fixed mid-market table per business day (16:00 London)
|
|
206
208
|
- [`request_trial_key`](#request_trial_key) β self-issue a 100-call, 7-day trial key, no account needed
|
|
207
209
|
|
|
208
|
-
`get_historical_rates` and `get_rates_authenticated` require `ALLRATES_API_KEY`; the other six work keyless.
|
|
210
|
+
`get_historical_rates` and `get_rates_authenticated` require `ALLRATES_API_KEY`; the other six of the eight work keyless. History (`get_historical_rates`, and `time` on `get_rates_authenticated`) needs a paid plan.
|
|
209
211
|
|
|
210
212
|
---
|
|
211
213
|
|
|
@@ -226,15 +228,30 @@ Current mid-market rate between two currencies.
|
|
|
226
228
|
{ "source": "USD", "target": "EUR" }
|
|
227
229
|
```
|
|
228
230
|
|
|
229
|
-
**Response:**
|
|
231
|
+
**Response (with a key):**
|
|
232
|
+
|
|
233
|
+
```json
|
|
234
|
+
{ "rate": 0.888889, "source": "interbank" }
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Response (keyless β `USD` β `GBP`, not in the ECB table, so the Bank of England table answers):**
|
|
230
238
|
|
|
231
239
|
```json
|
|
232
|
-
{
|
|
240
|
+
{
|
|
241
|
+
"rate": 0.7598784195,
|
|
242
|
+
"source": "Bank of England official rate (keyless mode)",
|
|
243
|
+
"bank": "boe",
|
|
244
|
+
"rate_date": "2026-10-14",
|
|
245
|
+
"derived": true,
|
|
246
|
+
"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."
|
|
247
|
+
}
|
|
233
248
|
```
|
|
234
249
|
|
|
250
|
+
`derived: true` means the bank publishes the inverse (GBPβUSD) and the rate was inverted. A pair no single bank publishes is refused keyless with `No keyless official source covers β¦` and a pointer to the key.
|
|
251
|
+
|
|
235
252
|
### `get_historical_rates`
|
|
236
253
|
|
|
237
|
-
Time-series data points for a currency pair over a fixed period.
|
|
254
|
+
Time-series data points for a currency pair over a fixed period. Needs an API key on a paid plan (free and trial keys get a 403).
|
|
238
255
|
|
|
239
256
|
**Input**
|
|
240
257
|
|
|
@@ -267,9 +284,10 @@ Time-series data points for a currency pair over a fixed period.
|
|
|
267
284
|
"target": "INR",
|
|
268
285
|
"period": "30d",
|
|
269
286
|
"data": [
|
|
270
|
-
{ "date": "2026-
|
|
271
|
-
{ "date": "2026-
|
|
272
|
-
"..."
|
|
287
|
+
{ "date": "2026-09-17", "rate": 96.1006, "timestamp": 1789603200000 },
|
|
288
|
+
{ "date": "2026-09-18", "rate": 95.8142, "timestamp": 1789689600000 },
|
|
289
|
+
"...",
|
|
290
|
+
{ "date": "2026-10-16", "rate": 94.9643, "timestamp": 1792108800000 }
|
|
273
291
|
]
|
|
274
292
|
}
|
|
275
293
|
```
|
|
@@ -284,7 +302,7 @@ Multiple targets in one call, with optional historical timestamp or grouping win
|
|
|
284
302
|
|---|---|---|---|
|
|
285
303
|
| `source` | string | yes | Source currency code |
|
|
286
304
|
| `target` | string | yes | One or more codes, comma-separated (`EUR,GBP,JPY`) |
|
|
287
|
-
| `time` | string (ISO 8601) | no | Historical point in time |
|
|
305
|
+
| `time` | string (ISO 8601) | no | Historical point in time (paid plans) |
|
|
288
306
|
| `group` | string | no | One of `hour`, `day`, `week`, `month` |
|
|
289
307
|
|
|
290
308
|
**Example call**
|
|
@@ -296,11 +314,13 @@ Multiple targets in one call, with optional historical timestamp or grouping win
|
|
|
296
314
|
**Response:**
|
|
297
315
|
|
|
298
316
|
```json
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
317
|
+
{
|
|
318
|
+
"rates": [
|
|
319
|
+
{ "rate": 0.888889, "source": "USD", "target": "EUR", "time": "2026-10-16T12:16:01+0000" },
|
|
320
|
+
{ "rate": 0.749766, "source": "USD", "target": "GBP", "time": "2026-10-16T12:16:01+0000" },
|
|
321
|
+
{ "rate": 157.985, "source": "USD", "target": "JPY", "time": "2026-10-16T12:16:01+0000" }
|
|
322
|
+
]
|
|
323
|
+
}
|
|
304
324
|
```
|
|
305
325
|
|
|
306
326
|
### `list_currencies`
|
|
@@ -319,7 +339,7 @@ All supported currencies with codes, names, and symbols. Cached upstream for 24
|
|
|
319
339
|
{ "code": "GBP", "name": "British Pound", "symbol": "Β£" },
|
|
320
340
|
"..."
|
|
321
341
|
],
|
|
322
|
-
"count":
|
|
342
|
+
"count": 163
|
|
323
343
|
}
|
|
324
344
|
```
|
|
325
345
|
|
|
@@ -327,7 +347,7 @@ All supported currencies with codes, names, and symbols. Cached upstream for 24
|
|
|
327
347
|
|
|
328
348
|
### `list_central_banks`
|
|
329
349
|
|
|
330
|
-
Every official source the server can quote β 121 central banks plus HMRC, the US Treasury and Swiss BAZG β with the `code` that `get_official_rates` takes as `bank`, the institution's name, its latest publication date and a `stale` flag when it is behind its own schedule. Keyless.
|
|
350
|
+
Every official source the server can quote β 121 central banks plus HMRC, the US Treasury and Swiss BAZG β with the `code` that `get_official_rates` takes as `bank`, the institution's name, its latest publication date, `age_days`, its publication `cadence` and a `stale` flag when it is behind its own schedule. Keyless.
|
|
331
351
|
|
|
332
352
|
**Input** β none.
|
|
333
353
|
|
|
@@ -336,12 +356,12 @@ Every official source the server can quote β 121 central banks plus HMRC, the
|
|
|
336
356
|
```json
|
|
337
357
|
{
|
|
338
358
|
"sources": [
|
|
339
|
-
{ "code": "ecb", "name": "European Central Bank", "latest": "2026-
|
|
340
|
-
{ "code": "fed", "name": "Federal Reserve", "latest": "2026-09
|
|
359
|
+
{ "code": "ecb", "name": "European Central Bank", "latest": "2026-10-15", "age_days": 1, "stale": false, "cadence": "daily" },
|
|
360
|
+
{ "code": "fed", "name": "US Federal Reserve (H.10)", "latest": "2026-10-09", "age_days": 7, "stale": false, "cadence": "weekly" },
|
|
341
361
|
"..."
|
|
342
362
|
],
|
|
343
|
-
"stale_count":
|
|
344
|
-
"checked_at": "2026-10-
|
|
363
|
+
"stale_count": 3,
|
|
364
|
+
"checked_at": "2026-10-16T12:16:46.232Z"
|
|
345
365
|
}
|
|
346
366
|
```
|
|
347
367
|
|
|
@@ -356,7 +376,7 @@ The fixed, citable rate an institution published β for invoices, VAT and tax r
|
|
|
356
376
|
| Field | Type | Required | Description |
|
|
357
377
|
|---|---|---|---|
|
|
358
378
|
| `bank` | string | yes | Source code from `list_central_banks`, e.g. `ecb`, `fed`, `boe`, `rbi`, `hmrc` |
|
|
359
|
-
| `date` | string | no | `YYYY-MM-DD`. Omit for the latest table (keyless). Needs
|
|
379
|
+
| `date` | string | no | `YYYY-MM-DD`. Omit for the latest table (keyless). Needs an API key on a **paid plan** β a free key gets `403 Historical central bank rates require a paid plan`. Weekends/holidays roll back to the last published date. |
|
|
360
380
|
| `source` | string | no | With `target`, narrows to one pair |
|
|
361
381
|
| `target` | string | no | With `source`, narrows to one pair |
|
|
362
382
|
|
|
@@ -365,18 +385,21 @@ The fixed, citable rate an institution published β for invoices, VAT and tax r
|
|
|
365
385
|
```json
|
|
366
386
|
{
|
|
367
387
|
"bank": "ecb",
|
|
368
|
-
"rate_date": "2026-
|
|
388
|
+
"rate_date": "2026-10-15",
|
|
369
389
|
"source": "EUR",
|
|
370
390
|
"target": "USD",
|
|
371
|
-
"rate": 1.
|
|
391
|
+
"rate": 1.1208,
|
|
372
392
|
"rate_type": "reference",
|
|
373
393
|
"derived": false,
|
|
374
394
|
"method": "published",
|
|
395
|
+
"age_days": 1,
|
|
396
|
+
"stale": false,
|
|
397
|
+
"cadence": "daily",
|
|
375
398
|
"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" }
|
|
376
399
|
}
|
|
377
400
|
```
|
|
378
401
|
|
|
379
|
-
Omit `source`/`target` for the whole table as `rates: [{ base, quote, type, value }]`.
|
|
402
|
+
Omit `source`/`target` for the whole table as `rates: [{ base, quote, type, value }]`. Keyless, only pairs the bank publishes and their inverses (flagged `derived: true`) are served; other crosses are refused. With a key, pairs the bank does not publish directly are cross-computed inside its own table and flagged `derived: true`. Always cite `rate_date`.
|
|
380
403
|
|
|
381
404
|
---
|
|
382
405
|
|
|
@@ -390,7 +413,7 @@ AllRatesToday's **Daily Reference Rate**: the per-currency median of samples tak
|
|
|
390
413
|
|---|---|---|---|
|
|
391
414
|
| `source` | string | no | With `target`, narrows to one pair (crossed via USD, flagged `derived`) |
|
|
392
415
|
| `target` | string | no | See above |
|
|
393
|
-
| `date` | string | no | Past business day `YYYY-MM-DD` (API key). Omit for the latest table |
|
|
416
|
+
| `date` | string | no | Past business day `YYYY-MM-DD` (API key on a paid plan). Omit for the latest table |
|
|
394
417
|
|
|
395
418
|
**Output** β `{ rate_date, base, time, rates }` for the table, or `{ rate_date, source, target, rate, derived }` for a pair, plus `method` and `disclaimer`. Keyless for the latest table. Docs: https://allratestoday.com/reference-rate/
|
|
396
419
|
|
|
@@ -410,23 +433,25 @@ Self-issues an API key with 100 lifetime calls, valid 7 days, with no account an
|
|
|
410
433
|
|
|
411
434
|
| Variable | Default | Required | Purpose |
|
|
412
435
|
|---|---|---|---|
|
|
413
|
-
| `ALLRATES_API_KEY` | β | no | Your API key
|
|
436
|
+
| `ALLRATES_API_KEY` | β | no | Your API key, sent as `Authorization: Bearer`. Unset β keyless mode (see above); set β real-time rates and the historical tools. |
|
|
414
437
|
| `ALLRATES_BASE_URL` | `https://allratestoday.com/api` | no | Override for self-hosted or staging deployments. |
|
|
415
438
|
|
|
416
439
|
Set these in your MCP client's config (in the `env` block) β not in your shell β because MCP servers are launched as subprocesses with isolated environments.
|
|
417
440
|
|
|
418
441
|
## π³ Plans
|
|
419
442
|
|
|
420
|
-
A free tier and paid plans are available β see [allratestoday.com/pricing](https://allratestoday.com/pricing) for current quotas.
|
|
443
|
+
A free tier and paid plans are available β see [allratestoday.com/pricing](https://allratestoday.com/pricing) for current quotas. The free tier is 300 requests, lifetime (it never resets), and covers real-time rates, mid-market history and multi-target lookups. Dated official and reference-rate tables need a paid plan. The Official Rates plan covers official central-bank and tax-authority rates only (no market rates).
|
|
421
444
|
|
|
422
445
|
## π οΈ Troubleshooting
|
|
423
446
|
|
|
424
447
|
| Symptom | Likely cause | Fix |
|
|
425
448
|
|---|---|---|
|
|
426
449
|
| Client shows "MCP server failed to start" or red dot | Not a missing key β 0.5.0+ starts fine 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 |
|
|
427
|
-
| Rates look like yesterday's, response mentions "keyless mode" | No key set, so answers come from
|
|
450
|
+
| Rates look like yesterday's, response mentions "keyless mode" | No key set, so answers come from an official central-bank table (see `bank` and `rate_date`) | Set `ALLRATES_API_KEY` for real-time mid-market rates |
|
|
451
|
+
| `No keyless official source covers X/Y` | Keyless mode, and no single central bank publishes that pair or its inverse | Set `ALLRATES_API_KEY` (free) |
|
|
452
|
+
| `HTTP 403 β Historical central bank rates require a paid plan` | `date` given to `get_official_rates` / `get_reference_rate` on a free key | Omit `date` for the latest table, or upgrade at /pricing |
|
|
428
453
|
| Every call returns "Invalid AllRatesToday API key" | Key is malformed (missing prefix, truncated, or revoked) | Copy a fresh key from the dashboard |
|
|
429
|
-
| Tools return "AllRatesToday API quota exceeded" |
|
|
454
|
+
| Tools return "AllRatesToday API quota exceeded" | Quota used up β the free tier is 300 requests lifetime and never resets; paid plans are monthly | Upgrade at [/pricing](https://allratestoday.com/pricing) |
|
|
430
455
|
| Historical tool returns "Bad request" | Invalid period or unknown currency code | Period must be `1d`/`7d`/`30d`/`1y`; codes must be 3 letters |
|
|
431
456
|
| Server starts but tools never appear | Client didn't reload after config change | Fully quit (not just close) and reopen the client |
|
|
432
457
|
| `npx` runs but hangs forever | The server is waiting for an MCP client to connect β normal when run from a shell | Let your MCP client launch it |
|
|
@@ -448,13 +473,15 @@ The server maps API errors to clear, actionable messages the assistant can relay
|
|
|
448
473
|
| 200 | Success | (rate returned) |
|
|
449
474
|
| 400 | Bad request β usually unknown currency code | `Bad request β possibly an unknown currency code` |
|
|
450
475
|
| 401 | Invalid or missing API key | `Invalid AllRatesToday API key` |
|
|
476
|
+
| 403 | Plan does not include it (e.g. a dated official table on a free key) | `HTTP 403 β <upstream message>` |
|
|
477
|
+
| 404 (keyless) | No keyless official source covers the pair | `No keyless official source covers X/Y. β¦` |
|
|
451
478
|
| 429 | Quota exceeded | `AllRatesToday API quota exceeded` |
|
|
452
479
|
| 5xx | Server-side issue at allratestoday.com | `HTTP 5xx β <upstream message>` |
|
|
453
480
|
|
|
454
481
|
## β FAQ
|
|
455
482
|
|
|
456
483
|
**Is the free plan really enough for normal use?**
|
|
457
|
-
|
|
484
|
+
For trying it out and light dev use. It is 300 requests in total (lifetime, no monthly reset); regular use or production needs a paid tier. Keyless mode costs nothing and has no quota.
|
|
458
485
|
|
|
459
486
|
**Do you store my conversation or query data?**
|
|
460
487
|
No. Only your API key and the request parameters (source, target, period, time) are sent to allratestoday.com β never the LLM's conversation context.
|
|
@@ -495,7 +522,8 @@ ALLRATES_BASE_URL=http://localhost:8080/api ALLRATES_API_KEY=test_key node dist/
|
|
|
495
522
|
```
|
|
496
523
|
src/
|
|
497
524
|
βββ index.ts # MCP server, tool registration, request handlers
|
|
498
|
-
|
|
525
|
+
βββ client.ts # HTTP client for AllRatesToday API + error mapping
|
|
526
|
+
βββ home-banks.ts # currency β issuing central bank, for the keyless get_exchange_rate fallback
|
|
499
527
|
dist/ # Compiled JS (gitignored)
|
|
500
528
|
server.json # MCP registry manifest
|
|
501
529
|
```
|
|
@@ -506,6 +534,7 @@ server.json # MCP registry manifest
|
|
|
506
534
|
|
|
507
535
|
See [GitHub Releases](https://github.com/AllRates-Today/mcp-server/releases) for the full list. Recent highlights:
|
|
508
536
|
|
|
537
|
+
- **0.7.4** β Keyless `get_exchange_rate` falls back from the ECB table to the central bank that issues the target or source currency (USD/GBP, GBP/JPY, USD/INR now answer keyless), same as the hosted endpoint; response adds `bank`. Dated-table errors say a paid plan is needed. README: real response shapes, tool counts, 300-lifetime free tier
|
|
509
538
|
- **0.7.0** β `get_reference_rate` (Daily Reference Rate, 16:00 London, keyless latest table) and `request_trial_key` (self-issued 100-call trial key adopted for the session)
|
|
510
539
|
- **0.6.1** β README: Claude Code plugin and hosted `/api/mcp` endpoint cross-links; coverage wording refreshed
|
|
511
540
|
- **0.6.0** β Official rates: new keyless `list_central_banks` and `get_official_rates` tools expose the latest table from 121 central banks + 3 tax authorities (dated tables need the key)
|
package/dist/client.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export declare class AllRatesTodayError extends Error {
|
|
|
14
14
|
* rather than a bare 401.
|
|
15
15
|
*/
|
|
16
16
|
export declare class NeedsKeyError extends AllRatesTodayError {
|
|
17
|
-
constructor(what: string);
|
|
17
|
+
constructor(what: string, paid?: boolean);
|
|
18
18
|
}
|
|
19
19
|
export declare class AllRatesTodayClient {
|
|
20
20
|
private apiKey?;
|
|
@@ -29,7 +29,7 @@ export declare class AllRatesTodayClient {
|
|
|
29
29
|
/**
|
|
30
30
|
* Daily Reference Rate: one never-revised mid-market table per business day,
|
|
31
31
|
* fixed at 16:00 London (median of samples in a 5-minute window). Latest
|
|
32
|
-
* table and single pairs are keyless; a dated table needs
|
|
32
|
+
* table and single pairs are keyless; a dated table needs a paid-plan key.
|
|
33
33
|
*/
|
|
34
34
|
getReferenceRate(params?: {
|
|
35
35
|
source?: string;
|
|
@@ -48,6 +48,13 @@ export declare class AllRatesTodayClient {
|
|
|
48
48
|
getRate(source: string, target: string): Promise<{
|
|
49
49
|
rate: number;
|
|
50
50
|
source: string;
|
|
51
|
+
bank: string;
|
|
52
|
+
rate_date: string;
|
|
53
|
+
derived: boolean;
|
|
54
|
+
note: string;
|
|
55
|
+
} | {
|
|
56
|
+
rate: number;
|
|
57
|
+
source: string;
|
|
51
58
|
}>;
|
|
52
59
|
getHistoricalRates(source: string, target: string, period?: '1d' | '7d' | '30d' | '1y'): Promise<{
|
|
53
60
|
source: string;
|
|
@@ -85,7 +92,7 @@ export declare class AllRatesTodayClient {
|
|
|
85
92
|
/**
|
|
86
93
|
* Latest OFFICIAL table published by a central bank or tax authority, or one
|
|
87
94
|
* pair from it (cross-computed inside the bank's own table when not published
|
|
88
|
-
* directly, flagged `derived`). Keyless; a dated table needs
|
|
95
|
+
* directly, flagged `derived`). Keyless; a dated table needs a paid-plan key.
|
|
89
96
|
*/
|
|
90
97
|
getOfficialRates(bank: string, params?: {
|
|
91
98
|
date?: string;
|
package/dist/client.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { VERSION } from './version.js';
|
|
2
|
+
import { HOME_BANKS } from './home-banks.js';
|
|
2
3
|
const DEFAULT_BASE_URL = 'https://allratestoday.com/api';
|
|
3
4
|
export class AllRatesTodayError extends Error {
|
|
4
5
|
status;
|
|
@@ -16,12 +17,17 @@ export class AllRatesTodayError extends Error {
|
|
|
16
17
|
* rather than a bare 401.
|
|
17
18
|
*/
|
|
18
19
|
export class NeedsKeyError extends AllRatesTodayError {
|
|
19
|
-
constructor(what) {
|
|
20
|
-
super(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
constructor(what, paid = false) {
|
|
21
|
+
super(paid
|
|
22
|
+
? `${what} needs an AllRatesToday API key on a paid plan (from β¬4.99/month; free and trial ` +
|
|
23
|
+
'keys get 403 for historical rates and dated tables) β see https://allratestoday.com/pricing, ' +
|
|
24
|
+
"then set ALLRATES_API_KEY in this MCP server's config and restart. Latest rates and the latest " +
|
|
25
|
+
'official tables need no paid plan.'
|
|
26
|
+
: `${what} needs an AllRatesToday API key. The free tier covers it β sign up at ` +
|
|
27
|
+
'https://allratestoday.com/register (no card, under a minute), then set ALLRATES_API_KEY ' +
|
|
28
|
+
"in this MCP server's config and restart. Without a key the server still answers " +
|
|
29
|
+
'get_exchange_rate from official central-bank tables (ECB first, then the issuing bank), ' +
|
|
30
|
+
'list_currencies, list_central_banks and get_official_rates (latest tables).');
|
|
25
31
|
this.name = 'NeedsKeyError';
|
|
26
32
|
}
|
|
27
33
|
}
|
|
@@ -88,7 +94,7 @@ export class AllRatesTodayClient {
|
|
|
88
94
|
/**
|
|
89
95
|
* Daily Reference Rate: one never-revised mid-market table per business day,
|
|
90
96
|
* fixed at 16:00 London (median of samples in a 5-minute window). Latest
|
|
91
|
-
* table and single pairs are keyless; a dated table needs
|
|
97
|
+
* table and single pairs are keyless; a dated table needs a paid-plan key.
|
|
92
98
|
*/
|
|
93
99
|
getReferenceRate(params = {}) {
|
|
94
100
|
if (Boolean(params.source) !== Boolean(params.target)) {
|
|
@@ -97,7 +103,7 @@ export class AllRatesTodayClient {
|
|
|
97
103
|
const pair = { source: params.source?.toUpperCase(), target: params.target?.toUpperCase() };
|
|
98
104
|
if (params.date) {
|
|
99
105
|
if (this.keyless)
|
|
100
|
-
return Promise.reject(new NeedsKeyError(`The reference-rate table for ${params.date}
|
|
106
|
+
return Promise.reject(new NeedsKeyError(`The reference-rate table for ${params.date}`, true));
|
|
101
107
|
return this.request(`/v1/reference-rate/${encodeURIComponent(params.date)}`, pair);
|
|
102
108
|
}
|
|
103
109
|
return this.request('/open/reference-rate', pair);
|
|
@@ -140,27 +146,51 @@ export class AllRatesTodayClient {
|
|
|
140
146
|
'at https://allratestoday.com/register (300 calls) or see https://allratestoday.com/pricing.',
|
|
141
147
|
};
|
|
142
148
|
}
|
|
143
|
-
getRate(source, target) {
|
|
144
|
-
// Keyless:
|
|
145
|
-
//
|
|
146
|
-
//
|
|
149
|
+
async getRate(source, target) {
|
|
150
|
+
// Keyless: answer from the open, edge-cached official tables. The ECB
|
|
151
|
+
// reference table goes first; when it does not cover the pair, the central
|
|
152
|
+
// bank that issues one of the two currencies almost always does (same
|
|
153
|
+
// order as the hosted /api/mcp server). Each answer is an official print
|
|
154
|
+
// with a publication date, not a live quote, so it is labelled for the
|
|
155
|
+
// model to relay honestly; `derived` is passed through from the API (true
|
|
156
|
+
// for an inverse or a cross inside that bank's own table).
|
|
147
157
|
if (this.keyless) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
+
const candidates = [{ code: 'ecb', name: 'European Central Bank' }];
|
|
159
|
+
for (const c of [target, source]) {
|
|
160
|
+
const home = HOME_BANKS[c];
|
|
161
|
+
if (home && !candidates.some((x) => x.code === home.code))
|
|
162
|
+
candidates.push(home);
|
|
163
|
+
}
|
|
164
|
+
let lastErr;
|
|
165
|
+
for (const bank of candidates) {
|
|
166
|
+
try {
|
|
167
|
+
const r = await this.request(`/open/central-bank/${bank.code}`, { source, target });
|
|
168
|
+
return {
|
|
169
|
+
rate: r.rate,
|
|
170
|
+
source: `${bank.name} official rate (keyless mode)`,
|
|
171
|
+
bank: bank.code,
|
|
172
|
+
rate_date: r.rate_date,
|
|
173
|
+
derived: r.derived ?? false,
|
|
174
|
+
note: `Keyless mode: this is the ${bank.name} official rate published on ${r.rate_date}, ` +
|
|
175
|
+
'not a live mid-market quote. For real-time rates across 160+ currencies set ' +
|
|
176
|
+
'ALLRATES_API_KEY β free tier at https://allratestoday.com/register.',
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
lastErr = err;
|
|
181
|
+
if (!(err instanceof AllRatesTodayError && err.status === 404))
|
|
182
|
+
throw err;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
throw new AllRatesTodayError(`No keyless official source covers ${source}/${target}. Real-time rates for 160+ currencies ` +
|
|
186
|
+
'need an API key β set ALLRATES_API_KEY (free tier at https://allratestoday.com/register).' +
|
|
187
|
+
(lastErr instanceof AllRatesTodayError ? ` Last upstream error: ${lastErr.message}` : ''), 404);
|
|
158
188
|
}
|
|
159
189
|
return this.request('/rate', { source, target });
|
|
160
190
|
}
|
|
161
191
|
getHistoricalRates(source, target, period = '7d') {
|
|
162
192
|
if (this.keyless)
|
|
163
|
-
return Promise.reject(new NeedsKeyError('Historical time-series'));
|
|
193
|
+
return Promise.reject(new NeedsKeyError('Historical time-series', true));
|
|
164
194
|
return this.request('/historical-rates', { source, target, period });
|
|
165
195
|
}
|
|
166
196
|
getAuthenticatedRates(params) {
|
|
@@ -175,7 +205,7 @@ export class AllRatesTodayClient {
|
|
|
175
205
|
/**
|
|
176
206
|
* Latest OFFICIAL table published by a central bank or tax authority, or one
|
|
177
207
|
* pair from it (cross-computed inside the bank's own table when not published
|
|
178
|
-
* directly, flagged `derived`). Keyless; a dated table needs
|
|
208
|
+
* directly, flagged `derived`). Keyless; a dated table needs a paid-plan key.
|
|
179
209
|
*/
|
|
180
210
|
getOfficialRates(bank, params = {}) {
|
|
181
211
|
const code = bank.trim().toLowerCase();
|
|
@@ -188,7 +218,7 @@ export class AllRatesTodayClient {
|
|
|
188
218
|
const pair = { source: params.source?.toUpperCase(), target: params.target?.toUpperCase() };
|
|
189
219
|
if (this.keyless) {
|
|
190
220
|
if (params.date)
|
|
191
|
-
return Promise.reject(new NeedsKeyError(`The ${code} table for ${params.date}
|
|
221
|
+
return Promise.reject(new NeedsKeyError(`The ${code} table for ${params.date}`, true));
|
|
192
222
|
return this.request(`/open/central-bank/${encodeURIComponent(code)}`, pair);
|
|
193
223
|
}
|
|
194
224
|
return this.request(`/v1/central-bank/${encodeURIComponent(code)}/${params.date ?? 'latest'}`, pair);
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// Home currency β the central bank that issues it, for the keyless
|
|
2
|
+
// get_exchange_rate fallback (mirrors the hosted /api/mcp server). Generated
|
|
3
|
+
// from the site's central-banks list: first non-ECB central bank per home
|
|
4
|
+
// currency, tax authorities and composites excluded.
|
|
5
|
+
export const HOME_BANKS = {
|
|
6
|
+
USD: { code: "fed", name: "US Federal Reserve (H.10)" },
|
|
7
|
+
GBP: { code: "boe", name: "Bank of England" },
|
|
8
|
+
CNY: { code: "pboc", name: "People's Bank of China (CFETS)" },
|
|
9
|
+
AUD: { code: "rba", name: "Reserve Bank of Australia" },
|
|
10
|
+
RUB: { code: "cbr", name: "Bank of Russia" },
|
|
11
|
+
TRY: { code: "tcmb", name: "Central Bank of TΓΌrkiye" },
|
|
12
|
+
BRL: { code: "bcb", name: "Banco Central do Brasil (PTAX)" },
|
|
13
|
+
IDR: { code: "bi", name: "Bank Indonesia" },
|
|
14
|
+
INR: { code: "rbi", name: "Reserve Bank of India" },
|
|
15
|
+
CAD: { code: "boc", name: "Bank of Canada" },
|
|
16
|
+
MYR: { code: "bnm", name: "Bank Negara Malaysia" },
|
|
17
|
+
LKR: { code: "cbsl", name: "Central Bank of Sri Lanka" },
|
|
18
|
+
CZK: { code: "cnb", name: "Czech National Bank" },
|
|
19
|
+
PLN: { code: "nbp", name: "Narodowy Bank Polski" },
|
|
20
|
+
NOK: { code: "norges", name: "Norges Bank" },
|
|
21
|
+
SEK: { code: "riksbank", name: "Sveriges Riksbank" },
|
|
22
|
+
NGN: { code: "cbn", name: "Central Bank of Nigeria" },
|
|
23
|
+
KWD: { code: "cbk", name: "Central Bank of Kuwait" },
|
|
24
|
+
BHD: { code: "cbb", name: "Central Bank of Bahrain" },
|
|
25
|
+
AZN: { code: "cbar", name: "Central Bank of Azerbaijan" },
|
|
26
|
+
BAM: { code: "cbbh", name: "Central Bank of Bosnia and Herzegovina" },
|
|
27
|
+
EUR: { code: "bnb", name: "Bulgarian National Bank" },
|
|
28
|
+
PEN: { code: "bcrp", name: "Central Reserve Bank of Peru" },
|
|
29
|
+
JPY: { code: "boj", name: "Bank of Japan" },
|
|
30
|
+
HKD: { code: "hkma", name: "Hong Kong Monetary Authority" },
|
|
31
|
+
ILS: { code: "boi", name: "Bank of Israel" },
|
|
32
|
+
ARS: { code: "bcra", name: "Central Bank of Argentina" },
|
|
33
|
+
ZAR: { code: "sarb", name: "South African Reserve Bank" },
|
|
34
|
+
CHF: { code: "snb", name: "Swiss National Bank" },
|
|
35
|
+
NZD: { code: "rbnz", name: "Reserve Bank of New Zealand" },
|
|
36
|
+
KRW: { code: "bok", name: "Bank of Korea" },
|
|
37
|
+
RON: { code: "bnr", name: "National Bank of Romania" },
|
|
38
|
+
UAH: { code: "nbu", name: "National Bank of Ukraine" },
|
|
39
|
+
MXN: { code: "banxico", name: "Banco de MΓ©xico" },
|
|
40
|
+
PHP: { code: "bsp", name: "Bangko Sentral ng Pilipinas" },
|
|
41
|
+
DOP: { code: "bcrd", name: "Banco Central de la RepΓΊblica Dominicana" },
|
|
42
|
+
PYG: { code: "bcp", name: "Banco Central del Paraguay" },
|
|
43
|
+
KHR: { code: "nbc", name: "National Bank of Cambodia" },
|
|
44
|
+
GHS: { code: "bog", name: "Bank of Ghana" },
|
|
45
|
+
EGP: { code: "cbe", name: "Central Bank of Egypt" },
|
|
46
|
+
ALL: { code: "boa", name: "Bank of Albania" },
|
|
47
|
+
GTQ: { code: "banguat", name: "Banco de Guatemala" },
|
|
48
|
+
MNT: { code: "bom", name: "Bank of Mongolia" },
|
|
49
|
+
SGD: { code: "mas", name: "Monetary Authority of Singapore" },
|
|
50
|
+
DKK: { code: "dnb", name: "Danmarks Nationalbank" },
|
|
51
|
+
COP: { code: "sfc", name: "Superintendencia Financiera de Colombia (TRM)" },
|
|
52
|
+
KZT: { code: "nbk", name: "National Bank of Kazakhstan" },
|
|
53
|
+
GEL: { code: "nbg", name: "National Bank of Georgia" },
|
|
54
|
+
UZS: { code: "cbu", name: "Central Bank of Uzbekistan" },
|
|
55
|
+
HUF: { code: "mnb", name: "Magyar Nemzeti Bank" },
|
|
56
|
+
ISK: { code: "cbi", name: "Central Bank of Iceland" },
|
|
57
|
+
AED: { code: "cbuae", name: "Central Bank of the UAE" },
|
|
58
|
+
PKR: { code: "sbp", name: "State Bank of Pakistan" },
|
|
59
|
+
NPR: { code: "nrb", name: "Nepal Rastra Bank" },
|
|
60
|
+
JOD: { code: "cbj", name: "Central Bank of Jordan" },
|
|
61
|
+
BDT: { code: "bb", name: "Bangladesh Bank" },
|
|
62
|
+
OMR: { code: "cbo", name: "Central Bank of Oman" },
|
|
63
|
+
MMK: { code: "cbm", name: "Central Bank of Myanmar" },
|
|
64
|
+
TWD: { code: "cbc", name: "Central Bank of the Republic of China (Taiwan)" },
|
|
65
|
+
THB: { code: "bot", name: "Bank of Thailand" },
|
|
66
|
+
MOP: { code: "amcm", name: "Monetary Authority of Macao" },
|
|
67
|
+
VND: { code: "sbv", name: "State Bank of Vietnam" },
|
|
68
|
+
LAK: { code: "bol", name: "Bank of the Lao PDR" },
|
|
69
|
+
VES: { code: "bcv", name: "Central Bank of Venezuela" },
|
|
70
|
+
CLP: { code: "bcch", name: "Central Bank of Chile" },
|
|
71
|
+
UYU: { code: "bcu", name: "Central Bank of Uruguay" },
|
|
72
|
+
BOB: { code: "bcbol", name: "Banco Central de Bolivia" },
|
|
73
|
+
SRD: { code: "cbvs", name: "Central Bank of Suriname" },
|
|
74
|
+
GYD: { code: "bogy", name: "Bank of Guyana" },
|
|
75
|
+
SAR: { code: "sama", name: "Saudi Central Bank (SAMA)" },
|
|
76
|
+
MAD: { code: "bam", name: "Bank Al-Maghrib" },
|
|
77
|
+
RSD: { code: "nbs", name: "National Bank of Serbia" },
|
|
78
|
+
BYN: { code: "nbrb", name: "National Bank of the Republic of Belarus" },
|
|
79
|
+
QAR: { code: "qcb", name: "Qatar Central Bank" },
|
|
80
|
+
IQD: { code: "cbiq", name: "Central Bank of Iraq" },
|
|
81
|
+
DZD: { code: "bda", name: "Bank of Algeria" },
|
|
82
|
+
CRC: { code: "bccr", name: "Banco Central de Costa Rica" },
|
|
83
|
+
XOF: { code: "bceao", name: "Central Bank of West African States (BCEAO)" },
|
|
84
|
+
ETB: { code: "nbe", name: "National Bank of Ethiopia" },
|
|
85
|
+
KES: { code: "cbke", name: "Central Bank of Kenya" },
|
|
86
|
+
MDL: { code: "nbm", name: "National Bank of Moldova" },
|
|
87
|
+
MKD: { code: "nbrm", name: "National Bank of North Macedonia" },
|
|
88
|
+
AMD: { code: "cba", name: "Central Bank of Armenia" },
|
|
89
|
+
XAF: { code: "beac", name: "Bank of Central African States (BEAC)" },
|
|
90
|
+
TND: { code: "bct", name: "Central Bank of Tunisia" },
|
|
91
|
+
RWF: { code: "bnrw", name: "National Bank of Rwanda" },
|
|
92
|
+
AOA: { code: "bna", name: "National Bank of Angola" },
|
|
93
|
+
TZS: { code: "botz", name: "Bank of Tanzania" },
|
|
94
|
+
UGX: { code: "bou", name: "Bank of Uganda" },
|
|
95
|
+
JMD: { code: "bojm", name: "Bank of Jamaica" },
|
|
96
|
+
NIO: { code: "bcn", name: "Banco Central de Nicaragua" },
|
|
97
|
+
HNL: { code: "bch", name: "Banco Central de Honduras" },
|
|
98
|
+
TTD: { code: "cbtt", name: "Central Bank of Trinidad and Tobago" },
|
|
99
|
+
MUR: { code: "bmu", name: "Bank of Mauritius" },
|
|
100
|
+
MZN: { code: "bdm", name: "Banco de MoΓ§ambique" },
|
|
101
|
+
BWP: { code: "bob", name: "Bank of Botswana" },
|
|
102
|
+
ZMW: { code: "boz", name: "Bank of Zambia" },
|
|
103
|
+
MWK: { code: "rbm", name: "Reserve Bank of Malawi" },
|
|
104
|
+
KGS: { code: "nbkr", name: "National Bank of the Kyrgyz Republic" },
|
|
105
|
+
CDF: { code: "bcc", name: "Banque Centrale du Congo" },
|
|
106
|
+
BBD: { code: "cbbd", name: "Central Bank of Barbados" },
|
|
107
|
+
LYD: { code: "cbl", name: "Central Bank of Libya" },
|
|
108
|
+
GMD: { code: "cbg", name: "Central Bank of The Gambia" },
|
|
109
|
+
HTG: { code: "brh", name: "Banque de la RΓ©publique d'HaΓ―ti" },
|
|
110
|
+
BTN: { code: "rma", name: "Royal Monetary Authority of Bhutan" },
|
|
111
|
+
TJS: { code: "nbt", name: "National Bank of Tajikistan" },
|
|
112
|
+
BZD: { code: "cbbz", name: "Central Bank of Belize" },
|
|
113
|
+
FJD: { code: "rbf", name: "Reserve Bank of Fiji" },
|
|
114
|
+
MVR: { code: "mma", name: "Maldives Monetary Authority" },
|
|
115
|
+
MRU: { code: "bcm", name: "Banque Centrale de Mauritanie" },
|
|
116
|
+
ZWG: { code: "rbz", name: "Reserve Bank of Zimbabwe" },
|
|
117
|
+
NAD: { code: "bon", name: "Bank of Namibia" },
|
|
118
|
+
MGA: { code: "bfm", name: "Central Bank of Madagascar (BFM)" },
|
|
119
|
+
TMT: { code: "cbt", name: "Central Bank of Turkmenistan" },
|
|
120
|
+
CUP: { code: "bccu", name: "Banco Central de Cuba" },
|
|
121
|
+
SLE: { code: "bsl", name: "Bank of Sierra Leone" },
|
|
122
|
+
STN: { code: "bcstp", name: "Banco Central de SΓ£o TomΓ© e PrΓncipe" },
|
|
123
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -41,15 +41,15 @@ async function main() {
|
|
|
41
41
|
' AllRatesToday MCP β running in KEYLESS mode.',
|
|
42
42
|
'',
|
|
43
43
|
' Available now, no key needed:',
|
|
44
|
-
' β’ get_exchange_rate β official
|
|
44
|
+
' β’ get_exchange_rate β official central-bank rate (ECB, else the issuing bank)',
|
|
45
45
|
' β’ list_currencies β all supported currency codes',
|
|
46
46
|
' β’ list_central_banks β 121 central banks + 3 tax authorities we carry',
|
|
47
47
|
' β’ get_official_rates β latest official table (or one pair) from any of them',
|
|
48
48
|
' β’ get_reference_rate β Daily Reference Rate, one fixed table per business day (16:00 London)',
|
|
49
49
|
' β’ request_trial_key β self-issue a 100-call, 7-day key without an account',
|
|
50
50
|
'',
|
|
51
|
-
' Needs a free API key (real-time mid-market rates for 160+ currencies
|
|
52
|
-
'
|
|
51
|
+
' Needs a free API key (real-time mid-market rates for 160+ currencies and',
|
|
52
|
+
' multi-target lookups). Historical series and point-in-time lookups need a paid plan:',
|
|
53
53
|
' 1. https://allratestoday.com/register β free tier, no card, under a minute',
|
|
54
54
|
' 2. Add to this server\'s MCP config: "env": { "ALLRATES_API_KEY": "art_live_..." }',
|
|
55
55
|
'',
|
|
@@ -62,13 +62,14 @@ async function main() {
|
|
|
62
62
|
const server = new McpServer({ name: 'allratestoday-mcp', version: VERSION });
|
|
63
63
|
server.registerTool('get_exchange_rate', {
|
|
64
64
|
title: 'Get live exchange rate',
|
|
65
|
-
description: "Use this when the user asks 'what is X in Y?', 'convert X to Y', 'current rate of EUR/USD', or any single fiat-to-fiat live exchange rate question. Returns the latest mid-market rate as a JSON object like { rate: 0.9234, source } meaning 1 source = 0.9234 target. Does NOT support cryptocurrencies, commodities, or arithmetic on amounts. For multiple targets in one call use get_rates_authenticated; for a past date or fixed lookback (7d/30d/1y) use get_historical_rates.",
|
|
65
|
+
description: "Use this when the user asks 'what is X in Y?', 'convert X to Y', 'current rate of EUR/USD', or any single fiat-to-fiat live exchange rate question. Returns the latest mid-market rate as a JSON object like { rate: 0.9234, source } meaning 1 source = 0.9234 target. Without an API key it answers from an official central-bank table instead (ECB first, else the bank that issues one of the two currencies) and says so in `note` β relay the `rate_date`; pairs no single bank publishes (or inverts) need a key. Does NOT support cryptocurrencies, commodities, or arithmetic on amounts. For multiple targets in one call use get_rates_authenticated; for a past date or fixed lookback (7d/30d/1y) use get_historical_rates.",
|
|
66
66
|
inputSchema: { source: ccy, target: ccy },
|
|
67
67
|
outputSchema: {
|
|
68
68
|
rate: z.number().describe('How much 1 unit of source is worth in target'),
|
|
69
69
|
source: z.string().describe('Upstream data provider the rate came from'),
|
|
70
|
-
// Keyless mode answers from
|
|
71
|
-
// publication date plus a note the assistant should relay.
|
|
70
|
+
// Keyless mode answers from an open central-bank table and adds the
|
|
71
|
+
// bank, publication date plus a note the assistant should relay.
|
|
72
|
+
bank: z.string().optional(),
|
|
72
73
|
rate_date: z.string().optional(),
|
|
73
74
|
derived: z.boolean().optional(),
|
|
74
75
|
note: z.string().optional(),
|
|
@@ -84,7 +85,7 @@ async function main() {
|
|
|
84
85
|
});
|
|
85
86
|
server.registerTool('get_historical_rates', {
|
|
86
87
|
title: 'Get historical rate time-series',
|
|
87
|
-
description: "Use this for fixed-window time-series questions like 'how has EUR/USD moved this week', 'show me the last month of GBP/JPY', or 'chart 1-year history of AUD/USD'. Returns { source, target, period, data: [{ date, rate, timestamp }, ...] } β sampling is fixed per period (1d=hourly, 7d/30d=daily, 1y=weekly) and the window always ends NOW. For a specific past datetime use get_rates_authenticated with `time`. For a single live rate use get_exchange_rate.",
|
|
88
|
+
description: "Use this for fixed-window time-series questions like 'how has EUR/USD moved this week', 'show me the last month of GBP/JPY', or 'chart 1-year history of AUD/USD'. Returns { source, target, period, data: [{ date, rate, timestamp }, ...] } β sampling is fixed per period (1d=hourly, 7d/30d=daily, 1y=weekly) and the window always ends NOW. Needs an API key on a paid plan; free and trial keys get a 403. For a specific past datetime use get_rates_authenticated with `time`. For a single live rate use get_exchange_rate.",
|
|
88
89
|
inputSchema: {
|
|
89
90
|
source: ccy,
|
|
90
91
|
target: ccy,
|
|
@@ -115,7 +116,7 @@ async function main() {
|
|
|
115
116
|
});
|
|
116
117
|
server.registerTool('get_rates_authenticated', {
|
|
117
118
|
title: 'Get multi-target or point-in-time rates',
|
|
118
|
-
description: "Use this for (a) one source against multiple targets in a single call ('USD vs EUR, GBP, JPY'), or (b) the rate at a specific past datetime ('EUR/USD at 2025-03-14T12:00Z'), optionally bucketed by hour/day/week/month. Returns { rates: [{ rate, source, target, time }, ...] } β one row per target Γ time bucket. For a single live pair use get_exchange_rate. For fixed lookback windows (1d/7d/30d/1y ending now) use get_historical_rates.",
|
|
119
|
+
description: "Use this for (a) one source against multiple targets in a single call ('USD vs EUR, GBP, JPY'), or (b) the rate at a specific past datetime ('EUR/USD at 2025-03-14T12:00Z'), optionally bucketed by hour/day/week/month. Returns { rates: [{ rate, source, target, time }, ...] } β one row per target Γ time bucket. Multi-target latest rates work on any key; a past datetime (`time`) needs a paid plan. For a single live pair use get_exchange_rate. For fixed lookback windows (1d/7d/30d/1y ending now) use get_historical_rates.",
|
|
119
120
|
inputSchema: {
|
|
120
121
|
source: ccy,
|
|
121
122
|
target: ccyList,
|
|
@@ -154,7 +155,7 @@ async function main() {
|
|
|
154
155
|
});
|
|
155
156
|
server.registerTool('list_currencies', {
|
|
156
157
|
title: 'List supported currencies',
|
|
157
|
-
description: "Call this BEFORE other tools when you are unsure whether a currency code is supported, or when the user asks 'what currencies do you support?', 'is X a valid currency?', or 'what is the symbol for X?'. Returns { currencies: [{ code: 'USD', name: 'US Dollar', symbol: '$' }, ...], count } covering
|
|
158
|
+
description: "Call this BEFORE other tools when you are unsure whether a currency code is supported, or when the user asks 'what currencies do you support?', 'is X a valid currency?', or 'what is the symbol for X?'. Returns { currencies: [{ code: 'USD', name: 'US Dollar', symbol: '$' }, ...], count } covering 160+ ISO 4217 fiat currencies. Does NOT include cryptocurrencies. Cheap to call (cached 24h upstream) β use it to validate user input and prevent downstream errors in get_exchange_rate / get_rates_authenticated / get_historical_rates.",
|
|
158
159
|
inputSchema: {},
|
|
159
160
|
outputSchema: {
|
|
160
161
|
currencies: z.array(z.object({
|
|
@@ -198,7 +199,7 @@ async function main() {
|
|
|
198
199
|
});
|
|
199
200
|
server.registerTool('get_official_rates', {
|
|
200
201
|
title: "Get a bank's official published rates",
|
|
201
|
-
description: "OFFICIAL rates a named institution published β 'what is the ECB rate for USD?', 'Bank of Japan rate today', 'HMRC rate for invoicing'. These are the fixed, citable rates for compliance, tax, customs and accounting β NOT live market rates (use get_exchange_rate for those). Omit `date` for the newest published table (no API key needed); give `date` (API key) for the table in force that day β weekends/holidays roll back to the last published date and the response's `rate_date` says which. Omit source/target for the full table; give both for one pair β cross-computed inside the bank's own table when not directly published, flagged `derived`. Always cite the returned `rate_date`.",
|
|
202
|
+
description: "OFFICIAL rates a named institution published β 'what is the ECB rate for USD?', 'Bank of Japan rate today', 'HMRC rate for invoicing'. These are the fixed, citable rates for compliance, tax, customs and accounting β NOT live market rates (use get_exchange_rate for those). Omit `date` for the newest published table (no API key needed); give `date` (API key, paid plan) for the table in force that day β weekends/holidays roll back to the last published date and the response's `rate_date` says which. Omit source/target for the full table; give both for one pair β cross-computed inside the bank's own table when not directly published, flagged `derived`. Always cite the returned `rate_date`.",
|
|
202
203
|
inputSchema: {
|
|
203
204
|
bank: z
|
|
204
205
|
.string()
|
|
@@ -239,7 +240,7 @@ async function main() {
|
|
|
239
240
|
});
|
|
240
241
|
server.registerTool('get_reference_rate', {
|
|
241
242
|
title: 'Get the Daily Reference Rate (16:00 London)',
|
|
242
|
-
description: "AllRatesToday's once-a-day, never-revised mid-market rate: the per-currency median of samples in a five-minute window centred on 16:00 London, published each business day. Use it when the user needs ONE reproducible rate per day β index levels, return series, research datasets, month-end reports β rather than a live quote (get_exchange_rate) or an institution's official rate (get_official_rates). Omit source/target for the whole table; give both for one pair (crossed via USD, flagged `derived`). Omit `date` for the latest table (no key needed); give `date` (API key) for a past business day. Not the WM/Refinitiv fix and not a registered benchmark β relay the disclaimer and the `rate_date`.",
|
|
243
|
+
description: "AllRatesToday's once-a-day, never-revised mid-market rate: the per-currency median of samples in a five-minute window centred on 16:00 London, published each business day. Use it when the user needs ONE reproducible rate per day β index levels, return series, research datasets, month-end reports β rather than a live quote (get_exchange_rate) or an institution's official rate (get_official_rates). Omit source/target for the whole table; give both for one pair (crossed via USD, flagged `derived`). Omit `date` for the latest table (no key needed); give `date` (API key, paid plan) for a past business day. Not the WM/Refinitiv fix and not a registered benchmark β relay the disclaimer and the `rate_date`.",
|
|
243
244
|
inputSchema: {
|
|
244
245
|
source: ccy.optional().describe('Optional. With target, narrows to one pair.'),
|
|
245
246
|
target: ccy.optional().describe('Optional. With source, narrows to one pair.'),
|
|
@@ -247,7 +248,7 @@ async function main() {
|
|
|
247
248
|
.string()
|
|
248
249
|
.regex(/^\d{4}-\d{2}-\d{2}$/)
|
|
249
250
|
.optional()
|
|
250
|
-
.describe('Optional past business day, YYYY-MM-DD (API key). Omit for the latest table.'),
|
|
251
|
+
.describe('Optional past business day, YYYY-MM-DD (API key, paid plan). Omit for the latest table.'),
|
|
251
252
|
},
|
|
252
253
|
outputSchema: {
|
|
253
254
|
rate_date: z.string().describe('Business day the table was fixed on β cite this'),
|
|
@@ -272,7 +273,7 @@ async function main() {
|
|
|
272
273
|
});
|
|
273
274
|
server.registerTool('request_trial_key', {
|
|
274
275
|
title: 'Request a trial API key',
|
|
275
|
-
description: 'Self-issue an AllRatesToday API key with 100 lifetime calls, valid 7 days, with no account and no email. Use it when another tool answered "needs an API key" and the user wants real-time rates
|
|
276
|
+
description: 'Self-issue an AllRatesToday API key with 100 lifetime calls, valid 7 days, with no account and no email. Use it when another tool answered "needs an API key" and the user wants real-time rates or history right now. The key is adopted by this server for the rest of the session and returned once β tell the user to put it in the MCP config as ALLRATES_API_KEY to keep it. Capped at 3 keys per IP per day. For a lasting key, register at https://allratestoday.com/register (free, 300 calls) or see https://allratestoday.com/pricing.',
|
|
276
277
|
inputSchema: {
|
|
277
278
|
agent: z.string().max(80).optional().describe('Optional: the agent or product requesting the key.'),
|
|
278
279
|
purpose: z.string().max(200).optional().describe('Optional: one line on what the rates are for.'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allratestoday/mcp-server",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"mcpName": "io.github.cahthuranag/mcp-server",
|
|
5
5
|
"description": "MCP server for AllRatesToday β let AI coding tools (Claude Code, Cursor, Claude Desktop) fetch real-time and historical currency exchange rates.",
|
|
6
6
|
"keywords": [
|