Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

io.github.cyanheads/exchange-rates-mcp-server

REMOTE · EXCHANGE-RATES.CASEYJHAND.COM · 2 COMPONENTS

Convert currencies, get FX rates, and query historical Frankfurter v1 exchange rate data.

0 this week 90 Trust /100

Last scanned (8 hours ago)

Scores higher than 98% of remote servers

Reachable. Last reached 5 Nov 2026.

Category Finance and Payments

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security83
Transport & Reachability100
Schema Quality & AI Usability81
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 2132 tokens (~164/item across 13 items; 7 tools + 6 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management100
  • No destabilizing schema changes in the last 30 days.Pass
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
  • Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • We read all 7 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
  • An AI judge read all 9 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 3 Nov 26 0
    • The server rewrote its instructions, which are the text every model session reads security
    • Tool “fx_list_currencies” rewrote its description, which is the text the model reads security
    • Tool “fx_get_timeseries” rewrote its description, which is the text the model reads security
    • Schema quality: 1896 → 2132 ▼ functional
    • New resource “exchange-rates-guide” functional
    • Server version: 0.5.1 → 0.6.0 functional
    • “fx_list_currencies” added an optional parameter “include_retired” cosmetic
    • “fx_get_timeseries” added an optional parameter “limit” cosmetic
  • 24 Oct 26 0
    • The server rewrote its instructions, which are the text every model session reads security
    • Tool “fx_get_rate” rewrote its description, which is the text the model reads security
    • Tool “fx_get_timeseries” rewrote its description, which is the text the model reads security
    • Tool “fx_list_currencies” rewrote its description, which is the text the model reads security
    • Server version: 0.5.0 → 0.5.1 functional
    • “fx_get_timeseries” reworded the description of “start_date” cosmetic
    • “fx_get_rates” reworded the description of “date” cosmetic
    • “fx_get_rate” reworded the description of “date” cosmetic
    • “fx_dataframe_query” reworded the description of “row_limit” cosmetic
    • “fx_dataframe_query” reworded the description of “query” cosmetic
    • “fx_convert_currency” reworded the description of “date” cosmetic
    • “fx_get_timeseries” reworded the description of “canvas_id” cosmetic
  • 20 Oct 26 0
    • The server rewrote its instructions, which are the text every model session reads security
    • Tool “fx_dataframe_describe” rewrote its description, which is the text the model reads security
    • Tool “fx_dataframe_query” rewrote its description, which is the text the model reads security
    • Tool “fx_get_timeseries” rewrote its description, which is the text the model reads security
    • Server version: 0.4.2 → 0.5.0 functional
  • 4 Oct 26 0
    • Server version: 0.4.1 → 0.4.2 functional
  • 28 Sept 26 0
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 25 Sept 26 0
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 19 Sept 26 0
    • Server version: 0.4.0 → 0.4.1 functional
  • 12 Sept 26 0
    • The server rewrote its instructions, which are the text every model session reads security
    • Tool “fx_get_rates” rewrote its description, which is the text the model reads security
    • Tool “fx_get_timeseries” rewrote its description, which is the text the model reads security
    • Schema quality: 136 → 152 ▼ functional
    • Server version: 0.3.1 → 0.4.0 functional
    • “fx_dataframe_query” added an optional parameter “row_limit” cosmetic
    • “fx_convert_currency” reworded the description of “quote_currency” cosmetic
    • “fx_get_rate” reworded the description of “quote_currency” cosmetic
    • “fx_get_rates” reworded the description of “symbols” cosmetic
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 5 Nov 2026 · Probed https://exchange-rates.caseyjhand.com/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=caseyjhand.com CN=WE1,O=Google Trust Services,C=US 2 Nov 2026 31 Jan 2027 ECDSA 256 ECDSA-SHA256 995a30681ab772540e934241ca1d576c
SANs: caseyjhand.com, *.caseyjhand.com
CN=WE1,O=Google Trust Services,C=US (CA) CN=GTS Root R4,O=Google Trust Services LLC,C=US 13 Dec 2023 20 Feb 2029 ECDSA 256 ECDSA-SHA384 7ff31977972c224a76155d13b6d685e3
CN=GTS Root R4,O=Google Trust Services LLC,C=US (CA) CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE 15 Nov 2023 28 Jan 2028 ECDSA 384 SHA256-RSA 7fe530bf331343bedd821610493d8a1b

Background: What to check on a remote MCP endpoint →

DNSSEC secure

Validation of exchange-rates.caseyjhand.com. — Secure

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
com. present 19718 13 Verified
caseyjhand.com. present 2371 13 Verified
exchange-rates.caseyjhand.com. Verified address RRset verified with the apex keys
Authentication No authorisation required

The endpoint answered without asking for a token. Anyone who knows the URL can reach it.

Result No authorisation required
HTTP status 200
Header Value
strict-transport-security max-age=63072000; includeSubDomains; preload
x-content-type-options nosniff

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://exchange-rates.caseyjhand.com/mcp Verified 200
http (plaintext) http://exchange-rates.caseyjhand.com/mcp HTTPS enforced 301 https://exchange-rates.caseyjhand.com/mcp
MCP tools · 7 exposed · ~1,657 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
fx_convert_currency ~203

Convert an amount between any two currencies at the latest or a historical rate. Returns the converted amount, the rate used, the actual rate date, and whether the date was snapped from a weekend/holiday to the prior business day. Cross-rates are triangulated through EUR automatically.

NameTypeReqDescription
amountnumberyesAmount in the base currency to convert. Must be greater than zero.
base_currencystringyesISO 4217 source currency code (e.g. USD). Call fx_list_currencies to get valid codes.
datestring–ISO 8601 date (YYYY-MM-DD) for a historical rate. Omit for the latest available rate. Frankfurter v1 data starts 1999-01-04. Future dates are not supported.
quote_currencystringyesISO 4217 target currency code (e.g. EUR). The amount will be expressed in this currency. Call fx_list_currencies to get valid codes.
NameTypeReqDescription
base_amountnumber–The input amount in the base currency.
base_currencystring–Source currency code.
date_snappedboolean–True when the API returned a different date than requested — Frankfurter v1 snaps weekend/holiday requests to the prior business day.
errorobject–Present when the call failed. Absent on success.
quote_amountnumber–The unrounded amount × rate product in the quote currency, using JavaScript floating-point precision; no currency minor-unit rounding policy is applied.
quote_currencystring–Target currency code.
ratenumber–Exchange rate used: units of quote currency per 1 unit of base currency.
rate_datestring–Actual date of the rate used for conversion.
rate_typestring–Always "Daily rate (Frankfurter v1)" — these are reference rates, not tradeable bid/ask.
sourcestring–Always "Frankfurter v1" — the upstream data provider.

No examples provided.

fx_dataframe_describe ~115

List tables and columns staged on a DataCanvas from a prior fx_get_timeseries call. Required first step before fx_dataframe_query — use it to discover table names and column schemas. Requires DataCanvas, which is on by default — a deployment that turns it off does not list this tool at all, and fx_get_timeseries returns every range inline there.

NameTypeReqDescription
canvas_idstringyesCanvas ID returned by fx_get_timeseries. Re-run fx_get_timeseries to obtain a fresh canvas_id if this one has expired.
NameTypeReqDescription
canvas_idstring–The canvas ID echoed back — use this in fx_dataframe_query.
errorobject–Present when the call failed. Absent on success.
expires_atstring–ISO 8601 timestamp when this canvas will be evicted.
tablesarray–All tables and views currently staged on this canvas.

No examples provided.

fx_dataframe_query ~275

Run a read-only SQL SELECT against DataCanvas tables staged by fx_get_timeseries. Supports aggregations, GROUP BY, window functions, and JOINs across multiple registered tables. Run fx_dataframe_describe first to discover table names and column schemas. Requires DataCanvas, which is on by default — a deployment that turns it off does not list this tool at all, and fx_get_timeseries returns every range inline there.

NameTypeReqDescription
canvas_idstringyesCanvas ID returned by fx_get_timeseries. Re-run fx_get_timeseries to obtain a fresh canvas_id if this one has expired.
querystringyesRead-only SQL SELECT statement. Reference tables by the names returned by fx_dataframe_describe or the table_name field from fx_get_timeseries. Example: SELECT date, rate FROM <table_name> WHERE date…
row_limitinteger–Most rows to return (positive integer, default 150; values above 10000 clamp to 10000 with a notice). When the query produces more, truncated is true — page with ORDER BY <column> LIMIT <n> OFFSET <m…
NameTypeReqDescription
canvas_idstring–The canvas ID used — pass to a subsequent fx_dataframe_query or fx_dataframe_describe call.
errorobject–Present when the call failed. Absent on success.
noticestring–Reports requested and effective row limits when clamped, and the ORDER BY … LIMIT … OFFSET query shape when the result is truncated.
row_countnumber–Rows returned — always the length of rows. When truncated is true this equals row_limit, not the full result size.
rowsarray–Result rows, at most row_limit (default 150). Each key is a column name from the query.
truncatedboolean–True when the query produced more rows than row_limit and rows holds only the first row_limit of them. Fetch the rest with ORDER BY <column> LIMIT <n> OFFSET <m> — ORDER BY is required for determinis…

No examples provided.

fx_get_rate ~240

Get the exchange rate for a currency pair on a given date (default: latest). Returns the rate, the actual rate date (which may differ from the requested date on weekends/holidays — daily observations may skip non-publication days), and source provenance. Cross-rates are triangulated through EUR automatically. A same-currency pair returns a rate of 1, dated to the same publication day any other pair would report for that date. Use fx_convert_currency when you want the converted amount; use this tool when you only need the rate number.

NameTypeReqDescription
base_currencystringyesISO 4217 base currency code (e.g. USD). Call fx_list_currencies to get valid codes.
datestring–ISO 8601 date (YYYY-MM-DD). Omit for the latest available rate. Frankfurter v1 data starts 1999-01-04. Future dates are not supported.
quote_currencystringyesISO 4217 quote currency code (e.g. EUR). The rate is expressed as "how many quote units per 1 base unit". Call fx_list_currencies to get valid codes.
NameTypeReqDescription
base_currencystring–The base currency code.
date_snappedboolean–True when the API returned a different date than requested — Frankfurter v1 snaps weekend/holiday requests to the prior business day.
errorobject–Present when the call failed. Absent on success.
quote_currencystring–The quote currency code.
ratenumber–Exchange rate: units of quote currency per 1 unit of base currency.
rate_datestring–Actual date of the rate returned.
rate_typestring–Always "Daily rate (Frankfurter v1)" — these are reference rates, not tradeable bid/ask.
sourcestring–Always "Frankfurter v1" — the upstream data provider.

No examples provided.

fx_get_rates ~240

Get all available exchange rates for one base currency in a single snapshot. Useful for bulk comparison and seeding downstream tools. Returns a map of quote currency → rate, the actual snapshot date, and whether a historical date was snapped from a weekend/holiday to the prior business day. Optionally filter to a subset of quote currencies via symbols. Listing the base currency itself in symbols is accepted and returns a rate of 1 for it.

NameTypeReqDescription
base_currencystringyesISO 4217 base currency code (e.g. USD). Call fx_list_currencies to get valid codes.
datestring–ISO 8601 date (YYYY-MM-DD). Omit for the latest available rate. Frankfurter v1 data starts 1999-01-04. Future dates are not supported.
symbolsarray–Optional list of quote currency codes to filter the response. When provided, must contain at least one currency code — omit the field entirely, not an empty array, to return all ~30 supported currenc…
NameTypeReqDescription
base_currencystring–The base currency code.
date_snappedboolean–True when the API returned a different date than requested — Frankfurter v1 snaps weekend/holiday requests to the prior business day. Always false when date is omitted.
errorobject–Present when the call failed. Absent on success.
rate_datestring–Actual date of the rates. May differ from requested date on weekends/holidays — daily observations may skip non-publication days; the API silently snaps to the prior business day.
rate_typestring–Always "Daily rate (Frankfurter v1)" — these are reference rates, not tradeable bid/ask.
ratesobject–Map of quote currency code → exchange rate (units of quote per 1 base).
sourcestring–Always "Frankfurter v1" — the upstream data provider.

No examples provided.

fx_get_timeseries ~449

Get historical daily Frankfurter v1 rates over an inclusive date range. Same-date EUR legs are divided without intermediate rounding; only days with both currencies appear, including observed self-pairs at 1 and historical retired currencies. Missing-leg served days produce coverage notices; weekends and holidays are not counted as missing. summary covers all observed days before delivery: arithmetic mean, earliest tied extrema, endpoints and percentage change, without accounting policy. limit bounds returned rows (default/max 500); 0 returns summary only. Continue inline with next_start_date, the same end_date and a positive limit. Long ranges (>90 days by default) stage beyond the 40,000-character preview budget, independently of limit. Explicit canvas_id always stages the complete series, including short/empty results, and fails if unavailable or unknown. Each registration preserves earlier tables with a unique table_name. spilled=true returns canvas_id and table_name; use fx_dataframe_describe then fx_dataframe_query for SQL. Without DataCanvas, omit canvas_id to page inline.

NameTypeReqDescription
base_currencystringyesISO 4217 base currency code (e.g. USD). Call fx_list_currencies to get valid codes.
canvas_idstring–Existing canvas ID from a prior call explicitly requesting staging even for short or empty results. Every call creates a uniquely named table. Omit for automatic staging or inline paging.
end_datestringyesISO 8601 end date (YYYY-MM-DD). Must be >= start_date. Future dates are not supported.
limitinteger–Maximum observations returned in rates, default 500, clamped to 500. Use 0 for summary only; continue inline with a positive limit. Does not affect summary, counts, bounds, staging eligibility or the…
quote_currencystringyesISO 4217 quote currency code (e.g. EUR). Call fx_list_currencies to get valid codes.
start_datestringyesISO 8601 start date (YYYY-MM-DD). Frankfurter v1 data starts 1999-01-04. The actual first data point may be later if start_date falls on a weekend/holiday.
NameTypeReqDescription
base_currencystring–Base currency code.
canvas_idstring–Canvas ID — present when spilled is true. Pass to fx_dataframe_describe to inspect the staged table, then to fx_dataframe_query to run SQL.
end_datestring–Last publication date in the requested range. Always inside the requested range — earlier than the requested end when that day had no Frankfurter v1 fix, and equal to it when the series is empty. Lat…
errorobject–Present when the call failed. Absent on success.
next_start_datestring–Present only when an inline page was cut short: the first publication date not in rates. Pass it as start_date with the same end_date and a positive limit to get the next page. For limit 0 it is the…
noticestring–Explains a result that would otherwise look broken or incomplete: an empty series (no publication day in the range); an inline page cut short (the start_date to continue from, plus why a long range w…
quote_currencystring–Quote currency code.
rate_countnumber–Total observed publication days in the requested range (the start_date through end_date passed on this call) — not the number of entries in rates, which is smaller when truncated is true. On a contin…
rate_typestring–Always "Daily rate (Frankfurter v1)" — these are reference rates, not tradeable bid/ask.
ratesobject–Date → rate map in date order, observed days inside the requested range only. Bounded by limit (default/max 500), and by the character budget for automatically staged previews. Empty for limit 0 or n…
sourcestring–Always "Frankfurter v1" — the upstream data provider.
spilledboolean–True when the complete result was staged on DataCanvas, either explicitly through canvas_id or automatically after exceeding the threshold and preview budget.
start_datestring–First observed publication date in the requested range, including when limit is 0. Always inside the requested range — later than the requested start when that day had no Frankfurter v1 fix, and equa…
summaryobject–Statistics over all observed days in the full clipped requested range before limit, paging or staging; omitted for empty ranges. Missing-leg coverage notices describe excluded served days. Continuati…
table_namestring–Canvas table name — present when spilled is true. Use it as the FROM target in fx_dataframe_query SQL; fx_dataframe_describe lists its columns.
truncatedboolean–True when rates holds only part of the series: an inline page (next_start_date continues it) or a spilled preview (spilled is true). False when rates holds every publication day in the requested rang…

No examples provided.

fx_list_currencies ~135

List current Frankfurter v1 currency codes and names with as_of, the latest served rate date. include_retired=true adds historical codes absent from the current set. Optional official ECB start_date/end_date are outer coverage bounds, not uninterrupted availability; a dated end_date does not imply retirement. Metadata outages are disclosed without failing current discovery. Historical availability remains validated from requested v1 data. Use this to disambiguate dollars (USD vs AUD vs CAD).

NameTypeReqDescription
include_retiredboolean–Include historical codes absent from current v1 discovery, default false. Optional official ECB coverage dates are outer bounds and may contain gaps.
NameTypeReqDescription
as_ofstring–Latest served daily rate date for this current-discovery list; historical availability is checked against historical data.
countnumber–Total number of supported currencies.
currenciesarray–All supported currencies, sorted alphabetically by code.
errorobject–Present when the call failed. Absent on success.
noticestring–Discloses unavailable optional coverage metadata or incomplete coverage dates.
sourcestring–Always "Frankfurter v1" — the upstream data provider.

No examples provided.

Install

How do I install the io.github.cyanheads/exchange-rates-mcp-server server?

io.github.cyanheads/exchange-rates-mcp-server is a hosted endpoint at https://exchange-rates.caseyjhand.com/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · exchange-rates.caseyjhand.com

# add to Claude Code
claude mcp add --transport http cyanheads-exchange-rates-mcp-server 'https://exchange-rates.caseyjhand.com/mcp'
Common questions

What is the io.github.cyanheads/exchange-rates-mcp-server server?

io.github.cyanheads/exchange-rates-mcp-server is listed in the public MCP registry as io.github.cyanheads/exchange-rates-mcp-server. Convert currencies, get FX rates, and query historical Frankfurter v1 exchange rate data. This page covers its hosted endpoint (https://exchange-rates.caseyjhand.com/mcp).

Is the io.github.cyanheads/exchange-rates-mcp-server server safe to use?

io.github.cyanheads/exchange-rates-mcp-server scores 90 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the io.github.cyanheads/exchange-rates-mcp-server server expose?

io.github.cyanheads/exchange-rates-mcp-server exposes 7 tools: fx_list_currencies, fx_get_rates, fx_get_rate, fx_convert_currency, fx_get_timeseries, and 2 more. Their descriptions and schemas cost roughly 1,657 tokens of context every time the server is loaded.

Does the io.github.cyanheads/exchange-rates-mcp-server server require authentication?

No. We connected to io.github.cyanheads/exchange-rates-mcp-server without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

Is the io.github.cyanheads/exchange-rates-mcp-server server still maintained?

io.github.cyanheads/exchange-rates-mcp-server is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.