Metro MCP

by aarekaz

Not rated
GitHub

About

A MCP server of washington DC's Metro

Details

Author
aarekaz
Categories
Search, Other

Setup

Install Metro MCP in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/aarekaz/metro-mcp

Follow the installation instructions in the repository README, then restart your MCP client.

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

Ask natural language questions about DC Metro or NYC Subway in Claude Desktop or any MCP-compatible client:

- "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?"

- "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?"

- "Where is the Smithsonian Metro station?"
- "Show me all the stations on the Green Line"

- "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"

- "Are there any elevator outages between here and National Airport?"
- "Which DC Metro stations have working elevators right now?"

- "Any transit delays right now in NYC?"
- "Is the DC Metro Orange Line running normally?"
- "Compare service quality between DC Metro and NYC Subway"

- Complete list of all Metro stations with coordinates
- Information about all six Metro lines (Red, Blue, Orange, Silver, Green, Yellow)

- 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/mcp
- Click "Connect" and authorize via GitHub
- Start asking questions about DC Metro or NYC Subway

Want to run your own instance? See theDeploymentsection below.

- WMATA API Key(required)
-
Cloudflare Account(free tier works)
-
Bunfor package management
-
Node.jsfor Wrangler and the Workerd Vitest pool; Bun remains the sole package manager and lockfile owner
-
GitHub OAuth App(for authentication)

For local development, create a dedicated GitHub OAuth App whose callback is exactlyhttp://localhost:8787/callback. Then copy the canonical.dev.vars.exampletemplate, replace everyreplace-with-...placeholder, and start Wrangler:

cp .dev.vars.example .dev.vars bun run dev

Keep the template'shttp://localhost:8787origin,localhosthost/origin allowlists, callback, andENVIRONMENT=developmentvalues together. In Wrangler's default local mode, the configuredOAUTH_KVbinding uses local non-production storage under.wrangler; it does not read or write the deployed production or preview namespace. Do not add--remotefor normal local development.

Create one OAuth Provider namespace for each deployed environment and put its ID in the correspondingOAUTH_KVbinding:

bunx wrangler kv namespace create OAUTH_KV bunx wrangler kv namespace create OAUTH_KV_preview

Production 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_HOSTNAMES
- OAUTH_REDIRECT_URIand the environment's public GitHubGITHUB_CLIENT_ID
- ENVIRONMENT(production,preview, ordevelopment)
- OAUTH_KV, pointing at the environment's dedicated namespace

Set production secrets interactively.MCP_REQUEST_STATE_KEYis a stable, environment-specific 32-byte-or-longer key used only for signed MRTR state.JWT_SECRETremains 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_SECRET

Set 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 preview

Wrangler must include bothnodejs_compatandglobal_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-preview

Use the canonical Streamable HTTP endpoint in Claude Code:

claude mcp add --transport http metro-mcp https://metro-mcp.anuragd.me/mcp

Then open/mcp, selectmetro-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 mcp add metro-mcp --url https://metro-mcp.anuragd.me/mcp codex mcp login metro-mcp --scopes transit:read

The checked-inmcp-config.jsonshows the equivalent generic remote-HTTP configuration. Access and refresh tokens stay in the client's credential store; do not paste them into project configuration.

- MCP2026-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 usehttps://metro-mcp.anuragd.me/mcp;/sseis never an OAuth resource.

The Workers OAuth Provider implements OAuth 2.1 with PKCE:

- Discovery:/.well-known/oauth-authorization-server
- Registration: CIMD first, with/registeras a temporary Dynamic Client Registration fallback
- Authorization:/authorize(GitHub OAuth integration)
- Token:/token(Authorization code exchange with PKCE verification)
- Callback:/callback(GitHub OAuth callback)

Clients receive an explicittransit:readconsent screen. Grants are bound to the canonical/mcpresource; 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 theAuthorizationheader. The DCR fallback sunsets on2027-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/mcpstop working at the earlier of their embedded expiry and2026-11-30T00:00:00Z.

The server currently supports these transit systems:

The server exposes the following tools through the MCP protocol:

Total: 13 MCP tools(11 core + 2 new NYC-specific tools)

- Version:MCP2026-07-28, with ordinary MCP 2025 stateless compatibility
- Transport: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 emitsstructuredContent(typed object matchingoutputSchema) alongside the legacycontent
[0].text(serialized JSON) for backwards compatibility.
- Tool annotations:Every tool declaresreadOnlyHint,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 receiveinput_requiredfor ambiguous stations; MCP 2025 clients receive deterministic retry guidance with exact station IDs
- Progress notifications: emitted forget_all_stationswhen the client opts in viaparams._meta.progressToken

The server interfaces with the official WMATA REST APIs. VisitWMATA's developer documentationfor 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

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
- 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 KVOAUTH_KV— OAuth Provider grants, tokens, and registrations
- No active protocol-session storage. The oldMetroMcpAgentexport and originalv1migration remain inactive solely for rollback.

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 cancellation

- Transit Abstraction:CommonTransitAPIClientinterface enables easy addition of new cities (BART, MBTA, etc.)
- City Routing:Single server handles all cities viacityparameter in MCP tool calls
- Normalized Responses:All transit clients return standardizedTransitStation,TransitPrediction, andTransitIncidenttypes
- Extensibility:Adding a new city only requires implementing the abstract client class

Run the complete local suite withbun 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_TOKEN

Seedocs/mcp-2026-verification.mdfor the automated and approval-gated acceptance record.

Rollback restores the prior Worker version and its prior bindings. Do not delete the originalMetroMcpAgentDurable Object namespace or add a deletion migration during the stabilization window; protocol session state is disposable, but retaining the class and originalv1migration keeps rollback possible.

MCP Apps and embedded interactive UI are intentionally deferred to the next PR.

Contributions are welcome! Feel free to:

- Report bugs or request features viaGitHub Issues
- Submit pull requests with improvements
- Share feedback on the MCP implementation

MIT License - seeLICENSEfile for details.

Built with ❤️ for the Washington DC Metro community

Search global news using natural language. Webz.io News Search API returns the most relevant articles and content, with filters for source, country, language, date, sentiment, and category.

-

BatchData MCP (Real Estate & Contact Data)

Real Estate & Contact Enrichment Data MCP

Best people search engine that reduces the time spent on talent discovery.

Enable Similarity-Distance-Magnitude statistical verification for your search, software, and data science workflows

Vectorize MCP server for advanced retrieval, Private Deep Research, Anything-to-Markdown file extraction and text chunking.

Job search engine with 500k+ listings across Austria, Germany and Switzerland (alleskralle.com).

Hosted MCP server for the APITube News API: search articles from 500,000+ sources in 60+ languages, filtered by sentiment, entities, topics and source quality.

Live Austin-area MLS listings in your AI assistant — active listings, property details, schools, taxes, and neighborhood data for the Austin metro. Free remote MCP server, no install.

An MCP server using the AviationStack API to fetch real-time flight data including airline flights, airport schedules, future flights and aircraft types.

By connecting to Baselight, you can browse, discover, and query 70,000+ datasets and 450+ billion rows directly from your preferred environment—whether you’re building, analysing, or exploring.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.