npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

metronorth-mcp

v2.3.0

Published

MCP server for Metro-North schedules, stations, service alerts, and real-time departures

Readme

Metro-North MCP Server

CI npm MIT License Node.js 22+

MCP server for Metro-North schedules, stations, service alerts, and real-time departures.

Uses public MTA GTFS and GTFS-Realtime feeds. No MTA API key required.

This package runs as a local stdio MCP server by default. The project does not operate or publish a shared hosted MCP endpoint.

Project Model

  • Local stdio MCP server; no maintainer-operated hosted endpoint, uptime commitment, or SLA.
  • Unofficial project; not affiliated with or endorsed by the MTA.
  • Best-effort public MTA schedule, realtime, and alert data.
  • Node.js 22 or newer is required. Current development expects npm and the native better-sqlite3 install path to work on the target machine.

Coverage

Covers Metro-North's east-of-Hudson lines: Hudson, Harlem, New Haven, New Canaan, Danbury, and Waterbury. The west-of-Hudson lines (Pascack Valley and Port Jervis) are operated by NJ Transit and are not part of the MTA Metro-North GTFS feed, so they are not included here. Requests for those lines return a not_covered error pointing to NJ Transit.

Install with an Agent

Paste this into your MCP-capable coding agent:

Install the Metro-North MCP server in this client as "metronorth".
Use command "npx" with args ["-y", "metronorth-mcp"].
After installing, reload MCP servers and test it by calling search_stations with query "Grand Central".

Install

npx -y metronorth-mcp

GitHub install:

npx -y --package github:NelsonSpencer/metronorth-mcp metronorth-mcp

Use metronorth as the MCP server name.

MCP Client Setup

Cursor

Copy and open this deeplink:

cursor://anysphere.cursor-deeplink/mcp/install?name=metronorth&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIm1ldHJvbm9ydGgtbWNwIl19

Manual .cursor/mcp.json config:

{
  "mcpServers": {
    "metronorth": {
      "command": "npx",
      "args": ["-y", "metronorth-mcp"]
    }
  }
}

Codex

codex mcp add metronorth -- npx -y metronorth-mcp
codex mcp list

Claude Code

claude mcp add metronorth -- npx -y metronorth-mcp
claude mcp list

Run /mcp in Claude Code to confirm the server is connected.

VS Code

code --add-mcp '{"name":"metronorth","command":"npx","args":["-y","metronorth-mcp"]}'

Open Copilot Chat in Agent mode and enable the server from the tools picker.

OpenClaw

openclaw mcp set metronorth '{"command":"npx","args":["-y","metronorth-mcp"]}'
openclaw mcp list

Hermes

hermes mcp add metronorth --command npx --args -y metronorth-mcp
hermes mcp test metronorth

Restart or reload MCP servers after installing.

Other MCP Clients

Use this server entry:

{
  "command": "npx",
  "args": ["-y", "metronorth-mcp"]
}

Full MCP config:

{
  "mcpServers": {
    "metronorth": {
      "command": "npx",
      "args": ["-y", "metronorth-mcp"]
    }
  }
}

Agent Usage

This server exposes usage guidance through MCP:

  • Read metronorth://usage for the recommended station, trip-planning, alert, and freshness workflow.
  • Read metronorth://examples for common tool-call examples.
  • Use the use-metro-north-mcp prompt when an agent needs a quick operating guide.

Recommended flow:

  1. Search stations first when names may be partial or ambiguous.
  2. Use plan_metro_north_trip for station-to-station questions.
  3. Use get_station_pair_schedule for direct train options between two stations.
  4. Use get_first_last_trains for first/last train questions.
  5. Read metronorth://system/status when data freshness matters.
  6. Treat realtime departures and alerts as best-effort public feed data.

Tools

Tool results include readable text and MCP structuredContent. Invalid inputs and unknown stations return structured errors.

| Tool | Use | | --------------------------- | ------------------------------------------------------ | | search_stations | Search stations by name | | get_departures | Get upcoming departures from a station | | get_trip_details | Get stop-level details for a trip | | get_route_schedule | Get a route schedule by date and direction | | get_service_alerts | Get current service alerts | | get_station_info | Get station metadata and served routes | | get_system_status | Check feed availability and local data freshness | | get_station_pair_schedule | Find direct trains between two stations | | get_first_last_trains | Get first and last direct trains for a service date | | plan_metro_north_trip | Plan a direct or one-transfer trip with options, alerts, and freshness | | get_accessibility_status | Report elevator/escalator/accessibility alerts (derived from text alerts) |

Example:

{
  "origin_station": "Grand Central",
  "destination_station": "White Plains",
  "limit": 3,
  "include_alerts": true
}

Resources and Prompts

Resources:

  • metronorth://usage
  • metronorth://examples
  • metronorth://system/status
  • metronorth://routes
  • metronorth://stations
  • metronorth://station/{station_name}

Prompts:

  • use-metro-north-mcp
  • plan-metro-north-trip
  • summarize-service-status

Local Development

git clone https://github.com/NelsonSpencer/metronorth-mcp.git
cd metronorth-mcp
npm install
cp .env.example .env
npm run build
npm start

First run downloads the public Metro-North GTFS ZIP and imports it into SQLite.

Runtime Requirements

  • Node.js >=22.0.0.
  • better-sqlite3 uses a native SQLite binding. npm usually installs a prebuilt binary; if one is unavailable for your platform, npm may compile it locally. If a local build fails (for example on a very new Node release or a platform without build tooling), install on Node.js 22 or 24 LTS, where prebuilt binaries are published.
  • The local database defaults to ~/.cache/metronorth-mcp/metronorth.db and uses SQLite PRAGMAs for WAL mode, normal sync, cache size, and in-memory temp storage.
  • Redis is optional and only used when REDIS_URL is set.

Configuration

Create .env from .env.example.

NODE_ENV=development
LOG_LEVEL=info
REDIS_URL=
DB_PATH=
GTFS_UPDATE_INTERVAL_HOURS=24
CACHE_TTL_SECONDS=300

If DB_PATH is empty, schedule data is stored in ~/.cache/metronorth-mcp/metronorth.db.

Redis is optional. If REDIS_URL is empty, the server uses in-memory caching.

Network Access

Default runtime network access is outbound only:

  • Static GTFS ZIP: https://rrgtfsfeeds.s3.amazonaws.com/gtfsmnr.zip
  • Metro-North GTFS-Realtime trips: https://api-endpoint.mta.info/Dataservice/mtagtfsfeeds/mnr%2Fgtfs-mnr
  • MTA alerts: https://api-endpoint.mta.info/Dataservice/mtagtfsfeeds/camsys%2Fall-alerts

npm install may also contact the npm registry and package artifact hosts. The default stdio server does not listen on a network port.

Transport and Hosting

The public install path is local stdio:

npx -y metronorth-mcp

Do not point strangers at a maintainer-owned hosted URL unless you intentionally want to operate a public service. If you wrap this server with HTTP for a personal tool, bind it to localhost by default, require bearer-token authentication before exposing it beyond localhost, and keep tunnel URLs private. The built-in --http transport described below follows exactly this posture.

Remote / HTTP transport

metronorth-mcp speaks the local stdio transport by default. Passing --http instead exposes an opt-in Streamable HTTP endpoint, so any remote MCP host or assistant that speaks Streamable HTTP can reach the server. stdio stays the default; nothing about the existing npx -y metronorth-mcp install path or any stdio MCP client changes.

metronorth-mcp --http
# serves http://127.0.0.1:8000/mcp

The server speaks plain HTTP on loopback and does not terminate TLS. HTTPS and outside reachability come from whatever fronts it: a local tunnel, or a reverse proxy if you self-host. This stays a local, user-run capability, not a maintainer-operated endpoint.

Flags and environment variables

CLI flags take precedence over the MCP_HTTP* environment variables.

| Flag | Environment variable | Default | Purpose | | -------------------------- | -------------------------- | ---------------- | ---------------------------------------------------------------- | | --http | MCP_HTTP | false (stdio) | Enable the HTTP transport. | | --host <host> | MCP_HTTP_HOST | 127.0.0.1 | Bind address. Keep it on loopback unless you front it. | | --port <port> | MCP_HTTP_PORT | 8000 | Listen port. | | --token <token> | MCP_HTTP_TOKEN | unset | Require Authorization: Bearer <token> on /mcp. | | --allowed-hosts <list> | MCP_HTTP_ALLOWED_HOSTS | loopback names | Comma-separated Host allow-list (DNS-rebind protection). | | --allowed-origins <list> | MCP_HTTP_ALLOWED_ORIGINS | loopback origins | Comma-separated Origin allow-list (DNS-rebind protection). Header-less clients still pass. |

MCP_HTTP accepts 1, true, yes, or on. Run metronorth-mcp --help for the same summary.

Endpoints

  • POST / GET / DELETE /mcp — the Streamable HTTP MCP endpoint. A session is negotiated on the initialize request and carried in the mcp-session-id header.
  • GET /health — unauthenticated liveness probe returning {"status":"ok"}, for tunnels and proxies.

Connecting a remote MCP host

The endpoint is a generic Streamable HTTP MCP server with no host-specific code, so it works with any remote MCP host or assistant that speaks Streamable HTTP. Poke is one such host; others exist now and more will emerge. The two connection shapes below use Poke only as a worked example.

  1. Local tunnel (no hosting). Run the server locally, then point the host's tunnel at http://localhost:8000/mcp:

    metronorth-mcp --http
    # then, with your chosen host's tunnel command — for example:
    npx poke@latest tunnel http://localhost:8000/mcp -n "metronorth"
  2. Remote URL (self-host behind HTTPS). If you run the server behind your own HTTPS proxy, give the host your https://…/mcp URL plus a bearer token / API key. With Poke, for example, add it at poke.com/settings/connections/integrations/new.

Other assistants and hosts connect the same way: a tunnel to the loopback URL, or a self-hosted HTTPS URL with a token.

Security

The transport binds 127.0.0.1 by default and enables DNS-rebinding protection. It fails closed: binding a non-loopback address (for example --host 0.0.0.0) without a token is refused at startup. Set --token (or MCP_HTTP_TOKEN) for any exposure beyond loopback, and keep tunnel URLs and tokens private. See SECURITY.md and the full HTTP transport reference.

Development Checks

npm run typecheck
npm test
npm run lint
npm run build
npm run smoke:mcp
npm audit --omit=dev --audit-level=high

Docker

docker build -t metronorth-mcp .

MCP client config:

{
  "mcpServers": {
    "metronorth": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "metronorth-mcp"]
    }
  }
}

Docker Compose starts the MCP server with Redis and persistent storage.

docker-compose up -d
docker-compose logs -f metronorth-mcp

Additional Notes

  • Static schedules are cached locally from public MTA GTFS feeds.
  • Real-time departures and alerts use public GTFS-Realtime feeds and are best-effort.
  • Tools handle dynamic lookups; resources expose reference data; prompts provide reusable workflows.
  • Unofficial project. Not affiliated with or endorsed by the MTA.

Community Documents

License

MIT. See LICENSE.