{"name":"io.github.cyanheads/exchange-rates-mcp-server","slug":"cyanheads-exchange-rates-mcp-server","title":null,"description":"Convert currencies, get FX rates, and query historical ECB exchange rate data.","url":"https://mcp.market/server/cyanheads-exchange-rates-mcp-server","rating":null,"grade":"A","score":86,"certified":false,"status":"active","category":"other","tags":[],"presence":{"score":38,"stars":1,"forks":0,"downloads_week":874,"last_push_at":"2026-09-12T21:39:04.000Z","license":"Apache-2.0"},"uptime":{"percent":100,"checks":1,"ok":1,"last_checked_at":"2026-09-19T17:26:21.814Z","last_ok_at":"2026-09-19T17:26:21.814Z","latency_ms":894},"claimed":false,"transport":"mixed","callable_via_gateway":true,"default_price_micros":0,"repository":"https://github.com/cyanheads/exchange-rates-mcp-server","website":null,"version":"0.4.0","remotes":[{"type":"streamable-http","url":"https://exchange-rates.caseyjhand.com/mcp"}],"packages":[{"registryType":"npm","registryBaseUrl":"https://registry.npmjs.org","identifier":"@cyanheads/exchange-rates-mcp-server","version":"0.4.0","runtimeHint":"bun","transport":{"type":"stdio"},"packageArguments":[{"value":"run","type":"positional"},{"value":"start:stdio","type":"positional"}],"environmentVariables":[{"description":"Frankfurter API base URL. Override for local testing or self-hosted instances.","format":"string","default":"https://api.frankfurter.dev/v1","name":"FRANKFURTER_BASE_URL"},{"description":"Day range above which fx_get_timeseries spills results to DataCanvas for SQL analytics, when DataCanvas is enabled (CANVAS_PROVIDER_TYPE=duckdb). Longer ranges return inline otherwise.","format":"string","default":"90","name":"FX_TIMESERIES_CANVAS_THRESHOLD_DAYS"},{"description":"Enable fx_dataframe_drop, which permanently removes one staged table or view from a DataCanvas. Disabled by default; the tool stays listed but uncallable until set to true.","format":"string","default":"false","name":"FX_ENABLE_CANVAS_DROP"},{"description":"Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').","format":"string","default":"info","name":"MCP_LOG_LEVEL"}]},{"registryType":"npm","registryBaseUrl":"https://registry.npmjs.org","identifier":"@cyanheads/exchange-rates-mcp-server","version":"0.4.0","runtimeHint":"bun","transport":{"type":"streamable-http","url":"http://localhost:3010/mcp"},"packageArguments":[{"value":"run","type":"positional"},{"value":"start:http","type":"positional"}],"environmentVariables":[{"description":"Frankfurter API base URL. Override for local testing or self-hosted instances.","format":"string","default":"https://api.frankfurter.dev/v1","name":"FRANKFURTER_BASE_URL"},{"description":"Day range above which fx_get_timeseries spills results to DataCanvas for SQL analytics, when DataCanvas is enabled (CANVAS_PROVIDER_TYPE=duckdb). Longer ranges return inline otherwise.","format":"string","default":"90","name":"FX_TIMESERIES_CANVAS_THRESHOLD_DAYS"},{"description":"Enable fx_dataframe_drop, which permanently removes one staged table or view from a DataCanvas. Disabled by default; the tool stays listed but uncallable until set to true.","format":"string","default":"false","name":"FX_ENABLE_CANVAS_DROP"},{"description":"The hostname for the HTTP server.","format":"string","default":"127.0.0.1","name":"MCP_HTTP_HOST"},{"description":"The port to run the HTTP server on.","format":"string","default":"3010","name":"MCP_HTTP_PORT"},{"description":"The endpoint path for the MCP server.","format":"string","default":"/mcp","name":"MCP_HTTP_ENDPOINT_PATH"},{"description":"Authentication mode to use: 'none', 'jwt', or 'oauth'.","format":"string","default":"none","name":"MCP_AUTH_MODE"},{"description":"Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').","format":"string","default":"info","name":"MCP_LOG_LEVEL"}]}],"tools":[{"name":"fx_convert_currency","description":"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.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"base_currency":{"type":"string","description":"ISO 4217 source currency code (e.g. USD). Call fx_list_currencies to get valid codes."},"quote_currency":{"type":"string","description":"ISO 4217 target currency code (e.g. EUR). The amount will be expressed in this currency. Call fx_list_currencies to get valid codes."},"amount":{"type":"number","exclusiveMinimum":0,"description":"Amount in the base currency to convert. Must be greater than zero."},"date":{"description":"ISO 8601 date (YYYY-MM-DD) for a historical rate. Omit for the latest available rate. ECB data starts 1999-01-04. Future dates are not supported.","type":"string"}},"required":["base_currency","quote_currency","amount"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}},{"name":"fx_dataframe_describe","description":"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 (CANVAS_PROVIDER_TYPE=duckdb) — without it this tool is not listed at all and fx_get_timeseries returns every range inline.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"canvas_id":{"type":"string","description":"Canvas ID returned by fx_get_timeseries. Re-run fx_get_timeseries to obtain a fresh canvas_id if this one has expired."}},"required":["canvas_id"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}},{"name":"fx_dataframe_query","description":"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 (CANVAS_PROVIDER_TYPE=duckdb) — without it this tool is not listed at all and fx_get_timeseries returns every range inline.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"canvas_id":{"type":"string","description":"Canvas ID returned by fx_get_timeseries. Re-run fx_get_timeseries to obtain a fresh canvas_id if this one has expired."},"query":{"type":"string","description":"Read-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 fx_usd_eur WHERE date > '2024-01-01' ORDER BY date"},"row_limit":{"default":150,"description":"Most rows to return (1–10000, default 150). When the query produces more, truncated is true — page with ORDER BY <column> LIMIT <n> OFFSET <m> in the SQL, or aggregate, rather than raising this toward the maximum.","type":"integer","minimum":1,"maximum":10000}},"required":["canvas_id","query"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}},{"name":"fx_get_rate","description":"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 — ECB publishes business days only), 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.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"base_currency":{"type":"string","description":"ISO 4217 base currency code (e.g. USD). Call fx_list_currencies to get valid codes."},"quote_currency":{"type":"string","description":"ISO 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."},"date":{"description":"ISO 8601 date (YYYY-MM-DD). Omit for the latest available rate. ECB data starts 1999-01-04. Future dates are not supported.","type":"string"}},"required":["base_currency","quote_currency"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}},{"name":"fx_get_rates","description":"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.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"base_currency":{"type":"string","description":"ISO 4217 base currency code (e.g. USD). Call fx_list_currencies to get valid codes."},"date":{"description":"ISO 8601 date (YYYY-MM-DD). Omit for the latest available rate. ECB data starts 1999-01-04. Future dates are not supported.","type":"string"},"symbols":{"description":"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 currencies (the base is not among them). Including base_currency here is valid — it comes back with a rate of 1.","minItems":1,"type":"array","items":{"type":"string","description":"ISO 4217 currency code to include in the response."}}},"required":["base_currency"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}},{"name":"fx_get_timeseries","description":"Get historical daily exchange rates for a currency pair over a date range. ECB publishes on business days only — weekends and holidays produce no entry, and no date outside the requested range is ever returned, so a range covering only non-publication days comes back with an empty rates map and a notice explaining why. A same-currency pair returns a rate of 1 on each publication day in the range. Inline results are returned as a date→rate map paged at 500 publication days: rate_count is always the total for the requested range, and when a page is cut short the response carries truncated=true and next_start_date — call again with start_date set to next_start_date and the same end_date for the next page. When DataCanvas is enabled (CANVAS_PROVIDER_TYPE=duckdb) long ranges (>90 days by default) spill to it instead: the response carries spilled=true, a canvas_id, and a table_name — call fx_dataframe_describe to inspect the staged table, then fx_dataframe_query to run SQL against it. Without DataCanvas long ranges are paged inline (spilled=false) and the notice says so.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"base_currency":{"type":"string","description":"ISO 4217 base currency code (e.g. USD). Call fx_list_currencies to get valid codes."},"quote_currency":{"type":"string","description":"ISO 4217 quote currency code (e.g. EUR). Call fx_list_currencies to get valid codes."},"start_date":{"type":"string","description":"ISO 8601 start date (YYYY-MM-DD). ECB data starts 1999-01-04. The actual first data point may be later if start_date falls on a weekend/holiday."},"end_date":{"type":"string","description":"ISO 8601 end date (YYYY-MM-DD). Must be >= start_date. Future dates are not supported."},"canvas_id":{"description":"Optional canvas ID from a prior call. Omit on the first call to start a fresh canvas; pass the returned canvas_id to append tables to an existing canvas.","type":"string"}},"required":["base_currency","quote_currency","start_date","end_date"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}},{"name":"fx_list_currencies","description":"List all supported ISO 4217 currency codes with their full names. Call this before converting to disambiguate \"dollars\" (USD vs AUD vs CAD vs HKD vs SGD) or to validate a user-supplied currency code. Covers the ~30 ECB reference currencies.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{},"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}}],"scan":{"score":86,"grade":"A","scanned_at":"2026-09-19T16:03:00.020Z","report":{"scannerVersion":"0.1.3","scannedAt":"2026-09-19T16:03:00.053Z","components":{"code":{"score":25,"max":25,"notes":["42 source files scanned","42 source files scanned"]},"reliability":{"score":20,"max":20,"notes":["remote reachable in 728ms"]},"poisoning":{"score":15,"max":15,"notes":["7 tool descriptions checked"]},"auth":{"score":3,"max":15,"notes":["open endpoint exposes 1 write-action tools with no auth"]},"maintenance":{"score":15,"max":15,"notes":["last push 7 days ago"]},"identity":{"score":8,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[{"id":"auth.open-write","severity":"high","component":"auth","title":"Write-action tools reachable without authentication"}],"inputs":{"probes":[{"url":"https://exchange-rates.caseyjhand.com/mcp","reachable":true,"authRequired":false,"latencyMs":728,"serverInfo":{"name":"exchange-rates-mcp-server","version":"0.4.0"}}],"packages":[{"registryType":"npm","identifier":"@cyanheads/exchange-rates-mcp-server","version":"0.4.0","found":true,"license":"Apache-2.0","hasInstallScripts":false,"dependencyCount":4,"publishedAt":"2026-09-12T21:40:25.083Z","repositoryUrl":"git+https://github.com/cyanheads/exchange-rates-mcp-server.git","weeklyDownloads":437},{"registryType":"npm","identifier":"@cyanheads/exchange-rates-mcp-server","version":"0.4.0","found":true,"license":"Apache-2.0","hasInstallScripts":false,"dependencyCount":4,"publishedAt":"2026-09-12T21:40:25.083Z","repositoryUrl":"git+https://github.com/cyanheads/exchange-rates-mcp-server.git","weeklyDownloads":437}],"repo":{"found":true,"owner":"cyanheads","repo":"exchange-rates-mcp-server","archived":false,"pushedAt":"2026-09-12T21:39:04Z","stars":1,"forks":0,"openIssues":0,"ownerType":"User","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/10339515?v=4","ownerCreatedAt":"2014-12-29T13:01:12Z","license":"Apache-2.0"},"icon":{"url":"https://avatars.githubusercontent.com/u/10339515?v=4&s=128","source":"github"},"presence":{"stars":1,"forks":0,"downloadsWeek":874,"license":"Apache-2.0","lastPushAt":"2026-09-12T21:39:04.000Z","score":38}}}},"grade_history":[],"reviews":[]}