swiss-electricity-mcp
Click on "Install 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-electricity-mcpCompare Zurich tariff C3 to Swiss median since 2019"
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.
swiss-electricity-mcp
MCP server for Swiss electricity data — three official sources, twelve tools, zero authentication.
🌍 Read this in your language: 🇩🇪 Deutsch
Part of the Swiss Public Data MCP Portfolio — a coordinated set of MCP servers for Swiss public administration.
Anchor demo query
"How have ewz electricity tariffs for a typical school building (consumption category C3, ≈150'000 kWh/a) developed since 2019, and how do they compare to the Swiss median?"
A single conversation calls tariff_get_by_municipality (bfs_nr=261, category="C3") + tariff_get_median_swiss and returns a year-by-year comparison with full provenance — ready for a Geschäftsleitung slide.
Demo
Related MCP server: aemo-mcp
What's inside
Three official Swiss data sources combined into one MCP server, each with its own dedicated tool group:
Source | What it provides | Provenance |
Energiedashboard.ch (Bundesamt für Energie) | National production mix, consumption forecast, storage-lake fill, consumer price index |
|
ElCom electricity-price cubes (via LINDAS SPARQL) | Tariffs per municipality, category, year, with full breakdown (energy + grid usage + KEV + Abgaben) |
|
opendata.swiss + Stadt Zürich OGD (CKAN) | Dataset discovery for raw time series (e.g. quarter-hour NE5/NE7 consumption) |
|
No authentication required. All endpoints are public Swiss OGD.
Tools (12)
dashboard_* — Energiedashboard.ch (BFE)
dashboard_get_production_mix— Production mix by year (TWh + %): Kernkraft, Wasserkraft, PV, Wind, thermal.dashboard_get_consumption_forecast— Current consumption forecast + 5-day outlook + 5-year envelope.dashboard_get_storage_lakes— Speichersee fill level (CH or per region: Wallis, Tessin, Graubünden, Zentral/Ost) — critical winter-supply indicator.dashboard_get_consumer_price_index— Endverbraucher-Strompreis-Index (2020-01-01 = 100).
tariff_* — ElCom (via LINDAS SPARQL)
tariff_list_categories— H1–H8 (households) and C1–C7 (commercial). C3 ≈ 150'000 kWh/a is the typical reference for school buildings.tariff_get_by_municipality— Tariffs for a BFS-Nr + category + year range, broken into energy / grid usage / KEV / Abgaben.tariff_get_median_swiss— National median benchmark.tariff_get_median_canton— Cantonal median (e.g. for Kanton Zürich).tariff_compare_municipalities— Compare up to 20 municipalities side-by-side.
consumption_* — opendata.swiss + Stadt Zürich OGD
consumption_search_bfe_datasets— CKAN search across BFE-published datasets.consumption_search_zurich— CKAN search across Stadt Zürich OGD (includes quarter-hour NE5/NE7 consumption).
Status
electricity_check_status— Liveness probe across all four upstreams (HTTP status + latency + overall-healthy flag).
Installation
From PyPI
pip install swiss-electricity-mcpFrom source
git clone https://github.com/malkreide/swiss-electricity-mcp.git
cd swiss-electricity-mcp
pip install -e ".[dev]"Use with Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"swiss-electricity": {
"command": "swiss-electricity-mcp"
}
}
}Cloud deployment (Streamable HTTP)
SWISS_ELECTRICITY_TRANSPORT=streamable-http \
SWISS_ELECTRICITY_HOST=0.0.0.0 \
SWISS_ELECTRICITY_PORT=8000 \
swiss-electricity-mcpWorks on Render.com, Railway, Fly.io.
Host binding (security). In HTTP mode the host defaults to
127.0.0.1(loopback only). Bind to all interfaces withSWISS_ELECTRICITY_HOST=0.0.0.0only inside a container, where the network boundary is the container, not the host. Setting0.0.0.0on a developer machine exposes the server to the local network (NeighborJack).
Docker
A multi-stage Dockerfile is provided. It runs as a non-root user (UID 10001)
and sets SWISS_ELECTRICITY_HOST=0.0.0.0 explicitly for the containerised case.
docker build -t swiss-electricity-mcp .
docker run --rm -p 8000:8000 swiss-electricity-mcpObservability & configuration
Env var | Default | Purpose |
|
|
|
|
| HTTP bind host ( |
|
| HTTP port |
|
| Log level (DEBUG/INFO/WARNING/ERROR) |
| (empty) | Comma-separated allowed CORS origins (browser clients); never |
| (unset) | Enables OpenTelemetry tracing when set |
|
|
|
Logging is structured JSON on stderr (stdout is reserved for the stdio JSON-RPC channel). Upstream failures are logged in full server-side but masked in client-facing responses.
Tracing is opt-in. Install the extra and point it at a collector:
pip install "swiss-electricity-mcp[otel]" OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 swiss-electricity-mcpYou get one span per tool call (
mcp.tool.<name>) plus automatic httpx child spans for each upstream request. No argument values or PII are recorded.
Architecture
┌────────────────────────── MCP client (Claude etc.) ──────────────────────────┐
│ stdio or Streamable HTTP │
└───────────────────────────────────────┬──────────────────────────────────────┘
│ 12 read-only tools (annotated)
┌────────▼─────────┐
│ FastMCP server │ egress allow-list + HTTPS gate
│ + structlog/OTel │ per-source TTL cache + retry
└───┬────────┬───┬──┘
dashboard_* │ tariff_* │ │ │ consumption_*
▼ ▼ ▼ ▼
┌───────────────────┐ ┌───────────┐ ┌──────────────┐ ┌─────────────────────┐
│ Energiedashboard │ │ LINDAS │ │ opendata.swiss│ │ data.stadt-zuerich.ch│
│ .admin.ch (BFE) │ │ SPARQL │ │ CKAN │ │ CKAN (OGD) │
└───────────────────┘ └───────────┘ └──────────────┘ └─────────────────────┘Hybrid (live API + SPARQL + CKAN discovery), no authentication. Three reasons this is the right shape:
Different latency profiles per source: Energiedashboard responds in ~200 ms (great live); LINDAS SPARQL is slower and occasionally returns 504 (longer timeout + 3 retries); CKAN is metadata-only and inherently safe.
Different update cadences: Dashboard updates intraday; ElCom tariffs update once per year; OGD datasets are stable for months. Per-source TTL caching (600 s / 3600 s) reflects this.
Domain separation from
swiss-energy-mcp: that server covers geo and infrastructure data (power plants, grid lines).swiss-electricity-mcpcovers time-series and tariffs. Both compose cleanly.
Provenance discipline
Every tool response is a Pydantic envelope carrying:
source— full attribution string (e.g. "Daten: Bundesamt für Energie (BFE)…").provenance— exactly one oflive_api/sparql/cached/weekly_dump/stale_cache_fallback.retrieved_at— ISO-8601 UTC timestamp.
This makes accidental misattribution structurally impossible.
Resilience
Retry: 3 attempts with exponential backoff (2 s / 4 s / 8 s).
5xx + 429: retried. 4xx (except 429): raised immediately (permanent client error).
In-memory TTL cache: per-source TTLs reduce upstream load and round-trip during multi-step agent workflows.
MCP primitives — why Tools only
This server intentionally exposes only Tools, not Resources or Prompts. The
data is parametric and query-driven (a municipality BFS number, a category, a
year), which maps naturally to tool calls; there is no stable, enumerable set of
documents to expose as Resources, and no curated prompt templates to ship. If a
future use case needs, say, a fixed "national production mix" document, the
read-only dashboard_* tools are the obvious Resource-migration candidates.
Project phase
Phase 1 — read-only. All 12 tools are read-only (readOnlyHint=true) with no
write or destructive operations. Phase-transition criteria and the longer-term
plan live in docs/roadmap.md. Security posture (egress,
supply-chain, lethal-trifecta assessment) is documented in
docs/security-posture.md.
Testing
# Unit tests (mocked, fast, CI default) — tests/test_unit.py + tests/test_security.py
PYTHONPATH=src pytest -m "not live" -v
# Live tests (hits real upstreams) — tests/test_live.py
PYTHONPATH=src pytest -m live -vUnit tests cover the contract layers: Happy (response parsing), Retry
(5xx, 429, 4xx), Timeout (network errors → clean UpstreamUnreachableError),
envelope/attribution invariants, plus security (egress allow-list, SPARQL
escaping, tool-definition lock). CI runs ruff + pytest -m "not live" on
Python 3.11–3.13.
MCP protocol version
This server is built on the official MCP Python SDK (mcp[cli]), pinned to
>=1.2.0,<2.0.0. The MCP protocol version is negotiated by the SDK at the
initialize handshake; the supported spec version tracks the pinned SDK
(currently MCP spec 2025-11-25).
Update policy: SDK updates arrive as weekly Dependabot PRs. A protocol-spec
bump is only adopted via an explicit SDK minor/major bump, recorded in
CHANGELOG.md, and verified against the tool-definition lock
(tool-definitions.lock.json).
Known limitations
LINDAS SPARQL 504 timeouts: the LINDAS public endpoint occasionally returns 504 under load. The 3-retry policy handles transient cases; persistent unavailability surfaces as
UpstreamUnreachableError.No historical PV/wind detail: Energiedashboard exposes only aggregated production mix at year level. For sub-yearly PV or wind, use
consumption_search_bfe_datasets.No FHIR or smart-meter data: out of scope. Future work may add a
swiss-prosumer-mcpor similar.Year coverage: ElCom tariff data starts in 2009. Energiedashboard mix starts in 2014.
Portfolio synergy
This server composes naturally with other portfolio servers:
+
swiss-energy-mcp— combine geo/asset data (power plants) with time-series and tariffs for full energy-infrastructure analysis.+
meteoswiss-mcp— correlate consumption forecasts with weather (temperature drives heating/cooling load).+
fedlex-mcp— pair tariff data with the Stromversorgungsgesetz (StromVG) for compliance/legal context.+
zh-education-mcp— Schulamt-relevant queries combining tariffs, school counts, infrastructure budgets.
Data sources & licensing
All upstream data is Open Government Data Switzerland (OGD-CH):
Energiedashboard.ch © Bundesamt für Energie BFE — Open data, free to use.
ElCom / LINDAS © Eidgenössische Elektrizitätskommission ElCom — CC BY 4.0.
opendata.swiss © Various Swiss public bodies — Mostly CC0 / CC BY 4.0.
Stadt Zürich OGD © Stadt Zürich — CC0.
This MCP server is MIT-licensed (see LICENSE). Always cite the original data source — the response envelope includes the proper attribution string automatically.
Contributing
See CONTRIBUTING.md.
Security
See SECURITY.md for the security policy and how to report a vulnerability.
License
MIT License — see LICENSE. The upstream data keeps the licences listed under Data sources & licensing above.
Author
Hayal Oezkan · github.com/malkreide
Changelog
See CHANGELOG.md.
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-electricity-mcp": {
"command": "uvx",
"args": [
"swiss-electricity-mcp"
]
}
}
}Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityCmaintenanceSwiss open data MCP server — transport, weather, geodata, companies, etc,. Zero API keys.Last updated7612122MIT
- AlicenseAqualityBmaintenanceMCP server for the Australian Energy Market Operator (AEMO) National Electricity Market. Plain-English access to 5-min dispatch prices, regional demand, interconnector flows, generation by fuel, rooftop PV.Last updated5MIT
- AlicenseAqualityAmaintenanceMCP Server for Swiss road mobility — shared vehicles, EV charging, traffic alerts, Park & Rail, and multimodal trip planning.Last updated15MIT
- Alicense-qualityDmaintenanceMCP server exposing all major Swiss official public APIs as native tools for any MCP-compatible AI agent.Last updated29MIT
Related MCP Connectors
opendata.swiss MCP — Switzerland's federal open-data portal (CKAN catalogue).
Energi Data Service (Energinet) MCP — Denmark's official open energy data.
Swiss Transport MCP — wraps Transport Open Data API (free, no auth)
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/malkreide/swiss-electricity-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server