Skip to main content
Glama
manas-katyal

EnergiMCP

by manas-katyal

EnergiMCP

Read-only MCP server for Danish energy data: electricity prices, carbon intensity, consumption, production, grid capacity, balancing markets and gas — the 100 datasets Energinet publishes through Energi Data Service.

No API key, no account, no registration. It is open public data.

You   When should I run the dishwasher today?
      → get_electricity_prices · DK2 · today
AI    Wait until the afternoon. The cheapest quarter-hour is 14:15 at 0.91 kr/kWh;
      the morning peak at 07:15 is 2.96 kr/kWh. Average across the day is 1.43 kr/kWh.

Install

Needs Node 24 or newer. Add it to your MCP client:

{
  "mcpServers": {
    "energi": { "command": "npx", "args": ["-y", "energimcp"] }
  }
}

That is the whole setup.

From a clone instead:

npm install
npm test          # stubs fetch; never touches the API
npm run stdio     # the server an MCP client launches
npm run check     # config + a live call
npm run datasets  # the catalogue, one line per dataset

Related MCP server: Energy Charts MCP

Tools

Tool

What it does

list_datasets

Search the catalogue by text or publisher. Hides the 22 discontinued datasets unless asked.

describe_dataset

Every column with type and unit, the time column start/end filter on, resolution, update frequency, and the first and last timestamp that exist.

query_dataset

Any dataset, with start, end, columns, filter, sort, offset, limit. summary: true returns per-column statistics instead of rows.

download_url

A CSV, JSON or Excel link for extracts too large to read into a conversation. Builds the URL without fetching it.

get_electricity_prices

Day-ahead prices in 15-minute resolution with the cheapest and dearest periods worked out.

get_carbon_intensity

g CO₂/kWh in 5-minute resolution, with the forecast and the greenest upcoming window.

get_power_system_now

One-minute snapshot: production by source, wind and solar share, carbon intensity, every interconnector.

Three prompts ship with it: when-to-run, find-dataset and grid-snapshot.

What this API does that the code works around

Four things about Energi Data Service shaped the implementation, and all four are easy to get wrong:

Rate limits are per dataset and tight. The platform expects roughly one request per dataset update interval and answers 429 Rate limit is exceeded. Try again in N seconds. otherwise — in testing, the third request inside two minutes was refused. So every response is cached for that dataset's own update interval, identical in-flight calls are shared, outbound calls are spaced, and a 429 is reported to the model as something to wait out rather than retry.

22 of the 100 datasets are discontinued and still answer 200. Elspotprices stopped updating on 2025-09-30 and happily returns year-old rows. Retirement is recorded only in the title, and the replacement only as a markdown link in the description. query_dataset detects both and returns a warning naming the successor, so stale prices are not presented as current.

The metadata endpoint emits invalid JSON. Descriptions contain raw unescaped newlines, which JSON.parse rejects. parseLenientJson repairs the control characters inside strings.

Errors are plain text. 404 dataset not found X, 400 Invalid column X — and /meta/dataset/{unknown} answers 204 with an empty body rather than 404. A 400 is enriched with the dataset's actual column list, since the model cannot guess them.

One correctness note worth stating: in PowerSystemRightNow, positive exchange values are imports into Denmark, not exports. The metadata does not say so. It is verifiable in ProductionConsumptionSettlement, where production plus exchange equals gross consumption exactly.

Hosting it

npm start serves stateless streamable HTTP on /mcp, with /healthz for a probe. There is no auth, because there is nothing private behind it — do not put anything private behind it. The Dockerfile builds a container; CACHE_DIR is the only volume worth mounting, and only to keep the catalogue warm across restarts.

Hosting it is optional. The stdio server above is enough for a desktop client; deploy only if you want the tools on claude.ai or your phone, where a client cannot launch a local process.

Railway

.railway/railway.ts declares the service and health-checks /healthz; the build comes from the Dockerfile at the repository root, which Railway picks up automatically. From a clone:

npm i -g @railway/cli
railway login
railway init            # creates the project
railway up              # builds and deploys
railway domain          # gives it a public URL

Then add https://<your-domain>/mcp as a custom connector in your assistant. Nothing else to configure: there are no secrets, and BASE_URL is detected from RAILWAY_PUBLIC_DOMAIN.

The same container runs anywhere — Fly, Render, a VPS. It is stateless, so scale it to as many replicas as you like; the only cost of losing the cache is one extra catalogue fetch per instance.

Layout

src/eds.ts       API client: caching, request spacing, lenient JSON, typed errors
src/catalog.ts   the 100 datasets: search, name resolution, retirement, successors
src/data.ts      response shaping: dataset cards, freshness, per-column summaries
src/tools.ts     the seven tools
src/mcp.ts       server factory and the instructions the model reads first
src/stdio.ts     local entry point
src/server.ts    hosted entry point
data/catalog.json  catalogue snapshot, so discovery works on a cold start
docs/            the landing page (GitHub Pages)

Refresh the snapshot with npm run catalog.

Not affiliated

An independent open-source client for a public API. Not affiliated with Energinet, Energi Data Service or Anthropic. Data is published by Energinet under their own terms. Spot prices exclude tariffs, taxes and VAT, which roughly double a Danish household bill — DatahubPricelist has the tariffs if you want the real number. MIT licence.

Available Tools

7 tools
describe_datasetDescribe a datasetA
Read-only

Full metadata for one dataset: every column with type and unit, the time column that start/end filter on, the resolution, the update frequency, and the first and last timestamp that actually exist. Call this before query_dataset — column names cannot be guessed and the coverage window is different for every dataset.

ParametersJSON Schema
NameRequiredDescriptionDefault
datasetYesExact datasetName from list_datasets, e.g. DayAheadPrices

TDQS

A4.7/5.0
Behavior5/5

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

Annotations provide readOnlyHint=true, but the description goes further by detailing exactly what metadata is returned (column types/units, time column, resolution, update frequency, actual start/end timestamps). It also notes the dataset-specific coverage window, adding behavioral context beyond the annotation. No contradiction 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 two sentences with no fluff. The first sentence front-loads the purpose and contents; the second provides actionable usage guidance. Every word earns its place, making it both concise and well-structured.

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?

For a one-parameter metadata tool with no output schema, the description fully explains what will be returned and why it's needed before query_dataset. It gives the agent all necessary information to decide when to call it and what to expect, leaving no critical gaps for successful invocation.

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 100% for the single parameter 'dataset', with a clear explanation ('Exact datasetName from list_datasets, e.g. DayAheadPrices'). The description does not add additional parameter details beyond what the schema already provides, so baseline 3 is appropriate.

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 returns 'Full metadata for one dataset' and enumerates specific fields (columns, types, units, time column, resolution, update frequency, timestamps). This differentiates it from siblings like query_dataset, which is explicitly named, making the purpose unmistakable.

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

Usage Guidelines5/5

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

The description explicitly instructs 'Call this before query_dataset' and explains why: 'column names cannot be guessed and the coverage window is different for every dataset.' This provides clear when-to-use guidance and even identifies the prerequisite relationship, leaving no ambiguity about when to invoke this tool.

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

download_urlBuild a download linkA
Read-only

A URL that returns the whole result as CSV, JSON or Excel, for extracts too large to pass through a conversation. Nothing is fetched or rate-limited here; give the URL to the user or to a shell.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoDanish local time. Either a timestamp (2026-01-01 or 2026-01-01T00:00) or a relative expression: now, StartOfDay, StartOfMonth, StartOfYear, optionally with an ISO 8601 offset such as now-P1D, now-PT15M, StartOfYear, now+P1D.
sortNo
limitNo0 means every row in the range
startNoDanish local time. Either a timestamp (2026-01-01 or 2026-01-01T00:00) or a relative expression: now, StartOfDay, StartOfMonth, StartOfYear, optionally with an ISO 8601 offset such as now-P1D, now-PT15M, StartOfYear, now+P1D.
filterNo
formatNoXL is Excelcsv
columnsNo
datasetYesExact datasetName from list_datasets

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: it states that nothing is fetched or rate-limited, meaning the tool only constructs a URL and does not perform a download. This prevents an agent from expecting data to be returned directly. It could mention that the URL may expire or require authentication, but the existing disclosure is strong.

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 with no filler. The core purpose is front-loaded, and the key behavioral caveat ('Nothing is fetched or rate-limited here') is included without redundancy. Every sentence earns its place.

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 tool that generates a URL, the description covers the essential context: what it returns, when to use it, and what to do with the result. The schema provides parameter details, and annotations cover safety. A minor gap is that the description doesn't mention whether the URL is temporary or requires authentication, but given the tool's simplicity and the existing schema/annotations, it is largely complete.

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 63%, so the schema documents most parameters. The description adds context that the URL returns the whole result in a format, which maps to the 'format' parameter, but it doesn't explain the meaning of 'dataset', 'start', 'end', 'filter', 'columns', 'sort', or 'limit' beyond what the schema already provides. The description doesn't compensate for the undocumented parameters (e.g., 'sort' has no schema description), but the schema covers the majority.

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 a specific verb ('download'), resource ('URL'), and purpose ('returns the whole result as CSV, JSON or Excel'), and distinguishes it from conversation-passing by noting it's for extracts too large to pass through a conversation. It clearly differentiates from siblings like query_dataset by emphasizing it produces a URL rather than returning data inline.

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

Usage Guidelines5/5

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

The description explicitly says when to use it ('for extracts too large to pass through a conversation') and what to do with the result ('give the URL to the user or to a shell'). It also clarifies what it is not ('Nothing is fetched or rate-limited here'), which helps an agent avoid calling it when actual data retrieval is needed.

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

get_carbon_intensityCarbon intensityA
Read-only

Grams of CO2 per kWh on the Danish grid, in 5-minute resolution, with an optional forecast. Use it to answer when to run something power-hungry. Returns the latest reading, the range over the window, and the greenest upcoming period when the forecast is included.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoDefault now. Danish local time. Either a timestamp (2026-01-01 or 2026-01-01T00:00) or a relative expression: now, StartOfDay, StartOfMonth, StartOfYear, optionally with an ISO 8601 offset such as now-P1D, now-PT15M, StartOfYear, now+P1D.
startNoDefault now-PT1H. Danish local time. Either a timestamp (2026-01-01 or 2026-01-01T00:00) or a relative expression: now, StartOfDay, StartOfMonth, StartOfYear, optionally with an ISO 8601 offset such as now-P1D, now-PT15M, StartOfYear, now+P1D.
price_areaNoDK1 is west of the Great Belt, DK2 is eastDK1
include_forecastNoAlso read CO2EmisProg for the hours ahead

TDQS

A4.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, so the safety profile is covered. The description adds meaningful behavior beyond annotations: 5-minute resolution, optional forecast, and the specific return values (latest reading, range over the window, greenest upcoming period). No contradiction 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?

Three sentences with no redundancy: definition, use case, and return values are front-loaded and each earns its place. There is no filler or repeated schema information.

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 read-only look-up tool with no output schema, the description adequately covers what the tool does, when to use it, and what it returns. It could be more complete by explicitly contrasting with sibling tools, but that gap is minor given the strong schema and annotations.

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 100%, so the schema documents all parameters well. The description adds value by linking the forecast flag to the 'greenest upcoming period' return and the start/end window to the returned range, which enriches the schema's bare parameter descriptions.

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 resource (CO2 per kWh on the Danish grid), resolution (5-minute), and optional forecast, and clearly distinguishes it from siblings like get_electricity_prices and get_power_system_now by its focus on carbon intensity. The use-case phrasing 'Use it to answer when to run something power-hungry' makes the tool's purpose actionable.

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?

It explicitly says when to use the tool ('when to run something power-hungry'), giving clear context. It doesn't explicitly name sibling alternatives or exclusion conditions, but the unique carbon-intensity resource makes the intended use evident against the sibling list.

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

get_electricity_pricesElectricity pricesA
Read-only

Day-ahead electricity spot prices in 15-minute resolution, with the cheapest and most expensive periods worked out. Covers today and, once published in the early afternoon, tomorrow. Prices are per MWh excluding tariffs, taxes and VAT — a household bill is roughly double this.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoDefault now+P2D, which includes tomorrow once it is published. Danish local time. Either a timestamp (2026-01-01 or 2026-01-01T00:00) or a relative expression: now, StartOfDay, StartOfMonth, StartOfYear, optionally with an ISO 8601 offset such as now-P1D, now-PT15M, StartOfYear, now+P1D.
startNoDefault StartOfDay. Danish local time. Either a timestamp (2026-01-01 or 2026-01-01T00:00) or a relative expression: now, StartOfDay, StartOfMonth, StartOfYear, optionally with an ISO 8601 offset such as now-P1D, now-PT15M, StartOfYear, now+P1D.
price_areasNoDK1 (west of the Great Belt), DK2 (east), or a neighbouring area such as DE, SE3, SE4, NO2
include_periodsNoInclude every 15-minute price. Turn off for just the summary.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already cover readOnlyHint and openWorldHint. The description adds meaningful context: price granularity, exclusion of tariffs/taxes/VAT, and the release schedule. It does not describe response format or pagination, but with annotations covering safety and time-variance, the added details are sufficient.

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 tight sentences. The first sentence establishes purpose, resolution, and value-add; the second conveys temporal coverage and pricing basis. No filler, all information earns its place.

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 read-only retrieval tool with full schema coverage and annotations, the description is adequate. It explains the temporal scope and what the prices exclude. The absence of an output schema is offset by the include_periods parameter and mention of summaries. Slight room for improvement in stating return structure, but not a critical gap.

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%, so all four parameters (end, start, price_areas, include_periods) have detailed descriptions. The tool description adds context about 15-minute resolution and summary availability but does not specifically elaborate on parameter syntax beyond the schema. Baseline 3 applies.

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 a specific verb and resource: 'Day-ahead electricity spot prices in 15-minute resolution' with added value of cheapest/most expensive periods. This clearly distinguishes it from siblings like get_carbon_intensity and get_power_system_now, which target different data domains.

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 day-ahead electricity pricing and notes the publication timing ('once published in the early afternoon, tomorrow'), giving temporal context. It does not explicitly name alternatives or exclusions, but the resource focus is unambiguous, so the gap is minor.

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

get_power_system_nowPower system right nowA
Read-only

A one-minute snapshot of the Danish power system: production by source, wind and solar output, carbon intensity, and the flow on every interconnector. Positive exchange values are imports into Denmark; production plus net import equals consumption.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior5/5

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

Beyond the readOnlyHint and openWorldHint annotations, the description explains important semantics: positive exchange values mean imports, and it gives the balance identity 'production plus net import equals consumption.' This is exactly the kind of interpretational context that helps an agent use results correctly.

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 carry a large amount of useful information with no filler. The core subject is front-loaded, and the sign-convention detail is placed where it is most relevant.

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 no-parameter, no-output-schema tool, the description sufficiently enumerates the data categories and the key interpretation rule. It does not specify units or timestamp details, but the overview is complete enough for an agent to know what this tool returns and when to call it.

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 has zero parameters and the schema fully covers everything needed, so the description has no parameter burden. The baseline for a no-parameter tool is appropriately high, and the description provides no conflicting or missing parameter information.

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 clearly specifies the resource (Danish power system snapshot) and the included fields (production by source, wind/solar output, carbon intensity, interconnector flows). It lacks an explicit comparison to sibling tools like get_carbon_intensity or get_electricity_prices, so it does not quite reach the top score, but the purpose is unmistakable.

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 phrase 'one-minute snapshot' combined with 'right now' provides clear contextual guidance: this tool is for current, aggregate power-system state rather than historical or exploratory data. It does not explicitly mention alternatives or exclusions, so it stops short of a 5.

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

list_datasetsList datasetsA
Read-only

Search the Energi Data Service catalogue (100 datasets covering Danish electricity, gas and grid data). Returns dataset names and titles; call describe_dataset before querying one. Discontinued datasets are hidden unless asked for.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
searchNoFree text matched against name, title and description, e.g. 'price', 'wind', 'consumption', 'gas quality'
publisherNotso-electricity (71, transmission), tso-gas (15), dso-electricity (10, distribution), gas-storage-denmark (4)
include_discontinuedNoInclude the 22 retired datasets, which still hold history but no new rows

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already state readOnlyHint=true and openWorldHint=true, so the description adds value by disclosing the catalogue size (100 datasets), the return type (names and titles), and the hiding of discontinued datasets unless requested. No contradiction with annotations; this extra context helps an agent understand the tool's behavior beyond the safety hints.

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 with no wasted words. It front-loads the core purpose, then the return type, a necessary next step, and a behavioral note—all essential information. This is a model of concise, effective tool documentation.

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 discovery tool with 0 required parameters and no output schema, the description covers the key usage points: what it returns, how to proceed, and a special behavior (discontinued). It doesn't detail pagination or limit semantics, but those are present in the input schema, so the description is complete enough for correct invocation.

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 75%, and the description does not add significant meaning beyond what the schema already provides. It mentions 'search' and 'discontinued' indirectly, but those are already described in the schema. The baseline of 3 applies because the schema carries the 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 states a specific verb ('Search'), a resource ('Energi Data Service catalogue'), and scope ('Danish electricity, gas and grid data'). It also distinguishes itself from siblings by saying it returns dataset names and titles and pointing to describe_dataset for next steps, making it clear this is the metadata listing entry point.

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 clear context: it returns dataset names and titles and instructs to call describe_dataset before querying one, which implies the proper workflow. It doesn't explicitly exclude alternatives like query_dataset, but the guidance is sufficient to know when to use this tool as a discovery step.

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

query_datasetQuery a datasetA
Read-only

Fetch rows from any dataset. start/end filter on the dataset's own time column (see describe_dataset). Keep results small: name the columns you need, and use summary=true to get per-column statistics instead of rows when the range is long. Amounts and units are whatever the dataset documents; this tool does not convert them.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoEnd of the period, excluded. Danish local time. Either a timestamp (2026-01-01 or 2026-01-01T00:00) or a relative expression: now, StartOfDay, StartOfMonth, StartOfYear, optionally with an ISO 8601 offset such as now-P1D, now-PT15M, StartOfYear, now+P1D.
sortNoe.g. 'HourUTC desc' or 'PriceArea,HourUTC'. Defaults to newest first.
limitNoMaximum rows (default 200, or 5000 when summary=true). 0 is rejected here: to this API it means every row ever.
startNoStart of the period, included. Danish local time. Either a timestamp (2026-01-01 or 2026-01-01T00:00) or a relative expression: now, StartOfDay, StartOfMonth, StartOfYear, optionally with an ISO 8601 offset such as now-P1D, now-PT15M, StartOfYear, now+P1D.
filterNoColumn to allowed values, e.g. {"PriceArea": ["DK1", "DK2"]}. Values within a column are OR-ed, columns are AND-ed.
offsetNoRows to skip, for paging through a large result
columnsNoColumns to return. Omitting this returns all of them, which is often far more than you need.
datasetYesExact datasetName from list_datasets
summaryNoReturn min/max/mean/sum per numeric column and the distinct values of category columns, instead of the rows themselves

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already cover readOnly and openWorld hints. The description adds meaningful behavior beyond them: time filtering is against the dataset's own time column, amounts and units are not converted, and summary=true returns per-column statistics instead of rows. This is useful, non-duplicative context.

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?

Three sentences, front-loaded with the core action, followed by the most important usage caveats. Every sentence earns its place, and there is no redundant restatement of the schema.

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 9-parameter tool with no output schema, the description plus detailed schema covers the main decisions an agent needs to make: dataset selection, time filtering, column selection, and summarized output. It doesn't describe the exact response envelope, but row/statistics semantics are stated clearly enough for selection and invocation.

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 100%, so the baseline is 3. The description adds value by clarifying that start/end refer to the dataset's own time column and that summary=true is a substitute for rows over long ranges. It doesn't over-explain parameters already well documented in the 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 clearly states the tool fetches rows from any dataset, which is a specific action on a clear resource. It doesn't explicitly name sibling tools or contrast itself with get_electricity_prices, but 'any dataset' signals a generic query role versus the specialized sibling tools.

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 practical usage context: use start/end on the dataset's own time column, reference describe_dataset, keep results small by selecting columns, and use summary=true for long ranges. It does not explicitly state when to choose this tool over specialized siblings, but the guidance within the tool is clear.

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. 7 tool updatesv0.1.0
    • First observeddescribe_dataset
    • First observeddownload_url
    • First observedget_carbon_intensity
    • First observedget_electricity_prices
    • First observedget_power_system_now
    • First observedlist_datasets
    • First observedquery_dataset

TDQS

A4.3/5.0

Scored across 7 tools

Disambiguation4/5

The catalogue workflow tools (list_datasets, describe_dataset, query_dataset) and the three convenience getters are largely distinct, but query_dataset can in principle fetch data overlapping with get_electricity_prices, get_carbon_intensity, and get_power_system_now. That boundary is slightly ambiguous, though the specialized getters make the intended choice clear in most cases.

Naming Consistency4/5

Most tool names follow a predictable verb_noun snake_case pattern: list_datasets, describe_dataset, query_dataset, get_electricity_prices. Minor inconsistencies include list_datasets being plural while describe_dataset/query_dataset are singular, and download_url being less verb-like than the other retrieval helpers.

Tool Count5/5

Seven tools is a well-scoped set for this domain: three catalogue lifecycle tools, one export helper, and three high-value convenience queries. Each tool earns its place without redundancy or bloat.

Completeness5/5

The set covers the full read-only workflow: discover datasets, inspect metadata, query rows, and generate download URLs for large exports. It also anticipates common user questions with electricity prices, carbon intensity, and power system snapshots, while query_dataset covers anything else in the catalogue.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Provides access to Danish energy data from Energinet, including real-time electricity spot prices, CO2 emissions, and production mix. It enables users to monitor grid status and identify the most cost-effective hours for energy-intensive tasks.
    4
    2 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables querying European electricity generation, prices, and capacity data from Fraunhofer ISE's Energy-Charts platform.
    7 npm
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Read-only MCP server for Energinet's public Energi Data Service. Enables dataset search, arbitrary dataset queries with filters, and CO2 emissions retrieval for DK1/DK2 without an API key.
    -