uk-rail-mcp
README.md
# uk-rail-mcp
MCP server for live UK rail data, using the free-for-personal-use [Realtime Trains next-generation API](https://api-portal.rtt.io), with pre-filled thetrainline.com booking links. Trainline itself has no public API, so this wraps open rail data and hands off to Trainline for purchase.
## Tools
- `search_stations` — name/CRS lookup (2,608 GB stations bundled)
- `live_departures` — live board for a station, optionally filtered to a destination; includes a Trainline booking link when filtered
- `live_arrivals` — live arrivals board
- `service_details` — full calling pattern + real-time info for one train
- `trainline_booking_link` — pre-filled thetrainline.com search URL
## Setup
1. Sign in at https://api-portal.rtt.io (needs an RTT unified login account) and request an API token. The portal issues either a long-life **access token** or a **refresh token** — it will tell you which.
2. Build:
```bash
npm install
npm run build
```
### Run as a remote server (default) — for claude.ai custom connectors
```bash
RTT_ACCESS_TOKEN=... MCP_PATH_TOKEN=some-long-random-string npm start
# or, if the portal gave you a refresh token:
RTT_REFRESH_TOKEN=... MCP_PATH_TOKEN=some-long-random-string npm start
```
Serves Streamable HTTP MCP at `POST /mcp/<MCP_PATH_TOKEN>` (or `/mcp` if no token is set), plus `GET /healthz`. Stateless mode: no sessions, safe behind load balancers.
Claude connects from Anthropic's cloud, not your machine, so the server must be publicly reachable — deploy to Railway, Fly.io, Render, or any VPS (all read `PORT` automatically). Then in claude.ai: **Settings → Connectors → Add custom connector**, and paste `https://your-host/mcp/<token>`.
The path token is lightweight access control (this server has no OAuth): anyone with the full URL can burn your RTT quota, so use a long random token and treat the URL as a secret. For anything beyond personal use, put proper OAuth in front (the MCP SDK supports it).
### Run locally in Claude Desktop instead
```bash
node dist/index.js --stdio
```
`claude_desktop_config.json`:
```json
{
"mcpServers": {
"uk-rail": {
"command": "node",
"args": ["/absolute/path/to/trainline-mcp/dist/index.js", "--stdio"],
"env": {
"RTT_ACCESS_TOKEN": "your-token-from-api-portal.rtt.io"
}
}
}
}
```
## Things to verify (unofficial/undocumented behaviour)
- The client targets the RTT **next-generation** API (base `https://data.rtt.io`, bearer auth) and was written directly against the official OpenAPI spec (https://realtimetrains.github.io/api-specification/). Field parsing should be sanity-checked against one real response once you have a token.
- RTT forbids putting tokens in distributable client apps; this server-side proxy pattern is exactly what they require, but keep the token out of the repo.
- The Trainline deep-link format (`/book/results?origin=...&destination=...`) is not officially documented and may change — test one link in a browser.
## Limitations / roadmap
- UK (GB) only — RTT has no European coverage.
- No fares or journey planning with pricing; that data is licence-gated (National Rail OJP / Rail Data Marketplace, or a Trainline Partner Solutions agreement).
- No booking — deliberate; handled by the Trainline handoff link.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues