Journey Planner MCP
MCP server for Norwegian/Nordic public transport — trip planning, real-time departures, nearby stops, shared mobility, service alerts and geocoding, exposed as Model Context Protocol tools with embedded interactive UIs.
Journey Planner MCP is a Model Context Protocol (MCP) server in front of Entur's public travel APIs: the Journey Planner (OpenTripPlanner transmodel GraphQL), the Geocoder and the Mobility API. Connect it to an MCP-capable AI client (Claude, ChatGPT, GitHub Copilot, Cursor, …) and the assistant can plan trips, show live departure boards, find stops and rental vehicles near a place, and report service disruptions across Norway.
Connecting
Point your MCP client at https://api.entur.io/journey-planner-mcp/v1/mcp.
The endpoint is public and needs no authentication. It serves Entur's
open travel data only, holds no user data, and reads nothing on the
caller's behalf.
Interactive UIs (MCP Apps)
trip, departures, nearby-stops and nearby-mobility are
MCP Apps
tools: each names a ui:// HTML resource in _meta.ui.resourceUri
(a trip map, a departure board, a nearby-stops map and a
shared-mobility map). Hosts that support MCP Apps render it in a
sandboxed iframe; other hosts simply show the tool's text result.
The UIs call two app-only tools, poll-departures and poll-trip, to
refresh a departure board or re-plan a trip. Their _meta.ui.visibility
is ["app"], so hosts do not offer them to the model.
The apps load no third-party script: their libraries (Leaflet and the
MCP Apps SDK) are inlined into the HTML. Each resource declares a
content-security policy in _meta.ui.csp that admits only
OpenStreetMap tiles and the Entur API hosts (plus their WebSocket
endpoints for live vehicle positions on the trip map).
Tool results
The UI tools return a slim JSON document as content[0].text for the
model and carry the fields only the UI needs (geometry, styling data
and the like) under _meta["org.entur/ui"], so they do not consume the
model's context. A UI degrades gracefully when a host strips _meta.
geocode and alerts return plain JSON text.
trip, departures, nearby-stops and nearby-mobility take a
required language parameter (en, nb or nn; anything else falls
back to en), which the model detects from the conversation and which
sets the UI language.
An empty trip result carries a top-level noTripsFound advisory: the
query was valid and repeating it will not help. When a search with a
departureTime finds nothing, the server asks once more with a
day-long search window and reports the next available
nextDepartureTime.
Tool errors are returned as a JSON error document in the tool result
(error, message, type, details), never as internal stack
traces.
See the opentripplanner-mcp repository for the source, configuration and local development.