swiss-snb-mcp
Read-only access to Swiss National Bank (SNB) public data — exchange rates, balance sheet, interest rates, banking statistics and balance of payments — for macro-financial analysis and CHF conversions.
Exchange rates: monthly CHF rates for 28 currency series (optional month-end rates) via
snb_get_exchange_rates; annual averages back to 1980 viasnb_get_annual_exchange_rates.Currency conversion: convert any amount from a foreign currency to CHF at official SNB monthly-average rates (
snb_convert_currency).SNB balance sheet: monthly gold reserves, foreign exchange investments, banknotes in circulation, sight deposits and totals (
snb_get_balance_sheet).Interest rates via generic cubes: policy rate, SARON fixing and compound rates, international money-market and central bank rates (SNB/Fed/ECB/BoE/BoJ), monetary aggregates M1/M2/M3 — through
snb_get_cube_dataandsnb_get_cube_metadata.Banking statistics: balance sheets by bank group (assets/liabilities, annual or monthly) with
snb_get_banking_balance_sheet, and income statements withsnb_get_banking_income.Balance of payments: current/capital/financial account overview and international investment position, quarterly (
snb_get_balance_of_payments).Generic discovery: inspect dimensions and last-update dates of any Cube-API or Warehouse cube before querying (
snb_get_cube_metadata,snb_get_warehouse_metadata,snb_get_warehouse_data).Catalog resources (currencies, balance-sheet positions, cube IDs, warehouse cubes, bank groups) help discover valid IDs; the server is read-only, needs no authentication, and supports de/en/fr labels.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@swiss-snb-mcp What is the current EUR/CHF exchange rate?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
🇨🇭 Part of the Swiss Public Data MCP Portfolio
🏦 swiss-snb-mcp
MCP server for the Swiss National Bank (SNB) data portal — exchange rates, balance sheet, interest rates, SARON, monetary aggregates, banking statistics, and balance of payments.
Overview
swiss-snb-mcp connects AI models to the official Swiss National Bank data portal at data.snb.ch via the Model Context Protocol (MCP). It provides structured access to SNB's public REST API — no authentication required.
The server covers three tiers of datasets, all confirmed against the live API:
Phase 1 — Dedicated tools:
Exchange rates (monthly averages, month-end rates, annual averages) for the 28 currency series
devkumpublishes against CHF — including two USD forward rates, which are labelled as suchSNB balance sheet (Bilanz): gold reserves, foreign exchange investments, banknotes in circulation, sight deposits, and totals
Phase 2 — Via generic cube tools (snb_get_cube_data + snb_get_cube_metadata):
SNB policy rate (Leitzins) and SARON daily fixing, emergency facility rate, sight deposit rates
SARON compound rates: Overnight, 1M, 3M, 6M
International money market rates: SARON (CH), SOFR (USA), TONA (JP), SONIA (UK), €STR/EURIBOR (EZ)
Official central bank rates: SNB, Fed, ECB, Bank of England, Bank of Japan
Monetary aggregates M1, M2, M3: stock levels and year-on-year changes
Phase 3 — Warehouse API (banking statistics) and balance of payments:
Banking balance sheets (BSTA BIL): total assets and liabilities by bank group — annual and monthly
Banking income statements (BSTA EFR): operating income, expenses, taxes by bank group — annual
Balance of payments: current account, capital account, financial account (quarterly)
International investment position: components by investment type (quarterly)
Generic warehouse access: raw access to any SNB Warehouse cube by ID
Anchor demo query: "What was the EUR/CHF exchange rate during the 2015 Franc shock, and where does the SNB policy rate stand today compared to the Fed and ECB?"
Related MCP server: swiss-statistics-mcp
Features
💱 Exchange rates — monthly CHF rates for EUR, USD, JPY, GBP, CNY and 23 more series
📅 Annual averages — year-by-year rates from 1980 onwards
🏛️ SNB balance sheet — gold, foreign exchange investments, banknotes, sight deposits (monthly)
🔄 Currency conversion — convert any amount to CHF using official SNB rates
📈 Policy rate & SARON — daily fixing, Leitzins, compound rates (1M/3M/6M)
🌍 International rate comparison — SNB, Fed, ECB, Bank of England, Bank of Japan side by side
💰 Monetary aggregates — M1, M2, M3 stock levels and year-on-year growth
🏦 Banking statistics — balance sheets and income statements by bank group (12 groups)
📊 Balance of payments — current account, IIP, and international investment position
🔍 Generic cube access — query any SNB data cube or Warehouse cube by ID
🔓 No authentication required — fully public SNB data portal
Prerequisites
Python 3.11+
uvorpipMCP-compatible client (Claude Desktop, Claude Code, or any MCP host)
Installation
Via uvx (recommended — no permanent installation needed):
uvx swiss-snb-mcpVia pip:
pip install swiss-snb-mcpFrom source:
git clone https://github.com/malkreide/swiss-snb-mcp.git
cd swiss-snb-mcp
pip install -e .Usage / Quickstart
Claude Desktop — add to claude_desktop_config.json:
{
"mcpServers": {
"swiss-snb-mcp": {
"command": "uvx",
"args": ["swiss-snb-mcp"]
}
}
}Config file locations:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Try it immediately in Claude Desktop:
"What is the current EUR/CHF exchange rate according to the SNB?" "Show me the SNB balance sheet for the last 12 months — gold and foreign reserves."
Configuration
No API key or authentication required. The SNB data portal is fully public.
Optional environment variable:
Variable | Default | Description |
|
| HTTP request timeout in seconds |
Available Tools
Phase 1 — Dedicated Tools
Tool | Description |
| Monthly CHF rates for EUR, USD, JPY, GBP, CNY and 22 more currencies |
| Annual average rates, data from 1980 |
| SNB Bilanz positions in millions CHF (monthly) |
| Convert any amount to CHF using official SNB rates |
Phase 2 — Generic Cube Tools
Tool | Description |
| Generic access to any SNB cube by ID |
| Inspect dimensions and filter values of any cube |
Phase 3 — Warehouse API (Banking Statistics) and Balance of Payments
Tool | Description |
| Banking balance sheets by bank group (monthly/annual, assets/liabilities) |
| Banking income statements by bank group (annual) |
| Balance of payments and international investment position (quarterly) |
| Generic access to any SNB Warehouse cube by ID |
| Inspect dimensions and last update of a Warehouse cube |
Resources (static catalogs)
Discovery aids served as MCP resources rather than tools so they don't crowd the tool manifest:
URI | Description |
| All 28 currency IDs with labels and units |
| Asset and liability position IDs |
| All verified Cube-API IDs (Phase 1–2) + discovery guide |
| Available Warehouse cube IDs (BSTA) |
| All 12 bank group IDs with labels |
Example Use Cases
Query | Tool |
"What is the current EUR/CHF rate?" |
|
"Convert CHF 10,000 to USD" |
|
"Show SNB gold reserves over the last year" |
|
"What is the current SNB policy rate?" |
|
"How do SNB, Fed and ECB rates compare?" |
|
"What is the SARON 3M compound rate?" |
|
"How fast is M3 money supply growing?" |
|
"Total assets of all Swiss banks?" |
|
"Income statement of cantonal banks?" |
|
"Switzerland's balance of payments?" |
|
"Which cubes are available?" | resource |
→ More use cases by audience →
Safety & Limits
Aspect | Details |
Access | Read-only ( |
Personal data | No personal data — all sources are aggregated, public macroeconomic statistics |
Rate limits | SNB Warehouse API has WAF protection (HTTP 503 after ~100 rapid requests); the server retries automatically with exponential backoff (max 3 retries, delays 2/4/8s) |
Timeout | 15 seconds per API call |
Authentication | No API keys required — both APIs ( |
Data source | |
Terms of Service | Subject to SNB's Terms of Use and Copyright; data is free for non-commercial use with source attribution |
Architecture
┌─────────────────┐ ┌───────────────────────────┐ ┌──────────────────────┐
│ Claude / AI │────▶│ Swiss SNB MCP │────▶│ data.snb.ch │
│ (MCP Host) │◀────│ (MCP Server) │◀────│ │
└─────────────────┘ │ │ │ /api/cube/ (JSON) │
│ 11 Tools · 5 Resources │ │ /api/warehouse/ │
│ Stdio | SSE │ │ Public · No Auth │
│ │ │ │
│ Phase 1: dedicated tools │ │ Exchange rates │
│ Phase 2: generic cubes │ │ Balance sheet │
│ Phase 3: warehouse + │ │ Interest rates │
│ banking stats │ │ Banking statistics │
└───────────────────────────┘ │ Balance of payments │
└──────────────────────┘Cube Discovery Pattern
The SNB API follows a consistent cube-based structure. Read the data://snb/cubes resource to explore verified cube IDs, then snb_get_cube_metadata to inspect dimensions before querying with snb_get_cube_data. Phase 3 adds the Warehouse API (/api/warehouse/cube/) for granular banking statistics — start from the data://snb/warehouse-cubes and data://snb/bank-groups resources.
Project Structure
swiss-snb-mcp/
├── src/
│ └── swiss_snb_mcp/
│ ├── __init__.py
│ ├── server.py # Core tools and FastMCP server (Phase 1–2 + BoP)
│ └── warehouse.py # Warehouse API tools (Phase 3: banking statistics)
├── scripts/
│ └── record_fixtures.py # records tests/fixtures/* from data.snb.ch
├── tests/
│ ├── fixtures/ # recorded responses + PROVENANCE.md (date, rule, SHA-256)
│ ├── fixture_data.py # loader — a missing name is an error, not an empty dict
│ ├── test_unit.py # respx-mocked unit tests (run in CI)
│ ├── test_live_scenarios.py # 20 live scenarios for Phase 1–2 (nightly)
│ └── test_live_warehouse.py # 20 live scenarios for Phase 3 (nightly)
├── pyproject.toml # Build configuration (hatchling)
├── CHANGELOG.md
├── CONTRIBUTING.md # Contribution guidelines (English)
├── CONTRIBUTING.de.md # German version
├── SECURITY.md # Security policy & posture (English)
├── SECURITY.de.md # German version
├── LICENSE
├── README.md # This file (English)
└── README.de.md # German versionKnown Limitations
Exchange rates: Monthly averages only — no intraday or daily rates available via this API
Balance sheet: Monthly data; some positions may have a publication lag of 1–2 months
Cube access: Cube IDs are not officially documented by the SNB — read the
data://snb/cubesresource for verified IDsHistorical depth: Coverage varies by series; exchange rates go back to 1980, some interest rate series start later
No forecasts: All data is historical/realised — SNB does not publish forecasts via this API
MCP Protocol Version
This server speaks two protocol eras over the same endpoint. The client's first request on a connection decides which one applies; a later claim from the other era is refused.
Era | Revision | Who reaches it |
|
| What today's clients speak. The server answers with the revision asked for, or with the |
Per-request envelope |
| A request carrying the |
Both revisions are pinned in
tests/test_protocol_version.py and asserted
against the installed SDK, so a Dependabot bump of mcp cannot move either one
silently.
The table above is measured, not inferred. The same gate drives the
server's real serving loop over an in-memory stream pair — the loop stdio runs
in production — and sends actual JSON-RPC frames through it: an enveloped
request is served at 2026-07-28, an initialize asking for 2026-07-28 is
answered 2025-11-25, and a claim from the other era is refused on an
already-decided connection (-32022 one way, -32600 the other). An earlier
revision of this section claimed the measurement needed an ASGI app; it does
not — the modern era has no initialize, and the handshake never rode on HTTP
to begin with.
What the server reports about itself is measured the same way, in
tests/test_server_identity.py: the package
version and the project URL are read back off the wire, not off the
constructor.
Note that the SDK's LATEST_PROTOCOL_VERSION is an alias for the modern
era, not for the handshake era — pinning against it alone would leave the era
that current clients actually negotiate free to drift.
Update policy. When the gate fails, do not edit the constant blindly: read
the spec changelog between the two revisions, verify the server still behaves,
then move the constant, this section, README.de.md and
CHANGELOG.md together.
Testing
# Unit tests (no API key required)
PYTHONPATH=src pytest tests/ -m "not live"
# Integration tests (live SNB API)
PYTHONPATH=src pytest tests/ -m "live"
# Re-record the fixtures from data.snb.ch (writes tests/fixtures/PROVENANCE.md)
python scripts/record_fixtures.pyThe unit-test payloads are recorded, not invented. Source, retrieval date,
selection rule and SHA-256 per file are in
tests/fixtures/PROVENANCE.md. A hand-written
mock encodes its author's assumption and can therefore never refute it —
production code and fixture come from the same head, so where both are wrong,
both are wrong together and the suite stays green. Each file keeps every
series and only shortens the value lists: the code reasons about the
dimensions and merely displays the values, so cutting "the first N series"
would have hidden exactly what three of the findings depended on.
Changelog
See CHANGELOG.md
Contributing
See CONTRIBUTING.md for guidelines on reporting issues, suggesting new SNB cube IDs, and contributing code.
Security
This server is read-only, processes no personal data, and talks only to data.snb.ch. See SECURITY.md for the full security posture, audit results, and how to report a vulnerability.
License
MIT License — see LICENSE
Author
Hayal Oezkan · github.com/malkreide
Credits & Related Projects
Data: Swiss National Bank — SNB data portal (public REST API)
Protocol: Model Context Protocol — Anthropic / Linux Foundation
Related: zurich-opendata-mcp — MCP server for Zurich city open data
Related: swiss-transport-mcp — Swiss public transport MCP server
Portfolio: Swiss Public Data MCP Portfolio
Installation
Run via uv's uvx — no clone or manual install needed. Add to your MCP client config (mcpServers for Claude Desktop, Cursor and Windsurf; use a top-level servers key for VS Code in .vscode/mcp.json):
{
"mcpServers": {
"swiss-snb-mcp": {
"command": "uvx",
"args": [
"swiss-snb-mcp"
]
}
}
}Available Tools
11 toolssnb_convert_currencyARead-onlyIdempotent
Convert a foreign currency amount to CHF using official SNB exchange rates.
Uses the monthly average rate (Monatsmittel) from the SNB data portal. Suitable for budget calculations, cost estimations, and financial planning.
Args: params (ConvertCurrencyInput): - amount: Amount in foreign currency to convert. - currency_id: SNB currency ID (e.g. 'EUR1', 'USD1', 'JPY100'). - reference_month: Month YYYY-MM for the rate. Default: most recent.
Returns: str: CHF equivalent, exchange rate used, and reference date.
Example: amount=45000, currency_id='USD1' → CHF equivalent of USD 45,000 amount=100, currency_id='JPY100' → CHF equivalent of JPY 100
Inputs: params (required). Returns: result
snb_get_annual_exchange_ratesARead-onlyIdempotent
Retrieve annual average CHF exchange rates from the SNB (cube 'devkua').
Returns yearly average exchange rates for all major currencies against CHF. Useful for multi-year trend analysis, budget planning, and financial reporting. Data goes back to 1980 for most currencies.
Args: params (AnnualExchangeRatesInput): - currencies: List of currency IDs (e.g. ['EUR1', 'USD1']). Default: all. - from_year: Start year, e.g. '2015'. Default: 5 years ago. - to_year: End year, e.g. '2025'. Default: current year. - lang: Response language. Default: de.
Returns: str: Markdown summary and JSON data with annual exchange rates.
Inputs: params (required). Returns: result
snb_get_balance_of_paymentsARead-onlyIdempotent
Retrieve balance-of-payments or international investment position data.
Categories:
overview: Zahlungsbilanz — Übersicht (cube bopoverq)
iip: Auslandvermögen — Komponenten (cube auvekomq)
Args: params (BalanceOfPaymentsInput): - category: 'overview' or 'iip'. - from_date: Start date, e.g. '2020-Q1' or '2020'. - to_date: End date. - lang: Response language (de/en/fr).
Returns: str: Markdown summary with JSON data.
Inputs: params (required). Returns: result
snb_get_balance_sheetARead-onlyIdempotent
Retrieve SNB balance sheet (Bilanz) data from the data portal (cube 'snbbipo').
Returns monthly balance sheet positions of the Swiss National Bank in millions of CHF. Covers assets (gold, foreign exchange reserves, repos) and liabilities (banknotes in circulation, sight deposits of domestic banks, government deposits).
Key positions:
GFG: Gold und Forderungen aus Goldgeschäften
D: Devisenanlagen (foreign exchange reserves — the world's largest relative to GDP)
N: Notenumlauf (banknotes in circulation)
GB: Girokonten inländischer Banken (sight deposits)
T0/T1: Total Aktiven / Total Passiven
Args: params (BalanceSheetInput): - positions: List of position IDs. Default: key positions (GFG, D, N, GB, T0, T1). - from_date: Start month YYYY-MM. Default: 24 months ago. - to_date: End month YYYY-MM. Default: latest available. - lang: Response language. Default: de.
Returns: str: Markdown summary and JSON data in millions CHF.
Inputs: params (required). Returns: result
snb_get_banking_balance_sheetARead-onlyIdempotent
Retrieve banking balance sheet data from SNB Warehouse (BSTA BIL cubes).
Returns total assets and/or liabilities for selected bank groups from the Swiss banking statistics. Values are converted to millions of CHF.
Args: params (BankingBalanceSheetInput): - side: 'assets', 'liabilities', or 'both'. - bank_groups: Bank group IDs (default: ['A30'] = all banks). - frequency: 'annual' or 'monthly'. - currency: Currency filter (default: 'T' = Total). - from_date / to_date: Date range. - lang: Response language.
Returns: str: Markdown summary with values in Millionen CHF, plus JSON data.
Inputs: params (required). Returns: result
snb_get_banking_incomeARead-onlyIdempotent
Retrieve banking income statement data from SNB Warehouse (BSTA EFR cubes).
Returns key income statement positions (Geschäftsertrag, Geschäftsaufwand, etc.) for selected bank groups. Values are converted to millions of CHF.
Args: params (BankingIncomeInput): - bank_groups: Bank group IDs (default: ['A30'] = all banks). - from_year / to_year: Year range (YYYY). - lang: Response language.
Returns: str: Markdown summary with values in Millionen CHF, plus JSON data.
Inputs: params (required). Returns: result
snb_get_cube_dataARead-onlyIdempotent
Retrieve raw data from any SNB data cube by ID.
Generic tool for accessing SNB cubes beyond the dedicated tools. Use snb_get_cube_metadata first to understand the cube structure. Browse https://data.snb.ch to discover cube IDs from the URL pattern: data.snb.ch/de/topics/{topic}/cube/{cubeId}
Args: params (CubeDataInput): - cube_id: SNB cube identifier (lowercase), e.g. 'devkum', 'snbbipo'. - from_date: Start date (YYYY-MM for monthly, YYYY for annual). - to_date: End date. - lang: Response language (de/en/fr).
Returns: str: Raw timeseries data from the cube as JSON.
Inputs: params (required). Returns: result
snb_get_cube_metadataARead-onlyIdempotent
Get metadata and dimension structure for any SNB data cube.
Retrieves the cube's dimension definitions, available filter values, and structure. Use this before querying snb_get_cube_data to understand what parameters and filters are available.
Args: params (CubeMetadataInput): - cube_id: SNB cube identifier, e.g. 'devkum', 'snbbipo'. - lang: Language for labels (de/en/fr).
Returns: str: Cube ID, dimensions, and all available dimension item IDs with labels.
Inputs: params (required). Returns: result
snb_get_exchange_ratesARead-onlyIdempotent
Retrieve monthly CHF exchange rates from the Swiss National Bank (data.snb.ch).
Returns monthly average rates (and optionally month-end rates) for all major currencies against the Swiss Franc (CHF). Data source: SNB cube 'devkum'. Rates are expressed as the CHF value of the stated foreign currency unit (e.g. EUR1: 1 EUR = 0.9416 CHF; JPY100: 100 JPY = 0.58 CHF).
Args: params (ExchangeRatesInput): - currencies: List of currency IDs (e.g. ['EUR1', 'USD1']). Default: all. - from_date: Start month YYYY-MM. Default: 12 months ago. - to_date: End month YYYY-MM. Default: current month. - include_month_end: Also include month-end rates. Default: False. - lang: Response language (de/en/fr). Default: de.
Returns: str: Markdown table with dates and CHF exchange rates per currency. Includes publication date and data source metadata.
Schema: { "cube_id": "devkum", "publishing_date": "YYYY-MM-DD HH:MM", "currencies_returned": int, "timeseries": [ { "currency": str, "type": "Monatsmittel" | "Monatsende", "unit": str, "values": [{"date": "YYYY-MM", "value": float}] } ] }
Inputs: params (required). Returns: result
snb_get_warehouse_dataARead-onlyIdempotent
Retrieve raw data from any SNB Warehouse cube by ID.
Generic tool for accessing SNB Warehouse cubes (BSTA banking statistics). Use snb_get_warehouse_metadata first to understand the cube structure. Use snb_list_warehouse_cubes to discover available cube IDs.
Args: params (WarehouseDataInput): - cube_id: SNB Warehouse cube ID (uppercase, dot-separated). - from_date: Start date (YYYY for annual, YYYY-MM for monthly). - to_date: End date. - lang: Response language (de/en/fr).
Returns: str: Timeseries data from the warehouse cube as Markdown + JSON.
Inputs: params (required). Returns: result
snb_get_warehouse_metadataARead-onlyIdempotent
Get metadata and dimension structure for any SNB Warehouse cube.
Retrieves the cube's dimension definitions and last update date. Use this before querying snb_get_warehouse_data to understand what dimensions and filter values are available.
Args: params (WarehouseMetadataInput): - cube_id: SNB Warehouse cube ID to inspect. - lang: Language for labels (de/en/fr).
Returns: str: Cube ID, edition date, dimensions and their items.
Inputs: params (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 11 tools
Each tool targets a specific, distinct data type or operation: currency conversion, monthly/annual exchange rates, balance sheet, balance of payments, banking statistics, and generic cube/warehouse access. There is no overlap that would confuse an agent; even the exchange rate tools are clearly differentiated by frequency and purpose.
All tools follow the 'snb_' prefix and snake_case convention. Most are 'snb_get_' except for 'snb_convert_currency', which uses a different verb. This minor inconsistency is justified by the distinct action (conversion vs. retrieval), but it breaks the otherwise uniform pattern.
With 11 tools, the server covers the core SNB data domains (exchange rates, balance sheet, banking statistics) plus generic cube access without being overwhelming. The count is well-scoped for its purpose.
The tool set covers major SNB data categories: exchange rates, conversion, balance of payments, SNB balance sheet, banking balance sheet, and banking income. The generic cube and warehouse tools fill gaps for other SNB data. A minor gap is the lack of a dedicated tool for daily exchange rates, but monthly and annual are covered.
Maintenance
Related MCP Connectors
Live & historical FX rates and currency conversion for AI agents. No API keys.
Live & historical FX rates and currency conversion for AI agents. No API keys.
FRED macro data, Treasury yields, FX rates & macro indicators for AI agents. Pay-per-query via x402.
Utility data for AI agents: IBAN, EU holidays, VAT rates, time zones, ECB FX. Pay per call.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to query Norges Bank's open data API for exchange rates, policy rates, government securities, money market data, bank liquidity, and regional network survey data.MIT
- AlicenseAqualityBmaintenanceProvides AI-native access to Swiss Federal Statistical Office datasets through 9 tools for querying education, population, and cross-cantonal comparisons without authentication.31542 PyPI2MIT
- AlicenseAqualityBmaintenanceProvides access to macroeconomic indicators, FX rates, COT data, commodities, and release calendars through the FXMacroData API for AI agents.8MIT
- AlicenseAqualityBmaintenanceEnables AI models to access Swiss weather and climate data from MeteoSwiss, including current observations, forecasts, and warnings.633 PyPIMIT