Express API serving real-time Lviv public transport data with read-only MCP endpoint, no API key required.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent — or use 1-click editor setup below.
We ran the install command below but it didn't respond within our test window — this can mean a slow first-time install rather than a real problem.
npx -y @modelcontextprotocol/inspectorNo response to initialize.
This is an experimental automated check and can have false negatives — missing environment variables, a slow cold install, etc. It doesn’t necessarily mean something’s wrong. Last checked 1mo ago.
💡 Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Inspect callable tools, capabilities, and parameters exposed to AI agents by Timetable API Node.
Express-based API for Lviv transport timetable data with a read-only MCP endpoint.
.nvmrc)Two optional integrations, both off unless their environment variable is set:
| Variable | Effect |
|---|---|
SENTRY_DSN | Error reporting via instrument.js |
NEW_RELIC_LICENSE_KEY | New Relic APM via newrelic.cjs |
New Relic runs as a preloaded agent, so npm start carries the flags:
dotenv/config is preloaded first so .env is populated before the agent
reads its configuration. The config file is newrelic.cjs (the agent is
CommonJS and this project is ESM) and holds no secrets — the key comes from the
environment. /health is excluded from transactions via rules.ignore.
The account is in the EU region; its license key starts with eu01xx and
the agent picks the collector from that prefix. Use the 40-character ingest
license key, not an NRAK-... user API key.
Cloud Run reads the key from Secret Manager:
This service exposes a public read-only MCP endpoint over Streamable HTTP.
/mcp/.well-known/mcp/server-card.json/robots.txt (non-standard comment hint)Production deployment (see cloudbuild.yaml for Cloud Run) serves REST and MCP from api.lad.lviv.ua. The main site lad.lviv.ua is the public transport website (this repo still links there in HTML sitemap and tables for people, not for the API host). Use your own origin when running locally.
/mcp flowAn MCP client (Claude, Cursor, or the MCP SDK) talks JSON-RPC over Streamable HTTP to POST /mcp. Tool handlers reuse the same Express actions as the REST API, backed by LokiJS timetable data, GTFS SQLite (via gtfs), and live GTFS-RT feeds (for example track.ua-gis.com).
MCP Inspector (local): run npx @modelcontextprotocol/inspector, then open the UI with transport and server URL prefilled (from the inspector README):
http://localhost:6274/?transport=streamable-http&serverUrl=https%3A%2F%2Fapi.lad.lviv.ua%2Fmcp
POST https://api.lad.lviv.ua/mcp with Content-Type: application/json. The Streamable HTTP transport may require additional headers your MCP client sets automatically; for a quick manual test, follow the same sequence your MCP SDK uses (session initialize, then tools/call). Example tools/call body shape:
Successful tool responses return a natural-language text summary inside MCP content items (type: "text") — e.g. "Stop «Opera»: 3 arrivals. Next: T01 → «Rynok» in 2 min." The full structured payload is in the structuredContent field (for schema-aware clients). Each structuredContent payload follows a strict UI contract:
Consistency rule: each vehicle rendered on map must either have a matching ETA in list data or eta_status: "unassigned".
get_stop_realtimeget_route_staticget_route_realtimeget_stop_geometryget_stops_around_locationget_nearby_vehiclesget_vehicle_infoget_stop_realtime — input & exampleArguments (JSON):
| Field | Type | Required |
|---|---|---|
stop_id | positive integer or digits-only string | yes |
Example result (shape only; values from upstream):
get_route_static — input & exampleArguments (JSON):
| Field | Type | Required |
|---|---|---|
route_name | route short name (e.g. "T30", "32A") or numeric external ID | yes |
Example result (shape only; stops truncated for brevity):
stops[0] is direction 0 (outbound), stops[1] is direction 1 (return). departures and schedule are populated only for the first stop of direction 0; all other stops have empty arrays. schedule.workday contains Monday–Friday departure times; schedule.weekend contains Saturday–Sunday departure times. departures keeps today's schedule for backward compatibility. shapes follows the same two-element order. The map block uses direction-0 polyline and all unique stops as markers.
get_route_realtime — input & exampleArguments (JSON):
| Field | Type | Required |
|---|---|---|
route_name | route short name (e.g. "T30", "32A") or numeric external ID | yes |
Example result:
Factual signals from GitHub, npm, and our automated checks — not a rating.
No reviews yet — be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/vbhjckfd-timetable-api-node)<a href="https://allmcps.com/mcp/vbhjckfd-timetable-api-node"><img src="https://allmcps.com/api/badge/vbhjckfd-timetable-api-node?style=directory" alt="Timetable API Node on AllMCPs" /></a>