Skip to main content
Glama
Shadhai

IndianRailwaysMCP

by Shadhai


πŸ“‘ Table of Contents


Related MCP server: Indian Railway MCP

🎯 Purpose & Philosophy

Indian Railways runs over 13,000 trains a day, but its data lives behind inconsistent HTML pages and rate-limited endpoints β€” making it painful for AI agents to answer a simple question like "is my train running late?"

Indian Railways MCP Server solves this by normalizing schedules, live status, PNR, fares, and seat data into a single, structured MCP interface that any AI assistant can call directly.

  • πŸ” No auth, no secrets β€” every data source is public; there's nothing to leak

  • 🧩 Layered architecture β€” server, client, and parser layers are independently testable and swappable

  • πŸ“Š TTL-aware caching β€” every tool call respects a data-freshness window instead of hammering upstream sites

  • ⚑ Resilient by default β€” exponential-backoff retries absorb upstream flakiness so your agent doesn't crash mid-conversation


πŸ— Architecture

graph TD
    Client["πŸ–₯️ MCP Client<br/>(Claude Desktop / Cursor / Continue.dev)"] -->|MCP Protocol Β· stdio| Server

    subgraph Server["πŸš‚ Indian Railways MCP Server"]
        direction TB
        SL["πŸ› οΈ Server Layer<br/>Tool registration (10 tools)<br/>Pydantic input validation"]
        CL["🌐 Client Layer<br/>httpx session mgmt<br/>tenacity retry logic<br/>TTL response cache"]
        PL["πŸ”Ž Parser Layer<br/>BeautifulSoup HTML parsing<br/>Pydantic JSON parsing<br/>Regex extraction"]
        SL --> CL --> PL
    end

    PL -->|HTTP/HTTPS| ERail[("πŸ—„οΈ ERail.in<br/>Schedules Β· Live status<br/>PNR Β· Seats Β· Fares")]
    PL -->|HTTP/HTTPS| IRInfo[("πŸ—„οΈ IndianRailways.info<br/>Coach position<br/>Platform locator")]

Data flow: MCP client sends a tool call over stdio β†’ Server layer validates input with Pydantic β†’ Client layer issues an HTTP request with retry logic β†’ Parser layer extracts structured data from HTML/JSON β†’ Cache layer stores the result with a TTL β†’ response is formatted and returned to the client.


✨ Features

Module

Capability

Real-Time

Cache TTL

πŸ” Station & Train Search

Search 8,000+ stations and 10,000+ trains by name or code

❌

24 hours

πŸš‚ Train Schedule

Complete route with all stations, timings, and distances

❌

1 hour

πŸ“ Live Running Status

Real-time location, delays, and platform info

βœ…

2 minutes

🎫 PNR Status

Passenger details, coach/berth allocation, journey info

βœ…

30 seconds

πŸ’Ί Seat Availability

Class-wise availability β€” AVAILABLE / RAC / WL

βœ…

2 minutes

πŸ’° Fare Enquiry

Fare breakdown across all travel classes

❌

1 hour

πŸ”€ Trains Between Stations

Every train connecting two stations

❌

1 hour

🏒 Station Live

Upcoming departures from any station

βœ…

2 minutes

πŸšƒ Coach Position

Coach layout at any station platform

❌

1 hour


🧰 Tech Stack

Layer

Technology

Runtime

Python 3.10+

Protocol

Model Context Protocol (MCP) SDK 1.0+

HTTP Client

httpx

HTML Parsing

BeautifulSoup4

Validation

Pydantic 2.0+

Retry Logic

tenacity (exponential backoff)

Testing

pytest, pytest-cov, pytest-mock, pytest-asyncio

Packaging

pyproject.toml (pip-installable)

Containerization

Docker (python:3.11-slim)

Process Management

systemd (Linux server deployments)


πŸš€ Quick Start

Prerequisites

Tool

Version

Notes

Python

3.10+

Check with python --version

pip

Latest

Ships with Python

An MCP client

Any

Claude Desktop, Cursor, or Continue.dev

Step 1 β€” Clone

git clone https://github.com/Shadhai/Railway_mcp.git
cd Railway_mcp

Step 2 β€” Configure

# Create and activate a virtual environment (recommended)
python -m venv .venv
source .venv/bin/activate      # Linux/Mac
# .venv\Scripts\activate       # Windows

# Install dependencies
pip install mcp httpx beautifulsoup4 pydantic tenacity

Step 3 β€” Run

# Run directly
python -m src.indian_railways_mcp.server

# Or install as a package and run the entry point
pip install -e .
indian-railways-mcp

βœ… Success β€” expect this output:

βœ… Available tools: 10
  - search_stations: Search Indian Railways stations by name or code...
  - search_trains: Search Indian Railways trains by number or name...
  - get_train_schedule: Get complete train schedule with all stations...
  ...

βš™οΈ Environment Configuration

No credentials are required β€” every upstream source is publicly accessible. The only environment variable in use configures the Python import path:

# ── Runtime ─────────────────────────────────────────────
PYTHONPATH=/path/to/Railway_mcp/src

# <!-- VERIFY: add PORT/NODE_ENV-style vars here only if you front this
#      server with a custom HTTP/SSE transport wrapper. Stdio transport
#      (the default) needs nothing beyond PYTHONPATH. -->

πŸ›  MCP Tool Reference

This server communicates over the MCP stdio protocol, not a public REST API β€” tools are invoked by your AI client, not by HTTP requests you make yourself. Each tool maps to one or more upstream data-source calls.

Discovery Tools

Tool

Description

Auth

search_stations

Find station code(s) by name, with fuzzy/case-insensitive matching

❌

search_trains

Find train number(s) by name, with fuzzy/case-insensitive matching

❌

get_trains_between

List all trains connecting two stations

❌

Schedule & Status Tools

Tool

Description

Auth

get_train_schedule

Full route: every station, arrival/departure time, distance

❌

get_live_status

Real-time location, delay minutes, last station

❌

get_station_live

Upcoming departures at a given station

❌

Booking & Fare Tools

Tool

Description

Auth

check_pnr

PNR status, passenger list, coach/berth, confirmation state

❌

check_seat_availability

Class-wise seat status (AVAILABLE / RAC / WL)

❌

get_fare

Fare breakdown by class

❌

Platform Tools

Tool

Description

Auth

get_coach_position

Coach layout at a specific platform

❌

get_platform_locator

Locate which platform a train arrives at

❌

πŸ“– See docs/API_REFERENCE.md in the repo for full parameter schemas.


🌐 Data Sources

ERail.in (Primary)

Endpoint

Method

Format

Cache TTL

/js5/IRStations.js

GET

JS/JSON array

24 hours

/js5/IRTrains.js

GET

JS/JSON array

24 hours

/train-enquiry/{train}

GET

HTML table

1 hour

/train-running-status/{train}

GET

HTML

2 minutes

/pnr-status/{pnr}?format=json

GET

JSON

30 seconds

/train-seats/{train}

POST

HTML table

2 minutes

/train-fare/{train}

POST

HTML table

1 hour

/trains-between-stations/{from}/{to}

POST

HTML table

1 hour

/station-live/{station}

GET

HTML table

2 minutes

IndianRailways.info (Secondary)

Endpoint

Method

Format

Cache TTL

/coach_position/

POST

HTML table

1 hour

/platform_locator/

POST

HTML

1 hour


⏱ Caching Strategy

Data Type

TTL

Reason

Station List

24 hours

Rarely changes

Train List

24 hours

Rarely changes

Train Schedule

1 hour

Occasional updates

Live Status

2 minutes

Real-time data

PNR Status

30 seconds

Real-time data

Seat Availability

2 minutes

Frequent updates


🧭 Use Cases

πŸ—ΊοΈ AI Travel Planning Assistant

A chatbot built on Claude Desktop uses this server to plan an end-to-end journey β€” searching trains between two cities, checking live seat availability, pulling the fare, and confirming the schedule, all from one natural-language conversation.

πŸ“ Live Train Tracker for Commuters

A commuter-facing IVR or WhatsApp bot polls get_live_status every few minutes to tell passengers exactly how delayed their train is and which station it last passed.

🎫 PNR Concierge Bot

A support bot integrated with check_pnr answers "is my ticket confirmed?" instantly, including per-passenger coach, berth, and waitlist position β€” without a human agent.

πŸŽ“ Academic / Portfolio Project

A student building an MCP-based AI agent uses this repo as a reference implementation of a layered, cached, retry-safe scraping architecture behind the Model Context Protocol.


πŸ’‘ Usage Examples

Complete journey planning

from indian_railways_mcp.client import IndianRailwaysClient

client = IndianRailwaysClient()

trains = client.get_trains_between("NDLS", "BCT")
train = trains['trains'][0]

seats = client.check_seat_availability(
    train['train_number'], "NDLS", "BCT", "20-Jul-2026"
)

if any(c['status'] == 'AVAILABLE' for c in seats['classes']):
    fare = client.get_fare(train['train_number'], "NDLS", "BCT")
    print(f"Fare: β‚Ή{fare['classes'][0]['total_fare']}")

schedule = client.get_train_schedule(train['train_number'])
print(f"Travel time: {schedule['travel_time']} hours")

Live train tracking

status = client.get_live_status("04815")

if status['status'] == 'RUNNING':
    print(f"{status['train_name']} last seen at {status['last_station']}, "
          f"delayed {status['delay_minutes']} min")

PNR status check

pnr = client.check_pnr("4553137968")

for p in pnr['passengers']:
    print(f"Passenger {p['serial']}: {p['current_status']} | "
          f"Coach {p['coach']} | Berth {p['berth']} ({p['berth_type']})")

πŸ“ Project Structure

Railway_mcp/
β”œβ”€β”€ πŸ“„ README.md                     # Main documentation
β”œβ”€β”€ πŸ“„ pyproject.toml                # Package configuration
β”œβ”€β”€ πŸ“„ LICENSE                       # MIT License
β”œβ”€β”€ πŸ“„ .gitignore                    # Git ignore rules
β”œβ”€β”€ πŸ“ docs/
β”‚   β”œβ”€β”€ API_REFERENCE.md             # Complete tool/API documentation
β”‚   β”œβ”€β”€ ARCHITECTURE.md              # System architecture
β”‚   └── EXAMPLES.md                  # Usage examples
β”œβ”€β”€ πŸ“ src/
β”‚   └── πŸ“ indian_railways_mcp/
β”‚       β”œβ”€β”€ __init__.py              # Package init
β”‚       β”œβ”€β”€ server.py                # MCP server (10 tools)
β”‚       β”œβ”€β”€ client.py                # HTTP client (all endpoints)
β”‚       β”œβ”€β”€ parsers.py               # HTML/JSON parsers
β”‚       β”œβ”€β”€ models.py                # Pydantic data models
β”‚       └── utils.py                 # Caching + retry utilities
└── πŸ“ tests/
    β”œβ”€β”€ test_client.py               # Client tests
    └── test_parsers.py              # Parser tests

πŸ”Œ Client Integrations

Edit your config file:

  • Mac: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • Linux: ~/.config/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "indian-railways": {
      "command": "python",
      "args": ["-m", "src.indian_railways_mcp.server"],
      "cwd": "/path/to/Railway_mcp",
      "env": { "PYTHONPATH": "/path/to/Railway_mcp/src" }
    }
  }
}

Restart Claude Desktop β€” you'll see a πŸ”Œ icon with the Indian Railways tools listed.

Add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "indian-railways": {
      "command": "python",
      "args": ["-m", "src.indian_railways_mcp.server"],
      "cwd": "/path/to/Railway_mcp"
    }
  }
}

Add to ~/.continue/config.json:

{
  "experimental": {
    "modelContextProtocolServers": [
      {
        "transport": {
          "type": "stdio",
          "command": "python",
          "args": ["-m", "src.indian_railways_mcp.server"],
          "cwd": "/path/to/Railway_mcp"
        }
      }
    ]
  }
}
npx @modelcontextprotocol/inspector python -m src.indian_railways_mcp.server

🐳 Docker Deployment

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY src/ ./src/

ENV PYTHONPATH=/app

CMD ["python", "-m", "src.indian_railways_mcp.server"]
# Build
docker build -t indian-railways-mcp .

# Run (stdio requires interactive mode)
docker run -i indian-railways-mcp

/etc/systemd/system/indian-railways-mcp.service:

[Unit]
Description=Indian Railways MCP Server
After=network.target

[Service]
Type=simple
User=mcp
WorkingDirectory=/opt/indian-railways-mcp
Environment=PYTHONPATH=/opt/indian-railways-mcp/src
ExecStart=/usr/bin/python3 -m src.indian_railways_mcp.server
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable indian-railways-mcp
sudo systemctl start indian-railways-mcp
sudo systemctl status indian-railways-mcp

πŸ§ͺ Testing

# Install test dependencies
pip install pytest pytest-cov pytest-mock pytest-asyncio

# Run all tests
pytest tests/ -v

# Run with coverage
pytest tests/ -v --cov=src/indian_railways_mcp --cov-report=html

# Run a specific file / class / test
pytest tests/test_client.py -v
pytest tests/test_client.py::TestPNRStatus -v
pytest tests/test_client.py::TestPNRStatus::test_check_pnr_success -v

Coverage summary

Module

Tests

Coverage

client.py

40+

~95%

parsers.py

25+

~95%

utils.py

10+

~90%

models.py

5+

~85%

Total

80+

~92%


πŸ“ˆ Performance

Response times (typical)

Operation

Cold (ms)

Cached (ms)

Search Stations

800

5

Search Trains

1000

5

Train Schedule

1500

100

Live Status

2000

200

PNR Status

1200

50

Seat Availability

2000

100

Memory footprint: ~50MB base (Python + deps) Β· ~65MB with station/train cache warm Β· ~80MB peak during HTML parsing.


πŸ”’ Security Notes

  • No authentication required β€” every data source is public

  • Rate-limit safe β€” built-in exponential backoff prevents abusive request patterns

  • Validated inputs β€” all tool arguments pass through Pydantic models

  • No persistence β€” PNR and passenger data are never written to disk

  • HTTPS only β€” every outbound request is encrypted


πŸ”§ Troubleshooting

Symptom

Likely Cause

Fix

Module not found

PYTHONPATH not set

export PYTHONPATH="/path/to/Railway_mcp/src:$PYTHONPATH" or pip install -e .

Permission denied on server script

Missing execute bit

chmod +x src/indian_railways_mcp/server.py

Server silently exits

Docker missing -i flag

Always run with docker run -i indian-railways-mcp (stdio needs interactive mode)

Dependencies missing

Fresh clone, no install

pip install -r requirements.txt

Invalid Train error

Wrong or malformed train number

Verify it's a 5-digit number via search_trains

No Data Found

Train doesn't run that day

Check the train's days of operation

Station Not Found

Invalid station code

Run search_stations first to resolve the code

Connection Timeout

Upstream network issue

Handled automatically β€” 3x retry with exponential backoff

Parse Error

Upstream site changed its HTML structure

Requires a manual parser update in parsers.py

Rate Limited

Too many requests in a short window

Backs off automatically; avoid tight polling loops


πŸ—Ί Roadmap

  • Core tool set β€” station/train search, schedule, live status

  • PNR status, seat availability, and fare enquiry tools

  • TTL-based caching layer with retry/backoff

  • Docker + systemd deployment paths

  • 80+ test suite with ~92% coverage

  • 🚧 Streamable HTTP/SSE transport for remote (non-stdio) deployments

  • 🚧 Multi-language station/train name matching (Hindi, regional scripts)

  • 🚧 Webhook/push alerts for delay and platform changes

  • 🚧 Official llms.txt-based tool discovery for broader agent frameworks


🀝 Contributing

# 1. Fork the repository
# 2. Clone your fork
git clone https://github.com/YOUR_USERNAME/Railway_mcp.git
cd Railway_mcp

# 3. Create a feature branch
git checkout -b feature/your-feature-name

# 4. Make your changes and add tests
pytest tests/ -v

# 5. Commit and push
git commit -m "Add: your feature description"
git push origin feature/your-feature-name

# 6. Open a Pull Request against main

Please keep parser changes covered by tests in tests/test_parsers.py β€” upstream HTML structure changes are the most common source of regressions in this project.


πŸ‘₯ Contributors


⭐ Star History

Star History Chart


πŸ€– AI-Ready Files

This repo ships with agent-discovery stubs so AI coding assistants (and MCP-aware crawlers) can understand the project without parsing the full README:

  • llms.txt β€” machine-readable project summary for LLM tools

  • AGENTS.md β€” instructions for coding agents working in this repo


Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables real-time Indian Railways information retrieval, including live train running status, station schedules, and upcoming arrivals/departures.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables checking railway seat availability, berth types, and pricing for Indian trains through natural language queries.
    -
  • A
    license
    A
    quality
    C
    maintenance
    MCP server for Indian Railways data, enabling AI agents to search trains, get schedules, live status, PNR info, and more without an API key.
    11
    7
    MIT