{
  "markdown": "# Realtime Exchange Rate MCP Server — @allratestoday/mcp-server\n\nA Model Context Protocol server that lets Claude Code, Cursor, Claude Desktop, Windsurf, and any other MCP-compatible client fetch real-time currency rates, historical series, and multi-currency lookups from the [AllRatesToday](https://allratestoday.com) API. Rates come from institutional interbank market data.\n\n[![Powered by AllRatesToday](https://img.shields.io/badge/Powered%20by-AllRatesToday-orange.svg)](https://allratestoday.com)\n[![npm version](https://img.shields.io/npm/v/@allratestoday/mcp-server.svg)](https://www.npmjs.com/package/@allratestoday/mcp-server)\n[![npm downloads](https://img.shields.io/npm/dm/@allratestoday/mcp-server.svg)](https://www.npmjs.com/package/@allratestoday/mcp-server)\n[![CI](https://github.com/cahthuranag/realtime-exchange-rate-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/cahthuranag/realtime-exchange-rate-mcp/actions/workflows/ci.yml)\n[![MCP](https://img.shields.io/badge/Model%20Context%20Protocol-1.x-blue.svg)](https://modelcontextprotocol.io)\n[![TypeScript](https://img.shields.io/badge/TypeScript-3178C6.svg)](https://www.typescriptlang.org/)\n[![License](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)\n\nEnglish | [简体中文](./README-zh-CN.md)\n\nAfter installation, your assistant can answer questions like:\n\n- *\"What's the current USD to EUR rate?\"*\n- *\"Show me how GBP/JPY moved over the last 30 days.\"*\n- *\"Convert 250 USD into CAD at a real rate.\"*\n- *\"Compare USD against EUR, GBP, and JPY simultaneously.\"*\n- *\"List every supported currency.\"*\n\n## 🚀 Features\n\n- 💱 **Live mid-market rates** — current rate for any supported ISO 4217 pair\n- 📈 **Historical series built in** — `1d` (hourly), `7d` (daily), `30d` (daily), `1y` (weekly)\n- 🧰 **Four focused tools** — `get_exchange_rate`, `get_historical_rates`, `get_rates_authenticated`, `list_currencies`; a small surface the model uses correctly\n- 🔌 **Works everywhere MCP does** — stdio transport, MCP SDK 1.x; Claude Code, Cursor, Claude Desktop, Windsurf, or any generic stdio host\n- 🛡️ **Fail-fast and honest** — refuses to start without an API key and relays upstream API errors verbatim instead of guessing\n- 🔒 **Nothing leaks** — only the request parameters and your API key ever reach allratestoday.com; never conversation context\n- 📦 **Two runtime dependencies** — `@modelcontextprotocol/sdk` and `zod`; Node.js ≥ 18\n\nEverything these tools return is a **mid-market rate** — the interbank midpoint, the right number for price display and conversion. It is not the official rate a tax authority or auditor may require; for published central-bank and tax-authority rates, see the [AllRatesToday docs](https://allratestoday.com/docs).\n\n## 🔑 Get your API key\n\nThe server **will not start** without a valid `ALLRATES_API_KEY`, and all four tools require it. A free key is enough for development and personal use.\n\n1. Register at [allratestoday.com/register](https://allratestoday.com/register)\n2. Verify your email\n3. Copy your key from the dashboard (format: `art_live_xxxxx`)\n4. Use it as `ALLRATES_API_KEY` in the configs below\n\nIf the key is missing, the server prints registration instructions on stderr and exits with code 1.\n\n## 📦 Installation\n\nThe simplest install is **zero-install via `npx`**, which is what every config below uses:\n\n```bash\n# Run without installing (recommended)\nnpx -y @allratestoday/mcp-server\n```\n\n```bash\n# Or install globally\nnpm install -g @allratestoday/mcp-server\nallratestoday-mcp\n```\n\nBoth commands launch the stdio MCP server and wait for a client to connect — they are not meant to be run interactively from your shell; your MCP client launches them as a subprocess.\n\n## 🏁 Quick start\n\nEach client reads MCP servers from a different config file. Pick yours below.\n\n### Claude Code\n\nThe fastest path uses the built-in CLI:\n\n```bash\nclaude mcp add allratestoday -- npx -y @allratestoday/mcp-server\nclaude mcp env allratestoday ALLRATES_API_KEY=art_live_xxxxx\n```\n\nRestart Claude Code, then ask: *\"What's the current USD to EUR rate?\"*\n\n### Cursor\n\nEdit `~/.cursor/mcp.json` (or `.cursor/mcp.json` inside your project for a project-scoped server):\n\n```json\n{\n  \"mcpServers\": {\n    \"allratestoday\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@allratestoday/mcp-server\"],\n      \"env\": {\n        \"ALLRATES_API_KEY\": \"art_live_xxxxx\"\n      }\n    }\n  }\n}\n```\n\nRestart Cursor. The four tools should appear in the MCP tool picker.\n\n### Claude Desktop\n\nEdit the config file (path depends on OS):\n\n| OS | Path |\n|---|---|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n```json\n{\n  \"mcpServers\": {\n    \"allratestoday\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@allratestoday/mcp-server\"],\n      \"env\": {\n        \"ALLRATES_API_KEY\": \"art_live_xxxxx\"\n      }\n    }\n  }\n}\n```\n\n**Fully quit and reopen Claude Desktop** (Cmd+Q on macOS, right-click tray icon → Exit on Windows). Closing the window alone keeps the old config loaded.\n\n### Windsurf\n\nEdit `~/.codeium/windsurf/mcp_config.json` with the same `mcpServers` block as above, then restart Windsurf.\n\n### Generic stdio MCP client\n\nAny MCP host that supports stdio transport works. The launch command is:\n\n```bash\nnpx -y @allratestoday/mcp-server\n```\n\n…with `ALLRATES_API_KEY` set in the subprocess environment. The same block, ready to copy, also lives in [`.mcp.json`](./.mcp.json) in this repo; [`smithery.yaml`](./smithery.yaml) describes the same stdio launch for Smithery, and [`server.json`](./server.json) is the MCP registry manifest.\n\n### Verify it works\n\n1. **Server starts** — open the client. A red dot or \"failed to connect\" means the API key is missing or wrong (see [Troubleshooting](#-troubleshooting)).\n2. **Tools are listed** — most clients have a \"tools\" or \"MCP\" panel showing all four tools.\n3. **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 produces a number without a tool call, the server is not connected.\n\n## 📚 API reference\n\n| Tool | Purpose | Required input |\n|---|---|---|\n| [`get_exchange_rate`](#get_exchange_rate) | Current rate for one pair | `source`, `target` |\n| [`get_historical_rates`](#get_historical_rates) | Time series over a preset period | `source`, `target` |\n| [`get_rates_authenticated`](#get_rates_authenticated) | Multiple targets in one call, optional point-in-time | `source`, `target` |\n| [`list_currencies`](#list_currencies) | All supported codes, names, symbols | — |\n\nAll four tools require `ALLRATES_API_KEY`, and every input schema sets `additionalProperties: false` — unknown fields are rejected.\n\n### `get_exchange_rate`\n\nCurrent mid-market rate between two currencies. Calls `GET /rate`.\n\n| Field | Type | Required | Description |\n|---|---|---|---|\n| `source` | string (exactly 3 chars) | yes | ISO 4217 code, e.g. `USD` |\n| `target` | string (exactly 3 chars) | yes | ISO 4217 code, e.g. `EUR` |\n\n```json\n{ \"source\": \"USD\", \"target\": \"EUR\" }\n```\n\nResponse shape — `rate` (number) and `source` (string, the upstream data source identifier):\n\n```json\n{ \"rate\": 0.92145, \"source\": \"...\" }\n```\n\n### `get_historical_rates`\n\nTime-series data points for a currency pair over a fixed period. Calls `GET /historical-rates`.\n\n| Field | Type | Required | Description |\n|---|---|---|---|\n| `source` | string (exactly 3 chars) | yes | Source currency code |\n| `target` | string (exactly 3 chars) | yes | Target currency code |\n| `period` | string | no (default `7d`) | One of `1d`, `7d`, `30d`, `1y` |\n\nGranularity per period:\n\n| `period` | Granularity |\n|---|---|\n| `1d` | Hourly |\n| `7d` | Daily |\n| `30d` | Daily |\n| `1y` | Weekly |\n\n```json\n{ \"source\": \"USD\", \"target\": \"INR\", \"period\": \"30d\" }\n```\n\nResponse (truncated):\n\n```json\n{\n  \"source\": \"USD\",\n  \"target\": \"INR\",\n  \"period\": \"30d\",\n  \"data\": [\n    { \"date\": \"2026-03-27T00:00:00Z\", \"rate\": 83.42, \"timestamp\": 1743033600000 },\n    { \"date\": \"2026-03-28T00:00:00Z\", \"rate\": 83.51, \"timestamp\": 1743120000000 },\n    \"...\"\n  ]\n}\n```\n\n### `get_rates_authenticated`\n\nMultiple targets in one call, with an optional historical timestamp or grouping window. Calls `GET /v1/rates`.\n\n| Field | Type | Required | Description |\n|---|---|---|---|\n| `source` | string (exactly 3 chars) | yes | Source currency code |\n| `target` | string | yes | One or more codes, comma-separated (`EUR,GBP,JPY`) |\n| `time` | string (ISO 8601 date-time) | no | Historical point in time |\n| `group` | string | no | One of `hour`, `day`, `week`, `month` |\n\n```json\n{ \"source\": \"USD\", \"target\": \"EUR,GBP,JPY\" }\n```\n\nResponse — an array of `{ rate, source, target, time }`:\n\n```json\n[\n  { \"rate\": 0.9214, \"source\": \"USD\", \"target\": \"EUR\", \"time\": \"2026-04-26T11:00:00Z\" },\n  { \"rate\": 0.7891, \"source\": \"USD\", \"target\": \"GBP\", \"time\": \"2026-04-26T11:00:00Z\" },\n  { \"rate\": 151.34, \"source\": \"USD\", \"target\": \"JPY\", \"time\": \"2026-04-26T11:00:00Z\" }\n]\n```\n\n### `list_currencies`\n\nAll supported currencies with codes, names, and symbols. Calls `GET /v1/symbols`, cached 24 h upstream — cheap to call for validating user input before the other tools.\n\n**Input** — none.\n\nResponse (truncated):\n\n```json\n{\n  \"currencies\": [\n    { \"code\": \"USD\", \"name\": \"US Dollar\", \"symbol\": \"$\" },\n    { \"code\": \"EUR\", \"name\": \"Euro\", \"symbol\": \"€\" },\n    { \"code\": \"GBP\", \"name\": \"British Pound\", \"symbol\": \"£\" },\n    \"...\"\n  ],\n  \"count\": 162\n}\n```\n\n## 🗺️ Currencies covered\n\nEvery currency the AllRatesToday API serves is available through these tools — call `list_currencies` for the authoritative live list. Commonly used codes include:\n\n🇺🇸 `USD` · 🇪🇺 `EUR` · 🇬🇧 `GBP` · 🇯🇵 `JPY` · 🇨🇦 `CAD` · 🇮🇳 `INR`\n\nThe `source` and `target` fields of `get_exchange_rate` and `get_historical_rates` are validated as exactly three characters, so pass ISO 4217 codes, not currency names.\n\n## ⚙️ Environment variables\n\n| Variable | Default | Required | Purpose |\n|---|---|---|---|\n| `ALLRATES_API_KEY` | — | **yes** | Your API key. The server exits with code 1 at startup if unset; sent as a `Bearer` token in the `Authorization` header. |\n| `ALLRATES_BASE_URL` | `https://allratestoday.com/api` | no | Override for a self-hosted or staging deployment. Trailing slashes are stripped. |\n\nSet these in your MCP client's config (in the `env` block), not in your shell — MCP servers are launched as subprocesses with isolated environments.\n\n## 🛡️ Error handling\n\nTool failures come back as an MCP tool result with `isError: true`. The text is `AllRatesToday error (<status>): <message>`, where `<message>` is the `error` field from the API response body when present, and `HTTP <status>` otherwise.\n\n| HTTP status | Meaning |\n|---|---|\n| 400 | Bad request — usually an unknown or malformed currency code |\n| 401 | Invalid or missing API key |\n| 429 | Rate limit or quota exceeded |\n| 5xx | Server-side issue upstream |\n\nTwo errors are raised locally, before any HTTP call:\n\n- No API key at request time → `API key is required. Get one at https://allratestoday.com/register, then set ALLRATES_API_KEY in your MCP config.`\n- Unrecognised tool name → `Unknown tool: <name>`\n\nBecause these arrive as text, the assistant relays them to the user — a 429 surfaces as *\"the API quota has been exceeded.\"*\n\n## 🛠️ Troubleshooting\n\n| Symptom | Likely cause | Fix |\n|---|---|---|\n| Client shows \"MCP server failed to start\" or a red dot | `ALLRATES_API_KEY` not set | Add the key to the `env` block in your client config |\n| Every call returns a 401 error | Key malformed, truncated, or revoked | Copy a fresh key from the dashboard |\n| Calls return a 429 error | Plan request limit hit | Wait for the quota to reset or upgrade the plan |\n| `get_historical_rates` returns a 400 error | Invalid period or unknown currency code | `period` must be `1d`/`7d`/`30d`/`1y`; codes must be exactly 3 letters |\n| Server starts but tools never appear | Client did not reload after the config change | Fully quit (not just close) and reopen the client |\n| `npx` runs but hangs forever | Normal — the server is waiting for an MCP client on stdio | Let your MCP client launch it |\n\nTo inspect what the server is doing, run it manually with the key set:\n\n```bash\nALLRATES_API_KEY=art_live_xxxxx npx -y @allratestoday/mcp-server\n```\n\nNo output means healthy — stdout is reserved for the MCP protocol; errors print to stderr.\n\n## 💡 Notes\n\n**Do you store my conversation or query data?** No. Only your API key and the request parameters (`source`, `target`, `period`, `time`, `group`) are sent to allratestoday.com — never the model's conversation context.\n\n**What happens to my API key?** It is only sent as a `Bearer` token in the `Authorization` header on requests to the AllRatesToday API. The server does not log it.\n\n**Why is the first call slow?** Cold start of `npx` (the first run downloads the package) plus an upstream cache miss.\n\n**Can I run this without npm/Node?** Not currently — `engines` requires Node ≥ 18. If a standalone binary matters to you, open an issue.\n\n**Is there a self-hosted option?** Point `ALLRATES_BASE_URL` at your own instance.\n\n**Does it work with other clients?** Any MCP-compatible host with stdio transport works; the four clients above are simply the ones with documented config paths here.\n\n## 👩‍💻 Development\n\n```bash\ngit clone https://github.com/cahthuranag/realtime-exchange-rate-mcp.git\ncd realtime-exchange-rate-mcp\nnpm install\nnpm run build\nALLRATES_API_KEY=art_live_xxxxx node dist/index.js\n```\n\n`npm run build` runs `tsc`; `npm run dev` watches and rebuilds; `npm start` runs the compiled server. CI ([`.github/workflows/ci.yml`](./.github/workflows/ci.yml)) runs `npm ci && npm run build` on Node 22 for every push to `main` and every pull request.\n\nTo test against a local AllRatesToday instance:\n\n```bash\nALLRATES_BASE_URL=http://localhost:8080/api ALLRATES_API_KEY=test_key node dist/index.js\n```\n\nProject structure:\n\n```text\nsrc/\n├── index.ts      # MCP server, tool definitions, request handlers\n└── client.ts     # HTTP client for the AllRatesToday API + error mapping\ndist/             # Compiled JS (gitignored)\nserver.json       # MCP registry manifest\nsmithery.yaml     # Smithery launch config\n.mcp.json         # Ready-to-copy client config\n```\n\nIssues and PRs are welcome. Before opening a PR: `npm run build` must succeed, exercise the change against a real API key, and update both the tool descriptions in `src/index.ts` and the API reference above if tool behaviour changes.\n\n## 📝 Changelog\n\nSee [GitHub Releases](https://github.com/cahthuranag/realtime-exchange-rate-mcp/releases) for the full list. Recent highlights:\n\n- **0.3.x** — API key required for all tools; fail-fast at startup with clear instructions\n- **0.2.x** — Removed the news tool; required auth on `get_historical_rates`\n- **0.1.x** — Initial release with 5 tools\n\n## 🔗 Links\n\n- **Website:** [allratestoday.com](https://allratestoday.com)\n- **API docs:** [allratestoday.com/docs](https://allratestoday.com/docs)\n- **Free API key:** [allratestoday.com/register](https://allratestoday.com/register)\n- **Status:** [allratestoday.com/status](https://allratestoday.com/status)\n- **Support:** [allratestoday.com/contact](https://allratestoday.com/contact)\n- **npm:** [@allratestoday/mcp-server](https://www.npmjs.com/package/@allratestoday/mcp-server)\n- **MCP protocol:** [modelcontextprotocol.io](https://modelcontextprotocol.io)\n- **Bug reports:** [github.com/cahthuranag/realtime-exchange-rate-mcp/issues](https://github.com/cahthuranag/realtime-exchange-rate-mcp/issues)\n\n## 📜 License\n\nMIT — see [LICENSE](./LICENSE).\n",
  "bytes": 15777,
  "sha": "aef260848d3f3cfa11f5c485202bb62336f84b6adaa779630116122acd8e4e6c",
  "repo_slug": "cahthuranag/realtime-exchange-rate-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_cahthuranag_realtime_exchange__5a6ff648/readme"
}