vbhjckfd avatar

Lviv Public Transport

vbhjckfd/timetable-api-node

Provides programmatic access to Lviv's public transport network through eight MCP tools wrapping a read-only Express API. You can query stop arrivals with ETAs and live vehicle positions, fetch static route geometry and timetables, search stops by radius, plan trips, and pull individual vehicle telemetry. The backend runs LokiJS for timetable lookups, SQLite for GTFS static data, and polls GTFS-RT feeds for real-time updates. All tool responses return a natural-language summary plus structured JSON blocks designed for map and list rendering. Deploy it locally or point Claude at the public streamable-http endpoint at api.lad.lviv.ua/mcp. No API key, no rate limits mentioned.

GitHub stars
3
tools
9
transport
HTTP
last updated
Nov 11, 2026

Install

From registry metadata
$ npx add-mcp https://api.lad.lviv.ua/mcp --name timetable-api-node

Run in your terminal. add-mcp asks which agents to add it to (Claude Code, Codex, Cursor and more). Add -g to install it for every project.

Review the command, arguments and environment values before installing. MCP servers run with your local permissions.

Other ways

Claude Code

$ claude mcp add --transport http timetable-api-node https://api.lad.lviv.ua/mcp

Run in your terminal. Add --scope user to make it available in every project.

Tools

Verified live · 9 tools

Verified live against the running server on Nov 6, 2026.

get_stop_realtimeReturns live arrivals at a stop: route, destination, vehicle type, minutes until arrival, and each vehicle's position. Use this as the **default tool** when the user asks about arrivals, departures, or the next bus/tram at a specific stop. Requires a numeric stop ID (shown on...2 params

Returns live arrivals at a stop: route, destination, vehicle type, minutes until arrival, and each vehicle's position. Use this as the **default tool** when the user asks about arrivals, departures, or the next bus/tram at a specific stop. Requires a numeric stop ID (shown on...

Parameters* required
lowfloor_onlyboolean
Only low-floor arrivals (step-free: wheelchairs, prams). Timetable entries without a tracked vehicle are left out, since their floor is unknown. Default false.
stop_id*integer
Municipal stop code shown on stop signage (e.g. 707). Accepts a positive integer or an equivalent digit-only string.
search_stopsFinds stops by name (Ukrainian or English transliteration, case-insensitive, partial match) and returns each stop's numeric ID, coordinates, and the routes serving it. Use this as the **first step** when the user names a stop or landmark stop (e.g. "Опера", "Rynok", "Головний...2 params

Finds stops by name (Ukrainian or English transliteration, case-insensitive, partial match) and returns each stop's numeric ID, coordinates, and the routes serving it. Use this as the **first step** when the user names a stop or landmark stop (e.g. "Опера", "Rynok", "Головний...

Parameters* required
limitinteger
Maximum stops to return (1–25, default 10).
query*string
Stop name or part of it, e.g. "Ринок", "opera", "Стрийська".
find_routes_betweenLists the routes from one place to another: which stop to board, where to get off, the direction's destination, stops in between, and the walk at each end — best first, walking counted. Each end is a stop ID (`from_stop_id`) or coordinates (`from_lat` + `from_lng`), e.g. an ad...8 params

Lists the routes from one place to another: which stop to board, where to get off, the direction's destination, stops in between, and the walk at each end — best first, walking counted. Each end is a stop ID (`from_stop_id`) or coordinates (`from_lat` + `from_lng`), e.g. an ad...

Parameters* required
arrive_bystring
Arrive by this time: "HH:MM" Lviv time today, or ISO 8601. Not together with `depart_at`.
depart_atstring
Leave at this time: "HH:MM" Lviv time today, or ISO 8601. Default now. Not together with `arrive_by`.
from_latnumber
Decimal latitude of the start point, WGS84 (e.g. 49.842 for central Lviv).
from_lngnumber
Decimal longitude of the start point, WGS84 (e.g. 24.031 for central Lviv).
from_stop_idinteger
Stop ID where the trip starts. Give this or `from_lat` + `from_lng`.
to_latnumber
Decimal latitude of the destination, WGS84 (e.g. 49.842 for central Lviv).
to_lngnumber
Decimal longitude of the destination, WGS84 (e.g. 24.031 for central Lviv).
to_stop_idinteger
Stop ID where the trip ends. Give this or `to_lat` + `to_lng`.
get_route_staticReturns static route data: name, long name, vehicle type, colour, the ordered stop list for both directions, and the timetable of departures from the first stop (workday, Saturday and Sunday). Use when the user asks which stops a route serves, where it goes, or its scheduled d...2 params

Returns static route data: name, long name, vehicle type, colour, the ordered stop list for both directions, and the timetable of departures from the first stop (workday, Saturday and Sunday). Use when the user asks which stops a route serves, where it goes, or its scheduled d...

Parameters* required
include_shapesboolean
Include route polylines ([lat, lng] points per direction) for map drawing. Default false.
route_name*string
Route short name (e.g. "T30", "32A") or numeric external ID.
get_route_realtimeReturns every vehicle currently running on a route: position, the destination it is heading to, and its next stop with estimated arrival. `headways` sums up each direction: how many vehicles run, the live gaps between consecutive vehicles in minutes (front to back), and how of...2 params

Returns every vehicle currently running on a route: position, the destination it is heading to, and its next stop with estimated arrival. `headways` sums up each direction: how many vehicles run, the live gaps between consecutive vehicles in minutes (front to back), and how of...

Parameters* required
directioninteger
Only vehicles heading this way: 0 or 1, the index into get_route_static's `stops`. Omit for both.
route_name*string
Route short name (e.g. "T30", "32A") or numeric external ID.
get_disruptionsLists closures, detours and moved stops the city announced that are in force today: affected routes, the streets a detour uses, routes to take instead of a suspended one, reason, dates and source. The GTFS stop lists and timetables do not reflect any of this. Use when the user...2 params

Lists closures, detours and moved stops the city announced that are in force today: affected routes, the streets a detour uses, routes to take instead of a suspended one, reason, dates and source. The GTFS stop lists and timetables do not reflect any of this. Use when the user...

Parameters* required
routestring
Only disruptions on this route, by short name (e.g. "Т30", "А34"). Omit for all routes.
stop_idinteger
Only disruptions at this stop. Omit for all stops.
get_stops_around_locationFinds stops near a geographic point, returning each stop's numeric ID, name, coordinates, walking distance, and the routes serving it. Use this as the **first step** when the user gives an address or coordinates and you need stop IDs for `get_stop_realtime` or `find_routes_bet...3 params

Finds stops near a geographic point, returning each stop's numeric ID, name, coordinates, walking distance, and the routes serving it. Use this as the **first step** when the user gives an address or coordinates and you need stop IDs for `get_stop_realtime` or `find_routes_bet...

Parameters* required
latitude*number
Decimal latitude of the search centre, WGS84 (e.g. 49.842 for central Lviv).
longitude*number
Decimal longitude of the search centre, WGS84 (e.g. 24.031 for central Lviv).
radius_metersinteger
Search radius in metres (50–3000, default 1000). Use ~300 for dense urban intersections, up to 3000 for suburban or rural areas.
get_nearby_vehiclesReturns live vehicles near a point, nearest first, each with its route, destination, and distance. Use when the user asks "what transport is near me right now?" or wants a live map around a location. Narrow with `route` when the user cares about one line; prefer `get_route_rea...6 params

Returns live vehicles near a point, nearest first, each with its route, destination, and distance. Use when the user asks "what transport is near me right now?" or wants a live map around a location. Narrow with `route` when the user cares about one line; prefer `get_route_rea...

Parameters* required
latitude*number
Decimal latitude of the centre point, WGS84 (e.g. 49.842 for central Lviv).
limitinteger
Maximum vehicles to return, nearest first (1–50, default 15). `total` reports how many were in range.
longitude*number
Decimal longitude of the centre point, WGS84 (e.g. 24.031 for central Lviv).
lowfloor_onlyboolean
Only low-floor vehicles (step-free: wheelchairs, prams). Timetable entries without a tracked vehicle are left out, since their floor is unknown. Default false.
radius_metersinteger
Search radius in metres (100–1000, default 500).
routestring
Only vehicles on this route, by short name (e.g. "Т30", "А1"). Omit for all routes.
get_vehicle_infoReturns details for one vehicle by ID: position, route, destination, license plate, and its upcoming stops with names and estimated arrival times. Use when the user wants to follow a particular vehicle, e.g. "where does this tram go next?" or "when will it reach X?". Vehicle I...1 params

Returns details for one vehicle by ID: position, route, destination, license plate, and its upcoming stops with names and estimated arrival times. Use when the user wants to follow a particular vehicle, e.g. "where does this tram go next?" or "when will it reach X?". Vehicle I...

Parameters* required
vehicle_id*string
Vehicle ID as returned by get_route_realtime, get_nearby_vehicles, or get_stop_realtime.

Sponsors

Readme

Timetable API Node

CI Node.js License: WTFPL MCP Registry

Express-based API for Lviv transport timetable data with a read-only MCP endpoint.

smithery badge vbhjckfd/timetable-api-node MCP server


View the full README on GitHub

Details

Repository
github.com/vbhjckfd/timetable-api-node
Website
lad.lviv.ua
Transport
HTTP
Registry
MCP registry, active
Resources
4
Prompts
5
Tools verified
Nov 6, 2026