Skip to main content
ClaudeWave
malkreide avatar
malkreide

swiss-electricity-mcp

View on GitHub

MCP server for Swiss electricity data: BFE Energiedashboard, ElCom tariffs, OGD consumption. No-auth, 12 tools.

MCP ServersOfficial Registry0 stars0 forksPythonMITUpdated today
ClaudeWave Trust Score
87/100
Trusted
Passed
  • Open-source license (MIT)
  • Actively maintained (<30d)
  • Clear description
  • Topics declared
Last scanned: 6/11/2026
Install in Claude Code / Claude Desktop
Method: pip / Python · swiss-electricity-mcp
Claude Code CLI
claude mcp add swiss-electricity-mcp -- python -m swiss-electricity-mcp
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "swiss-electricity-mcp": {
      "command": "python",
      "args": ["-m", "swiss-electricity-mcp"],
      "env": {
        "SWISS_ELECTRICITY_HOST": "<swiss_electricity_host>"
      }
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
💡 Install first: pip install swiss-electricity-mcp
Detected environment variables
SWISS_ELECTRICITY_HOST
Use cases

MCP Servers overview

# swiss-electricity-mcp

> **MCP server for Swiss electricity data — three official sources, twelve tools, zero authentication.**

[![CI](https://github.com/malkreide/swiss-electricity-mcp/actions/workflows/test.yml/badge.svg)](https://github.com/malkreide/swiss-electricity-mcp/actions/workflows/test.yml)
[![PyPI](https://img.shields.io/pypi/v/swiss-electricity-mcp.svg)](https://pypi.org/project/swiss-electricity-mcp/)
[![Python](https://img.shields.io/pypi/pyversions/swiss-electricity-mcp.svg)](https://pypi.org/project/swiss-electricity-mcp/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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

![Demo: Claude using tariff_get_by_municipality and tariff_get_median_swiss](docs/assets/demo.svg)

---

## 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 `Up
bfeckanelcomelectricityenergylindasmcpmcp-servermodel-context-protocologdpythonsparqlsustainabilityswiss-open-dataswiss-public-data-mcpswitzerlandtariffs

What 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.

Featured on ClaudeWave: malkreide/swiss-electricity-mcp
[![Featured on ClaudeWave](https://claudewave.com/api/badge/malkreide-swiss-electricity-mcp)](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

swiss-electricity-mcp alternatives