@allratestoday/mcp-server 0.5.2 → 0.6.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/README.md CHANGED
@@ -21,7 +21,7 @@ After installation, your assistant can answer questions like:
21
21
 
22
22
  - 📡 **Live mid-market rates** — 150+ ISO 4217 currencies, refreshed every ~60 seconds
23
23
  - 📈 **Historical series built in** — `1d` / `7d` / `30d` / `1y` windows with sensible granularity per period
24
- - 🧰 **Four focused tools** — `get_exchange_rate`, `get_historical_rates`, `get_rates_authenticated`, `list_currencies`; small surface, easy for the model to use correctly
24
+ - 🧰 **Six focused tools** — `get_exchange_rate`, `get_historical_rates`, `get_rates_authenticated`, `list_currencies`, `list_central_banks`, `get_official_rates`; small surface, easy for the model to use correctly
25
25
  - 🔌 **Works everywhere MCP does** — stdio transport, MCP 1.x; Claude Code, Cursor, Claude Desktop, Windsurf, or any generic host
26
26
  - 🔓 **Works with no API key** — installs and answers out of the box from the open ECB reference table; a free key unlocks real-time rates for 160+ currencies
27
27
  - 🛡️ **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
@@ -29,7 +29,7 @@ After installation, your assistant can answer questions like:
29
29
 
30
30
  ## ⚖️ Mid-market vs official central-bank rates
31
31
 
32
- Everything this server returns is 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, AllRatesToday also serves **published central-bank and tax-authority rates** (100+ sources — ECB, Fed, HMRC, US Treasury, …) that are fixed once published and carry the institution's own publication date — via 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.
32
+ Everything this server returns is 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 tables and history sit behind 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.
33
33
 
34
34
  ## 🔓 Keyless mode — what works with no setup
35
35
 
@@ -39,6 +39,8 @@ Install it with no configuration at all and it starts, connects, and answers:
39
39
  |---|---|---|
40
40
  | `get_exchange_rate` | ✅ | Official **ECB daily reference rate**, ~30 major currencies. The response carries `rate_date` and a note saying so, so the assistant never passes it off as a live quote. |
41
41
  | `list_currencies` | ✅ | All 160+ supported ISO 4217 codes. |
42
+ | `list_central_banks` | ✅ | Codes, names and latest publication date of all 121 central banks + 3 tax authorities. |
43
+ | `get_official_rates` | ✅ | Latest **official table** (or one pair) published by any of them. A dated table needs the key. |
42
44
  | `get_historical_rates` | 🔑 | Returns one sentence explaining how to get a free key. |
43
45
  | `get_rates_authenticated` | 🔑 | Same. |
44
46
 
@@ -138,7 +140,7 @@ Edit `~/.cursor/mcp.json` (or `.cursor/mcp.json` inside your project for project
138
140
  }
139
141
  ```
140
142
 
141
- Restart Cursor. The four tools should appear in the MCP tool picker.
143
+ Restart Cursor. The six tools should appear in the MCP tool picker.
142
144
 
143
145
  ### Claude Desktop
144
146
 
@@ -185,7 +187,7 @@ npx -y @allratestoday/mcp-server
185
187
  After configuring your client, test in this order:
186
188
 
187
189
  1. **Server starts** — open the client. A red dot or "failed to connect" means the API key is missing or wrong (see Troubleshooting below).
188
- 2. **Tools are listed** — most clients have a "tools" or "MCP" panel showing the four tools.
190
+ 2. **Tools are listed** — most clients have a "tools" or "MCP" panel showing the six tools.
189
191
  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.
190
192
 
191
193
  ## 📚 Tools reference
@@ -194,8 +196,10 @@ After configuring your client, test in this order:
194
196
  - [`get_historical_rates`](#get_historical_rates) — time series over a preset period
195
197
  - [`get_rates_authenticated`](#get_rates_authenticated) — multiple targets in one call, optional point-in-time
196
198
  - [`list_currencies`](#list_currencies) — all supported currency codes, names, symbols
199
+ - [`list_central_banks`](#list_central_banks) — every covered central bank / tax authority with its code and latest publication date
200
+ - [`get_official_rates`](#get_official_rates) — the official table (or one pair) a named institution published
197
201
 
198
- All four tools require `ALLRATES_API_KEY`.
202
+ `get_historical_rates` and `get_rates_authenticated` require `ALLRATES_API_KEY`; the other four work keyless.
199
203
 
200
204
  ---
201
205
 
@@ -315,6 +319,61 @@ All supported currencies with codes, names, and symbols. Cached upstream for 24
315
319
 
316
320
  ---
317
321
 
322
+ ### `list_central_banks`
323
+
324
+ 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.
325
+
326
+ **Input** — none.
327
+
328
+ **Response (truncated):**
329
+
330
+ ```json
331
+ {
332
+ "sources": [
333
+ { "code": "ecb", "name": "European Central Bank", "latest": "2026-09-30", "stale": false },
334
+ { "code": "fed", "name": "Federal Reserve", "latest": "2026-09-29", "stale": false },
335
+ "..."
336
+ ],
337
+ "stale_count": 0,
338
+ "checked_at": "2026-10-01T09:00:00Z"
339
+ }
340
+ ```
341
+
342
+ ---
343
+
344
+ ### `get_official_rates`
345
+
346
+ The fixed, citable rate an institution published — for invoices, VAT and tax returns, customs, transfer pricing and audit. Not a live market rate.
347
+
348
+ **Input:**
349
+
350
+ | Field | Type | Required | Description |
351
+ |---|---|---|---|
352
+ | `bank` | string | yes | Source code from `list_central_banks`, e.g. `ecb`, `fed`, `boe`, `rbi`, `hmrc` |
353
+ | `date` | string | no | `YYYY-MM-DD`. Omit for the latest table (keyless). Needs the API key. Weekends/holidays roll back to the last published date. |
354
+ | `source` | string | no | With `target`, narrows to one pair |
355
+ | `target` | string | no | With `source`, narrows to one pair |
356
+
357
+ **Response (one pair):**
358
+
359
+ ```json
360
+ {
361
+ "bank": "ecb",
362
+ "rate_date": "2026-09-30",
363
+ "source": "EUR",
364
+ "target": "USD",
365
+ "rate": 1.1355,
366
+ "rate_type": "reference",
367
+ "derived": false,
368
+ "method": "published",
369
+ "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" }
370
+ }
371
+ ```
372
+
373
+ Omit `source`/`target` for the whole table as `rates: [{ base, quote, type, value }]`. Pairs the bank does not publish directly are cross-computed inside its own table and flagged `derived: true`. Always cite `rate_date`.
374
+
375
+ ---
376
+
318
377
  ## ⚙️ Environment variables
319
378
 
320
379
  | Variable | Default | Required | Purpose |
@@ -415,6 +474,8 @@ server.json # MCP registry manifest
415
474
 
416
475
  See [GitHub Releases](https://github.com/cahthuranag/mcp-server/releases) for the full list. Recent highlights:
417
476
 
477
+ - **0.6.1** — README: Claude Code plugin and hosted `/api/mcp` endpoint cross-links; coverage wording refreshed
478
+ - **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)
418
479
  - **0.5.0** — Keyless mode: the server starts and answers without an API key (`get_exchange_rate` via the open ECB reference table, `list_currencies` unchanged); metered tools return actionable sign-up guidance instead of the process exiting
419
480
  - **0.4.x** — README overhaul; registry metadata updates
420
481
  - **0.3.x** — API key required for all tools; fail-fast at startup with clear error
package/dist/client.d.ts CHANGED
@@ -50,6 +50,27 @@ export declare class AllRatesTodayClient {
50
50
  target: string;
51
51
  time: string;
52
52
  }[]>;
53
+ /** Every covered official source (121 central banks + 3 tax authorities). Keyless. */
54
+ listCentralBanks(): Promise<{
55
+ sources: {
56
+ code: string;
57
+ name: string;
58
+ latest: string | null;
59
+ stale?: boolean;
60
+ }[];
61
+ stale_count: number;
62
+ checked_at: string;
63
+ }>;
64
+ /**
65
+ * Latest OFFICIAL table published by a central bank or tax authority, or one
66
+ * pair from it (cross-computed inside the bank's own table when not published
67
+ * directly, flagged `derived`). Keyless; a dated table needs the key.
68
+ */
69
+ getOfficialRates(bank: string, params?: {
70
+ date?: string;
71
+ source?: string;
72
+ target?: string;
73
+ }): Promise<Record<string, unknown>>;
53
74
  listSymbols(): Promise<{
54
75
  currencies: {
55
76
  code: string;
package/dist/client.js CHANGED
@@ -20,8 +20,8 @@ export class NeedsKeyError extends AllRatesTodayError {
20
20
  super(`${what} needs an AllRatesToday API key. The free tier covers it — sign up at ` +
21
21
  'https://allratestoday.com/register (no card, under a minute), then set ALLRATES_API_KEY ' +
22
22
  "in this MCP server's config and restart. Without a key the server still answers " +
23
- 'get_exchange_rate for ~30 major currencies (official ECB daily reference rate) and ' +
24
- 'list_currencies.');
23
+ 'get_exchange_rate for ~30 major currencies (official ECB daily reference rate), ' +
24
+ 'list_currencies, list_central_banks and get_official_rates (latest tables).');
25
25
  this.name = 'NeedsKeyError';
26
26
  }
27
27
  }
@@ -109,6 +109,31 @@ export class AllRatesTodayClient {
109
109
  return Promise.reject(new NeedsKeyError('Multi-target and point-in-time rates'));
110
110
  return this.request('/v1/rates', params);
111
111
  }
112
+ /** Every covered official source (121 central banks + 3 tax authorities). Keyless. */
113
+ listCentralBanks() {
114
+ return this.request(this.keyless ? '/open/central-banks' : '/v1/central-banks', {});
115
+ }
116
+ /**
117
+ * Latest OFFICIAL table published by a central bank or tax authority, or one
118
+ * pair from it (cross-computed inside the bank's own table when not published
119
+ * directly, flagged `derived`). Keyless; a dated table needs the key.
120
+ */
121
+ getOfficialRates(bank, params = {}) {
122
+ const code = bank.trim().toLowerCase();
123
+ if (!/^[a-z0-9_-]{2,20}$/.test(code)) {
124
+ return Promise.reject(new AllRatesTodayError(`Unknown source code "${bank}" — call list_central_banks first.`));
125
+ }
126
+ if (Boolean(params.source) !== Boolean(params.target)) {
127
+ return Promise.reject(new AllRatesTodayError('Provide both source and target, or neither.'));
128
+ }
129
+ const pair = { source: params.source?.toUpperCase(), target: params.target?.toUpperCase() };
130
+ if (this.keyless) {
131
+ if (params.date)
132
+ return Promise.reject(new NeedsKeyError(`The ${code} table for ${params.date}`));
133
+ return this.request(`/open/central-bank/${encodeURIComponent(code)}`, pair);
134
+ }
135
+ return this.request(`/v1/central-bank/${encodeURIComponent(code)}/${params.date ?? 'latest'}`, pair);
136
+ }
112
137
  listSymbols() {
113
138
  return this.request('/v1/symbols', {});
114
139
  }
package/dist/index.js CHANGED
@@ -43,6 +43,8 @@ async function main() {
43
43
  ' Available now, no key needed:',
44
44
  ' • get_exchange_rate — official ECB daily reference rate, ~30 major currencies',
45
45
  ' • list_currencies — all supported currency codes',
46
+ ' • list_central_banks — 121 central banks + 3 tax authorities we carry',
47
+ ' • get_official_rates — latest official table (or one pair) from any of them',
46
48
  '',
47
49
  ' Needs a free API key (real-time mid-market rates for 160+ currencies,',
48
50
  ' historical series, multi-target and point-in-time lookups):',
@@ -169,6 +171,70 @@ async function main() {
169
171
  return fail(err);
170
172
  }
171
173
  });
174
+ server.registerTool('list_central_banks', {
175
+ title: 'List covered central banks & tax authorities',
176
+ description: "Call this FIRST when you need a bank code, or for 'which central banks do you cover?' / 'do you have rates from X?'. Returns every covered source — 121 central banks plus 3 tax authorities (HMRC, US Treasury, Swiss BAZG) — with `code` (what get_official_rates takes as `bank`), name, latest publication date and whether it is behind schedule. No API key needed.",
177
+ inputSchema: {},
178
+ outputSchema: {
179
+ sources: z.array(z.object({
180
+ code: z.string(),
181
+ name: z.string(),
182
+ latest: z.string().nullable(),
183
+ stale: z.boolean().optional(),
184
+ }).passthrough()),
185
+ stale_count: z.number(),
186
+ checked_at: z.string(),
187
+ },
188
+ annotations: READ_ONLY,
189
+ }, async () => {
190
+ try {
191
+ return ok(await client.listCentralBanks());
192
+ }
193
+ catch (err) {
194
+ return fail(err);
195
+ }
196
+ });
197
+ server.registerTool('get_official_rates', {
198
+ title: "Get a bank's official published rates",
199
+ 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`.",
200
+ inputSchema: {
201
+ bank: z
202
+ .string()
203
+ .regex(/^[A-Za-z0-9_-]{2,20}$/)
204
+ .describe("Source code from list_central_banks, e.g. 'ecb', 'fed', 'boe', 'rbi', 'hmrc'. Case-insensitive."),
205
+ date: z
206
+ .string()
207
+ .regex(/^\d{4}-\d{2}-\d{2}$/)
208
+ .optional()
209
+ .describe('Optional YYYY-MM-DD. Omit for the latest table.'),
210
+ source: ccy.optional().describe('Optional. With target, narrows to one pair.'),
211
+ target: ccy.optional().describe('Optional. With source, narrows to one pair.'),
212
+ },
213
+ outputSchema: {
214
+ bank: z.string(),
215
+ rate_date: z.string().describe('Publication date of the table — cite this, not today'),
216
+ // Full table (no pair given)
217
+ rates: z
218
+ .array(z.object({ base: z.string(), quote: z.string(), type: z.string(), value: z.number() }))
219
+ .optional(),
220
+ // One pair (source + target given)
221
+ source: z.string().optional(),
222
+ target: z.string().optional(),
223
+ rate: z.number().optional(),
224
+ rate_type: z.string().optional(),
225
+ derived: z.boolean().optional().describe('True when cross-computed inside the bank table'),
226
+ stale: z.boolean().optional().describe('True when the institution is behind its publication schedule'),
227
+ attribution: z.object({ source: z.string(), url: z.string(), terms: z.string() }).passthrough().optional(),
228
+ },
229
+ annotations: READ_ONLY,
230
+ }, async ({ bank, date, source, target }) => {
231
+ try {
232
+ return ok(await client.getOfficialRates(bank, { date, source, target }));
233
+ }
234
+ catch (err) {
235
+ return fail(err);
236
+ }
237
+ });
172
238
  const transport = new StdioServerTransport();
173
239
  await server.connect(transport);
174
240
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allratestoday/mcp-server",
3
- "version": "0.5.2",
3
+ "version": "0.6.1",
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": [