exchange-rates-mcp-server
Server Details
Convert currencies, get FX rates, and query historical ECB exchange rate data.
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP
- URL
- Repository
- cyanheads/exchange-rates-mcp-server
- GitHub Stars
- 1
- Server Listing
- @cyanheads/exchange-rates-mcp-server
Glama MCP Gateway
Connect through Glama MCP Gateway for full control over tool access and complete visibility into every call.
Full call logging
Every tool call is logged with complete inputs and outputs, so you can debug issues and audit what your agents are doing.
Tool access control
Enable or disable individual tools per connector, so you decide what your agents can and cannot do.
Managed credentials
Glama handles OAuth flows, token storage, and automatic rotation, so credentials never expire on your clients.
Usage analytics
See which tools your agents call, how often, and when, so you can understand usage patterns and catch anomalies.
Tool Definition Quality
Average 4.5/5 across 7 of 7 tools scored.
Each tool has a distinct, non-overlapping purpose: conversion, single rate, bulk rates, timeseries, currency listing, and DataFrame inspection/query. The descriptions clearly differentiate between getting a rate vs converting an amount, and between inline vs DataCanvas-stored timeseries.
All tools follow a consistent fx_verb_noun pattern (e.g., fx_get_rate, fx_convert_currency, fx_list_currencies). The two dataframe tools also adhere to fx_dataframe_verb, maintaining a uniform convention across the entire set.
Seven tools is well-scoped for an exchange-rate server. Each tool addresses a needed operation (conversion, rates, timeseries, metadata) without redundancy or bloat, and adding DataFrame analysis feels justified for handling large datasets.
The surface covers the full lifecycle of exchange-rate queries: listing currencies, fetching single or bulk rates, converting with historical dates, and retrieving timeseries. The optional DataCanvas integration fills the gap for large-range analysis, leaving no obvious dead ends for common use cases.
Available Tools
7 toolsfx_convert_currencyFx Convert CurrencyARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | 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. | |
| amount | Yes | Amount in the base currency to convert. Must be greater than zero. | |
| base_currency | Yes | ISO 4217 source currency code (e.g. USD). Call fx_list_currencies to get valid codes. | |
| quote_currency | Yes | ISO 4217 target currency code (e.g. EUR). The amount will be expressed in this currency. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rate | No | Exchange rate used: units of quote currency per 1 unit of base currency. |
| error | No | Present when the call failed. Absent on success. |
| source | No | Always "ECB via Frankfurter" — the upstream data provider. |
| rate_date | No | Actual date of the rate used for conversion. |
| rate_type | No | Always "ECB reference (mid-market)" — these are reference rates, not tradeable bid/ask. |
| base_amount | No | The input amount in the base currency. |
| date_snapped | No | True when the API returned a different date than requested — ECB silently snaps weekend/holiday requests to the prior business day. |
| quote_amount | No | The converted amount in the quote currency, rounded to 6 decimal places. |
| base_currency | No | Source currency code. |
| quote_currency | No | Target currency code. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint. The description adds valuable behavioral context beyond that: the weekend/holiday snapping behavior, the exact return fields (rate, actual date, snap flag), and automatic EUR triangulation. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences with zero filler. The primary purpose is front-loaded, and the return behavior is summarized in one breath. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a conversion tool with a well-populated schema and an output schema, this description covers all essential behavioral aspects: return values, date snapping, triangulation, and the optional nature of the date parameter. No missing information the agent needs to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with rich descriptions for all four parameters, so the schema does the heavy lifting. The description adds negligible parameter-level detail beyond what the schema already provides (e.g., date handling, amount constraints, currency code reference). Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific verb-resource pair ('Convert an amount between any two currencies') and differentiates from sibling rate-getters by framing the action as conversion, not just rate retrieval. It also lists what it returns, making the tool's role unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies usage for conversions (as opposed to rate-only queries like fx_get_rate) and mentions automatic EUR triangulation, but it does not explicitly name alternatives or state when to prefer this over siblings. The context is sufficient without being explicit about exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fx_dataframe_describeFx Dataframe DescribeARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| canvas_id | Yes | Canvas ID returned by fx_get_timeseries. Re-run fx_get_timeseries to obtain a fresh canvas_id if this one has expired. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| tables | No | All tables and views currently staged on this canvas. |
| canvas_id | No | The canvas ID echoed back — use this in fx_dataframe_query. |
| expires_at | No | ISO 8601 timestamp when this canvas will be evicted. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is known. The description adds valuable behavioral context: the tool's dependency on DataCanvas, that it may not be listed without one, and that a canvas_id can expire (referenced in the schema). It goes beyond the annotations by explaining how the tool fits into a workflow and the consequences of missing prerequisites.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is exactly two sentences, with the core purpose front-loaded and the conditional context provided in the second sentence. Every clause earns its place—no filler, no repetition of the tool name, and it efficiently packs purpose, usage, and environment constraints.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists (so return values are specified separately) and annotations cover read-only and idempotent behavior, the description provides all remaining context an agent needs: the tool's role, required first-step nature, prerequisite, and the fallback behavior if the prerequisite isn't met. Nothing essential is missing for a correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema itself already documents canvas_id with guidance on expiration and where to get a fresh one. The tool description does not add further parameter details beyond what the schema provides. Since the schema handles parameter semantics fully, a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List tables and columns staged on a DataCanvas.' It explicitly names the data source (prior fx_get_timeseries call) and clearly differentiates its role from sibling tools like fx_dataframe_query (which is the next step) and the fx_get_rates/currency tools. This leaves no ambiguity about what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Required first step before fx_dataframe_query — use it to discover table names and column schemas.' It also states a prerequisite (requires DataCanvas) and explains the alternative behavior if the prerequisite is missing ('fx_get_timeseries returns every range inline'). This fully orients an agent on when to call it versus relying on other tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fx_dataframe_queryFx Dataframe QueryARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | 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 | |
| canvas_id | Yes | Canvas ID returned by fx_get_timeseries. Re-run fx_get_timeseries to obtain a fresh canvas_id if this one has expired. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | No | Result rows, capped at the canvas row limit (default 10 000). Each key is a column name from the query. |
| error | No | Present when the call failed. Absent on success. |
| canvas_id | No | The canvas ID used — pass to a subsequent fx_dataframe_query or fx_dataframe_describe call. |
| row_count | No | Rows returned. Equals the materialized row count; when truncated is true this is the row cap, not the full result size. Narrow the SELECT (add WHERE/LIMIT or aggregate) to see all rows. |
| truncated | No | True when the query produced more rows than the canvas row cap and the result was capped. Refine the query to materialize the complete result. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the read-only nature is covered. The description adds valuable behavioral context: it notes the dependency on DataCanvas (CANVAS_PROVIDER_TYPE=duckdb) and that without it the tool is not listed, which is a behavioral condition. It also mentions that canvas_id may expire and advises re-running fx_get_timeseries, disclosing a stateful aspect. These go beyond annotations, though it doesn't describe return format or error handling. Given the strong annotation coverage, a 4 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loading the core purpose in the first sentence. The second sentence adds prerequisite and dependency context, followed by a conditional note about behavior. Every clause serves a purpose: capability, usage guidance, and environmental requirement. There is no redundancy or filler, making it highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of a SQL-query tool with joins and aggregations, the description covers the essential context: prerequisite tools (fx_dataframe_describe), data source (fx_get_timeseries), and environmental requirement (DataCanvas). The output schema exists, so return value details are not needed. The description also addresses the freshness of canvas_id, which is critical for correct invocation. For a tool of this complexity, the description is remarkably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for both parameters, with both canvas_id and query having detailed descriptions including an example query. The tool description reinforces these but adds little that is not already in the schema. The main addition is the reference to 'tables staged by fx_get_timeseries' and the note about re-running fx_get_timeseries for a fresh canvas_id, but these are more contextual than parameter-specific. With complete schema descriptions, the baseline of 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Run a read-only SQL SELECT against DataCanvas tables staged by fx_get_timeseries.' It specifies the resource (DataCanvas tables), the action (run SQL SELECT), and explicitly distinguishes from siblings by naming fx_get_timeseries and fx_dataframe_describe as partners. The added capabilities (aggregations, GROUP BY, window functions, JOINs) further clarify its specialized role among the sibling tools, such as fx_get_rate or fx_get_rates, which are likely simpler retrieval tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: it directs the user to 'Run fx_dataframe_describe first to discover table names and column schemas.' It also states the prerequisite of DataCanvas availability and indicates consequences if not present ('without it this tool is not listed at all'). This effectively tells the agent when the tool is appropriate and what to do before invoking it. It does not explicitly mention alternatives, but the naming of fx_get_timeseries and fx_dataframe_describe in the flow implicitly distinguishes usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fx_get_rateFx Get RateARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | ISO 8601 date (YYYY-MM-DD). Omit for the latest available rate. ECB data starts 1999-01-04. Future dates are not supported. | |
| base_currency | Yes | ISO 4217 base currency code (e.g. USD). Call fx_list_currencies to get valid codes. | |
| quote_currency | Yes | ISO 4217 quote currency code (e.g. EUR). The rate is expressed as "how many quote units per 1 base unit". |
Output Schema
| Name | Required | Description |
|---|---|---|
| rate | No | Exchange rate: units of quote currency per 1 unit of base currency. |
| error | No | Present when the call failed. Absent on success. |
| source | No | Always "ECB via Frankfurter" — the upstream data provider. |
| rate_date | No | Actual date of the rate returned. |
| rate_type | No | Always "ECB reference (mid-market)" — these are reference rates, not tradeable bid/ask. |
| date_snapped | No | True when the API returned a different date than requested — ECB silently snaps weekend/holiday requests to the prior business day. |
| base_currency | No | The base currency code. |
| quote_currency | No | The quote currency code. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already supply readOnlyHint, openWorldHint, and idempotentHint, and the description goes beyond them by disclosing key behaviors: date shifting on non-business days, EUR triangulation for cross-rates, and same-currency pairs returning 1 with a consistent publication date. This is material context an agent needs to interpret results correctly and is not present in the schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (three sentences) yet packs essential information: core purpose, key behavioral caveats, and selective routing. The most important facts come first, and every sentence contributes to correct invocation or interpretation. No waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (currency pairs, date handling, triangulation) and an existing output schema (which presumably documents return fields), the description covers all critical operational aspects: default behavior, date-shift caveat, same-currency edge case, and the presence of source provenance. It also names supporting tools for codes and conversion, making it complete for an agent to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with clear descriptions for each parameter, so the baseline is 3. The tool description adds value by explaining the rate direction ('how many quote units per 1 base unit') and the default-date semantics for the date parameter, which reinforces and extends the schema without redundancy.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Get the exchange rate for a currency pair on a given date') and immediately clarifies the core output (rate, actual rate date, source). It explicitly names the sibling fx_convert_currency for converted amounts, clearly distinguishing this tool from alternatives without needing to inspect schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing is given: 'Use fx_convert_currency when you want the converted amount; use this tool when you only need the rate number.' It also covers default behavior (latest date) and points to fx_list_currencies for valid codes, giving clear when-to-use guidance and a direct exclusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fx_get_ratesFx Get RatesARead-onlyIdempotentInspect
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 plus the snapshot date. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | ISO 8601 date (YYYY-MM-DD). Omit for the latest available rate. ECB data starts 1999-01-04. Future dates are not supported. | |
| symbols | No | Optional list of quote currency codes to filter the response. Omit 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. | |
| base_currency | Yes | ISO 4217 base currency code (e.g. USD). Call fx_list_currencies to get valid codes. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| rates | No | Map of quote currency code → exchange rate (units of quote per 1 base). |
| source | No | Always "ECB via Frankfurter" — the upstream data provider. |
| rate_date | No | Actual date of the rates. May differ from requested date on weekends/holidays — ECB publishes business days only; the API silently snaps to the prior business day. |
| rate_type | No | Always "ECB reference (mid-market)" — these are reference rates, not tradeable bid/ask. |
| base_currency | No | The base currency code. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only and idempotent behavior. The description adds valuable context about the return format (map of quote currency to rate plus snapshot date) and the special case of including the base currency (returns rate of 1). This goes beyond the annotations and provides actionable behavior details.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-organized, starting with the core purpose, then usage context, return format, filtering option, and a special edge case. Every sentence contributes information without redundancy, making it efficient for an agent to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 3 parameters, a rich output schema, and clear annotations, the description covers all necessary aspects: purpose, usage, return structure, and special behavior. The date handling is mentioned in the schema, and the description suffices for correct invocation without requiring additional context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 100% coverage with each parameter described in detail, including the base currency special case. The description reiterates the symbols filter but doesn't add meaning beyond the schema. Since the schema already carries the semantic load, the description adds no extra value, warranting the baseline score of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches all exchange rates for a base currency in one snapshot, with specific verbs and resource. It distinguishes itself from sibling tools by emphasizing the bulk snapshot nature versus single rate or timeseries, and mentions the filtering option.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It indicates when to use the tool (bulk comparison, seeding downstream tools) and mentions the optional filter for subset of symbols. However, it doesn't explicitly name alternative tools or provide exclusions (e.g., when to use fx_get_rate or fx_get_timeseries), relying on implicit context from the sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fx_get_timeseriesFx Get TimeseriesARead-onlyIdempotentInspect
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. Short ranges (≤90 days by default) are returned inline as a date→rate map. When DataCanvas is enabled (CANVAS_PROVIDER_TYPE=duckdb) long ranges spill to it: 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 stay inline (spilled=false) and the notice says so.
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | Yes | ISO 8601 end date (YYYY-MM-DD). Must be >= start_date. Future dates are not supported. | |
| canvas_id | No | 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. | |
| start_date | Yes | 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. | |
| base_currency | Yes | ISO 4217 base currency code (e.g. USD). Call fx_list_currencies to get valid codes. | |
| quote_currency | Yes | ISO 4217 quote currency code (e.g. EUR). Call fx_list_currencies to get valid codes. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| rates | No | Date → rate map for the inline result. Publication days inside the requested range only. Truncated to a preview when the result was spilled to canvas; empty when the range contains no publication day at all. |
| notice | No | Explains a result that would otherwise look broken — an empty series, or a long range that stayed inline because DataCanvas is not configured. |
| source | No | Always "ECB via Frankfurter" — the upstream data provider. |
| spilled | No | True when the full result was staged on the DataCanvas (range exceeded threshold). |
| end_date | No | Last date in the returned series. Always inside the requested range — earlier than the requested end when that day had no ECB fix, and equal to it when the series is empty. |
| canvas_id | No | Canvas ID — present when spilled is true. Pass to fx_dataframe_query. |
| rate_type | No | Always "ECB reference (mid-market)" — these are reference rates, not tradeable bid/ask. |
| rate_count | No | Total number of data points (publication days) inside the requested range. |
| start_date | No | First date in the returned series. Always inside the requested range — later than the requested start when that day had no ECB fix, and equal to it when the series is empty. |
| table_name | No | Canvas table name — present when spilled is true. Use in fx_dataframe_query SQL. |
| base_currency | No | Base currency code. |
| quote_currency | No | Quote currency code. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnly, idempotent, openWorld), the description discloses extensive behaviors: ECB publication days only, empty map with a notice for non-publication ranges, same-currency rate of 1, inline vs spill based on range length and DataCanvas configuration, and the exact response flags (spilled, canvas_id, table_name). This is far beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence serves a distinct purpose: purpose first, then edge cases, then spill logic. It is front-loaded with the primary function and organized in a logical flow. While it could be trimmed slightly, the structure is strong and there is no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (multiple conditional behaviors, spill integration, and response variations), the description is remarkably complete. It explains all return scenarios, the spill condition and how to proceed, and the same-currency case. The existence of an output schema further reduces the burden, but the description goes beyond that by describing response fields and follow-up actions, leaving nothing critical missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers all parameters at 100% with descriptions, so the baseline is 3. The description adds domain context (e.g., date-boundary behavior, ECB holidays) but does not explain individual parameters beyond what the schema already states. It does clarify the 'short range' default of 90 days, which relates to start/end dates, but this is more about behavior than parameter semantics. Therefore, it meets the baseline without exceeding it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Get historical daily exchange rates'), a precise resource ('currency pair over a date range'), and explicitly distinguishes itself from sibling tools by describing the spill workflow to fx_dataframe_describe/query. The purpose is unambiguous and not a tautology.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear conditional guidance: when long ranges spill to DataCanvas, it explicitly directs the agent to call fx_dataframe_describe and fx_dataframe_query. It also implies this is the tool for historical daily series as opposed to single-rate tools, though it never explicitly states 'use fx_get_rate for a single date'. The lack of explicit 'when not to use' is a minor gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fx_list_currenciesFx List CurrenciesARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| count | No | Total number of supported currencies. |
| error | No | Present when the call failed. Absent on success. |
| source | No | Always "ECB via Frankfurter" — the upstream data provider. |
| currencies | No | All supported currencies, sorted alphabetically by code. |
Tool Definition Quality
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint. The description adds useful context about scope ('~30 ECB reference currencies') and the disambiguation purpose, which is beyond the annotations. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, no filler. The main purpose is front-loaded, followed by usage context and scope. Every sentence earns its place, and the description is appropriately sized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters and an output schema exists, the description covers all needed context: what it returns (codes and names), when to use it (disambiguation/validation), and its scope (ECB currencies). Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero parameters, the schema provides no meaningful info to describe, so the baseline is 4. The description doesn't need to add parameter details and correctly stays silent on parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the exact action and resource: 'List all supported ISO 4217 currency codes with their full names.' It also distinguishes itself from conversion tools by explaining its disambiguation role, making it clear this is a lookup/list tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Call this before converting... or to validate a user-supplied currency code.' It does not name specific alternatives or exclusions, but the context is clear that this is for listing/validation prior to conversion, which is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Frequently Asked Questions
Claiming proves that you control a remote MCP connector. It does not move, proxy, or interrupt the server.
Open the connector listing, choose Claim ownership, and sign in to Glama.
Complete one verification method:
GitHub identity — fastest for official registry listings. For a namespace such as
io.github.alice/server, link the matching GitHub user or an account that owns the GitHub organization, then choose Claim with GitHub.HTTP challenge — works when you can deploy a public file. Generate a token, publish the exact JSON Glama shows at
/.well-known/glama.jsonon the same origin as the connector, then choose Check HTTP challenge.DNS challenge — works when you control DNS but cannot change the server. Generate a token, create the exact TXT record Glama shows, wait for it to propagate, then choose Check DNS challenge.
After verification, Glama sends a confirmation email and gives you access to listing details, thumbnails, health checks, and analytics. Keep the HTTP file or DNS record in place: Glama periodically checks it and ownership remains verified while the token is discoverable.
The HTTP ownership file has this structure:
{
"$schema": "https://glama.ai/mcp/schemas/connector.json",
"claim": "glama_claim_..."
}Claim tokens are opaque, stable, and bound to the signed-in Glama account. They contain no email address or other personal information. If Glama can no longer discover a verified HTTP or DNS token, it starts a seven-day grace period before removing claim-based access. Restore the same token during that period to keep ownership verified. Never publish an email address, Glama session token, GitHub token, or connector credential as ownership proof.
If verification fails, confirm that you copied the current token exactly. The HTTP file must be public, return valid JSON with a successful HTTP response, and stay on the connector's origin. DNS changes may need more time to propagate. A claim cannot transfer to a different origin or hostname: if the connector target changes, Glama starts the grace period and the new target must be claimed separately after the previous claim is released.
For a connector linked to the official MCP Registry, registry updates continue to replace its name, description, and URL by default. After claiming, open Manage connector and enable Use Glama listing details as the source of truth if edits made on Glama should be preserved. Categories and thumbnails are always managed on Glama; registry linkage and technical connection settings continue to sync.
Control your server's listing on Glama, including description and metadata
Access analytics and receive server usage reports
Get monitoring and health status updates for your server
Feature your server to boost visibility and reach more users
For users:
Full audit trail – every tool call is logged with inputs and outputs for compliance and debugging
Granular tool control – enable or disable individual tools per connector to limit what your AI agents can do
Centralized credential management – store and rotate API keys and OAuth tokens in one place
Change alerts – get notified when a connector changes its schema, adds or removes tools, or updates tool definitions, so nothing breaks silently
For server owners:
Proven adoption – public usage metrics on your listing show real-world traction and build trust with prospective users
Tool-level analytics – see which tools are being used most, helping you prioritize development and documentation
Direct user feedback – users can report issues and suggest improvements through the listing, giving you a channel you would not have otherwise
The connector status is unhealthy when Glama is unable to successfully connect to the server. This can happen for several reasons:
The server is experiencing an outage
The URL of the server is wrong
Credentials required to access the server are missing or invalid
If you are the owner of this MCP connector and would like to make modifications to the listing, including providing test credentials for accessing the server, please contact support@glama.ai.
Discussions
No comments yet. Be the first to start the discussion!
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables currency conversion and exchange rate lookups using real ECB reference rates, free and without an API key. Supports natural language queries like 'convert 100 USD to EUR' or 'what's the exchange rate between GBP and JPY?'.2MIT
- AlicenseAqualityDmaintenanceProvides access to currency exchange rates and conversion tools using the Frankfurter API, including latest rates, historical data, and time series from sources like the European Central Bank.5MIT
- FlicenseNot gradedqualityDmaintenanceProvides real-time and historical foreign exchange rates for 31+ currencies, enabling currency conversion, historical rate lookups, and time series analysis using data from the Frankfurter API.
- AlicenseNot gradedqualityBmaintenanceProvides live and historical foreign-exchange rates from the European Central Bank via Frankfurter API, enabling currency conversion, rate lookup, and trend analysis without API keys.MIT
Your Connectors
Sign in to create a connector for this server.