irail-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@irail-mcpShow departures from Brussels Central at 5 PM"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
iRail MCP Server
Disclaimer: This project was vibe coded and is not affiliated with or supported by iRail vzw. Train data may be inaccurate or outdated. Always verify with official sources (belgiantrain.be or the NMBS/SNCB app) before making travel decisions.
A Model Context Protocol (MCP) server that provides Belgian railway travel information via the iRail API.
Features
Search Stations - Find Belgian railway stations by name
Live Departures/Arrivals - Real-time departure and arrival boards
Find Connections - Route planning between stations with transfers
Train Information - Detailed stops, delays, and platforms for a specific train
Network Disturbances - Current disruptions and planned maintenance
Related MCP server: railinfo-mcp
Installation
Requires Python 3.11+ and uv.
git clone https://github.com/HansF/irail-mcp.git
cd irail-mcp
uv venv && source .venv/bin/activate
uv pip install -e .Usage with Claude Code
Add to your project's .mcp.json:
{
"mcpServers": {
"irail": {
"command": "uvx",
"args": ["irail-mcp"]
}
}
}Then ask Claude things like:
"What trains leave Brussels Central in the next hour?"
"Find a route from Antwerp to Bruges at 2:30 PM tomorrow"
"Are there any disruptions on the Belgian rail network?"
"Show me details for train IC2240"
Tools
search_stations
Search for stations by name.
query(required) - Station name or partial namelang(optional) - Language: en, nl, fr, de, it
get_liveboard
Real-time departures or arrivals from a station.
station(required) - Station namedate(optional) - YYYY-MM-DD, "today", "tomorrow", "+2 days"time(optional) - HH:MM (24h)arrival(optional) - Show arrivals instead of departureslang(optional)
find_connections
Find routes between two stations.
from_station(required) - Departure stationto_station(required) - Destination stationdate,time,lang(optional)arrival_time(optional) - If true, time is desired arrival time
get_train_info
Detailed information about a specific train.
train_id(required) - e.g. "IC1234" or "BE.NMBS.IC1234"date,lang(optional)
get_disturbances
Current network disruptions and planned works.
lang(optional)
Running Tests
uv pip install -e ".[dev]"
python -m pytest tests/ -vAPI Compliance
Rate limited to 3 requests/second per iRail guidelines
Proper User-Agent header set
30-second timeout for slow responses
License
MIT
References
Available Tools
5 toolsfind_connectionsB
Find routes between two stations with connection details
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Date in format YYYY-MM-DD or relative (today, tomorrow, +2 days) | |
| lang | No | Language code (en, nl, fr, de, it) | en |
| time | No | Time in 24-hour format (e.g., '14:30') | |
| to_station | Yes | Destination station name (e.g., 'Antwerp') | |
| arrival_time | No | If true, time is arrival time; if false, time is departure time (default: false) | |
| from_station | Yes | Departure station name (e.g., 'Brussels') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden for behavioral disclosure. It only states 'Find routes between two stations with connection details' without revealing behaviors like default time handling, pagination, or error conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no wasted words. It is front-loaded with the core purpose, though it could benefit from additional context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 6 parameters and no output schema or annotations, the description is too minimal. It does not explain return values, how date/time interact, or what 'connection details' entails.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and each parameter has a description. The tool description adds no extra meaning beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verbs and resources: 'Find routes between two stations with connection details'. It clearly distinguishes from sibling tools like get_liveboard (departures) and search_stations (station search).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide any guidance on when to use this tool versus alternatives, nor does it mention prerequisites or exclusions. It simply states what it does.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_disturbancesA
Get current network disruptions and planned maintenance works
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | Language code (en, nl, fr, de, it) | en |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility for behavioral disclosure. It only states what the tool does without revealing any behavioral traits such as read-only nature, data locality, rate limits, or response format.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no superfluous information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (1 optional parameter, no output schema), the description is minimally adequate but lacks details on return values, real-time nature, and typical use cases, which would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with the 'lang' parameter already well-described. The description adds no additional meaning beyond the schema, meeting the baseline for high coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get' and the resource 'current network disruptions and planned maintenance works', which is specific and distinguishes it from sibling tools like find_connections or get_liveboard.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies using this tool to retrieve current disruptions and maintenance, but provides no explicit when-to-use or when-not-to-use guidance, nor does it mention alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_liveboardB
Get real-time departures or arrivals from a station
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Date in format YYYY-MM-DD or relative (today, tomorrow, +2 days) | |
| lang | No | Language code (en, nl, fr, de, it) | en |
| time | No | Time in 24-hour format (e.g., '14:30') | |
| arrival | No | If true, show arrivals; if false, show departures (default: false) | |
| station | Yes | Station name or URI (e.g., 'Brussels Central', 'Gent-Sint-Pieters') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It discloses real-time nature and departure/arrival based on 'arrival' parameter, but omits details like authentication needs, rate limits, error handling, or response structure. The lack of transparency is significant for a data retrieval tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler, instantly conveying the core functionality. It is appropriately sized for the tool's simplicity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite high schema coverage and no output schema, the description lacks essential details for an agent: no mention of response format (e.g., list of departures with times, platforms), no error handling, no pagination. The tool has 5 parameters but the description provides no usage completement beyond what's in schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters (station, date, time, arrival, lang) with clear meanings. The description adds no extra semantic value beyond stating 'departures or arrivals', which is already covered by the 'arrival' parameter description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves real-time departures or arrivals from a station, using specific verb 'Get' and resource 'liveboard'. This distinguishes it from siblings like 'find_connections' (routes between stations) or 'get_train_info' (specific train details).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for real-time station data but does not explicitly state when to use this tool versus alternatives like 'find_connections'. No when-not-to-use or context provided, leaving the agent to infer from sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_train_infoB
Get detailed information about a specific train including all stops and current delays
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Date in format YYYY-MM-DD (default: today) | |
| lang | No | Language code (en, nl, fr, de, it) | en |
| train_id | Yes | Train ID from liveboard results (e.g., 'IC1234' or 'BE.NMBS.IC1234') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It indicates the tool provides detailed info including stops and delays, suggesting real-time or schedule data, but does not disclose data freshness, required permissions, rate limits, or any side effects. The parameter description hints at input format, but behavioral traits beyond the basic operation are absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence (14 words) that efficiently conveys the core purpose without any extraneous information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the absence of an output schema and annotations, the description is insufficient. It does not specify the return format (e.g., list of stops, delay structure), data source, or update frequency. For a tool with moderate complexity (stops and delays), the description lacks context needed for an agent to fully understand the tool's capabilities.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with all three parameters described in the schema. The description does not add any additional meaning for the parameters beyond what the schema already provides. The output hint about 'stops and current delays' is about return values, not parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves detailed information about a specific train, including stops and current delays. It uses a specific verb ('Get') and resource ('train'), and distinguishes from sibling tools like get_liveboard (station-based) and get_disturbances (general disruptions).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide guidance on when to use this tool versus alternatives, nor does it mention prerequisites (e.g., obtaining a train_id from get_liveboard). No when-not or exclusionary advice is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_stationsA
Search for railway stations in Belgium by name
| Name | Required | Description | Default |
|---|---|---|---|
| lang | No | Language code (en, nl, fr, de, it) | en |
| query | Yes | Station name or partial name to search for (e.g., 'Brussels', 'Antwerp') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, and description only states search purpose without detailing behavioral traits like maximum results, pagination, authentication needs, or rate limits. Minimal behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single short sentence with no extraneous information. Front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple search tool with no output schema, description is adequate but could include more details about result format, partial match behavior, or language usage. Not complete but functional.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers 100% of parameters with descriptions. The description adds 'by name' context but does not significantly enhance parameter understanding beyond the schema. Baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Search for railway stations in Belgium by name', providing a specific verb, resource, and scope. It distinguishes from sibling tools which focus on connections, disturbances, liveboard, and train info.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Purpose is clear, but no explicit guidance on when to use this tool versus siblings. No 'when not to use' or alternative tool mentioned. Usage is implied but not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.2.0- First observed
find_connections - First observed
get_disturbances - First observed
get_liveboard - First observed
get_train_info - First observed
search_stations
TDQS
Scored across 5 tools
Each tool has a clear, distinct purpose: route planning, disruptions, liveboard, train details, and station search. No overlap.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., find_connections, get_liveboard), making them predictable.
With 5 tools, the set is well-scoped for a railway information server, covering essential operations without being excessive.
The tool surface covers core railway info needs: station lookup, liveboard, connections, train details, and disturbances. No obvious gaps for an informational API.
Maintenance
Related MCP Connectors
iRail MCP — Belgian rail (SNCB/NMBS) real-time via the community iRail API
Real-time BART departures, trip planning, fares, stations, and advisories.
Stockholm transit: realtime departures, trip planning, disruptions and personal commute status.
Norwegian transport (Entur) and geodata (Kartverket): trips, departures, addresses, elevation.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides real-time Dutch Railways (NS) data for journey planning, live departures, disruptions, and station search.3-
- FlicenseNot gradedqualityDmaintenanceEnables real-time Indian Railways information retrieval, including live train running status, station schedules, and upcoming arrivals/departures.-
- FlicenseNot gradedqualityDmaintenanceEnables querying Swiss public transport (trains, buses, trams, boats) for stations, connections, and station boards via the opendata.ch API.-
- FlicenseNot gradedqualityDmaintenanceMCP server for querying Belgian railway data (SNCB/NMBS) via the iRail API, enabling station search, liveboard, and journey planning.-