An MCP server that lets AI agents query public-transit schedules from 6,000+ GTFS feeds across 99 countries.
gtfs-mcp demonstrates solid tool design with clear naming (verb_noun pattern), comprehensive parameter descriptions, and well-structured schemas using Zod. All 5 tools have descriptions (194 - 250 chars, within baseline 34 - 392 range) and typed parameters with descriptions. Output is JSON-structured. However, output schemas are not formally documented in code, error messages lack recovery guidance, and no tool annotations (readOnlyHint) are present despite all tools being read-only. Parameter validation is minimal, no enums for constrained inputs (e.g., country_code, date format), no explicit format constraints, and no pagination support despite tools returning lists.
Search stops/stations by name within a GTFS feed. Returns stop_id (needed for next_departures), name, and coordinates.
List the routes (lines) in a GTFS feed, with their transit mode.
Get upcoming scheduled departures from a stop, from the feed's static timetable. Provide a stop_id (from find_stops) or a stop_query (name). Optionally filter to a service date (YYYYMMDD) and a start time (HH:MM).
Search the MobilityData Mobility Database for GTFS public-transit feeds by free text (city, agency, region) and/or ISO country code. Returns feed sources, each with a `feed_url` to pass to the other tools.
Download a GTFS feed and summarize it: agencies, counts of routes/stops/trips, transit modes, and the service date range. Pass a feed_url from search_feeds, or any direct GTFS .zip URL.
Output schemas not formally documented. Tools return JSON via json() helper, but no schema definitions are visible in code. LLMs cannot predict response structure for planning downstream calls.
No input validation or enum constraints. country_code accepts any string (should be ISO 3166-1 alpha-2); date accepts any string (should validate YYYYMMDD format); time accepts any string (should validate HH:MM or HH:MM:SS). LLMs will pass invalid values.
Error messages lack recovery guidance. Errors return raw exception messages (e.g., 'summarize_feed failed: <message>') without suggesting next steps or alternative tools. Pattern: recovery-guide.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 61 | 2026-07-28+ | v2 |
No tool annotations. All 5 tools are read-only (no side effects), but readOnlyHint is not declared. Agents cannot distinguish safe tools from destructive ones without explicit hints.
No pagination support. list_routes and find_stops accept limit but no offset/cursor. Large result sets (e.g., 1000+ stops) will blow context window. Pattern: paginated-result.