MCP server for Swiss electricity data: BFE Energiedashboard, ElCom tariffs, OGD consumption. No-auth, 12 tools.
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
claude mcp add swiss-electricity-mcp -- python -m swiss-electricity-mcp{
"mcpServers": {
"swiss-electricity-mcp": {
"command": "python",
"args": ["-m", "swiss-electricity-mcp"],
"env": {
"SWISS_ELECTRICITY_HOST": "<swiss_electricity_host>"
}
}
}
}SWISS_ELECTRICITY_HOSTMCP Servers overview
# swiss-electricity-mcp
> **MCP server for Swiss electricity data — three official sources, twelve tools, zero authentication.**
[](https://github.com/malkreide/swiss-electricity-mcp/actions/workflows/test.yml)
[](https://pypi.org/project/swiss-electricity-mcp/)
[](https://pypi.org/project/swiss-electricity-mcp/)
[](LICENSE)
🌍 **Read this in your language:** [🇩🇪 Deutsch](README.de.md)
Part of the **[Swiss Public Data MCP Portfolio](https://github.com/malkreide/swiss-public-data-mcp)** — 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

---
## 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 | `live_api` |
| **ElCom electricity-price cubes** (via LINDAS SPARQL) | Tariffs per municipality, category, year, with full breakdown (energy + grid usage + KEV + Abgaben) | `sparql` |
| **opendata.swiss + Stadt Zürich OGD** (CKAN) | Dataset discovery for raw time series (e.g. quarter-hour NE5/NE7 consumption) | `live_api` |
**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
```bash
pip install swiss-electricity-mcp
```
### From source
```bash
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`:
```json
{
"mcpServers": {
"swiss-electricity": {
"command": "swiss-electricity-mcp"
}
}
}
```
---
## Cloud deployment (Streamable HTTP)
```bash
SWISS_ELECTRICITY_TRANSPORT=streamable-http \
SWISS_ELECTRICITY_HOST=0.0.0.0 \
SWISS_ELECTRICITY_PORT=8000 \
swiss-electricity-mcp
```
Works 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 with `SWISS_ELECTRICITY_HOST=0.0.0.0`
> **only inside a container**, where the network boundary is the container, not
> the host. Setting `0.0.0.0` on 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.
```bash
docker build -t swiss-electricity-mcp .
docker run --rm -p 8000:8000 swiss-electricity-mcp
```
---
## Observability & configuration
| Env var | Default | Purpose |
|---|---|---|
| `SWISS_ELECTRICITY_TRANSPORT` | `stdio` | `stdio` or `streamable-http` |
| `SWISS_ELECTRICITY_HOST` | `127.0.0.1` | HTTP bind host (`0.0.0.0` in containers only) |
| `SWISS_ELECTRICITY_PORT` | `8000` | HTTP port |
| `SWISS_ELECTRICITY_LOG_LEVEL` | `INFO` | Log level (DEBUG/INFO/WARNING/ERROR) |
| `SWISS_ELECTRICITY_CORS_ORIGINS` | _(empty)_ | Comma-separated allowed CORS origins (browser clients); never `*` |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | _(unset)_ | Enables OpenTelemetry tracing when set |
| `SWISS_ELECTRICITY_ENV` | `unknown` | `deployment.environment` resource attribute for traces |
- **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:
```bash
pip install "swiss-electricity-mcp[otel]"
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 swiss-electricity-mcp
```
You 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:
1. **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.
2. **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.
3. **Domain separation from `swiss-energy-mcp`**: that server covers geo and infrastructure data (power plants, grid lines). `swiss-electricity-mcp` covers 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 of `live_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`](docs/roadmap.md). Security posture (egress,
supply-chain, lethal-trifecta assessment) is documented in
[`docs/security-posture.md`](docs/security-posture.md).
---
## Testing
```bash
# 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 -v
```
Unit tests cover the contract layers: **Happy** (response parsing), **Retry**
(5xx, 429, 4xx), **Timeout** (network errors → clean `UpWhat people ask about swiss-electricity-mcp
What is malkreide/swiss-electricity-mcp?
+
malkreide/swiss-electricity-mcp is mcp servers for the Claude AI ecosystem. MCP server for Swiss electricity data: BFE Energiedashboard, ElCom tariffs, OGD consumption. No-auth, 12 tools. It has 0 GitHub stars and was last updated today.
How do I install swiss-electricity-mcp?
+
You can install swiss-electricity-mcp by cloning the repository (https://github.com/malkreide/swiss-electricity-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is malkreide/swiss-electricity-mcp safe to use?
+
Our security agent has analyzed malkreide/swiss-electricity-mcp and assigned a Trust Score of 87/100 (tier: Trusted). See the full breakdown of passed checks and flags on this page.
Who maintains malkreide/swiss-electricity-mcp?
+
malkreide/swiss-electricity-mcp is maintained by malkreide. The last recorded GitHub activity is from today, with 0 open issues.
Are there alternatives to swiss-electricity-mcp?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy swiss-electricity-mcp to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/malkreide-swiss-electricity-mcp)<a href="https://claudewave.com/repo/malkreide-swiss-electricity-mcp"><img src="https://claudewave.com/api/badge/malkreide-swiss-electricity-mcp" alt="Featured on ClaudeWave: malkreide/swiss-electricity-mcp" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!