Skip to main content
Glama

tcmb-mcp

TypeScript Coverage License: MIT

A Model Context Protocol server that gives AI assistants (Claude, Cursor, any MCP client) the official exchange rates of the Central Bank of the Republic of Türkiye (TCMB): daily rates, historical series and currency conversion, with correct handling of weekends, holidays and the 15:30 publication time.

You: How much is 1,000 euros in lira, and how has the dollar moved this past month?

Claude (calls convert_currency and get_rate_history): At TCMB's latest forex buying rate (bulletin 2026/193, 13 October 2026), €1,000 = ₺55,112.80. Over the past month the dollar rose 1.54% against the lira, from 48.5343 on 14 September to 49.2794. That is the high of the period; the low was the starting point.

Why

LLMs don't know today's exchange rate, and when they guess, they guess confidently. The TCMB feed is public, but using it correctly takes some care:

  • Rates are published once per business day around 15:30 Istanbul time. There is no bulletin on weekends, public holidays, or before 15:30, and the archive URL simply returns 404.

  • Some currencies are quoted per 100 units (JPY), so a naive conversion is off by 100×.

  • Cash (banknote) rates don't exist for many currencies (CNY, RUB, AED, …), and SDR has no selling rate.

This server handles all of that, and always tells the model which bulletin date the numbers come from, so the assistant says "as of Friday's bulletin" instead of presenting stale data as today's.

Related MCP server: evds-mcp-server

Tools

Tool

What it does

get_exchange_rates

All ~22 currencies (or a subset) for a date or the latest bulletin

convert_currency

Any amount between TRY and foreign currencies, or cross rates (EUR→USD) via TRY

get_rate_history

Daily, weekly or monthly series with first/last, min/max (with dates), mean and % change

list_currencies

Codes, names and quoting units in the latest bulletin

Also a resource (tcmb://bulletin/latest, the raw bulletin as JSON) and a prompt (fx_briefing: "brief me on TRY vs USD over the last 30 days").

Every tool is annotated read-only and idempotent, validates its input with zod, and returns both human-readable text and structured output matching a declared outputSchema.

Real output

>>> get_rate_history {"currency":"USD","start_date":"2026-09-14","end_date":"2026-10-13"}
USD forex_buying, daily, 2026-09-14 → 2026-10-13 (22 bulletins):
first 48.5343 · last 49.2794 · change +1.54%
min 48.5343 on 2026-09-14 · max 49.2794 on 2026-10-13 · mean 48.87898

>>> get_exchange_rates {"date":"2026-10-11","currencies":["USD","EUR","GBP"]}
No TCMB bulletin exists for 2026-10-11 (weekend, public holiday, or not yet published - bulletins
appear around 15:30 Istanbul time). Showing the most recent earlier bulletin: 2026/191 of 2026-10-09.

| Code | Currency | Unit | Forex buying | Forex selling | Banknote buying | Banknote selling |
|---|---|---:|---:|---:|---:|---:|
| USD | US DOLLAR | 1 | 49.1274 | 49.2160 | 49.0931 | 49.2898 |
| EUR | EURO | 1 | 55.1112 | 55.2105 | 55.0726 | 55.2933 |
| GBP | POUND STERLING | 1 | 64.9046 | 65.2430 | 64.8592 | 65.3409 |

Install

Requires Node.js 22.12+. No API key needed; TCMB's feed is public.

Claude Code

claude mcp add tcmb -- npx -y github:omergazi34/tcmb-mcp

Claude Desktop / Cursor / other MCP hosts (claude_desktop_config.json, .cursor/mcp.json, …)

{
  "mcpServers": {
    "tcmb": {
      "command": "npx",
      "args": ["-y", "github:omergazi34/tcmb-mcp"]
    }
  }
}

From source: npm ci && npm run build, then point the host at node /path/to/tcmb-mcp/dist/index.js.

How it works

MCP host ──stdio──► server.ts  (tools · resource · prompt, zod schemas, isError on domain errors)
                       │
                       ▼
                   tcmb.ts  TcmbClient
                       ├─ onOrBefore(date): skip weekends locally, walk back over 404s (holidays)
                       ├─ LRU cache: past bulletins forever, "no bulletin" days, latest for 10 min
                       ├─ in-flight de-duplication · bounded concurrency for history
                       └─ timeout + retries (5xx / network only) ──► tcmb.gov.tr/kurlar/YYYYMM/DDMMYYYY.xml
                       │
                   bulletin.ts (XML → typed rates) · convert.ts (via TRY, ÷ unit) · history.ts (stats)

Design decisions and trade-offs are in DESIGN.md.

Development

npm ci
npm test                 # 39 tests, ~98% line coverage, no network
npm run check            # typecheck + eslint (strict, type-aware) + prettier + tests
TCMB_LIVE=1 npx vitest run test/live.test.ts   # end-to-end over stdio against the real TCMB

Unit tests run against a real bulletin saved from tcmb.gov.tr (test/fixtures/13102026.xml). A fake TCMB site serves it under any date and returns 404s, 5xx and network errors on demand. MCP behaviour is tested with the SDK's own Client over an in-memory transport. The live test runs the built server over stdio against the real feed; live.yml schedules it weekly.

Disclaimer

Not affiliated with TCMB. Rates are TCMB's published indicative rates. For legal, tax or accounting use, check the official bulletin and the rules that apply to you.

License

MIT

Available Tools

4 tools
convert_currencyConvert currency at TCMB ratesA
Read-onlyIdempotent

Convert an amount between TRY and any TCMB currency, or between two foreign currencies (cross rate via TRY). Uses the bulletin for date, or the latest one.

ParametersJSON Schema
NameRequiredDescriptionDefault
toYesISO 4217 currency code, e.g. USD, EUR, GBP, JPY. TRY is allowed for conversions.
dateNoDate as YYYY-MM-DD (Istanbul calendar).
fromYesISO 4217 currency code, e.g. USD, EUR, GBP, JPY. TRY is allowed for conversions.
amountYes
rate_typeNoWhich TCMB rate to use. forex_buying ('döviz alış') is the commonly quoted official rate.forex_buying

Output Schema

ParametersJSON Schema
NameRequiredDescription
toYes
dateYes
fromYes
rateYes
amountYes
resultYes
rate_typeYes
requested_dateYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, and idempotentHint. The description adds that cross rates are computed via TRY and that the bulletin for a given date or the latest bulletin is used, which is useful behavioral context beyond the annotations. It does not cover error handling or rate-limit behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences, with the core conversion scope front-loaded and no filler. Every clause adds relevant scope or date behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the existing output schema and annotations, the description covers the essential conversion behavior, supported currency relationships, and date default. It omits rate_type selection detail, but that is documented in the schema and not required for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 80%, with descriptions for from, to, date, and rate_type, so the baseline is 3. The description clarifies the date fallback and cross-rate mechanism but does not add meaning beyond the schema for amount or rate_type.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States 'Convert an amount between TRY and any TCMB currency, or between two foreign currencies (cross rate via TRY),' a specific verb and resource with unique cross-rate scope. This distinguishes it from the retrieval-oriented siblings get_exchange_rates, list_currencies, and get_rate_history even without naming them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Describes conversion scenarios and the date fallback ('Uses the bulletin for `date`, or the latest one'), but does not say when to choose this over get_exchange_rates or get_rate_history. Usage is implied rather than explicit, with no exclusions or named alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_exchange_ratesGet TCMB exchange ratesA
Read-onlyIdempotent

Official TCMB exchange rates (TRY per unit of foreign currency) for a date. Omit date for the latest bulletin; omit currencies for all ~22 currencies.

ParametersJSON Schema
NameRequiredDescriptionDefault
dateNoDate as YYYY-MM-DD (Istanbul calendar).
currenciesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
dateYes
ratesYes
bulletin_noYes
requested_dateYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint and idempotentHint, so the safety profile is covered. The description adds real behavioral context beyond the schema: the data is the official TCMB bulletin, and omission of parameters yields the latest bulletin / all ~22 currencies. It stops short of saying what happens for non-publication days (weekends/holidays), which is the one behavior an agent would still want.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, zero filler, with the resource and unit front-loaded before the default-behavior clause. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

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 need no explanation, and annotations cover the safety profile, so the description only needs to cover purpose, defaults, and units — which it does. The remaining gap is edge-case behavior for dates with no published bulletin.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50% (the `currencies` array itself has no top-level description). The description compensates by defining the return unit (TRY per foreign currency), the default cardinality (~22 currencies), and the meaning of an omitted `date` (latest bulletin) — meaning that the schema does not carry.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (TCMB official exchange rates) with the semantic unit defined (TRY per unit of foreign currency) and the temporal scope (for a date). It is clearly distinct from convert_currency and get_rate_history by being a single-date official-bulletin lookup, though it never names those siblings explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description tells the agent how to use the parameters (omit `date` for latest, omit `currencies` for all) but gives no guidance on when to choose this tool over get_rate_history or convert_currency. Usage is implied by the 'for a date' framing rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_rate_historyGet TCMB rate historyA
Read-onlyIdempotent

Time series of one currency's TCMB rate (TRY per 1 unit) with summary statistics: first/last, min/max with dates, mean and % change. Ranges: daily up to 93 days, weekly up to 731, monthly up to 3660.

ParametersJSON Schema
NameRequiredDescriptionDefault
currencyYesISO 4217 currency code, e.g. USD, EUR, GBP, JPY. TRY is allowed for conversions.
end_dateNoDefaults to today.
intervalNodaily
rate_typeNoWhich TCMB rate to use. forex_buying ('döviz alış') is the commonly quoted official rate.forex_buying
start_dateYesDate as YYYY-MM-DD (Istanbul calendar).

Output Schema

ParametersJSON Schema
NameRequiredDescription
statsYes
pointsYes
currencyYes
intervalYes
rate_typeYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/openWorld/idempotent, and the description adds genuinely non-obvious behavior: the returned statistics (first/last, min/max with dates, mean, % change) and the hard interval caps (93/731/3660 days) that determine whether a call will succeed. Missing: behavior on weekends/holidays and on dates outside TCMB's published range.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences: output shape first, then the constraint that governs parameter choice. No filler, nothing duplicated from the schema, and the most decision-relevant information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the description is not obliged to explain returns, yet it does so briefly and usefully. Combined with the range caps and rate-unit convention, an agent has enough to call this correctly; only edge-case behavior (holidays, out-of-range dates, TRY conversions) is left unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 80%, so the baseline is 3, and the description earns an extra point by documenting the per-interval range limits (daily 93, weekly 731, monthly 3660) that constrain the interval parameter but appear nowhere in the schema. It does not touch rate_type or end_date, which the schema already covers adequately.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Time series of one currency's TCMB rate') and clarifies the unit convention (TRY per 1 unit), which cleanly separates it from convert_currency and get_exchange_rates. It never names a sibling explicitly, but the 'history/time series' framing makes the distinction inferable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by 'time series' and by the range limits, which tell the agent when a given interval is viable. There is no explicit statement of when to prefer this over get_exchange_rates or convert_currency, and no mention of prerequisites or error behavior when a range is exceeded.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_currenciesList TCMB currenciesA
Read-onlyIdempotent

Currencies in the latest TCMB bulletin, with their quoting unit.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
dateYes
currenciesYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so safety and repeatability are covered. The description adds genuinely useful context beyond them — that results come from the 'latest TCMB bulletin' (freshness/source) and that entries carry a 'quoting unit' (interpretation caveat). It says nothing about ordering, caching or coverage of currencies, so it is additive but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight clause with no filler, and the most decision-relevant qualifier ('latest TCMB bulletin') is placed first. Nothing could be removed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters, an output schema covering return values, and annotations covering safety, the remaining burden on the description is small. It supplies the two things the structured fields do not: the source/freshness of the data and the quoting-unit caveat. A note on ordering or currency coverage would complete it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a 0-param schema is 4. The mention of quoting unit is a data-shape note rather than parameter guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource (currencies) scoped to a specific source and freshness ('latest TCMB bulletin'), plus a data-shape detail ('their quoting unit'). This separates it from get_exchange_rates and get_rate_history, though the retrieval verb is only implied by the tool name rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description is a pure noun phrase with no when-to-use, when-not-to-use, or alternative-routing guidance. An agent must infer from the name and sibling set that this is the discovery step before convert_currency; nothing in the text says so.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedconvert_currency
    • First observedget_exchange_rates
    • First observedget_rate_history
    • First observedlist_currencies

TDQS

A3.9/5.0

Scored across 4 tools

Disambiguation4/5

Each tool targets a distinct operation: fetching rates by date, listing available currencies, converting amounts, and retrieving a historical time series. The only minor overlap is between get_exchange_rates and list_currencies, since the latter returns a subset of the same bulletin data, but the descriptions clarify the distinction.

Naming Consistency5/5

All four names follow a clean verb_noun snake_case pattern (get_exchange_rates, list_currencies, convert_currency, get_rate_history). The verbs are semantically appropriate and used consistently across the set.

Tool Count5/5

Four focused tools map cleanly to the core exchange-rate use cases (current rates, currency inventory, conversion, history) with no redundancy. The count is well within the ideal range and each tool earns its place.

Completeness4/5

The surface covers the full read lifecycle for TCMB rate data: rates by date, currency listing, cross-rate conversion, and historical series with stats. Minor gaps exist, such as bulk multi-currency historical queries or date-range rate retrieval beyond the single-currency history tool, but core workflows are supported.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    F
    maintenance
    Provides access to Turkish Central Bank (TCMB) exchange rates with current and historical data since 1996, currency conversion, rate history statistics, and multi-currency comparisons with smart caching.
    6
    1
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    Enables querying Turkish economic data (inflation, FX rates, policy rates, etc.) from TCMB EVDS via curated tools, preventing LLM hallucination.
    6
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to fetch official Uzbekistan Central Bank currency rates, including current and historical rates, and perform currency conversions via MCP.
    1
    -
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI assistants to query Turkey's public data, including central-bank FX rates, earthquake catalog, weather forecasts, public holidays, and offline validation of Turkish ID, tax, and IBAN numbers, with sourced and timestamped responses.
    44
    74 npm
    1
    MIT