
Metro MCP
β 3from Aarekaz
A MCP server of washington DC's Metro
π Metro MCP
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, Cursor, Codex, and any client that supports Streamable HTTP MCP servers.
Quick Links: Quick Start β’ What You Can Do β’ Deployment β’ Client Integration
What You Can Do
Ask natural language questions about DC Metro or NYC Subway in Claude Desktop or any MCP-compatible client:
π Real-Time Transit Information
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?"
πΊοΈ Station Information & Navigation
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"
βΏ Accessibility
Washington DC (Elevator Outages):
- "Are there any elevator outages between here and National Airport?"
- "Which DC Metro stations have working elevators right now?"
π Service Monitoring
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"
π System Information
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)
MCP Client Integration
Claude Desktop (Automatic OAuth)
Simple Setup:
Just add the server URL to Claude Desktop:
https://metro-mcp.anuragd.me/mcpClaude 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!
Other MCP Clients
For MCP clients that support OAuth 2.1 with automatic discovery:
Server URL:
https://metro-mcp.anuragd.me/mcpThe client will handle authentication automatically via the OAuth flow.
Manual Token Authentication (Legacy)
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/mcp - Authorization Header:
Bearer your-jwt-token-here
- Server URL:
OAuth Endpoints
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)
Security Features
- PKCE (S256) required for all authorization flows
- Persistent client registration via Cloudflare KV
- JWT tokens with 90-day expiration
- Rate limiting and origin validation
Supported Cities
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) | β | β | β |
Available MCP Tools
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)
Technical Details
MCP Protocol
- Version: 2025-06-18
- Transport: Streamable HTTP via
cloudflare/agentsMcpAgent. Sessions are Durable Object instances (one perMcp-Session-Id) with hibernatable WebSockets β the DO evicts while idle and wakes on incoming messages, so quiet sessions cost nothing. - Authentication: OAuth 2.1 with PKCE (S256) + RFC 8707 resource indicators (audience-bound tokens). The Worker shell verifies the JWT and propagates the user's identity to the DO via
ctx.props. - Tool result shape: Every tool emits
structuredContent(typed object matchingoutputSchema) alongside the legacycontent[0].text(serialized JSON) for backwards compatibility. - Tool annotations: Every tool declares
readOnlyHint,idempotentHint,openWorldHintso clients can render safe-action affordances. - Capabilities exposed:
toolsβ 13 transit query tools (DC + NYC)resourcesβ threetransit://URI templates (stations, routes, incidents)promptsβ three canned templates (service-briefing, commute-planner, accessibility-check)elicitationβ server asks the user to disambiguate when a station name matches multiple platforms- Server push: enabled (DurableObject-backed)
- Resumability: enabled via
DurableObjectEventStore(Last-Event-IDreplay) - Progress notifications: emitted for
get_all_stationswhen the client opts in viaparams._meta.progressToken
Transit APIs
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
Hosting
- Platform: Cloudflare Workers
- Static assets:
public/is deployed through Cloudflare Workers Static Assets and bound asenv.ASSETS; the Worker serves API/OAuth/MCP routes first, then delegates landing-page, docs, image, and icon requests to the assets binding. - Storage:
- Cloudflare KV
OAUTH_CLIENTSβ registered OAuth clients - Cloudflare KV
RATE_LIMIT_KVβ rate-limit counters - Durable Object
MCP_SESSION(classMetroMcpAgent) β per-session MCP state, transport, and event log
- Cloudflare KV
- Runtime: V8 isolates with global edge deployment
Source Structure
The codebase is organized for multi-city transit support with a clean separation of concerns:
src/
βββ index.ts # Cloudflare Worker entry point and DO export
βββ router.ts # Request routing (OAuth, MCP, info, static assets)
βββ server-info.ts # Public /info capability summary
βββ config.ts # Runtime config, caching, and rate-limit defaults
βββ 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-agent.ts # McpAgent tools, resources, prompts, sessions
β βββ mcp/ # MCP response format helpers
β
βββ Middleware
β βββ input-validator.ts
β βββ rate-limiter.ts
β βββ security-headers.ts
β
βββ 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)
βββ nyc-routes.ts # Bundled NYC route metadata
βββ nyc-stations.ts # Bundled NYC station metadataKey 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
# Using Bun (recommended)
bun install
# Or using npm
npm installQuick Start
Using the Public Server
The fastest way to get started is to use the hosted instance:
- Open your MCP Client
- Add this URL:
https://metro-mcp.anuragd.me/mcp - Click "Connect" and authorize via GitHub
- Start asking questions about DC Metro or NYC Subway
Deploy Your Own
Want to run your own instance? See the Deployment section below.
Deployment
Prerequisites
- WMATA API Key (required)
- Cloudflare Account (free tier works)
- Bun or Node.js installed
- GitHub OAuth App (for authentication)
Setup Steps
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.jsonc.
5. Configure environment:
Copy the example files and fill in your values:
# Copy wrangler config
cp wrangler.jsonc.example wrangler.jsonc
# Update the KV namespace IDs in wrangler.jsonc
# 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 deployNo common issues documented yet. If you hit a problem, the repository's GitHub Issues page is the best place to look.
Licensed under MITβ you can use, modify, and redistribute it under that license's terms.
License
MIT License - see LICENSE file for details.
Built with β€οΈ for the Washington DC Metro community