UNPKG

@allratestoday/mcp-server

Version:

MCP server for AllRatesToday — let AI coding tools (Claude Code, Cursor, Claude Desktop) fetch real-time and historical currency exchange rates.

66 lines (65 loc) 2.27 kB
const DEFAULT_BASE_URL = 'https://allratestoday.com/api'; const USER_AGENT = `allratestoday-mcp/0.3.1`; export class AllRatesTodayError extends Error { status; body; constructor(message, status, body) { super(message); this.status = status; this.body = body; this.name = 'AllRatesTodayError'; } } export class AllRatesTodayClient { apiKey; baseUrl; fetchImpl; constructor(options = {}) { this.apiKey = options.apiKey; this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, ''); this.fetchImpl = options.fetchImpl ?? fetch; } async request(path, query) { const url = new URL(this.baseUrl + path); for (const [key, value] of Object.entries(query)) { if (value !== undefined && value !== '') url.searchParams.set(key, value); } const headers = { 'Accept': 'application/json', 'User-Agent': USER_AGENT, }; if (!this.apiKey) { throw new AllRatesTodayError('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.'); } headers['Authorization'] = `Bearer ${this.apiKey}`; const res = await this.fetchImpl(url.toString(), { method: 'GET', headers }); const text = await res.text(); let body; try { body = text ? JSON.parse(text) : null; } catch { body = text; } if (!res.ok) { const msg = (body && typeof body === 'object' && 'error' in body && typeof body.error === 'string' ? body.error : `HTTP ${res.status}`); throw new AllRatesTodayError(msg, res.status, body); } return body; } getRate(source, target) { return this.request('/rate', { source, target }); } getHistoricalRates(source, target, period = '7d') { return this.request('/historical-rates', { source, target, period }); } getAuthenticatedRates(params) { return this.request('/v1/rates', params); } listSymbols() { return this.request('/v1/symbols', {}); } }