ttc-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| PORT | No | The HTTP port when --port isn't given; Cloud Run sets it. | 8080 |
| BASE_URL | No | The service's public origin; the OAuth redirect URI is BASE_URL/auth/callback. | |
| TTC_MCP_UA | No | The User-Agent on every request; several TTC servers refuse Python's default. If you run a copy, set your own contact here. | ttc-mcp/<version> (+https://github.com/LunaParker/ttc-mcp) |
| TTC_MCP_NOW | No | Pins the clock used for timetable lookups and closure windows to an ISO 8601 time, read as Toronto time when it has no offset; live feeds still answer with today's data. | |
| FASTMCP_HOME | No | Read by FastMCP: without Firestore the gate's OAuth state lives here, encrypted with a key derived from JWT_SIGNING_KEY. | FastMCP's per-user data directory |
| TTC_MCP_CACHE | No | Where the timetable files, their manifest.json and the build's downloads live. The image sets /data. | ~/.cache/ttc-mcp |
| ALLOWED_EMAILS | No | The Google accounts allowed in, comma-separated; an empty list refuses to start. | |
| TTC_MCP_PULL_S | No | How often the HTTP server pulls the bucket; values under 60 are refused. | 21600 |
| JWT_SIGNING_KEY | No | Signs the tokens the server issues. | |
| TTC_MCP_TRANSPORT | No | The transport when --transport isn't given. The image sets http. | stdio |
| GOOGLE_CLOUD_PROJECT | No | Keeps the OAuth state in this project's Firestore database. Unset by default, with OAuth state in encrypted files under FASTMCP_HOME. | |
| JWT_SIGNING_KEY_FILE | No | A file holding the JWT signing key, read and trimmed at startup, instead of the variable itself (never both); an unreadable or empty file refuses to start. | |
| TTC_MCP_SKIP_REFRESH | No | 1, true or yes skips the startup portal check and the 24-hour recheck. The image sets 1. | off |
| TTC_MCP_STATIC_BUCKET | No | HTTP server: pull the timetable from this Cloud Storage bucket at startup and every TTC_MCP_PULL_S seconds, and never check the portal. Build: pull the bucket's timetable first and push the result after. Needs the cloud extra (uv sync --extra cloud) and Google Cloud credentials. | |
| GOOGLE_OAUTH_CLIENT_ID | No | Turns on Google sign-in for the HTTP server; the next four become required, and a half-configured gate refuses to start. | |
| STORAGE_ENCRYPTION_KEY | No | The Fernet key that encrypts the OAuth state; required with GOOGLE_CLOUD_PROJECT. | |
| GOOGLE_OAUTH_CLIENT_SECRET | No | The OAuth client's secret. | |
| STORAGE_ENCRYPTION_KEY_FILE | No | A file holding the storage encryption key, read and trimmed at startup, instead of the variable itself (never both); an unreadable or empty file refuses to start. | |
| GOOGLE_OAUTH_CLIENT_SECRET_FILE | No | A file holding the OAuth client secret, read and trimmed at startup, instead of the variable itself (never both); an unreadable or empty file refuses to start. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": true
} |
| resources | {
"subscribe": false,
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| find_stopsB | Find TTC stops, platforms or stations by name, stop number, station name or alias (e.g. "Dundas" resolves to TMU). Stops are directional: the two sides of an intersection are different stop numbers with different headsigns. |
| nearest_stopsB | Stops and stations nearest to a coordinate (geocode addresses with a maps tool first), with walk minutes, the routes, directions and headsigns served, and active disruptions per result. |
| stopB | One stop or platform by public stop number: name, coordinates, wheelchair flag, routes/directions/headsigns served, station membership, and the disruptions touching it (its station's closures, detours skipping it, alerts on its routes). |
| stationB | A subway or LRT station by id, name or alias: rail platforms (with open/closed status), surface stops at the station (bus bays, streetcar platforms, with status), entrances, accessibility summary from the rail platforms, service per line (normal / reduced / suspended with the closure), and every disruption touching the station. |
| routesA | All TTC routes with mode (subway, lrt, streetcar, bus), series (rail, bus, express, blue-night, community, streetcar), service hours by day type and overnight share. overnight=true lists the Blue Night network. |
| route_stopsB | Ordered stops for a route and direction, grouped by stop pattern (branches, short turns) with trip counts, headsigns, typical minutes from the first stop, and a status per stop: open, closed (station closure) or skipped_by_detour. |
| service_hoursB | Whether a route runs on a date (calendar plus holiday exceptions) and its first and last trip times. GTFS times past 24:00 belong to the previous service day. |
| scheduled_departuresA | Timetable departures at a stop from a given time (default now), including previous-service-day trips that run past midnight. Schedule only; use arrivals for real time. |
| arrivalsB | Next vehicles at a bus or streetcar stop (BusTime predictions, crowding from the vehicle feed) or next trains at a rail platform (NTAS). Rows carry basis realtime or schedule: when no real-time prediction exists the timetable fills in and a note says so. A rail platform inside an active closure answers no arrivals at all (NTAS keeps predicting there) with a note and the closure. Every row carries detour_id (the vehicle's trip is on a detour) and the answer lists the stop's disruptions. Answers are best effort, from the TTC's own site endpoints; historical occupancy is out of scope. |
| next_trainsA | Next trains at every rail platform of a station (id, name or alias such as "Dundas" or "Bloor") or at one platform id, from the TTC's NTAS. A platform with no prediction falls back to the timetable (service no_prediction); an empty NTAS answer never means no trains. A platform inside an active closure is service suspended with the closure and no minutes (next_min [], no basis, NTAS's own numbers in ntas_min, no timetable); a closure's end station keeps real minutes on the platform facing the open line. Answers are best effort, from the TTC's own site endpoint. |
| vehiclesA | Live positions of the buses and streetcars on a route, or one vehicle by fleet number: coordinates, bearing, speed, current stop (public number), headsign and crowding. Rail lines (1, 2, 4, 5, 6) publish no positions and answer unavailable; use next_trains. Answers are best effort, from the TTC's BusTime GTFS-Realtime feed; historical occupancy is out of scope. |
| feed_statusA | Freshness of the static feed and of every real-time source as cached in this process (TTL state, age, feed timestamp, last error, NTAS coverage per line). probe=true makes one live request per source. |
| alertsA | Current TTC alerts as normalised elements: subway closures (with nightly windows and shuttle info), surface suspensions and detours (alerts and the TripModifications feed), reduced speed zones, elevator and escalator outages. Filter by route, station (id, name or alias), stop number or type. Stations and stops are resolved to objects; times are America/Toronto. Answers are best effort, from the TTC's own site endpoints. |
| service_statusA | The first call for any trip or "what's going on" question: subway closures as station spans with windows, active_now and shuttle info; suspended or detoured surface routes (with skipped-stop counts and reasons); reduced speed zones; elevators and escalators out by station; counts and as_of. Answers are best effort, from the TTC's own site endpoints. |
| detoursB | Active surface detours from the TTC's TripModifications feed, grouped by detour id: per pattern the skipped stops, where the vehicle leaves and rejoins the route, the detour path (encoded polyline and length), trips affected, service dates, and the reason when a service change matches (null otherwise). Answers are best effort, from the TTC's own site endpoints. |
| service_changesA | Board-period route changes: GTFS-RT MODIFIED_SERVICE alerts (title, text, period, url, routes) merged with ttc.ca's service-changes list when published. Filter by route and by a date the change must cover. Answers are best effort, from the TTC's own site endpoints. |
| route_shapeA | The geometry of a route and direction: the most-used stop pattern's shape (or another pattern by rank) as an encoded polyline or GeoJSON LineString, with its stops and their distance along the shape. Optional Douglas-Peucker simplification (metres) and a from_stop/to_stop span sliced by shape_dist_traveled (the first visit of each when a stop repeats). |
| accessibilityA | Accessibility of a station (id, name or alias) or a stop: platform and entrance wheelchair flags, the station summary, elevator and escalator units with their levels and live status (alerts joined to pathway nodes by unit code; codes without a node are reported with node_match false), uncoded node counts and a step-free verdict with its basis. Outages announced but not yet active are listed under upcoming and leave the units and the verdict alone. A platform or entrance id answers for its station, with queried_platform or queried_entrance naming what was asked. |
| connectionsA | Timetable-exact trips between two places on the TTC: every ride is a real trip with its departure and arrival, transfers are timed (walking or station pathways plus a 2-minute change buffer), and the options are the Pareto set over arrival time and transfers, ranked by arrival. origin and destination are a stop number, a station id or alias, or {"lat", "lon"} from a geocoder. depart_at (ISO, Toronto when it has no offset; default now) with window_min (0 to 60, default 30) returns the journeys found every five minutes across the window (every ten when window_min is over 30), one per route sequence; arrive_by instead returns the latest departures that arrive on time, latest first, the first within five minutes of the latest that does; give one or the other. max_transfers is 0 to 3, walk_m (metres to and from the stops) 1 to 2000, limit 1 to 10. Each ride carries basis realtime (an update was applied to its trip, within an hour of now), schedule, or estimate; the first ride lists the next departures in its direction. A closure masks the closed section; when its shuttle runs the shuttle is an estimated leg (assumed headway and speed, stated in its note) and the option is flagged estimate: true and ranked last. A detoured route's trips skip their stops with the published delay. Every option lists the disruptions it touches with the legs they affect, and an empty answer says why. Closures are judged at the query instant, so the note names one that starts or ends inside the search. Live departures and disruptions are best effort, from the TTC's own site endpoints. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 19 tools
Most tools have distinct roles, but several clusters overlap: alerts, service_status, detours and service_changes all surface disruption data; arrivals and next_trains both return next trains at platforms; and stop, station, accessibility and nearest_stops/find_stops all resolve locations. The detailed descriptions do provide routing hints (e.g. 'Schedule only; use arrivals for real time', 'service_status is the first call'), which mitigates but does not eliminate misselection risk.
All names use snake_case, giving a consistent surface form. Most are noun-only (stop, station, routes, alerts, accessibility), with a minority using verb_noun (find_stops, nearest_stops), which is a minor stylistic deviation but still readable and predictable.
19 tools is at the heavy end but each maps to a distinct slice of a genuinely large transit domain (search, real-time, schedules, disruptions, accessibility, trip planning, geometry, feed health). It is slightly over the comfortable range, but no tool appears clearly redundant.
The surface covers the full rider lifecycle: discovery (find/nearest/stop/station), routing (routes/route_stops/route_shape), scheduling (service_hours/scheduled_departures), real-time (arrivals/next_trains/vehicles), disruptions (alerts/service_status/detours/service_changes), accessibility, and trip planning (connections), plus feed health. No obvious operational gaps remain for a TTC transit server.