mcp-cbr-rates
mcp-cbr-rates is an MCP server that exposes official Bank of Russia (CBR) financial data to AI agents, requiring no API keys. It provides the following tools:
get_rate(char_code, on_date): Retrieve the official CBR exchange rate for a currency (e.g., USD, EUR, CNY) on a specific date or the latest available date.history_rates(char_code, date_from, date_to): Fetch a daily exchange rate time series for a currency over a date range (up to 366 days per call).key_rate(date_from, date_to): Access the CBR key interest rate as a time series for a specified period, defaulting to the most recent 30 days.inflation(year_from, year_to): Get monthly year-over-year CPI inflation data published by CBR, filterable by year range.statistics(): Get a compact macroeconomic snapshot combining the latest key rate, USD/EUR/CNY exchange rates, and the most recent inflation figure — all in a single call.
mcp-cbr-rates
A Model Context Protocol (MCP) server that exposes public Bank of Russia (Центральный банк РФ, CBR) data — currency quotes, key rate, inflation and a compact macro snapshot — to AI agents.
mcp-cbr-rates is part of the atomno family of MCP
servers focused on the Russian fintech ecosystem. It is fully open-source,
requires no API keys, and is built on top of the official public CBR
endpoints.
Features
Five high-quality MCP tools, each with a strict Pydantic schema:
get_rate,history_rates,key_rate,inflation,statistics.Built-in TTL (Time-To-Live) cache: 1 hour for daily quotes, 24 hours for historical series, to be polite to the source.
Async
httpxtransport with automatic retries on 5xx errors.Safe XML parsing via
defusedxml.50+ unit tests with
respx-mocked HTTP, ≥80 % coverage.No secrets, no telemetry, no third-party trackers.
Related MCP server: ozon-mcp
Quick start
Install from PyPI (recommended)
pipx install atomno-mcp-cbr-rates
atomno-mcp-cbr-rates # starts the MCP server over stdioOr with uv:
uv tool install atomno-mcp-cbr-ratesInstall from source
git clone https://github.com/atomno-mcp/mcp-cbr-rates.git
cd mcp-cbr-rates
pip install -e .
atomno-mcp-cbr-rates # starts the MCP server over stdioUse with Cursor
Add the following to .cursor/mcp.json (or your global ~/.cursor/mcp.json):
{
"mcpServers": {
"cbr-rates": {
"command": "atomno-mcp-cbr-rates"
}
}
}Use with Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"cbr-rates": {
"command": "atomno-mcp-cbr-rates"
}
}
}On Windows the config lives at
%APPDATA%\Claude\claude_desktop_config.json; on macOS at
~/Library/Application Support/Claude/claude_desktop_config.json.
Use with Claude Code
claude mcp add cbr-rates -- atomno-mcp-cbr-ratesTools
Name | Inputs | Returns |
|
|
|
|
|
|
|
|
|
|
|
|
| (none) |
|
Examples in plain English:
"What was the official EUR rate on April 25, 2024?" Tool:
get_rate(char_code="EUR", on_date="2024-04-25")
"Plot the daily USD-RUB rate over the last 90 days." Tool:
history_rates(char_code="USD", date_from=..., date_to=...)
"Give me the latest key rate, USD/EUR/CNY, and inflation in one go." Tool:
statistics()
The history_rates window is capped at 366 days; for longer periods, call
the tool repeatedly.
Configuration
All settings are optional and read from environment variables:
Variable | Default | Description |
|
| HTTP timeout in seconds for CBR calls. |
|
| Cache TTL for daily quotes (seconds). |
|
| Cache TTL for historical series and SOAP responses. |
|
| Standard Python log level. |
Legacy CBR_* names are still accepted for compatibility, but new configs should use MCP_CBR_*.
There are no API keys to configure — all CBR endpoints used here are public.
Development
git clone https://github.com/atomno-mcp/mcp-cbr-rates.git
cd mcp-cbr-rates
python -m venv .venv && source .venv/bin/activate # or .\.venv\Scripts\activate on Windows
pip install -e ".[dev]"
pytest --cov=src/mcp_cbr_ratesLayout:
apps/mcp-cbr-rates/
├── src/mcp_cbr_rates/
│ ├── server.py # FastMCP entry point, tool registration
│ ├── tools.py # high-level async tools with caching
│ ├── client.py # httpx wrapper around CBR XML / SOAP / HTML endpoints
│ ├── schemas.py # Pydantic v2 models for inputs & outputs
│ ├── cache.py # async TTL cache
│ ├── currency_codes.py # static ISO → CBR id map (with dynamic fallback)
│ └── errors.py # typed exception hierarchy
└── tests/ # respx-mocked unit tests + fixturesData sources
https://www.cbr.ru/scripts/XML_daily.asp— daily currency quotes.https://www.cbr.ru/scripts/XML_dynamic.asp— historical currency series.https://www.cbr.ru/scripts/XML_valFull.asp— currency code lookup.https://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx— SOAP service for the CBR key rate.https://www.cbr.ru/hd_base/infl/— monthly year-over-year inflation table.
All endpoints are read-only and free of charge.
Disclaimer
This project is not affiliated with the Bank of Russia in any way. It is an unofficial, best-effort wrapper around publicly available data. Use at your own risk; the authors disclaim any responsibility for the freshness, accuracy or applicability of the data delivered through this server.
If CBR's HTML or XML schemas change, individual tools may stop working until this package is updated. Please open an issue if you notice a regression.
License
MIT — see LICENSE.
Available Tools
5 toolsget_rateA
Get the official Bank of Russia exchange rate for a single currency on a given date (or the latest published date if 'on_date' is omitted). Returns nominal, value, per-unit rate and effective quote date.
| Name | Required | Description | Default |
|---|---|---|---|
| on_date | No | ||
| char_code | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| date | Yes | Effective quote date as published by CBR. |
| name | Yes | Russian-language currency name from CBR. |
| value | Yes | Rate of <nominal> units in RUB. |
| source | No | |
| nominal | Yes | Number of foreign units the rate is given for. |
| num_code | Yes | Numeric ISO 4217 code as string, e.g. '840'. |
| char_code | Yes | ISO-letter code, e.g. 'USD'. |
| vunit_rate | Yes | Rate per single unit (value / nominal). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries the behavioral burden. It indicates a read operation and lists returned fields, but does not disclose authentication needs, rate limits, error handling, or side effects. Adequate but minimal.
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 a single, well-structured sentence that conveys purpose, parameter usage, and return value in a compact form. No unnecessary words.
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?
The tool has an output schema, so return details are covered externally. The description provides essential context for a simple read operation. Slight deduction for not mentioning any constraints or error conditions.
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 has 0% coverage (no descriptions for parameters). The description adds meaning: char_code is implied as the currency code, and on_date is explained as an optional date with fallback behavior. This compensates well for the schema gap.
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 retrieves the official Bank of Russia exchange rate for a single currency on a given date, with fallback to latest date. It specifies returned fields (nominal, value, per-unit rate, effective quote date). Although sibling tools are present, the description is specific enough to distinguish usage.
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 explains when to use the tool (single currency, optional date) but does not provide explicit guidance on when not to use it or compare to sibling tools like history_rates or key_rate. Usage is implied but lacks alternatives or exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
history_ratesA
Get the official CBR exchange-rate series for a single currency between two dates inclusive. Range capped at 366 days; for longer windows call repeatedly.
| Name | Required | Description | Default |
|---|---|---|---|
| date_to | Yes | ||
| char_code | Yes | ||
| date_from | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | |
| points | Yes | |
| source | No | |
| date_to | Yes | |
| nominal | Yes | |
| char_code | Yes | |
| date_from | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the date range limit and the need for repeated calls for longer ranges. However, it does not describe the return format (though an output schema exists), potential errors, or whether the data is read-only. The mutation status is implied as read because it is a GET-like operation.
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 purpose and then immediately adding the critical constraint. Every word serves a purpose, no redundancy or 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?
The tool has 3 required parameters, no parameter descriptions, no annotations, and an output schema exists but is not referenced. The description covers the core purpose and a key limitation, but omits parameter semantics and return value context. It is adequate but feels incomplete for a new user.
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 0%, so the description must compensate. It only mentions 'single currency', hinting that char_code is a currency code, but provides no format or examples. It offers no additional meaning for date_from and date_to beyond what schema names imply (start and end dates).
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 exactly what the tool does with a specific verb ('Get'), resource ('exchange-rate series'), and scope ('official CBR', 'single currency', 'between two dates inclusive'). It clearly distinguishes from siblings like 'get_rate' (likely for a single rate) by emphasizing a series of rates over a date range.
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 explicitly mentions the 366-day cap and instructs to call repeatedly for longer windows. This provides clear when-to-use and when-not-to-use guidance. However, it does not explicitly mention alternatives or compare to sibling tools, such as suggesting 'get_rate' for a single day.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inflationA
Get monthly year-over-year consumer price index (CPI) inflation as published by CBR for the given year range (defaults to the previous and current year).
| Name | Required | Description | Default |
|---|---|---|---|
| year_to | No | ||
| year_from | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | Optional caveat (for example, when data is bundled rather than live-fetched). |
| points | Yes | |
| source | No | |
| year_to | Yes | |
| year_from | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description must cover behavior. It mentions data source and time range behavior but does not disclose any limitations, rate limits, or response details. Adequate for a simple retrieval.
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?
Single sentence of 22 words, front-loaded with action, no unnecessary words.
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 presence of output schema and simple parameters, the description covers source, metric, time range defaults. Could mention return format but not required with output schema.
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 0% and parameters are not individually described, but the description implies year_from and year_to define the range with defaults. Adds meaning beyond schema names.
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?
Clearly states the verb 'Get', the resource 'monthly year-over-year CPI inflation', the source 'CBR', and the time range. Distinct from sibling tools like get_rate or key_rate.
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?
Specifies the use case (year range, defaults to previous and current year). Does not explicitly exclude other scenarios or mention alternatives, but context implies use for inflation data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
key_rateA
Get the CBR key-rate (ставка рефинансирования) time series for the requested range. Defaults to the most recent 30 days.
| Name | Required | Description | Default |
|---|---|---|---|
| date_to | No | ||
| date_from | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| points | Yes | |
| source | No | |
| date_to | Yes | |
| date_from | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries the full burden. It implies a read operation ('Get') and time series data, but lacks details on data freshness, time zone, pagination, or whether the operation is safe. The description is not misleading but is minimal.
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 sentences, no redundant information. Front-loaded with the main action and defaults. Every word adds value.
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?
With an output schema present, return values are covered. The description explains the resource (CBR key-rate time series) and default range, but omits time zone, frequency, and any edge cases. Adequate for a simple tool but not fully 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 description coverage is 0%, so the description must compensate. It explains that parameters define the 'requested range' and notes a default of 30 days, adding some meaning beyond the schema. However, it does not clarify date format, optionality, or parameter semantics beyond this.
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 verb 'Get', the resource 'CBR key-rate time series', and the scope 'for the requested range' with a default of 'most recent 30 days'. This specificity distinguishes it from sibling tools like 'get_rate' (likely a single value) and 'history_rates' (broader).
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?
No explicit guidance on when to use this tool versus alternatives like 'get_rate' or 'inflation'. The description only states default behavior (30 days) but does not specify prerequisites, scenarios, or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
statisticsA
Get a compact macro snapshot: latest key rate, USD/EUR/CNY rates, latest YoY inflation, and the period the inflation refers to.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| as_of | Yes | |
| source | No | |
| cny_rate | No | |
| eur_rate | No | |
| usd_rate | No | |
| key_rate_pct | No | |
| inflation_period | No | ISO 'YYYY-MM' string of the inflation observation included in the snapshot. |
| inflation_yoy_pct | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description must carry full burden. It discloses what data is returned, but not behavioral traits like freshness, rate limits, or error handling. For a simple read tool, this is acceptable but not thorough.
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?
Single sentence that is direct and informative. No unnecessary words or repetition.
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 no parameters and a presumably descriptive output schema, the description covers the key output items. However, it could mention the structure or format briefly, but not required.
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?
Input schema is empty (0 parameters), so schema coverage is 100%. Baseline for 0 parameters is 4. Description adds no parameter info but focuses on output, which 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 clearly states the tool provides a 'compact macro snapshot' listing specific indicators (key rate, USD/EUR/CNY rates, YoY inflation, period). It distinguishes from siblings like 'get_rate' (singular) or 'inflation' (singular) by being a composite.
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?
No explicit guidance on when to use this tool versus alternatives, e.g., for a broader overview vs. specific indicators. Usage is implied by the composite nature, but lacks when-not or alternative names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool has a distinct purpose: getting a single rate, a historical series, inflation data, key rate, or a macro snapshot. There is no overlap or ambiguity.
Names use consistent snake_case and are clear, but not all follow verb_noun pattern (e.g., 'history_rates' and 'inflation' are nouns). Minor deviation but predictable.
Five tools appropriately cover the domain of Russian exchange rates and economic statistics without being too few or too many.
The tool set covers core operations: single rate, historical series, inflation, key rate, and a macro snapshot. No obvious gaps for its stated purpose.
Maintenance
Related MCP Connectors
Public Data Ukraine Mcp connects AI agents to real public APIs via MCP. Tools include
Live & historical FX rates and currency conversion for AI agents. No API keys.
Package intelligence MCP for AI agents — 22 tools, 19 ecosystems, AGPL SDK, free.
Macroeconomic and FX time-series data for AI agents: indicators, calendars, COT, forex, commodities.
Related MCP Servers
- AlicenseAqualityCmaintenanceEuropean financial data for AI agents — ECB interest rates, Eurostat inflation, GDP and unemployment by country. Zero API key needed.6741MIT
- AlicenseAqualityDmaintenanceozon-mcp is a knowledge-rich MCP server that turns the entire Ozon seller toolkit into 15 high-leverage tools. AI agents (Claude, Cursor, Cline, Continue, Goose, Zed, …) can search the API in Russian or English, drill into any of 466 methods with a fully-resolved JSON Schema, and execute calls with built-in safety guards. Subscription- aware, automatic pagination over all 4 cursor styles, retry/ba1520MIT
- AlicenseAqualityBmaintenanceMCP server for verifying Russian counterparties (legal entities and individual entrepreneurs) via public Federal Tax Service data: EGRUL/EGRIP, bankruptcy registry (EFRSB), Transparent Business, bailiff service (FSSP), and arbitration courts (KAD).815MIT
- FlicenseNot gradedqualityCmaintenanceRussian-market marketing & ops MCP toolkit. 7 unified servers for Yandex.Direct, Yandex.Webmaster, Google Search Console (RU), YouTube Data API, VK Wall, Telegram publishing, and Click.ru (Telegram Ads + VK Ads + Yandex.Direct unified). The only complete RU-platform bundle for AI agents.2-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/atomno-mcp/mcp-cbr-rates'
If you have feedback or need assistance with the MCP directory API, please join our Discord server