Skip to main content
Glama
Live Transit MCP Server

Live Transit MCP Server

by loama
README.md
# Live Transit

Live status, alerts, line maps and vehicle positions for public transport networks worldwide, straight from the
operators. Metros, trains, trams, buses, ferries and airport boards from about 300 sources in dozens of countries,
normalized into one data model and served as a website, a REST API and an MCP server.

Live at [livetransit.vercel.app](https://livetransit.vercel.app).

- **Website**: a live map of every vehicle and line, network and line pages with status and alerts, airport boards.
- **REST API**: `/api/v1/*`, documented at `/api/v1/openapi.json` and on the `/developers` page.
- **MCP server**: `/api/mcp` (Streamable HTTP), with tools such as `search`, `network_status`, `line_status`,
  `disruptions`, `airport` and `vehicles_near`. A plain-text guide for agents is at `/llms.txt`.

## How it works

- **Connectors** (`src/connectors/`) each read one operator feed (GTFS-Realtime, a JSON or XML API, a flight
  board, or a scraped status page) and return alerts, line statuses, vehicles, stations and departures in the
  shared model in `src/lib/types.ts`. Around 230 standard GTFS-Realtime feeds come from the
  [Mobility Database](https://mobilitydatabase.org) catalog (`scripts/gen-global-gtfs.ts`); the rest are written
  by hand.
- **Ingest** (`src/ingest/runner.ts`) polls each source on its own interval from a once-a-minute cron, with
  backoff for failing feeds, and stores the latest snapshot in Postgres.
- **Line catalog**: most realtime feeds name routes only by id, so each source is linked to its static GTFS
  schedule (`src/connectors/static-gtfs.json`, generated by `bun scripts/gen-static-gtfs.ts`). Routes, colors and
  simplified shapes are imported into the `routes` table by reading only `routes.txt`, `trips.txt` and
  `shapes.txt` over HTTP Range requests, so even 500 MB feeds import in about a minute. On every ingest,
  vehicles get route names and colors from the catalog, and sources without per-line status get one line per
  route, with state derived from the alerts that name it.
- **Realtime reads**: `GET /api/v1/sources/{id}/live` reads the operator's vehicle feed on request (cached for
  about 10 seconds) when the connector supports it. The maps poll it and animate vehicles between updates.
- **Maps** use [MapLibre GL](https://maplibre.org) with [OpenFreeMap](https://openfreemap.org) tiles built from
  OpenStreetMap data. No API key needed.

## Running locally

Requires [Bun](https://bun.sh).

```bash
bun install
cp .env.example .env.local

# A local Postgres. Any Postgres 15+ with pg_trgm works; this one needs no install.
bunx pglite-server --db=.localdb/pg --port=5433 -e pg_trgm --max-connections=4

bun run db:migrate             # apply src/db/schema.sql (idempotent)
bun run ingest --force         # poll every source once
bun run import:static          # import line catalogs and route shapes (a few minutes for all sources)
bun run dev                    # http://localhost:3000
```

Other scripts:

| Command | What it does |
|---|---|
| `bun run try <id or prefix> [--json]` | Run connectors live without a database and print samples |
| `bun run ingest [--force] [id ...]` | Run due (or all) connectors against `DATABASE_URL` |
| `bun run import:static [--force] [id ...]` | Import static GTFS line catalogs |
| `bun test` | Unit, API and MCP tests (API tests need `DATABASE_URL`; connector tests hit live feeds) |
| `bun run typecheck`, `bun run lint` | Static checks |

## Deploying

Built for Vercel with a Postgres database such as Neon. Set `DATABASE_URL` and `CRON_SECRET`; the crons in
`vercel.json` poll sources every minute, prune old rows hourly and refresh line catalogs.

## Data and licenses

The code is MIT licensed (see `LICENSE`). Transit data belongs to the operators and is used under each feed's
own terms; every source lists its operator, license and endpoints on its network page and in the API.
This project is not affiliated with any operator and is not a substitute for official information.