nordpool-ee-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@nordpool-ee-mcpwhat are Estonia's electricity prices right now?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Estonia electricity prices CLI and MCP server
nordpool_ee.py is a small, dependency-free command-line tool that prints
Estonia's Nord Pool day-ahead wholesale electricity prices for the next
Europe/Tallinn calendar day. mcp_server.py exposes validated current-day
and next-day data as typed Model Context Protocol tools over stdio.
Repository: https://github.com/vasilyevstan/electro
Requirements
Python 3.10 or newer
Internet access to
dashboard.elering.ee
Related MCP server: Steddion Energy MCP Server
Setup
Clone the repository and install its locked dependencies:
git clone https://github.com/vasilyevstan/electro.git
cd electro
uv sync --lockedCLI usage
From a checkout:
uv run nordpool-eeWithout a checkout:
uvx --from "git+https://github.com/vasilyevstan/electro.git@main" nordpool-eeThe output contains every published market interval in Tallinn local time, followed by the minimum, maximum, and duration-weighted average. Each price is shown in:
EUR/MWh, the unit returned by Eleringeuro
cents/kWh, calculated asEUR/MWh / 10
These are wholesale energy prices only. VAT, electricity supplier margin, network charges, excise, and other consumer costs are not included.
Day-ahead prices are normally published during the afternoon before delivery. If tomorrow's prices are not available yet, the command reports that explicitly and exits with a non-zero status instead of showing today's or partial data.
Exit statuses:
0: complete next-day data was printed2: next-day prices have not been published3: Elering could not be reached successfully4: Elering returned invalid or incomplete data
MCP server
Start the local stdio server from a checkout:
uv run nordpool-ee-mcpOr launch it directly from GitHub:
uvx --from "git+https://github.com/vasilyevstan/electro.git@main" \
nordpool-ee-mcpIt exposes three tools:
get_estonia_current_day_prices
get_estonia_next_day_prices
get_estonia_prices_for_hourThe current-day and next-day tools take no arguments and return typed structured content containing:
the Estonia bidding area and delivery date
timezone, currency, source, and interval metadata
every complete 15-minute interval in EUR/MWh and cents/kWh, with and without VAT
minimum, maximum, and duration-weighted average prices on both VAT bases
hourly_averagesfor every elapsed hour, with offset-aware start/end timesthe applied
vat_rate_percentand excluded consumer costs
The current-day response includes current_interval, identifying the active
Estonia quarter-hour price, and current_hour, containing the full-hour average
at the time of the call. These are different prices: show both and label the
time period and VAT basis. The next-day response returns null for both fields.
get_estonia_prices_for_hour accepts:
delivery_date: an Estonia delivery date inYYYY-MM-DDformathour: an Estonia local clock hour from0through23
It returns all quarter-hour prices in that local hour plus the hourly minimum,
maximum, and average on both VAT bases. A repeated daylight-saving hour contains
eight intervals and two separate hourly_averages, distinguished by UTC offset.
Its summary averages both occurrences for compatibility. Day responses contain
23, 24, or 25 hourly averages; no missing or repeated hour is fabricated or
collapsed. Requesting a skipped hour returns a tool error.
VAT and price fields
Each interval (including summary minima/maxima and current_interval) includes
excluding_vat and including_vat, each containing eur_per_mwh and
cents_per_kwh. Summaries and hourly averages use average_excluding_vat and
average_including_vat with the same units. The MCP text response includes these
same labeled values as its structured response.
For compatibility, existing interval fields eur_per_mwh / cents_per_kwh
and summary fields average_eur_per_mwh / average_cents_per_kwh remain
VAT-exclusive. The standalone CLI also remains VAT-exclusive.
The MCP adds Estonia's standard 24% VAT to the wholesale energy component. This rate has applied since 1 July 2025 and covers the supported 15-minute price period. Source: Estonian Tax and Customs Board. Historical hourly-era and incomplete-day support is unchanged.
VAT-inclusive price = VAT-exclusive price multiplied by 1.24.
Calculations use decimal arithmetic before serialization, without rounding
individual intervals first. Negative and zero spot prices are retained.
For example, the four 23:00-hour prices on 2026-09-28 were 20.01, 8.77, 7.05, and 6.05 EUR/MWh. The hourly average is 10.47 EUR/MWh:
{
"vat_rate_percent": 24,
"average_excluding_vat": {
"eur_per_mwh": 10.47,
"cents_per_kwh": 1.047
},
"average_including_vat": {
"eur_per_mwh": 12.9828,
"cents_per_kwh": 1.29828
}
}That is approximately 1.30 cents/kWh including VAT for the full hour, not
the price for its first quarter-hour. wholesale_only still denotes the energy
component, not a final consumer tariff. excluded_costs now lists only charges
absent from both VAT bases: supplier margin, network charges, excise, and other
consumer fees.
Expected retrieval failures are returned as MCP tool errors, not successful responses containing error text.
GitHub Copilot CLI
Register the server in Copilot CLI's user-level configuration so it is available in every new session:
copilot mcp add \
--transport stdio \
--tools get_estonia_current_day_prices,get_estonia_next_day_prices,get_estonia_prices_for_hour \
electro -- \
uvx --from "git+https://github.com/vasilyevstan/electro.git@main" \
nordpool-ee-mcpFor an immutable installation, replace @main with @<commit-sha>.
The equivalent ~/.copilot/mcp-config.json entry is:
{
"mcpServers": {
"electro": {
"type": "stdio",
"command": "uvx",
"args": [
"--from",
"git+https://github.com/vasilyevstan/electro.git@main",
"nordpool-ee-mcp"
],
"tools": [
"get_estonia_current_day_prices",
"get_estonia_next_day_prices",
"get_estonia_prices_for_hour"
]
}
}
}Copilot CLI inherits PATH for local MCP servers, so uvx must be available
on PATH. The server writes only MCP protocol messages to stdout, as required
for stdio transport.
Data source
The tool queries Elering, Estonia's transmission system operator:
https://dashboard.elering.ee/api/nps/priceThe Estonia series is returned as data.ee in EUR/MWh. Elering explains that
Nord Pool day-ahead prices use 15-minute market periods from September 30,
2025:
The implementation calculates the requested day in Europe/Tallinn and does
not assume exactly 96 intervals. Daylight-saving transitions produce 92 or 100
quarter-hour intervals.
Nord Pool applies separate terms to customer-facing display and data redistribution. Publishing this source code under the MIT License does not grant rights to redistribute upstream market data. Review the applicable terms before exposing price data through a public website or API:
Validation
Run the deterministic test suite without live network access:
uv run python -m unittest discover -s tests -vCheck syntax:
uv run python -m py_compile nordpool_ee.py mcp_server.pyRun the CLI for a live next-day source check:
uv run nordpool-eeLicense
The source code is available under the MIT License. The license does not cover Nord Pool or Elering data, trademarks, or third-party content.
Available Tools
3 toolsget_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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| area | Yes | |
| source | Yes | |
| summary | Yes | |
| currency | Yes | |
| timezone | Yes | |
| intervals | Yes | |
| current_hour | Yes | |
| delivery_date | Yes | |
| excluded_costs | Yes | |
| interval_count | Yes | |
| wholesale_only | Yes | |
| hourly_averages | Yes | |
| current_interval | Yes | |
| interval_minutes | Yes | |
| vat_rate_percent | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| area | Yes | |
| source | Yes | |
| summary | Yes | |
| currency | Yes | |
| timezone | Yes | |
| intervals | Yes | |
| current_hour | Yes | |
| delivery_date | Yes | |
| excluded_costs | Yes | |
| interval_count | Yes | |
| wholesale_only | Yes | |
| hourly_averages | Yes | |
| current_interval | Yes | |
| interval_minutes | Yes | |
| vat_rate_percent | Yes |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| hour | Yes | ||
| delivery_date | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| area | Yes | |
| hour | Yes | |
| source | Yes | |
| summary | Yes | |
| currency | Yes | |
| timezone | Yes | |
| intervals | Yes | |
| delivery_date | Yes | |
| excluded_costs | Yes | |
| interval_count | Yes | |
| wholesale_only | Yes | |
| hourly_averages | Yes | |
| vat_rate_percent | Yes |
TDQS
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.
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.
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.
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.
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.
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.
3 tool updates
v0.3.0- First observed
get_estonia_current_day_prices - First observed
get_estonia_next_day_prices - First observed
get_estonia_prices_for_hour
TDQS
Scored across 3 tools
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.
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.
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.
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
Related MCP Connectors
Real-time electricity price signals for AI agents. Spot prices, cheapest hours, and contract recommendations. 31 countries across Europe and Oceania. No authentication required.
Live and historical electricity prices and demand for 25 grids; carbon intensity for GB.
Real-time electricity prices for AI agents. 40+ countries, 100+ zones. No auth required.
European day-ahead electricity prices (43 zones), accuracy-published forecasts, carbon, optimize.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceMCP 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-
- FlicenseNot gradedqualityDmaintenanceProvides tools for Dutch energy market data: day-ahead and imbalance prices, weather forecasts, and battery storage business case calculations.-

Voltcast MCP Serverofficial
AlicenseNot gradedqualityBmaintenanceEnables access to European electricity data including day-ahead prices, probabilistic forecasts, carbon intensity, and cheapest-window optimization for 43 bidding zones.MIT- FlicenseNot gradedqualityCmaintenanceProvides real-time electricity prices, cheapest hours, and contract comparison for 40+ countries, enabling AI agents to make energy-aware decisions.4-