Metro MCP
Provides real-time train arrival predictions, service alerts, station information, route details (express/local, operating hours), and transfer walk times for the New York City Subway (MTA).
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Metro MCPWhen is the next Red Line train at Dupont Circle?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
π 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 β’ Transit Board β’ 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)
Related MCP server: marta-mcp
Quick 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/mcpClick "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 for package management
Node.js for Wrangler and the Workerd Vitest pool; Bun remains the sole package manager and lockfile owner
GitHub OAuth App (for authentication)
Environment setup
Install exactly what bun.lock records:
bun install --frozen-lockfileFor local development, create a dedicated GitHub OAuth App whose callback is exactly http://localhost:8787/callback. Then copy the canonical .dev.vars.example template, replace every replace-with-... placeholder, and start Wrangler:
cp .dev.vars.example .dev.vars
bun run devKeep the template's http://localhost:8787 origin, localhost host/origin allowlists, callback, and ENVIRONMENT=development values together. In Wrangler's default local mode, the configured OAUTH_KV binding uses local non-production storage under .wrangler; it does not read or write the deployed production or preview namespace. Do not add --remote for normal local development.
Create one OAuth Provider namespace for each deployed environment and put its ID in the corresponding OAUTH_KV binding:
bunx wrangler kv namespace create OAUTH_KV
bunx wrangler kv namespace create OAUTH_KV_previewProduction and preview must also use distinct GitHub OAuth apps. Configure each callback as ${MCP_PUBLIC_ORIGIN}/callback; never reuse the production app or OAuth KV for preview. Each environment sets:
MCP_PUBLIC_ORIGIN,MCP_ALLOWED_HOSTNAMES, andMCP_ALLOWED_ORIGIN_HOSTNAMESOAUTH_REDIRECT_URIand the environment's public GitHubGITHUB_CLIENT_IDENVIRONMENT(production,preview, ordevelopment)OAUTH_KV, pointing at the environment's dedicated namespace
Set production secrets interactively. MCP_REQUEST_STATE_KEY is a stable, environment-specific 32-byte-or-longer key used only for signed MRTR state. JWT_SECRET remains temporarily for the legacy /mcp-audience bridge.
bunx wrangler secret put MCP_REQUEST_STATE_KEY
bunx wrangler secret put GITHUB_CLIENT_SECRET
bunx wrangler secret put WMATA_API_KEY
bunx wrangler secret put JWT_SECRETSet the same four secret names independently for preview; named Wrangler environments do not inherit production secrets:
bunx wrangler secret put MCP_REQUEST_STATE_KEY --env preview
bunx wrangler secret put GITHUB_CLIENT_SECRET --env preview
bunx wrangler secret put WMATA_API_KEY --env preview
bunx wrangler secret put JWT_SECRET --env previewWrangler must include both nodejs_compat and global_fetch_strictly_public. Validate both shapes before any approved deployment:
bunx wrangler deploy --dry-run --outdir /tmp/metro-mcp-production
bunx wrangler deploy --dry-run --env preview --outdir /tmp/metro-mcp-previewMCP Client Integration
Claude
Use the canonical Streamable HTTP endpoint in Claude Code:
claude mcp add --transport http metro-mcp https://metro-mcp.anuragd.me/mcpThen open /mcp, select metro-mcp, and complete GitHub login and consent. Claude.ai/Desktop users can add the same URL as a remote custom connector where their plan and workspace policy permit it.
Codex
codex mcp add metro-mcp --url https://metro-mcp.anuragd.me/mcp
codex mcp login metro-mcp --scopes transit:readThe checked-in mcp-config.json shows the equivalent generic remote-HTTP configuration. Access and refresh tokens stay in the client's credential store; do not paste them into project configuration.
Transport compatibility
MCP
2026-07-28requests are stateless and do not requireinitialize.Ordinary tools, resources, and prompts remain available to MCP 2025 stateless clients.
POST /sseandOPTIONS /sseare URL aliases rewritten to canonical/mcpbefore authorization.Legacy HTTP+SSE is removed.
GETandDELETEon/sseor/mcp, session message URLs, and/sse/return405.OAuth audience and discovery always use
https://metro-mcp.anuragd.me/mcp;/sseis never an OAuth resource.
OAuth Endpoints
The Workers OAuth Provider implements OAuth 2.1 with PKCE:
Discovery:
/.well-known/oauth-authorization-serverRegistration: CIMD first, with
/registeras a temporary Dynamic Client Registration fallbackAuthorization:
/authorize(GitHub OAuth integration)Token:
/token(Authorization code exchange with PKCE verification)Callback:
/callback(GitHub OAuth callback)
Clients receive an explicit transit:read consent screen. Grants are bound to the canonical /mcp resource; access tokens last at most 60 minutes, refresh tokens last at most 30 days and rotate on use, and bearer tokens are accepted only in the Authorization header. The DCR fallback sunsets on 2027-06-30.
Version 5.0 requires reauthorization for tokens without an audience, tokens bound to /sse, and clients registered in the old DCR store. Existing compatible legacy JWTs bound to /mcp stop working at the earlier of their embedded expiry and 2026-11-30T00:00:00Z.
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 real-time train arrival predictions for a station | DC, NYC |
| Search for stations by name or code | DC, NYC |
| Get all stations on a specific line | DC, NYC |
| Check current service disruptions and advisories | DC, NYC |
| Get a complete list of all stations with coordinates | DC, NYC |
| Get transfer connections and walk times between nearby stations | NYC only |
| Get detailed route information (express/local, service patterns, hours) | NYC only |
| Find elevator and escalator outages | DC only |
| Get real-time bus arrival predictions (7-digit stop ID) | DC only |
| Get list of all available bus routes | DC only |
| Search bus stops by location or get all stops | DC only |
| Get live positions of all buses (optionally filter by route) | DC only |
| Get live positions of all trains on the system | DC only |
Total: 13 MCP tools (11 core + 2 new NYC-specific tools)
MCP Apps: Transit Board
All 13 tools above reference one self-contained Transit Board MCP App. An Apps-capable host can render each result as a dedicated arrivals, service, station/network, route, or vehicle view. Hosts without Apps support receive the same content text fallback and structuredContent contract; the enhancement does not add tools or change transit calls.
The compiled app is committed at public/apps/transit-board.html. That public asset contains application code only: no transit result, identity, token, secret, or configuration value is embedded in it. The sandboxed view makes no direct browser network request, uses no browser storage, and requests no browser permissions. Refresh is the only server interaction and goes through the host to the originating allowlisted tool with its original arguments.
Build and run the deterministic local Apps acceptance suite with:
bun run build:apps
bun run test:appsSee docs/mcp-apps-verification.md for the exact host boundary, all thirteen view mappings, Chromium coverage, and the distinction between Apps rendering and fallback-client acceptance. For this release, Codex validates MCP discovery and ordinary tool results as a fallback client; inline Apps rendering in Codex is not claimed.
Technical Details
MCP Protocol
Version: MCP
2026-07-28, with ordinary MCP 2025 stateless compatibilityTransport: Stateless Streamable HTTP through a fresh SDK v2 server for each request. JSON and request-scoped SSE responses are supported; protocol sessions, resumability, and server push are not advertised.
Authentication: The Cloudflare Workers OAuth Provider owns discovery, CIMD/DCR validation, PKCE, RFC 9207 issuer identifiers, RFC 8707 resource binding, RFC 9728 protected-resource metadata, refresh rotation, revocation, and Provider token storage.
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)MRTR input β modern clients receive
input_requiredfor ambiguous stations; MCP 2025 clients receive deterministic retry guidance with exact station IDsProgress 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:
Environment-specific Cloudflare KV
OAUTH_KVβ OAuth Provider grants, tokens, and registrationsNo active protocol-session storage. The old
MetroMcpAgentexport and originalv1migration remain inactive solely for rollback.
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 # Outer route normalization and Provider composition
βββ public-handler.ts # /info, OAuth UI, and static assets
βββ route-normalizer.ts # Exact /mcp admission and /sse URL alias
βββ oauth/ # Provider configuration, GitHub consent, legacy bridge
βββ mcp/ # Stateless server factory, tools, resources, and prompts
βββ mcp-agent.ts # Inactive 4.x rollback class only
βββ transit/ # WMATA and MTA clients with request cancellationKey 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 callsNormalized Responses: All transit clients return standardized
TransitStation,TransitPrediction, andTransitIncidenttypesExtensibility: Adding a new city only requires implementing the abstract client class
Verification and rollback
Run the complete local suite with bun run test. The authenticated conformance runner requires an operator-obtained short-lived Provider access token in the process environment; it never stores the token or puts it in command arguments:
export MCP_CONFORMANCE_TARGET_URL=https://metro-mcp-preview.anuragd.me/mcp
export MCP_CONFORMANCE_ALLOW_REMOTE=1
read -rsp 'Short-lived MCP token: ' MCP_CONFORMANCE_TOKEN && export MCP_CONFORMANCE_TOKEN
./scripts/run-conformance.sh
unset MCP_CONFORMANCE_TOKENSee docs/mcp-2026-verification.md for the core protocol acceptance record and docs/mcp-apps-verification.md for the Transit Board browser boundary.
Rollback restores the prior Worker version and its prior bindings. Do not delete the original MetroMcpAgent Durable Object namespace or add a deletion migration during the stabilization window; protocol session state is disposable, but retaining the class and original v1 migration keeps rollback possible.
Rolling back Transit Board removes the Apps metadata/resource, browser source and build dependencies while leaving transit providers, OAuth, routing, bindings, and the version unchanged.
Contributing
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
License
MIT License - see LICENSE file for details.
Built with β€οΈ for the Washington DC Metro community
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceMCP server that provides tools for querying live transit data (stops, departures, routes, vehicles, alerts) from any WP GTFS Pro site, enabling AI assistants to answer rider questions.14GPL 2.0
- AlicenseAqualityAmaintenanceMCP server for Atlanta MARTA real-time transit data, enabling queries about train arrivals and bus positions via natural language.4MIT
- AlicenseNot gradedqualityBmaintenanceMCP server for Japanese public transit journey planning with interactive map UI, enabling station search, route planning, and departure lookups via natural language.MIT
- FlicenseNot gradedqualityCmaintenanceAn MCP server that provides real-time Hong Kong public transport ETA information.
Related MCP Connectors
SEPTA MCP β Philadelphia SEPTA real-time transit (www3.septa.org/api, keyless)
Amtrak MCP β live Amtrak train tracking via the community Amtraker API
MBTA MCP β Boston real-time transit via the MBTA v3 API (api-v3.mbta.com)
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Aarekaz/metro-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server