Skip to main content
Glama

MCP METRO

Moscow 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. Works in 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.

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

  • 🌍 Understands humans, not codes β€” fuzzy station matching in four languages; typos, transliteration (hovrino) and Russian case forms (Π΄ΠΎ ЧСховской) all resolve to the right station.

  • πŸ–Ό Interactive widget (MCP Apps) β€” SEP-1865 hosts get clickable route cards; text-only hosts get clean Markdown. Nobody gets a wall of JSON.

  • πŸ”„ Swap stations right in the card β€” pick another Β«fromΒ» or Β«toΒ» from a searchable dropdown and the card recomputes the route in place, without asking the bot again.

  • 🚈 The whole network β€” Metro, MCC and MCD, plus ground transport at both ends, station services and vestibule opening hours.

  • ⚑ Never hostage to the network β€” a primary source, a backup source 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).

Related MCP server: BVG MCP Server

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

Route Search

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

Station Resolution

Fuzzy matching in four languages, interchange-hub clustering, clarifications

Route Widget

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

Data Sources

Primary/backup 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. 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. Any of the four languages, typos 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. St. Petersburg data is not wired in yet: for now every value falls back to the Moscow dataset.

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.

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.

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.

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

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