Model Context Protocol Server for US Transit Systems (DC Metro & NYC Subway)
A unified remote Model Context Protocol (MCP) server supporting multiple US transit systems. Currently supports Washington DC Metro (WMATA) and New York City Subway (MTA). Built for seamless integration with MCP-compatible clients like Claude Desktop.
Quick Links: Quick Start • What You Can Do • Deployment • Client Integration
Ask natural language questions about DC Metro or NYC Subway in Claude Desktop or any MCP-compatible client:
Washington DC:
- "When is the next Red Line train at Dupont Circle?"
- "What bus routes are available?"
- "Find bus stops near Dupont Circle"
- "Where are all the 30N buses right now?"
- "When is the next bus at stop 1001195?"
- "Show me all trains currently running on the Metro system"
- "Are there any delays on the Blue Line right now?"
- "Are all the elevators working at Union Station?"
New York City:
- "When is the next 1 train at Times Square?"
- "Are there delays on the A/C line?"
- "What trains are arriving at Grand Central?"
- "What is the A train and where does it go?"
- "What nearby stations can I walk to from Times Square?"
- "How long does it take to walk between Times Square platforms?"
Washington DC:
- "Where is the Smithsonian Metro station?"
- "Show me all the stations on the Green Line"
New York City:
- "Where is the Union Square station?"
- "Show me all 496 stations on the NYC Subway"
- "Which stations connect to Times Square?"
- "Explain the difference between express and local trains"
Washington DC (Elevator Outages):
- "Are there any elevator outages between here and National Airport?"
- "Which DC Metro stations have working elevators right now?"
Both Cities:
- "Any transit delays right now in NYC?"
- "Is the DC Metro Orange Line running normally?"
- "Compare service quality between DC Metro and NYC Subway"
Washington DC:
- Complete list of all Metro stations with coordinates
- Information about all six Metro lines (Red, Blue, Orange, Silver, Green, Yellow)
New York City:
- Complete coverage: All 496 NYC Subway stations with coordinates
- Transfer information: Walk times between connected stations (87 stations with transfers)
- Route descriptions: Detailed service patterns for all 29 routes (express vs local, operating hours)
- Platform clarity: Explains directional platforms (e.g., "127N" = northbound at Times Square)
The fastest way to get started is to use the hosted instance:
- Open your MCP Client
- Add this URL:
https://metro-mcp.anuragd.me/sse - Click "Connect" and authorize via GitHub
- Start asking questions about DC Metro!
Want to run your own instance? See the Deployment section below.
- WMATA API Key (required)
- Cloudflare Account (free tier works)
- Bun or Node.js installed
- GitHub OAuth App (for authentication)
1. Install dependencies:
# Using Bun (recommended)
bun install
# Or using npm
npm install2. Generate JWT secret:
openssl rand -hex 323. Create GitHub OAuth App:
- Go to github.com/settings/developers
- Click "New OAuth App"
- Set Homepage URL:
https://metro-mcp.your-subdomain.workers.dev - Set Authorization callback URL:
https://metro-mcp.your-subdomain.workers.dev/callback - Save the Client ID and Client Secret
4. Create KV Namespaces:
# Create OAuth storage namespace
bunx wrangler kv namespace create "OAUTH_CLIENTS"
bunx wrangler kv namespace create "OAUTH_CLIENTS" --preview
# Create rate limiting namespace
bunx wrangler kv namespace create "RATE_LIMIT_KV"
bunx wrangler kv namespace create "RATE_LIMIT_KV" --previewCopy the IDs from the output and update wrangler.toml.
5. Configure environment:
Copy the example files and fill in your values:
# Copy wrangler config
cp wrangler.toml.example wrangler.toml
# Update the KV namespace IDs in wrangler.toml
# Copy local development secrets
cp .dev.vars.example .dev.vars
# Add your actual secrets to .dev.vars6. Set production secrets:
# These are encrypted and stored securely by Cloudflare
bunx wrangler secret put WMATA_API_KEY
bunx wrangler secret put GITHUB_CLIENT_SECRET
bunx wrangler secret put JWT_SECRET7. Deploy:
# Deploy to Cloudflare Workers
bunx wrangler deploySimple Setup:
Just add the server URL to Claude Desktop:
https://metro-mcp.anuragd.me/sse
Claude Desktop will automatically:
- Discover OAuth endpoints via
/.well-known/oauth-authorization-server - Register as a client
- Open your browser for GitHub authentication
- Receive and store the access token
- Connect to the MCP server
No manual token copying required!
For MCP clients that support OAuth 2.1 with automatic discovery:
Server URL:
https://metro-mcp.anuragd.me/sse
The client will handle authentication automatically via the OAuth flow.
If your MCP client doesn't support OAuth, you can still authenticate manually:
- Visit
https://metro-mcp.anuragd.me/authorizein your browser - Authorize via GitHub
- Copy the JWT token displayed
- Configure your client with:
- Server URL:
https://metro-mcp.anuragd.me/sse - Authorization Header:
Bearer your-jwt-token-here
- Server URL:
The server implements OAuth 2.1 with PKCE for secure authentication:
- Discovery:
/.well-known/oauth-authorization-server - Registration:
/register(Dynamic client registration - RFC 7591) - Authorization:
/authorize(GitHub OAuth integration) - Token:
/token(Authorization code exchange with PKCE verification) - Callback:
/callback(GitHub OAuth callback)
- PKCE (S256) required for all authorization flows
- Persistent client registration via Cloudflare KV
- JWT tokens with 90-day expiration
- Rate limiting and origin validation
The server currently supports these transit systems:
| City | System | Real-Time Data | Service Alerts | Elevator Status |
|---|---|---|---|---|
| Washington DC | WMATA (Metro) | ✅ | ✅ | ✅ |
| New York City | MTA (Subway) | ✅ | ✅ | ❌ |
The server exposes the following tools through the MCP protocol:
| Tool | Description | Supported Cities |
|---|---|---|
get_station_predictions |
Get real-time train arrival predictions for a station | DC, NYC |
search_stations |
Search for stations by name or code | DC, NYC |
get_stations_by_line |
Get all stations on a specific line | DC, NYC |
get_incidents |
Check current service disruptions and advisories | DC, NYC |
get_all_stations |
Get a complete list of all stations with coordinates | DC, NYC |
get_station_transfers 🆕 |
Get transfer connections and walk times between nearby stations | NYC only |
get_route_info 🆕 |
Get detailed route information (express/local, service patterns, hours) | NYC only |
get_elevator_incidents |
Find elevator and escalator outages | DC only |
get_bus_predictions |
Get real-time bus arrival predictions (7-digit stop ID) | DC only |
get_bus_routes |
Get list of all available bus routes | DC only |
get_bus_stops |
Search bus stops by location or get all stops | DC only |
get_bus_positions |
Get live positions of all buses (optionally filter by route) | DC only |
get_train_positions |
Get live positions of all trains on the system | DC only |
Total: 13 MCP tools (11 core + 2 new NYC-specific tools)
- Version: 2025-03-26
- Transport: SSE (Server-Sent Events)
- Authentication: OAuth 2.1 with PKCE (S256)
WMATA (DC Metro):
The server interfaces with the official WMATA REST APIs. Visit WMATA's developer documentation for details:
- Station predictions: Real-time train arrival information
- Station information: Station names, codes, and locations
- Incidents: Service disruptions and advisories
- Elevator/escalator outages: Accessibility information
MTA (NYC Subway):
The server uses GTFS-Realtime feeds from the MTA. Public API endpoints (no API key required):
- Real-time feeds: Protocol Buffers format with 30-second update intervals
- 8 separate feeds: Covering all subway lines (1-7, A/C/E, B/D/F/M, etc.)
- NYCT extensions: Train IDs, track assignments, and direction information
- Service alerts: Embedded in GTFS-Realtime alert entities
- Platform: Cloudflare Workers
- Storage: Cloudflare KV (for OAuth client registration)
- Runtime: V8 isolates with global edge deployment
The codebase is organized for multi-city transit support with a clean separation of concerns:
src/
├── index.ts # Cloudflare Worker entry point
├── router.ts # Request routing (OAuth, MCP, API endpoints)
├── types.ts # Shared TypeScript type definitions
│
├── OAuth & Authentication
│ ├── auth.ts # JWT token management and verification
│ └── oauth-handler.ts # OAuth 2.1 flow implementation with PKCE
│
├── MCP Protocol
│ ├── mcp-handler.ts # MCP request processing and tool routing
│ ├── mcp-tools.ts # MCP tool definitions (11 tools)
│ └── mcp-types.ts # MCP protocol type definitions
│
├── Error Handling
│ └── error-handler.ts # Multi-city validation and error handling
│
└── Transit Abstraction Layer
├── base.ts # Abstract TransitAPIClient class
├── registry.ts # Transit client factory (city routing)
├── wmata-client.ts # DC Metro client (WMATA REST APIs)
└── mta-client.ts # NYC Subway client (GTFS-Realtime)
Key Architecture Decisions:
- Transit Abstraction: Common
TransitAPIClientinterface enables easy addition of new cities (BART, MBTA, etc.) - City Routing: Single server handles all cities via
cityparameter in MCP tool calls - Normalized Responses: All transit clients return standardized
TransitStation,TransitPrediction, andTransitIncidenttypes - Extensibility: Adding a new city only requires implementing the abstract client class
Contributions are welcome! Feel free to:
- Report bugs or request features via GitHub Issues
- Submit pull requests with improvements
- Share feedback on the MCP implementation
MIT License - see LICENSE file for details.
Built with ❤️ for the Washington DC Metro community