Skip to main content
Glama
vasilyevstan

nordpool-ee-mcp

by vasilyevstan

Home automation

Nine independent local stdio MCP servers for electricity data, household costs, and explicitly selected device controls, plus integration with Home Assistant's native HTTP MCP server. The local servers share one installable Python distribution, not a hosted service or a background automation daemon.

Repository: https://github.com/vasilyevstan/home_automation

MCP folders

Each folder contains its implementation, a README.md with setup/tool documentation, and an AGENTS.md with maintenance and safety guidance.

MCP registration

Folder and README

Purpose

Optional runtime extra

electro

electricity_market

Published Estonia prices, standalone CLI, and separate experimental forecast

None

elering-kodala-consumption

household_consumption

Authorized household grid import/export

None

electrisity-price

electricity_pricing

Effective-dated costs, bills, and incremental scenarios

None

sensibo-mcp

sensibo

Enrolled Sensibo Sky climate devices

None

tp-tapo-mcp

tapo

Local MAC-addressed sockets and measurements

tapo

starlink-mcp

starlink

Local dish telemetry and opt-in controls

starlink

sonos-mcp

sonos

Local speakers, playback, groups, and queues

sonos

govee-mcp

govee

LAN-enabled lights

None

terrace-heater-mcp

terrace_heater

Privately provisioned direct-LAN heater

heater

home-assistant (native remote)

home_assistant

Direct HA device integrations and SDK-free household price sensors

Runs in HA; no extra MCP gateway

The heater's one-time provisioning utility additionally uses heater-setup. Tests and synthetic examples remain in the shared tests/ and examples/ directories. The pricing server reuses the market and household clients directly rather than launching other MCP processes.

The HA pricing integration bundles the same pure financial engine without its MCP dependencies. It calculates inside HA; it does not call the pricing MCP or require the checkout/CLI to stay running. See its guide for installation, private profiles, scoped MCP access, and direct-device handover.

The distribution name estonia-nordpool-prices, all existing console commands, MCP registration names, and tool names are retained for compatibility. Root-level Python files are small compatibility entry points: imports such as electricity_pricing and nordpool_ee still refer to the real implementation modules, including their state and exception classes. Put implementation changes in the relevant home_automation/ folder, not those compatibility files.

Related MCP server: Steddion Energy MCP Server

Requirements

  • Python 3.10 or newer

  • Python 3.11 or newer and the optional tapo extra for tp-tapo-mcp only

  • The optional starlink extra and a trusted LAN route to the dish for starlink-mcp

  • The optional sonos extra and trusted LAN access to Sonos speakers for sonos-mcp; no Sonos cloud credentials are required

  • Trusted LAN access to supported Govee devices with LAN Control enabled in Govee Home for govee-mcp; no Govee cloud credentials are required

  • The optional heater extra and verified private provisioning for the heater

  • Internet access to dashboard.elering.ee for published electricity prices

  • Internet access to wattcast.eu for the optional forecast tool (no API key)

  • Elering customer API credentials and access to estfeed.elering.ee and kc.elering.ee for household consumption and automatic household pricing; pricing supplied readings or individual quantities needs no household credentials

  • Sensibo cloud access and explicit enrollment for sensibo-mcp

  • uv

Setup

Clone the repository and install its locked dependencies:

git clone https://github.com/vasilyevstan/home_automation.git
cd home_automation
uv sync --locked --inexact

Run checkout commands from this repository root. Choose the optional extra listed for the MCP you need; for example:

uv run --locked --extra tapo --inexact tp-tapo-mcp

The standalone electricity-price CLI is still uv run nordpool-ee. Each MCP README includes its own launch and registration instructions. --inexact preserves other extras already installed in a shared development environment. Persistent installations should use a published Git commit or their own non-editable environment outside the checkout.

Keep credentials, real tariffs, household readings, device inventories, and invoice or device captures outside the public repository. GitHub publishes the generic code; repository secrets do not make a local MCP a hosted service.

Repository and local-folder rename

The GitHub repository is vasilyevstan/home_automation. An existing checkout may still be named electro; its directory name is not part of the MCP API. The remote can be updated without moving the checkout:

git remote set-url origin https://github.com/vasilyevstan/home_automation.git

For registrations that must survive a later checkout rename, use a Git-commit-pinned uvx --from launch or a non-editable installation in a separate persistent environment. Do not point those registrations at uv run --directory /path/to/the/checkout. Preserve their tool allowlists and private environment settings when updating the executable source.

After moving a development checkout, run uv sync --locked --inexact from its new root to refresh the editable installation and generated entry points. Keep any needed --extra selections. Independently installed MCPs do not need the checkout to be present.

Existing ~/.config/electro/, ~/.local/share/electro/, environment variable names, and Keychain services are intentionally unchanged. Do not move private configuration or re-provision devices merely because the repository was renamed.

Validation

Run the deterministic test suite without live network access:

uv run --locked --inexact python -m unittest discover -s tests -v

Check syntax:

uv run --locked --inexact python -m compileall -q home_automation *.py

Run the CLI for a live next-day source check:

uv run nordpool-ee

The deterministic suite also covers forecast schema/transport/cache errors, quantile and VAT arithmetic, partial/stale data, missing accuracy, DST windows, and MCP text/structured output agreement. Live integration checks must compare the same forecast issuance, distinguish published from predicted hours, and report actual coverage and freshness. Faithful reproduction of provider metrics does not independently validate future predictive accuracy.

Household tests cover credential loading and redaction, OAuth expiry/retries, rate limits, private upstream errors, date/DST boundaries, null-versus-zero readings, independent import/export completeness and MCP output. Live checks should compare the same authorized meter/date window and resolution to the source, without publishing private response data or claiming independent verification of the physical meter.

Pricing tests cover synthetic profile validation, interval weighting, raw/net flows, holiday/time-band and DST boundaries, negative prices, source status, rounding stages/ties, fixed-fee identity, daily allocations, annual/monthly composition, bounded market batches and both MCP input modes. Real invoice replays belong outside the public repository and CI logs.

Run the optional Tapo tests, and then the complete suite with the extra:

uv run --locked --extra tapo python -m unittest discover -s tests -p 'test_tapo*.py' -v
uv run --locked --extra tapo python -m unittest discover -s tests -v

Tapo tests use synthetic identities and mocked network/relay operations. They cover IP reassignment, unsupported discovery, retained inventory, credential redaction, null versus zero, units, strict boolean commands, serialized mutations, and confirmed/uncertain read-back. Without the extra, the library-dependent tests are explicitly skipped; base startup/credential and MCP schema tests still run. Automated tests never require real Tapo or GitHub secrets and must not switch household loads.

For the complete optional-runtime suite:

uv run --locked --all-extras --inexact python -m unittest discover -s tests -v

test_package_layout.py checks packaged console commands, legacy module identity, per-MCP documentation, and lazy imports. Each MCP's maintenance file lists its focused tests. Device tests use synthetic identities and mocked controls; a repository refactor or installation check does not authorize physical switching, heating, playback, regrouping, or dish reconfiguration.

License

The source code is available under the MIT License. The license does not cover Nord Pool, Elering or Wattcast data, trademarks, or third-party content.

Available Tools

3 tools
get_estonia_current_day_pricesGet Estonia current-day electricity pricesA

Get complete current-day Nord Pool prices for Estonia.

Returns 15-minute prices and hourly averages with and without VAT, in
EUR/MWh and euro cents/kWh. Show current_hour's average and the active
current_interval separately, using Estonia-local time. Supplier margin,
network charges, excise, and other fees remain excluded.
ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
areaYes
sourceYes
summaryYes
currencyYes
timezoneYes
intervalsYes
current_hourYes
delivery_dateYes
excluded_costsYes
interval_countYes
wholesale_onlyYes
hourly_averagesYes
current_intervalYes
interval_minutesYes
vat_rate_percentYes

TDQS

A3.6/5.0
Behavior4/5

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

No annotations exist, so the description must carry the load, and it does well: it discloses the time resolution (15-minute and hourly), VAT treatment, both unit systems, Estonia-local time, and explicitly what is excluded (supplier margin, network charges, excise, other fees). It omits whether prices are final day-ahead versus provisional and any refresh/auth behavior.

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

Conciseness4/5

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

Short and front-loaded: the scope sentence leads, followed by return-shape and exclusion details. Slight redundancy between 'current_hour's average' and the hourly-averages mention, but no wasted padding.

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?

With an output schema present and zero parameters, the description need not explain return values, yet it still characterizes coverage and exclusions usefully. Complete enough to invoke correctly; only the freshness/finality of the data is unstated.

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?

The tool takes zero parameters, so there is nothing for the description to disambiguate. Baseline 4 applies; the description adds relevant framing around output shape without inventing parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specifies verb + resource + scope precisely: current-day Nord Pool prices for Estonia. The 'current-day' qualifier implicitly separates it from the 'next_day' sibling, but the description never names the alternatives, so differentiation relies on the reader inferring it from the name.

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 when-to-use, when-not-to-use, or alternative-tool guidance beyond what the name implies. With siblings like get_estonia_prices_for_hour and get_estonia_next_day_prices, the agent gets no explicit routing rule for choosing among them.

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

get_estonia_next_day_pricesGet Estonia next-day electricity pricesA

Get complete next-day Nord Pool prices for Estonia.

Returns each 15-minute interval and hourly averages in Europe/Tallinn local time, with and without VAT, in EUR/MWh and euro cents/kWh. Supplier margin, network charges, excise, and other fees remain excluded.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
areaYes
sourceYes
summaryYes
currencyYes
timezoneYes
intervalsYes
current_hourYes
delivery_dateYes
excluded_costsYes
interval_countYes
wholesale_onlyYes
hourly_averagesYes
current_intervalYes
interval_minutesYes
vat_rate_percentYes

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the full burden, and it does disclose meaningful behavioral traits: 15-minute granularity plus hourly averages, Europe/Tallinn local time, with-and-without-VAT, and dual units. It also states what is excluded (supplier margin, network charges, excise, other fees). It does not cover auth or rate limits, but for a zero-param read tool this is a strong disclosure.

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 short sentences, front-loaded with the core purpose, followed by the return-shape and exclusion caveats. Every clause adds information; nothing is padded.

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?

An output schema exists, so return values need not be re-explained, yet the description usefully summarizes granularity, timezone, VAT treatment, and units, and clarifies fees are excluded. Nothing an agent needs to call this correctly is missing.

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?

There are zero parameters, so the baseline is 4; the description correctly avoids inventing parameter semantics that do not exist.

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?

States a specific verb (Get), resource (next-day Nord Pool prices), and geographic scope (Estonia), which cleanly separates it from get_estonia_current_day_prices and get_estonia_prices_for_hour. An agent can route on the name/description alone without opening the schema.

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?

Usage is implied by the 'next-day' qualifier against the 'current day' and 'for hour' siblings, but the description never explicitly says when to pick this tool over them or adds any prerequisite/exclusion. It is adequate but leaves the routing inference to the agent.

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

get_estonia_prices_for_hourGet Estonia electricity prices for an hourA

Get Estonia prices for a specific local date and clock hour.

Args:
    delivery_date: Estonia delivery date in YYYY-MM-DD format.
    hour: Estonia local clock hour from 0 through 23.

Returns every 15-minute market interval in the requested hour plus minimum,
maximum, and average prices with and without VAT. Repeated daylight-saving
hours include two offset-distinct hourly_averages and eight intervals;
summary averages both occurrences. A skipped hour returns a tool error.
Supplier margin, network charges, excise, and other fees remain excluded.
ParametersJSON Schema
NameRequiredDescriptionDefault
hourYes
delivery_dateYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
areaYes
hourYes
sourceYes
summaryYes
currencyYes
timezoneYes
intervalsYes
delivery_dateYes
excluded_costsYes
interval_countYes
wholesale_onlyYes
hourly_averagesYes
vat_rate_percentYes

TDQS

A4/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so well: it discloses DST behavior (two offset-distinct hourly_averages, eight intervals, summary averaging both occurrences), that a skipped hour returns a tool error, and that supplier margin, network charges, excise and other fees are excluded. These are exactly the behavioral traits an agent needs before calling.

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

Conciseness4/5

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

The purpose is front-loaded, followed by an Args block and a Returns block. Given the 0% schema coverage the parameter restatement earns its place, and the DST/error sentences are dense with information rather than filler.

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 two-parameter read tool with an output schema, the description is thorough: it covers edge cases (DST, skipped hour error) and cost exclusions. Minor omissions such as authentication or rate-limit notes are not material here, and the presence of an output schema makes the return-value detail a bonus rather than a requirement.

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 0%, so the description must compensate, and it does: it specifies the YYYY-MM-DD format for delivery_date, identifies it as the Estonia delivery date, and clarifies hour is Estonia local clock time from 0 through 23. Both parameters gain meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource (get Estonia prices) with a clear scope qualifier (for a specific local date and clock hour). It is distinguishable from the siblings in intent (arbitrary date/hour vs current-day or next-day), though it never names them explicitly.

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?

"For a specific local date and clock hour" implies when to reach for this over the sibling current/next-day tools, but there is no explicit when-to-use, when-not-to-use, or alternative routing. Usage is left to inference.

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.

  1. 3 tool updatesv0.3.0
    • First observedget_estonia_current_day_prices
    • First observedget_estonia_next_day_prices
    • First observedget_estonia_prices_for_hour

TDQS

A3.9/5.0

Scored across 3 tools

Disambiguation4/5

The three tools target distinct time windows (current day, next day, specific hour), but get_estonia_prices_for_hour partially overlaps with get_estonia_current_day_prices since the current-day tool also surfaces the active interval and current-hour average. An agent can still choose correctly in most cases because each description clearly states its scope.

Naming Consistency4/5

All three follow a get_estonia_*_prices pattern in snake_case with a consistent verb, which is highly readable. The only minor deviation is the 'for_hour' prepositional suffix versus the adjective prefixes (current_day/next_day), so the shapes aren't perfectly parallel.

Tool Count4/5

Three tools is on the thin side but reasonably well-scoped for a niche single-zone price feed. Each tool earns its place by covering a distinct temporal window, so nothing feels redundant or bloated.

Completeness4/5

The surface covers the core lifecycle of price retrieval: current day, next day, and arbitrary date/hour lookups (which also enable historical queries). There's no range or multi-zone query and no 'all zones' option, but for an Estonia-focused server the essential operations are present.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server for real-time electricity prices, carbon intensity, and energy analytics across 41+ zones in Europe, Great Britain, the United States, and Australia. Query live prices, compare zones, check gas storage levels, get green scores, find optimal charging windows, and access advanced analytics. Free Basic tier requires no API key. Install via npx gridpulse-mcp or connect directly via Streamab
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables access to European electricity data including day-ahead prices, probabilistic forecasts, carbon intensity, and cheapest-window optimization for 43 bidding zones.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides real-time electricity prices, cheapest hours, and contract comparison for 40+ countries, enabling AI agents to make energy-aware decisions.
    4
    -