@allratestoday/central-bank-mcp 0.1.0 → 0.2.0

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,22 +21,60 @@ Everything this server returns is an **official published rate**: fixed once the
21
21
 
22
22
  ## 🚀 Why this server?
23
23
 
24
- - 🏛️ **60+ official sources** — central banks (ECB, Fed, BOJ, SNB, RBI, …) plus tax authorities (HMRC, US Treasury, …), each served from its own published tables
24
+ - 🏛️ **100+ official sources** — central banks (ECB, Fed, BOJ, SNB, RBI, …) plus tax authorities (HMRC, US Treasury, …), each served from its own published tables
25
25
  - 📅 **Point-in-time correctness** — ask for any date; weekends and holidays roll back to the rate legally in force, and the response tells you which publication date applied
26
26
  - 📊 **Cross-bank comparison** — one call returns every institution's rate for a pair, with min/max/median and spread stats
27
27
  - 🧮 **Honest derivations** — pairs a bank doesn't publish directly are cross-computed only within that bank's own table and flagged `derived`; banks are never mixed
28
+ - 🔓 **Works with no API key** — installs and answers out of the box; the latest published table of every source is open
28
29
  - 🧰 **Five focused tools** — small surface, easy for the model to use correctly
29
30
  - 🔌 **Works everywhere MCP does** — stdio transport, MCP 1.x; Claude Code, Cursor, Claude Desktop, Windsurf, or any generic host
30
31
 
31
- ## 🔑 Get your API key
32
+ ## 🔓 Keyless mode — what works with no setup
32
33
 
33
- The server **will not start** without a valid `ALLRATES_API_KEY`. A free key covers the latest published tables — **no credit card required**. Dated tables and history need a paid plan.
34
+ Install it with no configuration at all and it starts, connects, and answers:
35
+
36
+ | Tool | Keyless | What you get |
37
+ |---|---|---|
38
+ | `list_central_banks` | ✅ | Every covered institution, from a catalogue bundled with the package (no coverage dates). |
39
+ | `get_official_rates` | ✅ | The **latest published table** of any source, or one pair from it, with the publisher's own `rate_date`. |
40
+ | `get_official_rates` with a `date` | 🔑 | One sentence explaining how to get a key. |
41
+ | `get_official_rate_history` | 🔑 | Same. |
42
+ | `compare_official_rates` | 🔑 | Same. |
43
+ | `get_publication_calendar` | 🔑 | Same. |
44
+
45
+ The keyless path reads the open, edge-cached `/api/open/central-bank/{bank}`
46
+ endpoint — free to use with a visible attribution link back to allratestoday.com
47
+ (the exact wording ships in each response's `attribution` field).
48
+
49
+ ## 🔑 Get your API key (free)
50
+
51
+ A key adds historical dates, time series, cross-bank comparison and publication
52
+ calendars. The free tier covers the latest published tables and light historical
53
+ use — **no credit card required**. Deep history and dated tables need a paid plan.
34
54
 
35
55
  1. Register at [allratestoday.com/register](https://allratestoday.com/register) — 30 seconds
36
56
  2. Verify your email
37
57
  3. Copy your key from the dashboard (format: `art_live_xxxxx`)
38
58
  4. Use it as `ALLRATES_API_KEY` in the configs below
39
59
 
60
+ Without one the server prints a short summary of keyless mode on stderr and
61
+ keeps running — it never exits, because an MCP server that exits breaks the
62
+ host client's whole configuration.
63
+
64
+ ## 🧩 Easiest install: the Claude Code plugin
65
+
66
+ If you use Claude Code, install the plugin instead of configuring this server by
67
+ hand — it bundles both AllRatesToday MCP servers, two skills, and five slash
68
+ commands (`/rate`, `/convert`, `/official-rate`, `/fx-history`,
69
+ `/add-currency-support`):
70
+
71
+ ```
72
+ /plugin marketplace add AllRates-Today/claude-code-plugin
73
+ /plugin install allratestoday@allratestoday
74
+ ```
75
+
76
+ Everything below still applies for other MCP clients.
77
+
40
78
  ## 📦 Installation
41
79
 
42
80
  ```bash
@@ -89,11 +127,11 @@ Edit `claude_desktop_config.json` (Settings → Developer → Edit Config) and a
89
127
 
90
128
  | Tool | What it does | Plan |
91
129
  |---|---|---|
92
- | `list_central_banks` | All covered institutions with codes, metadata, latest date | Free |
93
- | `get_official_rates` | A bank's published table (or one pair), latest or for a given date | Free (latest) / Paid (dated) |
130
+ | `list_central_banks` | All covered institutions with codes, metadata, latest date | Free (keyless: bundled catalogue) |
131
+ | `get_official_rates` | A bank's published table (or one pair), latest or for a given date | Keyless (latest) / Paid (dated) |
94
132
  | `get_official_rate_history` | Date-by-date official series for one pair | Paid, billed ~1 call per month covered |
95
- | `compare_official_rates` | One pair across every bank, with spread stats | Free |
96
- | `get_publication_calendar` | Dates a bank actually published (no values) | Free |
133
+ | `compare_official_rates` | One pair across every bank, with spread stats | Free (key required) |
134
+ | `get_publication_calendar` | Dates a bank actually published (no values) | Free (key required) |
97
135
 
98
136
  ## 🔒 Privacy
99
137
 
@@ -0,0 +1,9 @@
1
+ export interface BankCatalogEntry {
2
+ code: string;
3
+ name: string;
4
+ country: string;
5
+ home_ccy: string;
6
+ kind: string;
7
+ npm?: string;
8
+ }
9
+ export declare const BANK_CATALOG: BankCatalogEntry[];
package/dist/banks.js ADDED
@@ -0,0 +1,113 @@
1
+ // GENERATED FILE — do not edit by hand.
2
+ // Offline catalogue of the sources AllRatesToday covers, mirrored from the
3
+ // site's src/data/central-banks.js. It exists so list_central_banks answers in
4
+ // keyless mode, where /api/v1/central-banks (which carries coverage dates and
5
+ // needs a key) is unavailable. Regenerate with scripts/gen-banks.mjs.
6
+ export const BANK_CATALOG = [
7
+ { "code": "fed", "name": "US Federal Reserve (H.10)", "country": "United States", "home_ccy": "USD", "kind": "central_bank", "npm": "fed-exchange-rate" },
8
+ { "code": "boe", "name": "Bank of England", "country": "United Kingdom", "home_ccy": "GBP", "kind": "central_bank", "npm": "boe-exchange-rate" },
9
+ { "code": "pboc", "name": "People's Bank of China (CFETS)", "country": "China", "home_ccy": "CNY", "kind": "central_bank", "npm": "pboc-exchange-rate" },
10
+ { "code": "rba", "name": "Reserve Bank of Australia", "country": "Australia", "home_ccy": "AUD", "kind": "central_bank", "npm": "rba-exchange-rate" },
11
+ { "code": "cbr", "name": "Bank of Russia", "country": "Russia", "home_ccy": "RUB", "kind": "central_bank", "npm": "cbr-exchange-rate" },
12
+ { "code": "tcmb", "name": "Central Bank of Türkiye", "country": "Türkiye", "home_ccy": "TRY", "kind": "central_bank", "npm": "tcmb-exchange-rate" },
13
+ { "code": "bcb", "name": "Banco Central do Brasil (PTAX)", "country": "Brazil", "home_ccy": "BRL", "kind": "central_bank", "npm": "bcb-exchange-rate" },
14
+ { "code": "bi", "name": "Bank Indonesia", "country": "Indonesia", "home_ccy": "IDR", "kind": "central_bank", "npm": "bank-indonesia-exchange-rate" },
15
+ { "code": "rbi", "name": "Reserve Bank of India", "country": "India", "home_ccy": "INR", "kind": "central_bank", "npm": "rbi-exchange-rate" },
16
+ { "code": "boc", "name": "Bank of Canada", "country": "Canada", "home_ccy": "CAD", "kind": "central_bank", "npm": "boc-exchange-rate" },
17
+ { "code": "bnm", "name": "Bank Negara Malaysia", "country": "Malaysia", "home_ccy": "MYR", "kind": "central_bank", "npm": "bnm-exchange-rate" },
18
+ { "code": "cbsl", "name": "Central Bank of Sri Lanka", "country": "Sri Lanka", "home_ccy": "LKR", "kind": "central_bank", "npm": "cbsl-exchange-rate" },
19
+ { "code": "cnb", "name": "Czech National Bank", "country": "Czech Republic", "home_ccy": "CZK", "kind": "central_bank", "npm": "czech-national-bank-exchange-rate" },
20
+ { "code": "ecb", "name": "European Central Bank", "country": "Eurozone", "home_ccy": "EUR", "kind": "central_bank", "npm": "ecb-exchange-rate" },
21
+ { "code": "nbp", "name": "Narodowy Bank Polski", "country": "Poland", "home_ccy": "PLN", "kind": "central_bank", "npm": "nbp-exchange-rate" },
22
+ { "code": "norges", "name": "Norges Bank", "country": "Norway", "home_ccy": "NOK", "kind": "central_bank", "npm": "norges-bank-exchange-rate" },
23
+ { "code": "riksbank", "name": "Sveriges Riksbank", "country": "Sweden", "home_ccy": "SEK", "kind": "central_bank", "npm": "riksbank-exchange-rate" },
24
+ { "code": "cbn", "name": "Central Bank of Nigeria", "country": "Nigeria", "home_ccy": "NGN", "kind": "central_bank", "npm": "cbn-exchange-rate" },
25
+ { "code": "cbk", "name": "Central Bank of Kuwait", "country": "Kuwait", "home_ccy": "KWD", "kind": "central_bank", "npm": "cbk-exchange-rate" },
26
+ { "code": "cbb", "name": "Central Bank of Bahrain", "country": "Bahrain", "home_ccy": "BHD", "kind": "central_bank", "npm": "cbb-exchange-rate" },
27
+ { "code": "cbar", "name": "Central Bank of Azerbaijan", "country": "Azerbaijan", "home_ccy": "AZN", "kind": "central_bank", "npm": "cbar-exchange-rate" },
28
+ { "code": "cbbh", "name": "Central Bank of Bosnia and Herzegovina", "country": "Bosnia and Herzegovina", "home_ccy": "BAM", "kind": "central_bank", "npm": "cbbh-exchange-rate" },
29
+ { "code": "bnb", "name": "Bulgarian National Bank", "country": "Bulgaria", "home_ccy": "EUR", "kind": "central_bank", "npm": "bnb-exchange-rate" },
30
+ { "code": "bcrp", "name": "Central Reserve Bank of Peru", "country": "Peru", "home_ccy": "PEN", "kind": "central_bank", "npm": "bcrp-exchange-rate" },
31
+ { "code": "boj", "name": "Bank of Japan", "country": "Japan", "home_ccy": "JPY", "kind": "central_bank", "npm": "boj-exchange-rate" },
32
+ { "code": "hkma", "name": "Hong Kong Monetary Authority", "country": "Hong Kong", "home_ccy": "HKD", "kind": "central_bank", "npm": "hkma-exchange-rate" },
33
+ { "code": "boi", "name": "Bank of Israel", "country": "Israel", "home_ccy": "ILS", "kind": "central_bank", "npm": "bank-of-israel-exchange-rate" },
34
+ { "code": "bcra", "name": "Central Bank of Argentina", "country": "Argentina", "home_ccy": "ARS", "kind": "central_bank", "npm": "bcra-exchange-rate" },
35
+ { "code": "sarb", "name": "South African Reserve Bank", "country": "South Africa", "home_ccy": "ZAR", "kind": "central_bank", "npm": "sarb-exchange-rate" },
36
+ { "code": "snb", "name": "Swiss National Bank", "country": "Switzerland", "home_ccy": "CHF", "kind": "central_bank", "npm": "snb-exchange-rate" },
37
+ { "code": "rbnz", "name": "Reserve Bank of New Zealand", "country": "New Zealand", "home_ccy": "NZD", "kind": "central_bank", "npm": "rbnz-exchange-rate" },
38
+ { "code": "bok", "name": "Bank of Korea", "country": "South Korea", "home_ccy": "KRW", "kind": "central_bank", "npm": "bok-exchange-rate" },
39
+ { "code": "bnr", "name": "National Bank of Romania", "country": "Romania", "home_ccy": "RON", "kind": "central_bank", "npm": "bnr-exchange-rate" },
40
+ { "code": "nbu", "name": "National Bank of Ukraine", "country": "Ukraine", "home_ccy": "UAH", "kind": "central_bank", "npm": "nbu-exchange-rate" },
41
+ { "code": "banxico", "name": "Banco de México", "country": "Mexico", "home_ccy": "MXN", "kind": "central_bank", "npm": "banxico-exchange-rate" },
42
+ { "code": "bsp", "name": "Bangko Sentral ng Pilipinas", "country": "Philippines", "home_ccy": "PHP", "kind": "central_bank", "npm": "bsp-exchange-rate" },
43
+ { "code": "bcrd", "name": "Banco Central de la República Dominicana", "country": "Dominican Republic", "home_ccy": "DOP", "kind": "central_bank", "npm": "bcrd-exchange-rate" },
44
+ { "code": "bcp", "name": "Banco Central del Paraguay", "country": "Paraguay", "home_ccy": "PYG", "kind": "central_bank", "npm": "bcp-exchange-rate" },
45
+ { "code": "nbc", "name": "National Bank of Cambodia", "country": "Cambodia", "home_ccy": "KHR", "kind": "central_bank", "npm": "nbc-cambodia-exchange-rate" },
46
+ { "code": "bog", "name": "Bank of Ghana", "country": "Ghana", "home_ccy": "GHS", "kind": "central_bank", "npm": "bank-of-ghana-exchange-rate" },
47
+ { "code": "cbe", "name": "Central Bank of Egypt", "country": "Egypt", "home_ccy": "EGP", "kind": "central_bank", "npm": "cbe-exchange-rate" },
48
+ { "code": "boa", "name": "Bank of Albania", "country": "Albania", "home_ccy": "ALL", "kind": "central_bank", "npm": "bank-of-albania-exchange-rate" },
49
+ { "code": "banguat", "name": "Banco de Guatemala", "country": "Guatemala", "home_ccy": "GTQ", "kind": "central_bank", "npm": "banguat-exchange-rate" },
50
+ { "code": "bom", "name": "Bank of Mongolia", "country": "Mongolia", "home_ccy": "MNT", "kind": "central_bank", "npm": "bank-of-mongolia-exchange-rate" },
51
+ { "code": "mas", "name": "Monetary Authority of Singapore", "country": "Singapore", "home_ccy": "SGD", "kind": "central_bank", "npm": "mas-exchange-rate" },
52
+ { "code": "bdi", "name": "Banca d'Italia", "country": "Italy", "home_ccy": "EUR", "kind": "central_bank", "npm": "bdi-exchange-rate" },
53
+ { "code": "dnb", "name": "Danmarks Nationalbank", "country": "Denmark", "home_ccy": "DKK", "kind": "central_bank", "npm": "danmarks-nationalbank-exchange-rate" },
54
+ { "code": "sfc", "name": "Superintendencia Financiera de Colombia (TRM)", "country": "Colombia", "home_ccy": "COP", "kind": "central_bank", "npm": "colombia-trm-exchange-rate" },
55
+ { "code": "nbk", "name": "National Bank of Kazakhstan", "country": "Kazakhstan", "home_ccy": "KZT", "kind": "central_bank", "npm": "nbk-exchange-rate" },
56
+ { "code": "nbg", "name": "National Bank of Georgia", "country": "Georgia", "home_ccy": "GEL", "kind": "central_bank", "npm": "nbg-exchange-rate" },
57
+ { "code": "cbu", "name": "Central Bank of Uzbekistan", "country": "Uzbekistan", "home_ccy": "UZS", "kind": "central_bank", "npm": "cbu-exchange-rate" },
58
+ { "code": "mnb", "name": "Magyar Nemzeti Bank", "country": "Hungary", "home_ccy": "HUF", "kind": "central_bank", "npm": "magyar-nemzeti-bank-exchange-rate" },
59
+ { "code": "cbi", "name": "Central Bank of Iceland", "country": "Iceland", "home_ccy": "ISK", "kind": "central_bank", "npm": "central-bank-of-iceland-exchange-rate" },
60
+ { "code": "cbuae", "name": "Central Bank of the UAE", "country": "United Arab Emirates", "home_ccy": "AED", "kind": "central_bank", "npm": "cbuae-exchange-rate" },
61
+ { "code": "sbp", "name": "State Bank of Pakistan", "country": "Pakistan", "home_ccy": "PKR", "kind": "central_bank", "npm": "sbp-exchange-rate" },
62
+ { "code": "nrb", "name": "Nepal Rastra Bank", "country": "Nepal", "home_ccy": "NPR", "kind": "central_bank", "npm": "nrb-exchange-rate" },
63
+ { "code": "cbj", "name": "Central Bank of Jordan", "country": "Jordan", "home_ccy": "JOD", "kind": "central_bank", "npm": "cbj-exchange-rate" },
64
+ { "code": "bb", "name": "Bangladesh Bank", "country": "Bangladesh", "home_ccy": "BDT", "kind": "central_bank", "npm": "bangladesh-bank-exchange-rate" },
65
+ { "code": "cbo", "name": "Central Bank of Oman", "country": "Oman", "home_ccy": "OMR", "kind": "central_bank", "npm": "cbo-exchange-rate" },
66
+ { "code": "pma", "name": "Palestine Monetary Authority", "country": "Palestine", "home_ccy": "ILS", "kind": "central_bank", "npm": "palestine-monetary-authority-exchange-rate" },
67
+ { "code": "cbm", "name": "Central Bank of Myanmar", "country": "Myanmar", "home_ccy": "MMK", "kind": "central_bank", "npm": "cbm-exchange-rate" },
68
+ { "code": "cbc", "name": "Central Bank of the Republic of China (Taiwan)", "country": "Taiwan", "home_ccy": "TWD", "kind": "central_bank", "npm": "taiwan-central-bank-exchange-rate" },
69
+ { "code": "bot", "name": "Bank of Thailand", "country": "Thailand", "home_ccy": "THB", "kind": "central_bank", "npm": "bank-of-thailand-exchange-rate" },
70
+ { "code": "amcm", "name": "Monetary Authority of Macao", "country": "Macao", "home_ccy": "MOP", "kind": "central_bank", "npm": "amcm-exchange-rate" },
71
+ { "code": "sbv", "name": "State Bank of Vietnam", "country": "Vietnam", "home_ccy": "VND", "kind": "central_bank", "npm": "sbv-exchange-rate" },
72
+ { "code": "bol", "name": "Bank of the Lao PDR", "country": "Laos", "home_ccy": "LAK", "kind": "central_bank", "npm": "bank-of-laos-exchange-rate" },
73
+ { "code": "bcv", "name": "Central Bank of Venezuela", "country": "Venezuela", "home_ccy": "VES", "kind": "central_bank", "npm": "central-bank-of-venezuela-exchange-rate" },
74
+ { "code": "bcch", "name": "Central Bank of Chile", "country": "Chile", "home_ccy": "CLP", "kind": "central_bank", "npm": "central-bank-of-chile-exchange-rate" },
75
+ { "code": "bcu", "name": "Central Bank of Uruguay", "country": "Uruguay", "home_ccy": "UYU", "kind": "central_bank", "npm": "bcu-exchange-rate" },
76
+ { "code": "bcbol", "name": "Banco Central de Bolivia", "country": "Bolivia", "home_ccy": "BOB", "kind": "central_bank", "npm": "banco-central-de-bolivia-exchange-rate" },
77
+ { "code": "cbvs", "name": "Central Bank of Suriname", "country": "Suriname", "home_ccy": "SRD", "kind": "central_bank", "npm": "central-bank-of-suriname-exchange-rate" },
78
+ { "code": "bogy", "name": "Bank of Guyana", "country": "Guyana", "home_ccy": "GYD", "kind": "central_bank", "npm": "bank-of-guyana-exchange-rate" },
79
+ { "code": "sama", "name": "Saudi Central Bank (SAMA)", "country": "Saudi Arabia", "home_ccy": "SAR", "kind": "central_bank", "npm": "sama-exchange-rate" },
80
+ { "code": "bam", "name": "Bank Al-Maghrib", "country": "Morocco", "home_ccy": "MAD", "kind": "central_bank", "npm": "bank-al-maghrib-exchange-rate" },
81
+ { "code": "nbs", "name": "National Bank of Serbia", "country": "Serbia", "home_ccy": "RSD", "kind": "central_bank", "npm": "national-bank-of-serbia-exchange-rate" },
82
+ { "code": "nbrb", "name": "National Bank of the Republic of Belarus", "country": "Belarus", "home_ccy": "BYN", "kind": "central_bank", "npm": "nbrb-exchange-rate" },
83
+ { "code": "qcb", "name": "Qatar Central Bank", "country": "Qatar", "home_ccy": "QAR", "kind": "central_bank", "npm": "qcb-exchange-rate" },
84
+ { "code": "cbiq", "name": "Central Bank of Iraq", "country": "Iraq", "home_ccy": "IQD", "kind": "central_bank", "npm": "central-bank-of-iraq-exchange-rate" },
85
+ { "code": "bda", "name": "Bank of Algeria", "country": "Algeria", "home_ccy": "DZD", "kind": "central_bank", "npm": "bank-of-algeria-exchange-rate" },
86
+ { "code": "bccr", "name": "Banco Central de Costa Rica", "country": "Costa Rica", "home_ccy": "CRC", "kind": "central_bank", "npm": "bccr-exchange-rate" },
87
+ { "code": "bceao", "name": "Central Bank of West African States (BCEAO)", "country": "West Africa (WAEMU)", "home_ccy": "XOF", "kind": "central_bank", "npm": "bceao-exchange-rate" },
88
+ { "code": "nbe", "name": "National Bank of Ethiopia", "country": "Ethiopia", "home_ccy": "ETB", "kind": "central_bank", "npm": "national-bank-of-ethiopia-exchange-rate" },
89
+ { "code": "cbke", "name": "Central Bank of Kenya", "country": "Kenya", "home_ccy": "KES", "kind": "central_bank", "npm": "central-bank-of-kenya-exchange-rate" },
90
+ { "code": "nbm", "name": "National Bank of Moldova", "country": "Moldova", "home_ccy": "MDL", "kind": "central_bank", "npm": "nbm-exchange-rate" },
91
+ { "code": "nbrm", "name": "National Bank of North Macedonia", "country": "North Macedonia", "home_ccy": "MKD", "kind": "central_bank", "npm": "nbrm-exchange-rate" },
92
+ { "code": "cba", "name": "Central Bank of Armenia", "country": "Armenia", "home_ccy": "AMD", "kind": "central_bank", "npm": "cba-exchange-rate" },
93
+ { "code": "beac", "name": "Bank of Central African States (BEAC)", "country": "Central Africa (CEMAC)", "home_ccy": "XAF", "kind": "central_bank", "npm": "beac-exchange-rate" },
94
+ { "code": "bct", "name": "Central Bank of Tunisia", "country": "Tunisia", "home_ccy": "TND", "kind": "central_bank", "npm": "bct-exchange-rate" },
95
+ { "code": "bnrw", "name": "National Bank of Rwanda", "country": "Rwanda", "home_ccy": "RWF", "kind": "central_bank", "npm": "national-bank-of-rwanda-exchange-rate" },
96
+ { "code": "bna", "name": "National Bank of Angola", "country": "Angola", "home_ccy": "AOA", "kind": "central_bank", "npm": "bna-exchange-rate" },
97
+ { "code": "botz", "name": "Bank of Tanzania", "country": "Tanzania", "home_ccy": "TZS", "kind": "central_bank", "npm": "bank-of-tanzania-exchange-rate" },
98
+ { "code": "bou", "name": "Bank of Uganda", "country": "Uganda", "home_ccy": "UGX", "kind": "central_bank", "npm": "bou-exchange-rate" },
99
+ { "code": "bojm", "name": "Bank of Jamaica", "country": "Jamaica", "home_ccy": "JMD", "kind": "central_bank", "npm": "bank-of-jamaica-exchange-rate" },
100
+ { "code": "bcn", "name": "Banco Central de Nicaragua", "country": "Nicaragua", "home_ccy": "NIO", "kind": "central_bank", "npm": "bcn-exchange-rate" },
101
+ { "code": "bch", "name": "Banco Central de Honduras", "country": "Honduras", "home_ccy": "HNL", "kind": "central_bank", "npm": "bch-exchange-rate" },
102
+ { "code": "cbtt", "name": "Central Bank of Trinidad and Tobago", "country": "Trinidad and Tobago", "home_ccy": "TTD", "kind": "central_bank", "npm": "cbtt-exchange-rate" },
103
+ { "code": "bmu", "name": "Bank of Mauritius", "country": "Mauritius", "home_ccy": "MUR", "kind": "central_bank", "npm": "bmu-exchange-rate" },
104
+ { "code": "bdm", "name": "Banco de Moçambique", "country": "Mozambique", "home_ccy": "MZN", "kind": "central_bank", "npm": "bdm-exchange-rate" },
105
+ { "code": "bob", "name": "Bank of Botswana", "country": "Botswana", "home_ccy": "BWP", "kind": "central_bank", "npm": "bob-exchange-rate" },
106
+ { "code": "boz", "name": "Bank of Zambia", "country": "Zambia", "home_ccy": "ZMW", "kind": "central_bank", "npm": "boz-exchange-rate" },
107
+ { "code": "rbm", "name": "Reserve Bank of Malawi", "country": "Malawi", "home_ccy": "MWK", "kind": "central_bank", "npm": "rbm-exchange-rate" },
108
+ { "code": "nbkr", "name": "National Bank of the Kyrgyz Republic", "country": "Kyrgyzstan", "home_ccy": "KGS", "kind": "central_bank", "npm": "nbkr-exchange-rate" },
109
+ { "code": "hmrc", "name": "HM Revenue & Customs", "country": "United Kingdom", "home_ccy": "GBP", "kind": "tax", "npm": "hmrc-exchange-rate" },
110
+ { "code": "bazg", "name": "Swiss Federal Office for Customs and Border Security", "country": "Switzerland", "home_ccy": "CHF", "kind": "tax", "npm": "bazg-exchange-rate" },
111
+ { "code": "ustreasury", "name": "U.S. Department of the Treasury", "country": "United States", "home_ccy": "USD", "kind": "tax", "npm": "ustreasury-exchange-rate" },
112
+ { "code": "composite", "name": "Composite Official Rate", "country": "Global", "home_ccy": "USD", "kind": "composite" },
113
+ ];
package/dist/client.d.ts CHANGED
@@ -8,6 +8,14 @@ export declare class CentralBankApiError extends Error {
8
8
  readonly body?: unknown;
9
9
  constructor(message: string, status?: number | undefined, body?: unknown);
10
10
  }
11
+ /**
12
+ * Thrown when a tool needs an endpoint that is behind the API key. Carries the
13
+ * sign-up instructions so the assistant can relay one actionable sentence
14
+ * instead of a bare 401.
15
+ */
16
+ export declare class NeedsKeyError extends CentralBankApiError {
17
+ constructor(what: string);
18
+ }
11
19
  export interface CbRate {
12
20
  base: string;
13
21
  quote: string;
@@ -19,8 +27,26 @@ export declare class CentralBankClient {
19
27
  private readonly baseUrl;
20
28
  private readonly fetchImpl;
21
29
  constructor(options?: ClientOptions);
30
+ /** True when no API key is configured: only the open endpoints are reachable. */
31
+ get keyless(): boolean;
22
32
  private request;
33
+ /**
34
+ * GET against the keyless, CORS-open, edge-cached /api/open/* surface.
35
+ * Same plumbing as request(), minus the Authorization header.
36
+ */
37
+ private openRequest;
23
38
  listBanks(): Promise<{
39
+ banks: {
40
+ code: string;
41
+ name: string;
42
+ country: string;
43
+ home_ccy: string;
44
+ kind: string;
45
+ npm?: string;
46
+ }[];
47
+ catalog: 'bundled';
48
+ disclaimer: string;
49
+ }> | Promise<{
24
50
  banks: Array<Record<string, unknown>>;
25
51
  disclaimer: string;
26
52
  }>;
package/dist/client.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { VERSION } from './version.js';
2
+ import { BANK_CATALOG } from './banks.js';
2
3
  const DEFAULT_BASE_URL = 'https://allratestoday.com/api';
3
4
  export class CentralBankApiError extends Error {
4
5
  status;
@@ -10,6 +11,21 @@ export class CentralBankApiError extends Error {
10
11
  this.name = 'CentralBankApiError';
11
12
  }
12
13
  }
14
+ /**
15
+ * Thrown when a tool needs an endpoint that is behind the API key. Carries the
16
+ * sign-up instructions so the assistant can relay one actionable sentence
17
+ * instead of a bare 401.
18
+ */
19
+ export class NeedsKeyError extends CentralBankApiError {
20
+ constructor(what) {
21
+ super(`This lookup (${what}) needs an AllRatesToday API key. The free tier covers it — ` +
22
+ 'sign up at https://allratestoday.com/register (no card, under a minute), then set ' +
23
+ 'ALLRATES_API_KEY in the MCP server config and restart. Without a key this server can ' +
24
+ 'still return the latest published table for any source (get_official_rates) and the ' +
25
+ 'source catalogue (list_central_banks).');
26
+ this.name = 'NeedsKeyError';
27
+ }
28
+ }
13
29
  function errorMessage(status, upstream) {
14
30
  switch (status) {
15
31
  case 400:
@@ -36,15 +52,18 @@ export class CentralBankClient {
36
52
  this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, '');
37
53
  this.fetchImpl = options.fetchImpl ?? fetch;
38
54
  }
55
+ /** True when no API key is configured: only the open endpoints are reachable. */
56
+ get keyless() {
57
+ return !this.apiKey;
58
+ }
39
59
  async request(path, query = {}) {
40
60
  const url = new URL(this.baseUrl + path);
41
61
  for (const [key, value] of Object.entries(query)) {
42
62
  if (value !== undefined && value !== '')
43
63
  url.searchParams.set(key, value);
44
64
  }
45
- if (!this.apiKey) {
46
- throw new CentralBankApiError('AllRatesToday API key is required. Sign up free at https://allratestoday.com/register to get a key, then set ALLRATES_API_KEY in your MCP config.');
47
- }
65
+ if (!this.apiKey)
66
+ throw new NeedsKeyError(path);
48
67
  const headers = {
49
68
  'Accept': 'application/json',
50
69
  'User-Agent': `central-bank-mcp/${VERSION}`,
@@ -67,11 +86,61 @@ export class CentralBankClient {
67
86
  }
68
87
  return body;
69
88
  }
89
+ /**
90
+ * GET against the keyless, CORS-open, edge-cached /api/open/* surface.
91
+ * Same plumbing as request(), minus the Authorization header.
92
+ */
93
+ async openRequest(path, query = {}) {
94
+ const url = new URL(this.baseUrl + path);
95
+ for (const [key, value] of Object.entries(query)) {
96
+ if (value !== undefined && value !== '')
97
+ url.searchParams.set(key, value);
98
+ }
99
+ const res = await this.fetchImpl(url.toString(), {
100
+ method: 'GET',
101
+ headers: {
102
+ 'Accept': 'application/json',
103
+ 'User-Agent': `central-bank-mcp/${VERSION} (keyless)`,
104
+ },
105
+ });
106
+ const text = await res.text();
107
+ let body;
108
+ try {
109
+ body = text ? JSON.parse(text) : null;
110
+ }
111
+ catch {
112
+ body = text;
113
+ }
114
+ if (!res.ok) {
115
+ const upstream = body && typeof body === 'object' && 'error' in body && typeof body.error === 'string'
116
+ ? body.error
117
+ : undefined;
118
+ throw new CentralBankApiError(errorMessage(res.status, upstream), res.status, body);
119
+ }
120
+ return body;
121
+ }
70
122
  listBanks() {
123
+ // Keyless: the bundled catalogue. It carries every code and name but no
124
+ // coverage dates, so it is labelled as such by the caller.
125
+ if (this.keyless) {
126
+ return Promise.resolve({
127
+ banks: BANK_CATALOG.map((b) => ({ ...b })),
128
+ catalog: 'bundled',
129
+ disclaimer: 'Offline source catalogue bundled with this MCP server. Coverage dates and history ' +
130
+ 'depth need an API key (free tier at https://allratestoday.com/register).',
131
+ });
132
+ }
71
133
  return this.request('/v1/central-banks');
72
134
  }
73
135
  // date undefined -> /latest; date given -> /{YYYY-MM-DD} (paid plans).
74
136
  getRates(bank, opts = {}) {
137
+ // Keyless: the latest published table is open (edge-cached, no upstream
138
+ // cost). A past date is not — that is the metered part.
139
+ if (this.keyless) {
140
+ if (opts.date)
141
+ return Promise.reject(new NeedsKeyError(`${bank} table for ${opts.date}`));
142
+ return this.openRequest(`/open/central-bank/${encodeURIComponent(bank)}`, { source: opts.source, target: opts.target });
143
+ }
75
144
  const path = `/v1/central-bank/${encodeURIComponent(bank)}/${opts.date ?? 'latest'}`;
76
145
  return this.request(path, {
77
146
  source: opts.source,
package/dist/index.js CHANGED
@@ -34,23 +34,26 @@ function fail(err) {
34
34
  }
35
35
  async function main() {
36
36
  const apiKey = process.env.ALLRATES_API_KEY;
37
+ // No key is NOT a fatal error. The latest published table of every source is
38
+ // served by the open, edge-cached /api/open/central-bank/* endpoints, so the
39
+ // server starts and answers the most common question out of the box; tools
40
+ // that need the metered endpoints say so, with the sign-up link, when called.
41
+ // Exiting here instead would break the whole MCP config in the host client.
37
42
  if (!apiKey) {
38
43
  console.error([
39
44
  '',
40
- ' AllRatesToday central-bank MCP server requires an API key.',
45
+ ' AllRatesToday central-bank MCP — running in KEYLESS mode.',
41
46
  '',
42
- ' 1. Sign up free at https://allratestoday.com/register (free tier — no card required)',
43
- ' 2. Copy your API key from the dashboard',
44
- ' 3. Set ALLRATES_API_KEY in your MCP client config:',
47
+ ' Available now, no key needed:',
48
+ ' • list_central_banks — every covered source',
49
+ ' • get_official_rates — the latest published table (any source)',
45
50
  '',
46
- ' "central-bank-rates": {',
47
- ' "command": "npx",',
48
- ' "args": ["-y", "@allratestoday/central-bank-mcp"],',
49
- ' "env": { "ALLRATES_API_KEY": "art_live_..." }',
50
- ' }',
51
+ ' Needs a free API key (historical dates, time series, cross-bank compare,',
52
+ ' publication calendars):',
53
+ ' 1. https://allratestoday.com/register — free tier, no card, under a minute',
54
+ ' 2. Add to this server\'s MCP config: "env": { "ALLRATES_API_KEY": "art_live_..." }',
51
55
  '',
52
56
  ].join('\n'));
53
- process.exit(1);
54
57
  }
55
58
  const client = new CentralBankClient({
56
59
  apiKey,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@allratestoday/central-bank-mcp",
3
- "version": "0.1.0",
4
- "mcpName": "io.github.cahthuranag/central-bank-mcp",
3
+ "version": "0.2.0",
4
+ "mcpName": "com.allratestoday/central-bank-mcp",
5
5
  "description": "MCP server for official central-bank and tax-authority exchange rates — let AI tools (Claude Code, Cursor, Claude Desktop) fetch published rates from 60+ institutions (ECB, Fed, HMRC, BOJ, ...) via the AllRatesToday API.",
6
6
  "keywords": [
7
7
  "mcp",