Skip to main content
Glama

MCP METRO

Moscow and Saint Petersburg metro for AI agents. Ask "how do I get from Khovrino to Sportivnaya?" in plain language β€” get real route variants with travel times, transfers, car-boarding hints and today's closures. Both networks answer through one tool. Understands Russian, English, Arabic and Chinese. Typos welcome.

License Node.js TypeScript MCP MCP Apps fa-mcp-sdk

What it does

  • πŸš‡ Routes people can actually follow β€” up to 3 variants with travel time, every station on the way, transfer walks, a door-to-door estimate and "board the first car" hints for faster interchanges.

  • πŸ™ Two cities, one tool β€” 21 Moscow lines with MCC and MCD, 6 Saint Petersburg lines; one city argument switches datasets, and each city is loaded and refreshed independently.

  • 🚧 Knows what's closed today β€” escalator repairs, closed stations, closed transfers and official detours are applied to the route graph before the search runs, not footnoted after.

  • 🌍 Understands humans, not codes β€” typos, transliteration (hovrino) and Russian case forms (Π΄ΠΎ ЧСховской) all resolve; Moscow names are matched and returned in four languages, Petersburg names in Russian.

  • πŸ–Ό Interactive widget (MCP Apps) β€” SEP-1865 hosts get clickable route cards whose Β«fromΒ» / Β«toΒ» selects recompute the trip in place; text-only hosts get clean Markdown, and nobody gets a wall of JSON.

  • 🚈 Beyond the tunnel β€” vestibule hours and first/last trains in both cities; in Moscow also ground transport at either end and on-station services.

  • ⚑ Never hostage to the network β€” every city has a backup source behind its primary one and an atomic disk cache, refreshed daily; the server answers within a second of starting.

  • πŸ”Œ Every way in β€” MCP over STDIO / HTTP / SSE, a rate-limited REST API with Swagger at /docs, and a built-in Agent Tester that drives the tool through a real LLM.

One tool β€” metro_info β€” answers the two questions a passenger asks: how do I get from A to B (search_route) and what is there at station X (get_station_info), in the city its city argument selects.

Related MCP server: tomsk-transport

Try it in 60 seconds

npm install
npm run build
npm start            # HTTP mode β†’ http://localhost:9049
curl http://localhost:9049/health

MCP endpoint: http://localhost:9049/mcp. No database, no API keys, no credentials β€” it just runs. Client configs are one click away: Connect your client below.

Documentation

Topic

What's inside

Getting Started

Install, run, connect MCP clients, transports, build & test commands

Tool Reference

metro_info parameters and answers, MCP resources and prompts

Cities

Moscow and Saint Petersburg: sizes, what each answer carries, what differs

Route Search

The graph, Yen's algorithm, the time model, closures, operating hours

Station Resolution

Fuzzy matching, transliteration, case forms, hub clustering, clarifications

Route Widget

MCP Apps contract, signed links, in-card station selects, reverse proxy, CORS

Data Sources

Per-city source cascade, disk cache, refresh schedule, Telegram alerts

REST API

Five read-only endpoints, rate limits, status codes, response shapes

Configuration

Every setting, resolution order, environment variables

Authentication

JWT / Basic / permanent tokens, issuing tokens, what stays open

Testing

Unit tests, MCP protocol tests, Agent Tester and the Headless API

Deployment

Docker + systemd, reverse proxy, the self-update loop

Skills

Claude Code skills shipped with the project

The tool, up close

One tool β€” metro_info, read-only. action=search_route builds up to 3 route variants between two stations; action=get_station_info describes one station. city picks the network β€” Moscow by default, Saint Petersburg on request. Answers are English Markdown; station and line names are localized to the user's language.

Parameter

Required

Description

first_metro_station

yes

Departure station (for a route) or the station to describe. Typos, transliteration and Russian case forms allowed β€” resolved by fuzzy search.

second_metro_station

for routes

Arrival station. Required for action=search_route, unused for get_station_info.

action

yes

search_route β€” build routes between two stations; get_station_info β€” describe first_metro_station.

city

no

Moscow (default) or StPetersburg. Each city has its own dataset; an unrecognized value falls back to Moscow.

language

no

Language the user communicates in: en (default), ru, ar or cn. Station and line names are localized to it; all other response text is English.

walk_to_metro_minutes

no

Walk time to the departure station, 1–600. Added to the total and shown as a walking segment. Set only when the conversation states it β€” never guessed.

walk_from_metro_minutes

no

Walk time from the arrival station, same rules.

A search_route answer contains: up to 3 route variants with travel time and a door-to-door estimate, the full station sequence of every leg, transfers with "board the first car" hints, which legs run on MCD / MCC, ground transport at both ends, advisories along the route, and the vestibule status of the departure hub.

A get_station_info answer contains: lines at the station, city exits with nearby ground transport, on-station services, first and last train times per direction, available interchanges, and current advisories.

Saint Petersburg answers carry the same routes, transfers, hours and closures, but no ground transport, no on-station services and no train-car hints β€” its sources do not publish them; station names come in Russian.

When a name is ambiguous the answer is a numbered list to choose from; for a route request with two ambiguous names, both lists come at once.

Full reference, including MCP resources and prompts: Tool Reference. What each city carries: Cities.

Connect your client

{
  "mcpServers": {
    "mcp-metro": {
      "type": "http",
      "url": "http://localhost:9049/mcp",
      "headers": {
        "Authorization": "Bearer <jwt-token>"
      }
    }
  }
}

Omit the headers block entirely while authentication is off (the default).

Option 1 β€” STDIO (local build, direct spawn):

{
  "mcpServers": {
    "mcp-metro": {
      "command": "node",
      "args": ["<path-to-project>/dist/src/start.js", "stdio"],
      "env": {}
    }
  }
}

Option 2 β€” HTTP (remote server via mcp-remote):

{
  "mcpServers": {
    "mcp-metro": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote@latest",
        "https://mcp-metro.time-gold.com/mcp",
        "--header",
        "Authorization:Bearer <jwt-token>",
        "--allow-http",
        "--transport",
        "http-only"
      ]
    }
  }
}

Important: in --header values there must be no space after the :. "Authorization:Bearer abc" is correct, "Authorization: Bearer abc" is not.

{
  "mcpServers": {
    "mcp-metro": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote@latest",
        "https://mcp-metro.time-gold.com/mcp",
        "--header",
        "Authorization:Bearer <jwt-token>",
        "--allow-http",
        "--transport",
        "http-only"
      ]
    }
  }
}

The same no-space-after-: rule applies to --header values.

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "mcp-metro": {
      "type": "remote",
      "url": "http://localhost:9049/mcp",
      "enabled": true,
      "headers": {
        "Authorization": "Bearer <jwt-token>"
      }
    }
  }
}

Omit the headers block entirely while authentication is off (the default).

[mcp_servers.mcp-metro]
url = "https://mcp-metro.time-gold.com/mcp"
http_headers = { "Authorization" = "Bearer <jwt-token>" }

Transports, endpoints and STDIO mode: Getting Started.

Under the hood

TypeScript (ESM) on Node.js β‰₯ 20, built on fa-mcp-sdk β€” server core, transports, auth, Swagger and Agent Tester come from the SDK. Routing is Yen's k-shortest-paths over a weighted graph rebuilt for the requested moment; the routing, search and widget layers are city-agnostic and simply receive the dataset of the requested city. Data lives in JSON on disk β€” no database.

License

MIT Β© Michael Makarova. See LICENSE.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

–Maintainers
–Response time
–Release cycle
–Releases (12mo)
Commit activity

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

View all related MCP servers

Related MCP Connectors

  • Geo-based flight search MCP server. Find more flights between any two places on earth

  • MCP server for URL shortening and management

  • MCP server for fcc-ecfs

View all MCP Connectors

Latest Blog Posts

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/OlliMakarova/mcp-metro'

If you have feedback or need assistance with the MCP directory API, please join our Discord server