Skip to main content
Glama
norway-location-transport-mcp

norway-location-transport-mcp

by trondbjoroy

norway-location-transport-mcp

An MCP server that gives AI agents structured access to Norwegian public transport and geospatial data, through the free Entur and Kartverket / Geonorge APIs.

The two sources compose: trip planning needs geocoding, elevation needs address resolution, and admin lookups tie coordinates to places. One server answers practical local questions — "how do I get from here to Bergen?", "what is the elevation along this hike?", "which kommune is this address in?", "are there e-scooters nearby?".

Both data sources are free with no paid tiers and no API keys. Entur requires only a self-identifying ET-Client-Name header (see below); Kartverket requires nothing.

Tools

Location & geodata (Kartverket)

  • search_address(query?, street?, number?, postal_code?, municipality_number?, max_results) — search official addresses by free text or fields; supports the * wildcard. Returns coordinates and cadastral numbers.

  • find_addresses_near(latitude, longitude, radius_m, max_results) — all addresses within a radius of a point, with distances.

  • validate_address(address) — validate and normalize a free-text address (fuzzy). Returns valid, the normalized match, and alternatives.

  • search_place_names(query, max_results) — search official place names; returns feature type (Fjell, Innsjø, …), municipality, county, and coordinates. Supports *.

  • find_place_names_near(latitude, longitude, radius_m, max_results) — nearest named features to a point, with distances.

  • get_elevation(latitude, longitude) — terrain elevation from the national elevation model (DTM).

  • get_elevation_profile(path, samples) — elevation sampled along a path; returns the profile plus total distance, ascent, and descent.

  • transform_coordinates(x, y, from_epsg, to_epsg) — convert between reference systems (e.g. WGS84 4326 → UTM33 25833).

  • lookup_admin_unit(latitude?, longitude?, address?) — which kommune and fylke a coordinate or address falls in, with official codes.

  • lookup_property(address?, latitude?, longitude?, max_results) — cadastral (matrikkel) identifiers (kommune / gnr / bnr / fnr) via the open address register.

Public transport (Entur)

  • resolve_stop_place(query, max_results) — resolve a place or address to Entur Stop Place IDs.

  • find_stops_near(latitude, longitude, radius_m, max_results) — reverse-geocode a coordinate to the nearest stop places.

  • plan_trip(from_place?/from_latitude/from_longitude, to_place?/to_latitude/to_longitude, date_time?, arrive_by?, transport_modes?, walk_speed?, num_trip_patterns) — plan a point-to-point journey; filter by mode and walk speed. Returns trip patterns with legs, modes, durations, and realtime times.

  • get_departures(stop_place_id, count) — next departures from a stop, with realtime delays, cancellations, and platform.

  • get_realtime_status(stop_place_id? | line_id?) — realtime health: for a stop, on-time/delayed/cancelled counts; for a line, active vehicles and delays.

  • get_stop_accessibility(stop_place_id) — per-quay wheelchair access and a summary. (See the accessibility note below.)

  • list_quays(stop_place_id) — all quays (platforms) at a stop, with codes and coordinates.

  • get_fare_zones(stop_place_id) — the fare (tariff) zone(s) a stop belongs to.

  • find_shared_vehicles(latitude, longitude, range_m, form_factors?, count) — free-floating shared vehicles (bikes, e-scooters, cars, mopeds) across all operators.

  • find_docking_stations(latitude, longitude, range_m, count) — docking stations with available vehicle and free-dock counts.

  • get_vehicle_positions(codespace_id?, line_id?, max_results) — live vehicle positions with bearing, speed, and delay.

Tool definitions live in src/kartverket.ts and src/entur.ts, combined in src/tools.ts and shared by both the stdio and HTTP entry points.

Related MCP server: mcp-entur

Setup

npm install
npm run build
npm test

npm test spawns the server over stdio and calls every tool against the live APIs.

Run it

Over stdio (for most MCP clients):

node dist/index.js

Over Streamable HTTP (for HTTP-based clients):

node dist/http.js
# listens on http://localhost:3000/mcp  (override with PORT)

The Entur client-name requirement

Entur's terms require every request to carry an identifying ET-Client-Name header, formatted like company-app. This server sends one on every Entur request. Set your own value with the ET_CLIENT_NAME environment variable:

ET_CLIENT_NAME="acme-travelbot" node dist/index.js

If unset, a package default is used. Kartverket needs no header or key.

Use with Claude Code

claude mcp add norway -- node C:\Users\trond\norway-location-transport-mcp\dist\index.js

Then ask, for example: "Plan a trip from Oslo S to Bergen and tell me the elevation of Galdhøpiggen."

Remote version (Cloudflare Workers)

worker/ holds a remote deployment: the same 21 tools served over MCP Streamable HTTP, so the server can be added as a claude.ai connector. It shares the tool definitions with the local server (src/tools.ts takes z as a parameter, so it works with both the local MCP SDK v1 / zod 3 and the worker's SDK v2 / zod 4).

cd worker
npm install
npm run dev     # local test at http://127.0.0.1:8787/mcp
node test-http.mjs

Deploy it (needs a Cloudflare account and wrangler login):

cd worker
npm run deploy

Set your Entur client name as a worker variable:

cd worker
npx wrangler secret put ET_CLIENT_NAME

After deploy, add the remotes entry with your workers.dev URL to server.json.

Example calls

Get the next departures from Oslo S:

{ "name": "get_departures", "arguments": { "stop_place_id": "NSR:StopPlace:59872", "count": 5 } }

Plan a bus/tram-only trip with a set walk speed:

{ "name": "plan_trip", "arguments": {
  "from_place": "NSR:StopPlace:59872",
  "to_latitude": 59.95, "to_longitude": 10.78,
  "transport_modes": ["bus", "tram"], "walk_speed": 1.4
} }

Elevation profile along a short path:

{ "name": "get_elevation_profile", "arguments": {
  "path": [{ "latitude": 61.636, "longitude": 8.312 }, { "latitude": 61.64, "longitude": 8.32 }],
  "samples": 20
} }

Convert a WGS84 coordinate to UTM33:

{ "name": "transform_coordinates", "arguments": { "x": 10.7461, "y": 59.9127, "from_epsg": 4326, "to_epsg": 25833 } }

Notes and limits

  • Coordinates are WGS84 latitude/longitude everywhere. The Kartverket APIs are queried with EPSG 4326 so the numbers match; EUREF89 (4258) differs by well under a metre in Norway.

  • Accessibility: Entur's free JourneyPlanner exposes wheelchair access per quay. Deeper equipment detail (elevators, tactile guidance) lives only in Entur's authenticated Stop Register API and is not available here; the tool says so.

  • Rate limiting from either source is surfaced as a clear error asking the agent to retry.

  • Attribution: data from Kartverket / Geonorge and Entur is under NLOD. Credit the sources when you show the data.

How it works

  • src/index.ts speaks MCP over stdio (JSON-RPC on stdin/stdout). src/http.ts speaks MCP over Streamable HTTP with session management. Both build the same server via src/server.ts.

  • Each tool declares a Zod input schema with descriptions the LLM reads directly — no external docs needed to call a tool.

  • Results are JSON text trimmed to what an agent needs, not the raw upstream payloads.

  • Never write to stdout with console.log; it corrupts the stdio protocol. Log to stderr.

License

MIT © Trond Bjørøy. Data © Kartverket and Entur, under NLOD.

Available Tools

21 tools
find_addresses_nearFind addresses near a coordinateAInspect

Find all official addresses within a radius of a coordinate (Kartverket). Each result includes its distance from the point. Good for 'what is at this location?'.

Inputs: latitude (required), longitude (required), radius_m, max_results.

find_docking_stationsFind docking stations nearbyAInspect

Find shared-mobility docking stations (e.g. city bike stations) near a coordinate (Entur Mobility), with available vehicle and free-dock counts per station.

Inputs: latitude (required), longitude (required), count, range_m.

find_place_names_nearFind place names near a coordinateAInspect

Find the nearest official named features to a coordinate (Kartverket). Each result includes its feature type and distance from the point.

Inputs: latitude (required), longitude (required), radius_m, max_results.

find_shared_vehiclesFind shared vehicles nearbyAInspect

Find free-floating shared vehicles (city bikes, e-scooters, car share, mopeds) near a coordinate across all Norwegian operators (Entur Mobility). Each result shows the operator, type, battery, and location.

Inputs: latitude (required), longitude (required), count, range_m, +1 more.

find_stops_nearFind stop places near a coordinateAInspect

Reverse-geocode a coordinate to the nearest public transport stop places (Entur), each with its distance. Use the returned IDs with the departure and trip tools.

Inputs: latitude (required), longitude (required), radius_m, max_results.

get_departuresGet next departures from a stopAInspect

Get the next departures from a stop place (Entur), including realtime delays and cancellations. Each departure shows line, destination, scheduled and expected times, delay, platform, and whether it is cancelled.

Inputs: stop_place_id (required), count.

get_elevationGet elevation at a coordinateAInspect

Get the terrain elevation (metres above sea level) at a coordinate from the Norwegian national elevation model (Kartverket DTM). Covers mainland Norway.

Inputs: latitude (required), longitude (required).

get_elevation_profileGet an elevation profile along a pathAInspect

Sample the terrain elevation evenly along a path of coordinates (Kartverket DTM) and return the profile plus total distance, ascent, and descent. Useful for hikes and routes. Give the path vertices in order; samples controls resolution.

Inputs: path (required), samples.

get_fare_zonesGet fare zones for a stopAInspect

Get the fare (tariff) zone(s) a stop place belongs to (Entur). Fare zones set the ticket price for a journey.

Inputs: stop_place_id (required).

get_realtime_statusGet realtime status for a stop or lineAInspect

Get a realtime health summary. For a stop, pass stop_place_id: it summarizes how many upcoming departures are on time, delayed, or cancelled. For a line, pass line_id: it reports how many vehicles are currently active and their delays.

Inputs: line_id, stop_place_id.

get_stop_accessibilityGet stop accessibilityAInspect

Get accessibility information for a stop place (Entur): per-quay (platform) wheelchair access, and a summary. Note: Entur's free API exposes wheelchair access per quay; deeper equipment detail (elevators, tactile guidance) is only in Entur's authenticated Stop Register API and is not available here.

Inputs: stop_place_id (required).

get_vehicle_positionsGet live vehicle positionsAInspect

Get live positions of public transport vehicles (Entur realtime), filtered by operator codespace and/or line. Each vehicle shows its position, bearing, speed, and delay. Codespace examples: ATB (Trondheim), KOL (Stavanger), SKY (Bergen area). Get a line_id from get_departures.

Inputs: line_id, max_results, codespace_id.

list_quaysList quays (platforms) for a stopBInspect

List all quays (platforms/stopping points) at a stop place (Entur), with their public codes, coordinates, and wheelchair access.

Inputs: stop_place_id (required).

lookup_admin_unitLook up municipality and countyBInspect

Find which municipality (kommune) and county (fylke) a location falls in, with official codes (Kartverket). Give either a coordinate or a free-text address.

Inputs: address, latitude, longitude.

lookup_propertyLook up property (matrikkel) infoAInspect

Look up cadastral (matrikkel) identifiers for a property via the open address register (Kartverket): municipality number, gårdsnummer (gnr), bruksnummer (bnr), and festenummer. Give a free-text address or a coordinate. Full ownership data requires Kartverket's authenticated Matrikkel API; this returns the open address-linked identifiers.

Inputs: address, latitude, longitude, max_results.

plan_tripPlan a public transport tripAInspect

Plan a point-to-point public transport journey in Norway (Entur JourneyPlanner). Give each endpoint either as a Stop Place ID or as coordinates. Optionally set a departure or arrival time, filter transport modes, and set walk speed. Returns trip patterns with legs, modes, durations, and realtime times.

Inputs: to_place, arrive_by, date_time, from_place, +7 more.

resolve_stop_placeResolve a place to a Stop Place IDAInspect

Turn a place or address into Entur Stop Place IDs (public transport stops/stations). Use the returned ID with the departure, trip, accessibility, quay, and fare-zone tools.

Inputs: query (required), max_results.

search_addressSearch Norwegian addressesAInspect

Search official Norwegian addresses (Kartverket) and get coordinates. Use query for free text, or the specific fields for a structured search. Wildcards with * are supported (e.g. street 'Storg*'). Returns coordinates, postal code, municipality, and cadastral numbers for each match.

Inputs: query, number, street, max_results, +2 more.

search_place_namesSearch Norwegian place namesAInspect

Search official Norwegian place names (Kartverket Sentralt stedsnavnregister). Returns each name's feature type (e.g. Fjell, Innsjø, By), municipality, county, and coordinates. Supports the * wildcard and corrects small spelling errors.

Inputs: query (required), max_results.

transform_coordinatesTransform coordinates between systemsAInspect

Convert a coordinate between reference systems using Kartverket's transformer. Give EPSG codes for source and target. Axis order: x is easting (longitude for geographic systems), y is northing (latitude). Common EPSG codes: 4326 WGS84, 4258 EUREF89 (both lon/lat), 25832 UTM32/EUREF89, 25833 UTM33, 25835 UTM35 (east/north in metres).

Inputs: x (required), y (required), to_epsg (required), from_epsg (required).

validate_addressValidate and normalize an addressAInspect

Check whether a free-text address exists in the official register and return its normalized form with coordinates. Uses fuzzy matching, so it also corrects small spelling errors. Returns valid, the best normalized match, and alternatives.

Inputs: address (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 21 tools

    Disambiguation5/5

    Each tool targets a distinct resource and action: address search vs. place name search vs. near-location queries, separate tools for elevation, coordinate transformation, admin lookup, property lookup, and transport-specific tools (stops, departures, trip planning, realtime status, accessibility, quays, fare zones, shared mobility, vehicle positions). No two tools have overlapping purposes that would cause misselection.

    Naming Consistency5/5

    The naming follows a consistent verb_noun pattern throughout (e.g., search_address, find_place_names_near, get_elevation, lookup_admin_unit, plan_trip, get_departures). The 'find_*_near' variant is uniformly applied to both addresses and place names, and all tools use snake_case with descriptive verbs. Minor variation like 'list_quays' is still within a clear convention.

    Tool Count4/5

    21 tools is on the higher end of the typical range, but the server covers a broad domain combining location data (addresses, place names, elevation, coordinates) and transport (stops, journeys, realtime, mobility). Each tool serves a distinct function, so the count feels justified for the scope, though it is slightly heavier than the ideal 3-15 tool range.

    Completeness5/5

    The tool surface is remarkably complete for Norwegian location and transport services. It covers address and place name search (with near-location variants), validation, elevation (point and profile), coordinate transformation, administrative unit lookup, property lookup, stop place resolution and reverse geocoding, journey planning, departures, realtime status, accessibility, quay listing, fare zones, and both free-floating and docking shared mobility. No obvious gaps in core workflows were identified.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Provides LLM-friendly weather tools and Norwegian place name resolution via MCP, enabling weather forecasts, air quality, marine conditions, and activity planning.
      1
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Provides access to Norway's nationwide public transport data (all modes) via the Entur API, enabling queries about routes, stops, and departures through natural language.
      156 npm
      MIT
    • A
      license
      B
      quality
      B
      maintenance
      MCP server providing typed tools for Norwegian public data sources, enabling natural language queries to official datasets like SSB, Brønnøysund, MET, Kartverket, Entur, and more, without requiring API keys.
      47
      MIT