Skip to content

Norway Open Data MCP v0.3.0 — Maritime toolset

Choose a tag to compare

@iamkm1 iamkm1 released this 26 Jul 04:20
5143db7

A curated maritime toolset built on the new ais, marine and fisheries namespaces in norway-open-data-sdk@0.7.0. The curated tool set grows from 12 to 20.

No existing tool changes its name, input schema or data payload, and the first twelve entries of tools/list keep their names and their order. One existing behaviour does change, and it is a fix rather than a feature — see Fixed.

Added

Three BarentsWatch AIS tools, all gated on the ais credential scope:

  • get_vessel_profile — one vessel by MMSI, answered from BarentsWatch AIS, the Norwegian fishing-vessel register, MET Norway and Kartverket at once. Delegates the composition to the SDK's profiles.vessel() and surfaces its per-section provenance, distinguishing "not configured", "not applicable", "not found", "not covered" and "provider error".
  • get_vessel_track — recorded positions for one vessel. Defaults to the provider's last-24-hours endpoint; an explicit window of up to 14 days (the provider's retention) routes to the ranged endpoint.
  • get_live_vessel_positions — a bounded sample of the live AIS feed. A bounding box, a result limit (≤ 200) and a timeout (≤ 15 s) are required arguments with no defaults. The sample stops at whichever bound is reached first, and the connection is closed on every path including caller cancellation and provider error. No infinite stream is exposed through MCP.

Four Fiskeridirektoratet tools, anonymous — no credential of any kind: search_fishing_vessels, get_fishing_vessel, search_aquaculture_locations, get_aquaculture_location.

get_marine_forecast — BarentsWatch wave and sea-current forecasts for a coordinate, gated on the api credential scope. The two models are independent: if one fails the other is still returned, with the failure recorded in partial and in the warnings. An uncovered coordinate returns null sections rather than failing, so "no model covers this point" stays distinguishable from "the provider failed".

Four environment variables, in two independent pairs, because BarentsWatch issues separate registered clients for AIS and for its other services:

Variable Scope
NORWAY_MCP_BARENTSWATCH_AIS_CLIENT_ID / _SECRET ais
NORWAY_MCP_BARENTSWATCH_CLIENT_ID / _SECRET api

A half-configured pair is refused outright and reported by --doctor, rather than passed through to fail at the token endpoint.

Also adds reusable strict input schemas for MMSI (a string, so a leading zero survives), registration marks, radio call signs, aquaculture site numbers, production-area codes and WGS84 bounding boxes; boxes reject inverted edges, antimeridian crossings and spans large enough to make a sample meaningless.

Changed

  • Requires norway-open-data-sdk@^0.7.0 (previously ^0.6.0). ^0.6.x does not accept 0.7.0, so the floor is raised deliberately and enforced by a release guard over both the manifest range and the resolved lockfile version.
  • OAuth2 client ids and secrets are added to the redactor's literal secret set, alongside the contact email and the NVE key.
  • --doctor reports the four new variables as (set, masked) or (not set), and the readiness of all twenty tools.

Fixed

Composed profiles credited a source that carries no licence and no attribution. A profile's top-level source is a synthetic composite the SDK builds for the composition itself — profiles.vessel() returns barentswatch-ais+kartverket with a homepage pointing at the SDK's own repository and no license or attribution field at all. Crediting it silently dropped every licence term the providers require, including the BarentsWatch AIS condition that Kystverket be credited.

Provenance for get_vessel_profile, get_norwegian_company_profile, get_norwegian_location_profile and get_norwegian_municipality_profile is now built from the profile's components, each carrying the real provider descriptor. Only components that actually returned data are credited; the composite is used solely as a fallback when none did.

This changes the sources[] array of those four tools — the envelope schema is unchanged, but a result now lists one entry per contributing provider, each with its licence and attribution, instead of a single composite entry with neither. Found by calling the live API: the offline fixtures had been written with the real per-provider source, so the suite could not have caught it. The fixtures now carry the composite verbatim and a regression test asserts the composite never reaches an envelope.

Sea-current speed rendered at full float precision in the text form (0.21719335266844905). Wave and current values are now rounded in the human-readable summary; the structured payload keeps the provider's exact value.

Note on the streaming bounds

The get_live_vessel_positions limits are limits of this MCP server, not of BarentsWatch. BarentsWatch publishes no maximum bounding-box size, result cap or connection time limit, and a caller using the SDK directly is subject to none of them. The 6° × 12° box, the 200-result cap and the 15-second timeout exist because a tool call returns one bounded result into a model's context window.

Install

npx -y norway-open-data-mcp