Skip to main content
Glama
malkreide

swiss-electricity-mcp

by malkreide

swiss-electricity-mcp

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

CI PyPI Python License: MIT

🌍 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

Demo: Claude using tariff_get_by_municipality and tariff_get_median_swiss


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

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

pip install swiss-electricity-mcp

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

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:

    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. Security posture (egress, supply-chain, lethal-trifecta assessment) is documented in docs/security-posture.md.


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

initialize handshake

2024-11-052025-11-25

What today's clients speak. The server answers with the revision asked for, or with the 2025-11-25 ceiling when the request asks for something newer.

Per-request envelope

2026-07-28

A request carrying the 2026-07-28 _meta envelope opens a modern connection.

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 handshake ceiling is measured against a live initialize through the assembled ASGI stack, not read off a constant name.

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

Auditing the ruff pin across the portfolio

scripts/pin_audit.py checks whether a server's own pin guards actually hold. It is not a CI gate — it needs the sibling repositories on disk — but it is worth running whenever a pin convention changes or a new server joins:

python scripts/pin_audit.py ../*-mcp

It measures black-box: prepend an ordinary second pre-commit hook with its own rev:, run the guard, read the exit code, restore the file. Two guards in the portfolio used to report that hook's version as the ruff pin, turning CI red with a number nobody had written. A positive control (misconfigure the ruff hook's own rev) separates "correctly scoped" from "never reads the file" — without it, a guard that ignores the config looks like a clean bill of health.

Where the test data comes from

The fixtures under tests/fixtures/ are recorded from the live sources and dated. Source, retrieval date, selection rule and SHA-256 for every file: tests/fixtures/PROVENANCE.md.

python scripts/record_fixtures.py   # re-record

The requests are built by the production code. The script calls ElComSparqlClient and EnergyDashboardClient and captures the answer through an httpx transport, rather than retyping the SPARQL alongside. A fixture that answers a slightly different question than the server asks proves the wrong answer — quietly, because it looks plausible. At 40 lines of SPARQL, "slightly different" is the normal case, not the exception.

Two selection rules are deliberately more than "the first N":

  • The storage-lake series runs into the future. After the last measured day come rows with a null measurement — 94 of them on the recording day. They are kept on purpose: without them, no test could show that the tool skips them.

  • What counts as a measurement is named per file, not guessed. The first version of this used "any field other than date is non-null", which is wrong: those future rows do carry values — the five-year reference curves — just no measurement.

Where a search is trimmed, count keeps its real value: it says how much is not in the file.


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-mcp or 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"
      ]
    }
  }
}

Available Tools

12 tools
consumption_search_bfe_datasetsA
Read-only

Search opendata.swiss CKAN for energy / electricity datasets. Filter by BFE organisation. Use to find raw datasets not covered by other tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYesFree-text search
offsetNo
bfe_onlyNo
response_formatNomarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is clear. The description adds that it queries CKAN and filters by BFE organisation, providing useful behavioral context beyond the annotations.

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 sentences, front-loaded with action, no redundant information. Every word adds value.

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?

For a search tool with output schema and adequate annotations, the description provides sufficient context about the data source and purpose. Could mention response format options, but schema already provides enum.

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

Parameters2/5

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

Schema coverage is only 20% (only query has a description: 'Free-text search'). The tool description does not elaborate on the other parameters (limit, offset, bfe_only, response_format) despite low coverage, leaving gaps for the agent.

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?

Clearly states the verb (search), the resource (opendata.swiss CKAN for energy/electricity datasets), and distinguishes it from siblings by noting it covers raw datasets not handled by other tools. The mention of 'BFE organisation' adds specificity.

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

Usage Guidelines4/5

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

Explicitly says 'Use to find raw datasets not covered by other tools', which guides when to use and implies alternatives. Does not explicitly state when not to use, but the context is sufficient.

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

consumption_search_zurichA
Read-only

Search the Stadt Zuerich OGD catalogue for energy datasets, including the quarter-hour consumption time series for grid levels NE5 and NE7.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
offsetNo
response_formatNomarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, so the description adds limited behavioral context beyond confirming it is a search. The description does not elaborate on pagination, result formatting, or potential limitations, but with annotations covering the core traits, a baseline score of 3 is appropriate.

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?

The description is a single sentence that efficiently states the tool's purpose and a key example. It is front-loaded with the verb 'Search' and contains no unnecessary words.

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 presence of an output schema and annotations, the description adequately defines the search scope. It mentions the specific dataset included, which adds context. However, it could briefly note that results are paginated via limit/offset, especially given openWorldHint, but overall it is reasonably complete for the tool's complexity.

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

Parameters2/5

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

Schema description coverage is 0%, meaning parameters have no descriptions. The tool description does not explain individual parameters (query, limit, offset, response_format) beyond their implicit meaning from names and types. It adds minimal value, so a score of 2 reflects this gap.

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?

The description clearly states the tool searches the Stadt Zuerich OGD catalogue for energy datasets, specifically mentioning the quarter-hour consumption time series for grid levels NE5 and NE7. This specifies the resource and scope, and distinguishes from the sibling consumption_search_bfe_datasets which likely targets a different catalogue.

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

Usage Guidelines4/5

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

The description provides clear context for when to use the tool: when searching for energy datasets from the Zurich OGD catalogue, particularly consumption time series. It implicitly contrasts with the sibling tool by specifying the catalogue, but does not give explicit exclusions or when-not-to-use guidance.

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

dashboard_get_consumer_price_indexA
Read-only

Get the Endverbraucher-Strompreis-Index (consumer electricity price index, indexed to 2020-01-01 = 100). Monthly time series.

ParametersJSON Schema
NameRequiredDescriptionDefault
limit_monthsNo
response_formatNomarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint. Description adds that data is a monthly time series with a fixed index base, which provides context beyond annotations.

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

Conciseness3/5

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

Single sentence, but missing parameter details. Conciseness is adequate but at the expense of completeness.

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

Completeness3/5

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

Output schema exists, so return values don't need explanation. Description covers core data characteristics but omits parameter usage, which is needed for a complete understanding.

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

Parameters2/5

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

Schema coverage is 0% and description does not explain parameters (limit_months, response_format). The description adds no meaning beyond the schema; for a tool with two parameters, this is insufficient.

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?

Description clearly states the tool retrieves the Endverbraucher-Strompreis-Index with base 2020-01-01=100, a monthly time series. This verb+resource combination is distinct from siblings like dashboard_get_production_mix.

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?

No explicit guidance on when to use this tool versus alternatives. Usage is implied by the index name, but no context on exclusions or prerequisites.

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

dashboard_get_consumption_forecastB
Read-only

Get current Swiss national electricity consumption forecast: today's value, 5-day-ahead forecast, trend signal, and 5-year-window comparison series. Source: Energiedashboard.ch (BFE).

ParametersJSON Schema
NameRequiredDescriptionDefault
limit_daysNo
response_formatNomarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true. Description adds value by specifying the data source (Energiedashboard.ch) and the exact forecast types and comparison window, which clarifies the scope and nature of the output.

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 sentences, no wasted words. Key information is front-loaded: what the tool does, specific outputs, source. Highly efficient.

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

Completeness3/5

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

Given the existence of an output schema (not shown), description does not need to explain return values. However, it lacks parameter semantics and usage guidelines, making it only minimally complete for a tool with two parameters and sibling tools.

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

Parameters1/5

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

Schema coverage is 0% and description does not mention the two parameters (limit_days, response_format) or their meaning. The agent cannot infer what limit_days controls (e.g., number of historical days? forecast horizon?) and how it relates to the 5-day-ahead forecast mentioned.

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?

Description clearly states verb 'get', resource 'current Swiss national electricity consumption forecast', and lists specific output components (today's value, 5-day-ahead forecast, trend signal, 5-year-window comparison series). It distinguishes from sibling tools like dashboard_get_production_mix by specifying the domain (consumption forecast).

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?

No explicit guidance on when to use this tool vs alternatives. The sibling tools are listed but the description does not mention them or provide usage context. An agent would need to infer from names alone.

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

dashboard_get_production_mixA
Read-only

Get the Swiss electricity production mix (Kernkraft, Wasserkraft, PV, Wind ...) by year, with absolute TWh and percentage shares. Source: Energiedashboard.ch (BFE).

ParametersJSON Schema
NameRequiredDescriptionDefault
response_formatNoOutput format. 'json' for processing, 'markdown' for display.markdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

Annotations (readOnlyHint, openWorldHint) cover safety and data volatility; description adds source and data specifics, enhancing transparency beyond annotations.

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 sentences, no fluff, front-loaded with purpose and data details.

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

Completeness5/5

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

Given low complexity, single optional parameter, and presence of output schema, description is complete and sufficient.

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 100% and parameter description is already clear; description doesn't add extra meaning but is consistent.

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?

Description clearly states it retrieves Swiss electricity production mix by year with TWh and percentages, distinguishing it from sibling tools about consumption, storage, tariffs, etc.

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

Usage Guidelines4/5

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

Purpose is obvious but no explicit when/not to use or alternatives. Still clear given sibling names.

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

dashboard_get_storage_lakesA
Read-only

Get storage-lake (Speichersee) fill level for Switzerland or a region: current fill in % and GWh, 5-year envelope, full time series. Critical indicator for winter supply security.

ParametersJSON Schema
NameRequiredDescriptionDefault
regionNoRegion selector.totalCH
limit_weeksNo
response_formatNomarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already provide readOnlyHint=true and openWorldHint=true. Description adds beyond annotations by specifying the exact data returned (current fill, 5-year envelope, time series). No contradictory information. It would benefit from mentioning pagination or limits, but overall transparent.

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?

Description is two sentences, front-loaded with the main action and key details, with zero wasted words. Every part adds value.

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 that an output schema exists (context signals indicate so), description need not explain return values. It covers the tool's purpose and scope well. However, it could mention default behaviors or limitations (e.g., max limit_weeks) for completeness.

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

Parameters2/5

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

Schema description coverage is only 33% (only 'region' has a description: 'Region selector.'). Description does not explain the other parameters (limit_weeks, response_format) beyond their existence in the schema. Since coverage is low, the description should compensate but fails to do so.

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?

Description clearly states specific verb (Get) and resource (storage-lake fill levels) with scope (Switzerland or region) and data details (% and GWh, 5-year envelope, full time series). Sibling tools like dashboard_get_production_mix are distinct, so no confusion.

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

Usage Guidelines4/5

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

Description implicitly signals usage context by calling it a critical indicator for winter supply security. While it does not explicitly state when not to use or list alternatives, the siblings are clearly different data domains, so agents can infer usage easily.

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

electricity_check_statusA
Read-only

Check liveness of all four upstream sources. Returns HTTP status, latency, and an overall-healthy flag.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already provide readOnlyHint and openWorldHint. The description adds value by specifying the return fields (HTTP status, latency, overall-healthy flag). No contradictory or hidden behaviors are implied.

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 sentences, front-loaded with verb, no unnecessary words. Every sentence earns its place.

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

Completeness5/5

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

Given zero parameters and existence of output schema, the description is complete. It mentions all key output fields. No gaps are apparent.

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?

No parameters exist (0 params), and schema description coverage is 100% (vacuously). Baseline is 4, and the description does not need to add parameter info.

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?

Description clearly states the verb 'check liveness' and the specific resource 'all four upstream sources'. It unambiguously distinguishes from sibling tools which deal with production mix, consumption, tariffs, etc.

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

Usage Guidelines4/5

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

While no explicit when-to-use or alternatives are given, the purpose is so distinct among siblings that usage guidance is implicitly clear. The description could mention that this is for health-checking upstream electricity sources, but it's not necessary.

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

tariff_compare_municipalitiesA
Read-only

Compare electricity tariffs across multiple municipalities (BFS-Nrs) for one category and year. One row per (municipality, operator). Useful for procurement, benchmarking, school-network analysis.

ParametersJSON Schema
NameRequiredDescriptionDefault
periodYes
categoryYesVerbrauchskategorie (e.g. C3)
bfs_numbersYes
response_formatNomarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

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

Annotations already mark it as readOnly and openWorld. The description adds 'per municipality, operator' row structure, but no additional behavioral traits beyond what annotations cover.

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 no redundancy. Front-loaded with action and key constraints.

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

Completeness5/5

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

With output schema present, description covers all necessary context: inputs, output structure, and use cases. Complete for the tool's complexity.

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 low (25%), but description clarifies that bfs_numbers refers to municipalities, category is one category, period is a year. It adds meaningful context for the main parameters, though response_format is not explained.

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?

Clearly states the tool compares electricity tariffs across multiple municipalities by BFS numbers, category, and year. It uses specific verbs and resource, and distinguishes from sibling tools like tariff_get_by_municipality (single) and tariff_get_median_* (aggregated).

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

Usage Guidelines4/5

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

Explicitly mentions use cases: procurement, benchmarking, school-network analysis. Does not explicitly state when not to use or list alternatives, but context from siblings makes it clear.

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

tariff_get_by_municipalityA
Read-only

Get ElCom tariff observations for a Swiss municipality (BFS-Nr). Returns total rate in Rp./kWh broken down by energy, grid usage, public charges (KEV, Abgaben). Filterable by category (e.g. C3 for schools) and year range. Example: bfs_nr=261 for Zuerich, category='C3', period_from=2019.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
bfs_nrYesBFS-Gemeindenummer (e.g. 261=Zuerich)
categoryNoVerbrauchskategorie
period_toNo
period_fromNo
response_formatNomarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already indicate readOnlyHint and openWorldHint. The description adds useful behavioral context: return value breakdown and filterability. However, it omits details on data freshness, possible empty results, or pagination behavior, which would enhance transparency.

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?

The description is three sentences, each adding value: purpose, output breakdown, and filter options with example. No extraneous information; front-loaded with the core action.

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 presence of an output schema and moderate complexity, the description covers the main functional aspects and provides a practical example. It lacks guidance on optional parameters like limit and response_format, but the example compensates for typical use.

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 description coverage is only 33%, and the description compensates partially by explaining bfs_nr with an example and mentioning category and year range. However, it does not clarify limit, period_to, period_from, or response_format beyond what the schema provides.

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?

The description clearly states it retrieves ElCom tariff observations for a specific Swiss municipality, detailing the output breakdown and filter options. This distinguishes it from sibling tools like tariff_get_median_swiss or tariff_compare_municipalities that operate at different levels.

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

Usage Guidelines4/5

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

The description implies usage for obtaining detailed tariff data for a single municipality, but it does not explicitly contrast with sibling tools nor specify when not to use it. The example and filter mentions provide context but lack direct guidance on alternatives.

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

tariff_get_median_cantonA
Read-only

Get cantonal median electricity tariff. Useful to position a municipality against its canton. Pass canton name in German (e.g. 'Zuerich', 'Bern').

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cantonYesCanton name in German
categoryNo
period_toNo
period_fromNo
response_formatNomarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

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

Annotations already declare readOnlyHint and openWorldHint. The description adds the constraint that canton names must be in German, which is useful, but does not disclose additional behavioral traits beyond what annotations provide. No contradictions with annotations.

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?

The description is very concise at three sentences, with the purpose stated first, followed by usage context and a parameter hint. No fluff or redundant information.

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

Completeness2/5

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

With 6 parameters and only one partially explained, the description leaves out important details (e.g., what limit does, filtering options for category/period). The output schema exists but is not referenced. Overall, the description is too sparse for the tool's complexity.

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

Parameters2/5

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

Schema description coverage is only 17% (only canton has a description). The description adds guidance for the canton parameter (German name examples) but offers no help for the other 5 parameters (limit, category, period_from, period_to, response_format). Given low coverage, the description should compensate more.

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?

The description states the tool gets the cantonal median electricity tariff, with a specific verb and resource. It also explains its usefulness for positioning a municipality against its canton, distinguishing it from sibling tools like tariff_get_median_swiss or tariff_get_by_municipality.

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 implies usage context (positioning a municipality) but does not explicitly state when to use this tool versus alternatives like tariff_get_median_swiss. No direct comparison or exclusion criteria are provided.

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

tariff_get_median_swissA
Read-only

Get Swiss median electricity tariff (across all distribution operators) by year and category. Useful as benchmark for individual municipality tariffs.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
categoryNo
period_toNo
period_fromNo
response_formatNomarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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

Annotations already indicate readOnlyHint=true and openWorldHint=true, so the description does not need to repeat safety information. It adds behavioral context by specifying the data is aggregated across all operators and filtered by year and category. This sufficiently discloses the tool's behavior beyond the annotations.

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?

The description is two sentences, front-loading the purpose in the first sentence and usage in the second. Every sentence adds value, with no extraneous information. It is highly concise and well-structured.

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

Completeness3/5

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

The tool has 5 parameters, a read-only annotation, and an output schema. The description provides a high-level purpose but lacks details on how parameters affect results (e.g., limit controls result count) and the output format. Given the low complexity of the tool, the description is minimally complete but could be improved by explaining the remaining parameters.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate. The description mentions 'by year and category', which maps to period_from/period_to and category parameters, but it does not explain 'limit' (default 200) or 'response_format' (json/markdown). It also lacks detail on valid category values or year formatting. With 0% schema coverage, this is insufficient to fully convey parameter semantics.

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?

The description clearly states the verb 'Get', the resource 'Swiss median electricity tariff', and the scope 'across all distribution operators' with dimensions 'by year and category'. It distinguishes from sibling tools like tariff_get_by_municipality and tariff_get_median_canton by specifying it's the Swiss-wide median, useful as a benchmark.

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

Usage Guidelines4/5

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

The description explicitly states the tool is 'Useful as benchmark for individual municipality tariffs', providing clear guidance on when to use it. While it does not list alternatives or when not to use, the context from sibling tools implies that more granular queries exist. A score of 4 reflects the clear usage context given.

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

tariff_list_categoriesA
Read-only

List the standard ElCom Verbrauchskategorien (H1-H8 households, C1-C7 commercial). Use C3 for typical school buildings (~150'000 kWh/year). Static data, no upstream call.

ParametersJSON Schema
NameRequiredDescriptionDefault
response_formatNomarkdown

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior4/5

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

Annotations declare readOnlyHint=true and openWorldHint=false, and the description adds that it is 'static data, no upstream call,' which aligns. It could be more transparent about the structure of the returned list, but the output schema covers that.

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?

The description is extremely concise with three sentences, each serving a purpose: stating what it lists, giving a usage example, and noting static nature. No unnecessary words.

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?

The description covers the resource and usage guidance. Parameter semantics are lacking but the parameter is simple. The output schema exists, so return structure details are covered. Overall, it is adequate for a list-categories tool.

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

Parameters1/5

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

The single parameter 'response_format' has no description in the schema (0% coverage) and the description does not mention it at all. No additional meaning is provided beyond the enum definition.

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?

The description clearly states the verb 'List' and the resource 'standard ElCom Verbrauchskategorien (H1-H8 households, C1-C7 commercial)'. It provides concrete examples and distinguishes itself from siblings by specifying it lists categories, not tariffs or other data.

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

Usage Guidelines4/5

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

The description gives explicit usage guidance: 'Use C3 for typical school buildings (~150'000 kWh/year)' and notes it's static data with no upstream call. It lacks explicit exclusion criteria or alternatives but context from sibling names helps.

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. Dates show when Glama detected each change.

  1. 12 tool updatesv0.2.3
    • First observedconsumption_search_bfe_datasets
    • First observedconsumption_search_zurich
    • First observeddashboard_get_consumer_price_index
    • First observeddashboard_get_consumption_forecast
    • First observeddashboard_get_production_mix
    • First observeddashboard_get_storage_lakes
    • First observedelectricity_check_status
    • First observedtariff_compare_municipalities
    • First observedtariff_get_by_municipality
    • First observedtariff_get_median_canton
    • First observedtariff_get_median_swiss
    • First observedtariff_list_categories

TDQS

A4.1/5.0

Scored across 12 tools

Disambiguation5/5

Each tool has a distinct purpose: dashboard tools cover different aspects of energy data, tariff tools handle various tariff queries, consumption search tools target specific catalogs, and health check is unique. No overlapping responsibilities.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern with snake_case, using prefixes like dashboard_, tariff_, consumption_search_, and electricity_. No mixed conventions.

Tool Count5/5

12 tools is well-scoped for the Swiss electricity domain, covering production, consumption, storage, pricing, tariffs, dataset search, and system health. Each tool has a clear role.

Completeness4/5

The set covers key areas well (production mix, consumption forecast, storage, tariffs, dataset search). Minor gaps like historical consumption time series are mitigated by dataset search tools that can find additional data.

Maintenance

ActivityActive
ResponsivenessUnresponsive

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    One-call Australian energy-market plumbing via AEMO — cited, structured responses for market data and analysis, not a data broker.
    5
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    MCP server for Switzerland's national metadata catalogue, enabling AI agents to discover datasets, APIs, public services, and publishers through free-text search and structured queries.
    13
    MIT

Latest Blog Posts

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