Skip to content

Releases: kitfunso/luminus

v0.6.1 — Scotland coverage polish

21 Apr 21:08

Choose a tag to compare

v0.6.1 Release Notes

Released: 2026-04-21

Polish patch for 0.6.0 Scotland coverage. Two semantic fixes surfaced by live end-to-end smoke across nine GB coordinates.

What's fixed

Scottish flood_zone no longer falsely "unknown"

Before 0.6.1, a Scottish coordinate with no flood risk returned flood_zone: "unknown", planning_risk: "unknown" when the Environment Agency service errored on Scottish geometries (which it does, because EA is England-only). The SEPA service correctly returned zero matches but the aggregated verdict treated the EA errors as "we don't know."

Fix: when SEPA is queried successfully with zero errors AND zero matches, that is a confident "clear" signal, even if EA errored for coverage reasons. flood_zone now returns "1" and planning_risk returns "low" in this case.

Verified live at Glasgow River Clyde adjacent (55.8642, -4.2518) and River Ness at Inverness (57.4778, -4.2247) — both now resolve cleanly to "1" / "low" instead of the misleading "unknown".

A secondary fix: the "all queries failed" throw path now only fires when both EA and SEPA have actually failed. Previously it threw when EA failed even though SEPA had returned a successful empty response.

classification_basis honestly labels LCA data

Before 0.6.1, a Scottish LCA result surfaced with classification_basis: "post_1988" or "provisional", which misleadingly implied a Natural England Agricultural Land Classification survey. These basis values belong to English ALC.

Fix: two new ClassificationBasis values introduced:

  • "lca_detailed" — James Hutton 1:50k LCA (improved agricultural land, partial Scotland cover)
  • "lca_broad" — James Hutton 1:250k LCA (national Scotland cover)

The buildExplanation string was extended accordingly and now reads, e.g., "James Hutton LCA (1:50k detailed) classifies this site as 3.1, equivalent to Best and Most Versatile agricultural land."

Verified live at Edinburgh (55.9533, -3.1883): classification_basis: "lca_detailed" with effective_grade: "Built-up area" and bmv_status: "unknown" (LCCODE 888).

Live smoke verification

Nine coordinates tested end-to-end through the Python SDK against real NESO / NatureScot / SEPA / James Hutton / Natural England / Environment Agency services:

Site Result
Arthur's Seat (Scottish) 2 SSSIs via NatureScot, has_hard_constraint: true
Glasgow Clyde adjacent flood_zone: "1" (was "unknown" in 0.6.0)
River Ness at Inverness flood_zone: "1" (was "unknown" in 0.6.0)
Edinburgh (LCA built-up) basis: "lca_detailed" (was "post_1988" in 0.6.0)
Carse of Gowrie, Shetland Lerwick Empty LCA (real upstream data gap — 50k is partial, 250k has gaps)
Kelso, Scottish Borders River Tweed SSSI + SAC via NatureScot
Berwick (English border) 8 constraints from BOTH natural-england + nature-scot, union'd correctly
Cambridge (English control) basis: "provisional", no Scottish sources — English behaviour unchanged

What is NOT changed

  • No API shape changes beyond the two new ClassificationBasis enum values. post_1988, provisional, none still exist.
  • English-only queries behave identically.
  • No new upstreams, no new tools, no new dependencies.
  • Python SDK remains at 0.5.0 — the new enum values flow through dynamic MCP binding without SDK changes.

Known upstream data gaps (not bugs)

The James Hutton 1:50k LCA covers only improved agricultural land patches, approximately one third of Scotland's area. The 1:250k LCA covers the whole country but has some no-data gaps (e.g., Shetland). When both return empty, classification_basis is "none" and bmv_status is "unknown" — this is honest coverage reporting, not a bug.

Verification

  • 400 JS tests passed across 39 test files + 2 env-gated integration tests
  • 33 Python tests passed (unchanged)
  • TypeScript build clean
  • npm audit 0 vulnerabilities

Versions

  • luminus-mcp@0.6.1
  • luminus-py==0.5.0 (unchanged)

v0.6.0 — Scotland coverage for screening tools

21 Apr 20:52

Choose a tag to compare

v0.6.0 Release Notes

Released: 2026-04-21

Scotland coverage — the three main GB screening tools now return meaningful results for Scottish coordinates, using NatureScot, SEPA, and James Hutton Institute public data. Before 0.6.0, a Scottish site would silently return empty English results with a "coverage: England only" caveat. Now it returns the right Scottish data alongside.

Minor release. Non-breaking — existing English queries behave identically. Scottish coordinates now get real answers. Border-region coordinates get both English and Scottish results union'd.

What's new

NatureScot protected areas

New library module src/lib/nature-scot.ts queries the NatureScot Spatial Data Hub (services1.arcgis.com/LM9GyVFsughzHdbO) for six Scottish designation layers: SSSI, SAC, SPA, Ramsar, NNR, MPA. Integrated into get_land_constraints. Designations from both Natural England and NatureScot merge into a single constraints array with source: "nature-scot" on Scottish features.

SEPA Flood Risk Management Maps

New library module src/lib/sepa-flood.ts queries SEPA's public map service (map.sepa.org.uk/server/rest/services/Open) for nine flood-extent services — the cross product of river / coastal / surface-water sources with high / medium / low likelihoods (1-in-10 / 1-in-200 / 1-in-1000 year return periods). Integrated into get_flood_risk.

Features:

  • Runtime layer-ID discovery (SEPA services don't uniformly use layer 0; the module caches the right layer per service)
  • Approximate mapping: SEPA Medium → EA Zone 3, SEPA Low → EA Zone 2
  • Raw SEPA matches returned under a new sepa_matches field for callers who want the full detail
  • Parallel query via Promise.allSettled — per-service failures degrade gracefully

James Hutton Institute LCA

New library module src/lib/james-hutton-lca.ts queries the James Hutton Institute ArcGIS server (druid.hutton.ac.uk) for Scottish Land Capability for Agriculture. Detailed-first (1:50k, ~1/3 Scotland coverage, improved agricultural land only), falls back to broad (1:250k, national coverage). Integrated into get_agricultural_land.

Features:

  • LCCODE normalisation: handles both numeric and decimal class labels (313.1, etc.)
  • Non-agricultural codes (888 = built-up) map to is_agricultural: false and bmv_status: "unknown"
  • BMV mapping: LCA classes 1, 2, 3.1 → BMV; 3.2 and coarser → non-BMV
  • Output surfaces under a new scotland_lca field on get_agricultural_land, preserving the existing English post_1988 / provisional fields untouched

Scotland bounding-box helper

src/lib/scotland-bbox.ts exports a coarse bbox check (isScottishCoord(lat, lon)) used by the three tools to gate Scottish-upstream queries. The box is intentionally generous, erring toward "query both" for border coordinates. Dedupe + empty-result handling in each upstream makes border queries clean.

Source metadata + health checks

Three new entries in verify_gis_sources:

  • nature-scot — live health-check against NatureScot's SSSI service
  • sepa-flood-map — health-check against SEPA's /layers?f=json
  • james-hutton-lca — health-check against the Hutton 50k service (20-second timeout, longer than Esri-hosted services)

Total GIS source coverage now 24 (was 21 at 0.5.1).

Non-breaking additions

  • additional_sources?: GisSourceMetadata[] — optional field on get_land_constraints / get_flood_risk / get_agricultural_land results, populated when Scottish upstreams contributed data
  • sepa_matches?: SepaFloodMatch[] — raw SEPA flood-extent hits on get_flood_risk
  • scotland_lca?: LcaResult — full LCA structured result on get_agricultural_land

What is NOT changed

  • Existing English-only queries behave identically. Same shape, same source_metadata, same caveats.
  • No changes to get_grid_connection_intelligence, get_site_connection_report, get_gate2_readiness_check, or any other tool.
  • Python SDK API surface unchanged — the new fields flow through dynamic MCP binding without SDK changes.

Out of scope for 0.6.0

  • Wales — Natural Resources Wales (NRW) has equivalent data but a separate tranche's worth of integration work.
  • Northern Ireland — no integrated upstreams today.
  • National Scenic Areas (NSA) — the Scottish AONB-equivalent. Not in this release; add in a later tranche.
  • EU TYNDP integration and NGED internal signals — remain out of scope per the connection-intelligence pitch primer (see docs/outreach/gb-grid-pitch-primer.md).

Verification

  • 398 JS tests passed across 39 test files
  • 2 env-gated live integration tests still pass (LUMINUS_RUN_INTEGRATION=1)
  • 33 Python tests passed (unchanged)
  • TypeScript build clean
  • npm audit 0 vulnerabilities

Versions

  • luminus-mcp@0.6.0
  • luminus-py==0.5.0 (unchanged — no SDK-level changes)

v0.5.1 — Critical GSP lookup fix + polish

21 Apr 19:05

Choose a tag to compare

v0.5.1 Release Notes

Released: 2026-04-21

Critical fix for a GB GSP lookup bug that shipped silently in 0.5.0, plus post-0.5.0 polish: Python SDK parity for the two new 0.5.0 composite tools, a connection-intelligence Jupyter notebook, a GB bounding-box guard on get_site_connection_report, and surfacing of previously-silent polygon-path degradations.

This is a patch release. Anyone using get_grid_connection_intelligence, get_site_connection_report, or shortlist_bess_sites should upgrade immediately.

The critical fix

lookupGspRegion() in src/lib/neso-gsp.ts returned WALP_1 (Walpole, Norfolk) for every GB coordinate in 0.5.0. The cause: pointOnSegment() treated the closed-ring degenerate zero-length segment (GeoJSON rings always close by repeating the first vertex as the last) as containing every point. pointInRing short-circuited to true on the closing edge before ray-casting ran, and the first feature in iteration order (WALP_1 early in the file) always won.

Fix: early-return false from pointOnSegment when squaredLength < 1e-18 so degenerate segments are treated as points, not segments.

Downstream impact of the fix:

Site 0.5.0 (wrong) 0.5.1 (correct)
Berkswell (52.39, -1.64) WALP_1 @ 129.86 km BESW_1 @ 1.83 km
Canary Wharf (51.505, -0.019) WALP_1 @ 136.78 km WHAM_1 @ 2.15 km
Birmingham (52.486, -1.89) WALP_1 @ 143.59 km NECE_1 @ 3.49 km
Manchester (53.477, -2.23) WALP_1 @ 182.29 km STAL_1 @ 12.72 km

Affected tools now return the correct nearest GSP, TEC queue data for the right GSP, and DNO headroom for the right area.

Why mocked unit tests missed it. All existing tests fed BASE_GRID_RESULT with nearest_gsp: { gsp_name: "BERKSWELL", ... } directly. No test exercised the real lookupGspRegion() against live NESO data.

Why it ships now. A new env-gated live integration test at src/lib/neso-gsp.integration.test.ts hits real NESO data and asserts Berkswell resolves to a BESW* GSP within 5 km and Canary Wharf resolves to a non-Walpole London GSP within 5 km. Run with LUMINUS_RUN_INTEGRATION=1.

Silent polygon degradations now surface

Two latent silent-failure paths are now visible:

  1. fetchGspBoundaries() previously swallowed all polygon ZIP fetch/parse errors with a bare catch { return []; }. It now returns a structured outcome with a warning message on failure.
  2. findContainedRecord() previously returned a silent null when a polygon contained the query point but its GSPs property codes did not resolve to any CSV record. It now returns a warning naming the mismatched codes.

Both warnings flow into GspLookupResult.warnings and are surfaced by get_grid_connection_intelligence and get_nged_connection_signal in their confidence_notes, so future NESO format changes stop being invisible.

Polish work included

Python SDK parity (luminus-py@0.5.0, bumped in-source, not yet published to PyPI):

  • Luminus.get_site_connection_report_snapshot(**arguments) and Luminus.get_gate2_readiness_check_snapshot(**arguments)
  • Typed snapshot dataclasses: SiteConnectionReportSnapshot, Gate2ReadinessCheckSnapshot, CanonicalConnectionEntrySnapshot, Gate2ReadinessProject, Gate2ReadinessRuleResult, Gate2ReadinessSummary
  • New Jupyter notebook python/examples/connection_intelligence_workflow.ipynb

GB bounding-box guard on get_site_connection_report:

The tool now rejects coordinates outside a generous GB bounding box (49.5 to 61.0 lat, -8.5 to 2.0 lon) with a clear error pointing EU callers to screen_site. Previously the tool silently returned a mostly-empty "GB" report for EU coordinates.

compare_sites transparency:

The disclaimer and heuristics_used now explicitly state that the scoring weights are judgment-based and have not been calibrated against realised project outcomes. No weight changes.

Expanded verify_gis_sources coverage:

Added health check for neso-gsp-boundaries — validates that the NESO GSP dataset still publishes a ZIP resource with the region-boundary GeoJSON. The runtime hardcodes the current ZIP URL by filename (embedding a rotation date), so future rotations that drop the resource now surface here instead of silently falling back to nearest-point CSV. Total coverage now 21 sources.

Verification

  • 375 JS tests passed across 36 test files + 2 env-gated integration tests
  • 33 Python tests passed
  • TypeScript build clean
  • npm audit 0 vulnerabilities
  • Live end-to-end smoke against real NESO confirms post-fix correctness

Versions

  • luminus-mcp@0.5.1
  • luminus-py==0.5.0 (bumped in source for the new typed helpers; published to PyPI separately)

v0.5.0 — GB connection-intelligence tranche

21 Apr 19:05

Choose a tag to compare

v0.5.0 Release Notes

Released: 2026-04-21

GB connection-intelligence tranche. This release adds a canonical schema for GB connection rows from heterogeneous public sources, a composite site-screening tool that combines grid + land + flood + agricultural signals into a single structured memo, and a transparent, rules-based Gate 2 readiness checklist backed by live public references.

This is a minor release. Nothing previously shipped changes behaviour.

What's in the box

Canonical GB connections schema

New module src/lib/gb-connections/ with:

  • schema.tsCanonicalConnectionEntry type plus ConnectionSource, ConnectionLifecycleStage, and CapacityKind enums.
  • normalise.ts — three structural normalisers mapping upstream rows into the canonical shape:
    • normaliseTecRow (NESO TEC register)
    • normaliseNgedQueueRow (NGED public per-GSP queue)
    • normaliseDnoHeadroomRow (SSEN / NPG / UKPN / SPEN / ENWL headroom)

Normalisers are deliberately structural: they do not invent capacity, status, or identifiers that the upstream row does not publish. source_row_id is derived from the upstream row's own identifiers; lifecycle_stage is text-matched against the upstream status field, with "unknown" when the upstream does not publish a lifecycle column.

get_site_connection_report

GB-only composite tool. Calls get_grid_connection_intelligence, get_land_constraints, get_flood_risk, and get_agricultural_land in parallel via Promise.allSettled, so partial upstream failures degrade the report rather than failing it. Returns:

  • summary — markdown memo with coordinates, nearest GSP, DNO headroom, TEC queue context, hard constraints, flood zone, and ALC grade.
  • structured — normalised nearest GSP, top TEC entries as CanonicalConnectionEntry[], canonical headroom entry, and boolean flags for protected-area, flood, and ALC constraints.
  • traffic_lightsqueue, headroom, land_constraints each as green | amber | red | unknown, driven only by published upstream signals (DNO generation RAG, literal-zero TEC+NGED counts, Natural England hard-designation categories).
  • traffic_light_thresholds — the inline rules used, so the reader can see exactly how each colour was derived.
  • confidence_notes, source_metadata, disclaimer.

No invented thresholds, no proprietary scoring, no prediction.

get_gate2_readiness_check

Rules-based checklist against publicly documented NESO Gate 2 entry criteria. Ten rules across planning, land rights, technology, capacity, connection point, grid reference, energisation window, and strategic alignment. Each rule returns one of pass | warn | fail | not_applicable with a human-readable reason and its own reference_url pointing at the live public source (NESO connections reform, queue management, Clean Power 2030 Action Plan).

Explicit non-goal: this is not a Gate 2 likelihood model, probability, or score. The disclaimer states this explicitly.

connections profile

New profile in src/lib/profiles.ts grouping the seven GB connection-intelligence tools for lower context-window cost when only connection work is needed:

npx luminus-mcp --profile connections

Deliberate non-goals

This tranche explicitly does NOT add:

  • A predictive Gate 2 likelihood model, score, or probability.
  • A GB-wide "queue oracle" or ML overlay on the public data.
  • A workflow SaaS, hosted layer, persistence, or auth.
  • A demand-centre siting or portfolio ranker.

The rationale is honest evidence: we do not have the training data to justify a predictive Gate 2 model, and shipping one would burn credibility with the network operators we depend on for upstream data.

Verification

  • 368 JS tests passed across 36 test files
  • TypeScript build passed
  • npm audit shows only pre-existing transitive issues, unchanged from 0.4.3

Versions

  • luminus-mcp@0.5.0
  • luminus-py==0.4.1 (unchanged)

v0.4.3

17 Apr 08:29

Choose a tag to compare

Patch release fixing intraday price queries (PR #14 by @antondelorme). See CHANGELOG.

Luminus MCP v0.2.0

01 Apr 12:12

Choose a tag to compare

Luminus MCP v0.2.0

Luminus MCP 0.2.0 is the first release where the project clearly becomes more than a plain European power-data MCP.

This release adds a real GIS screening layer for PV and BESS workflows, tightens backend reliability, introduces context-saving MCP profiles, and starts a notebook-friendly Python SDK for analysts who want DataFrames instead of raw MCP plumbing.

Highlights

1. GIS site screening for PV and BESS

New and expanded GIS capabilities now cover:

  • terrain analysis
  • grid proximity
  • GB transmission connection queue access
  • GB grid-connection intelligence
  • land constraints
  • EU land-cover screening
  • England agricultural-land screening
  • England flood-risk screening
  • composite site screening
  • multi-site comparison and ranking
  • screening-level site revenue estimation

This gives Luminus a practical site-screening workflow for GB and a reduced but still useful EU mode.

2. Profiles to cut context-window cost

Luminus now supports focused MCP profiles such as:

  • trader
  • grid
  • regional
  • bess
  • weather
  • gis

The point is simple: users and agents should not need to load the full tool surface when they only need one slice of it.

3. Backend hardening

This release includes a full backend review and a bunch of real fixes, including:

  • runtime auth consistency for key-gated tools
  • better cache-key stability
  • full-window pagination for Fingrid
  • corrected hydro chronology handling
  • safer Overpass rate-limit behaviour
  • corrected GIS math and screening bugs
  • clearer CLI profile handling

4. Python SDK preview

A first notebook-first Python SDK now exists under python/.

Current shape:

  • starts luminus-mcp over stdio
  • exposes a Python Luminus client
  • supports dynamic tool binding for the live MCP surface
  • returns result objects with to_pandas()
  • adds to_geojson() and to_geodataframe() for geospatial notebook work
  • includes quickstart and GIS/BESS screening examples

Removed

  • EMBER was removed from the live tool surface and docs because the public API path is no longer reliable enough to present as a working integration

Verification

  • 238 JS tests passed
  • Python SDK tests passed
  • TypeScript build passed
  • npm audit reported 0 vulnerabilities

Published artifacts

  • npm: luminus-mcp@0.2.0
  • git tag: v0.2.0

Upgrade

npm install -g luminus-mcp@0.2.0

v0.1.0 - 22 MCP Tools for European Energy Data

20 Mar 20:27

Choose a tag to compare

First release of Luminus: 22 MCP tools covering the complete EU/UK electricity market stack.

Install: \
pm install luminus-mcp\\

Tools: Generation mix, day-ahead prices, cross-border flows, carbon intensity, gas storage, LNG terminals, weather forecasts, US gas data, UK carbon/demand/frequency, balancing prices, renewable/demand forecasts, power plant database, capacity auctions, outages, net positions, transfer capacities, hydro reservoirs, solar irradiance, EU grid frequency, transmission lines.

Data sources: ENTSO-E, GIE AGSI+/ALSI, Elexon BMRS, Carbon Intensity API, Open-Meteo, EIA, PVGIS, JAO, Open Power System Data, OpenStreetMap, mainsfrequency.com.

All free. No paid APIs.