MCP_Trenitalia
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 6 GitHub stars
Code Pass
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Unofficial MCP Server of Trenitalia, built using viaggiatreno and NeTex Database crosschek
MCP Trenitalia
Ciuff is a free, self-hosted MCP server for Italian railway information. It combines official Trenitalia and Italo timetables with their public live-information services.
ciuff.org is the existing project website. The server works over stdio, Streamable HTTP or legacy SSE. It needs no paid API account, subscription, database or cloud service.
Features
- Search stations and direct journeys across Trenitalia and Italo.
- Query Trenitalia train status, arrivals and departures.
- Query Italo train status and station boards.
- Report timetable coverage, sources and update timestamps.
- Keep future timetables separate from today's live information.
- Provide official ticket-site links. Live prices, seat availability and booking are not implemented.
Example questions:
Which direct Trenitalia and Italo trains leave Roma Termini for Milano Centrale tomorrow after 08:00?
What is the current status of Italo 8908?
Do the downloaded timetables cover my travel date?
Install
Requires Python 3.12 or newer. Dependencies are open source; network access is needed to download timetables and query live information.
git clone https://github.com/Fanfulla/MCP_Trenitalia.git
cd MCP_Trenitalia
python -m venv .venv
Activate the environment:
# Windows PowerShell
.venv\Scripts\Activate.ps1
# macOS / Linux
source .venv/bin/activate
Then install and download current validated timetables:
python -m pip install -r requirements.txt
python update_data.py
With uv, uv venv and uv pip install -r requirements.txt are alternatives.
Timetable caches are created under data/ and are not distributed in this repository. The first download can take a few minutes. Live tools can still run without the caches; schedule tools report missing or invalid coverage explicitly.
Run and connect
# Local MCP client
python server.py
# Recommended HTTP transport: POST /mcp
python server.py --streamable-http
# Existing SSE clients: GET /sse and POST /messages/
python server.py --sse
--http remains an alias for legacy SSE, preserving the original runtime behavior. Older README versions incorrectly described that flag as Streamable HTTP.
Example stdio client configuration on Windows:
{
"mcpServers": {
"MCP Trenitalia": {
"command": "C:\\path\\to\\MCP_Trenitalia\\.venv\\Scripts\\python.exe",
"args": ["C:\\path\\to\\MCP_Trenitalia\\server.py"]
}
}
}
On macOS/Linux, use absolute paths to .venv/bin/python and server.py. For HTTP clients, select the matching transport and connect to http://127.0.0.1:8000/mcp or http://127.0.0.1:8000/sse.
Tools
The five original names and nested params input envelope remain available.
| Tool | Purpose |
|---|---|
trenitalia_cerca_stazione |
Local station lookup with Viaggiatreno fallback |
trenitalia_monitora_partenze |
Live Trenitalia departures |
trenitalia_monitora_arrivi |
Live Trenitalia arrivals |
trenitalia_traccia_treno |
Live Trenitalia train details with origin station |
trenitalia_orari_tra_stazioni |
Date-aware direct Trenitalia journeys and today's live enrichment |
ciuff_cerca_stazioni |
Station search across one or both operators |
ciuff_cerca_viaggi |
Direct scheduled journeys across one or both operators |
ciuff_stato_treno |
Public train status for an explicitly selected operator |
italo_tabellone |
Italo arrivals or departures by station name or Italo code |
ciuff_stato_fonti |
Local timetable coverage and provenance, not upstream uptime |
ciuff_link_biglietti |
Official purchase-site links, with prices explicitly unavailable |
The six new tools return MCP structured content. Example arguments for ciuff_cerca_viaggi:
{
"params": {
"stazione_a": "Roma Termini",
"stazione_b": "Milano Centrale",
"data": "2026-09-28",
"orario_da": "08:00",
"operatore": "all",
"limite": 10
}
}
operatore accepts all, trenitalia or italo for station/journey searches. Train status requires a specific operator and numero_treno. ciuff_stato_fonti takes no arguments. Station IDs belong to their source; use names to search both operators. Ambiguous names return choices instead of selecting the first match.
Sources and freshness
| Data | Source | Limits |
|---|---|---|
| Trenitalia schedules | National NeTEx feed, CCISS | Static schedules with service calendars and validity periods |
| Italo schedules | NeTEx feed, CCISS | Direct rail services; combined itineraries are excluded |
| Trenitalia live information | Viaggiatreno | Undocumented public endpoints, currently accessed over HTTP |
| Italo live information | Italo In Viaggio | Undocumented public endpoints, without a reliable service-date field |
Live verification on 2026-09-27 found:
- Trenitalia feed published on 2026-09-25, valid 2026-09-26 through 2026-12-12.
- Italo feed published on 2026-09-26, valid 2026-09-25 through 2027-02-02.
- Both feeds returned direct Roma Termini to Milano Centrale journeys.
- Both public live-information adapters returned data.
These are verification snapshots, not guarantees of continued upstream availability. Check ciuff_stato_fonti for your local feed dates.
# Refresh all, or just one provider
python update_data.py
python update_data.py --provider italo
python update_data.py --provider trenitalia
Refresh validates the feed before atomically replacing the previous cache. A failed refresh preserves the old file; expired coverage is still reported as expired. Running servers pick up cache changes without restarting. For unattended refresh, run the command daily with your operating-system scheduler. No scheduler or subscription is installed automatically.
The parser supports the Italian-profile structures in the verified feeds, including UIC calendar bits, explicit date exceptions, boarding restrictions and overnight offsets. It is not a general NeTEx implementation. Unsupported calendars, unresolved references and ambiguous/nonexistent daylight-saving wall times fail closed. Searches cover direct trains, not transfers or historic telemetry.
Italo output distinguishes request time (observed_at) from the source update time. When the service date cannot be verified, service_date is null and freshness is date_unverified. Such delays are not attached to a dated scheduled journey. Missing delays remain null; they never mean "on time". Stale responses are labeled separately. Cancellation meanings are not guessed from undocumented numeric codes.
Self-hosting
The server defaults to loopback. It includes a health endpoint, allowed-host checks, a per-peer request limit and an optional bearer token. Outbound requests use an in-process cache and connection pool, with bounded concurrency, response sizes and transient retries.
| Variable | Default | Purpose |
|---|---|---|
PORT |
8000 |
HTTP listen port |
MCP_HOST |
127.0.0.1 |
Bind address; use 0.0.0.0 to expose the service intentionally |
LOG_LEVEL |
info |
Uvicorn log level |
MCP_ALLOWED_HOSTS |
localhost,127.0.0.1,[::1] |
Comma-separated hostnames, without scheme or port |
MCP_RATE_LIMIT |
60 |
Requests per minute per connected peer, per process |
MCP_API_KEY |
unset | Optional token required as Authorization: Bearer ... |
Use TLS at your reverse proxy for remote access and add its hostname to MCP_ALLOWED_HOSTS. Forwarded client IP headers are not trusted: behind a proxy, the built-in limit applies to its address. Configure per-user limits at your proxy if needed. /health is token-exempt and reports process/local-cache status, not live upstream health. The optional token is static access control, not OAuth.
The existing Procfile preserves legacy SSE. Configure MCP_HOST and MCP_ALLOWED_HOSTS for your host, or change the launch command to python server.py --streamable-http. The project requires no hosting subscription; operating a public host is your responsibility. The existing web/ website remains separate.
Development
python -m pip install -r requirements-dev.txt
python -m pytest -q
python -m compileall -q server.py models.py rail_service.py timetable.py build_timetable.py update_data.py viaggiatreno.py italo.py http_client.py http_app.py time_utils.py
Tests use local fixtures and mocked network transports. They cover calendars, midnight/DST, stale data, station ambiguity, retries, malformed responses, structured MCP output, HTTP limits and multi-client SSE cleanup. Live checks are separate from the offline suite. CI runs the offline tests on Windows and Linux.
The server uses the official MCP Python SDK, not the separate fastmcp distribution. See CHANGELOG.md for migration notes.
License
Project code is MIT licensed. Upstream datasets and provider responses have their own terms and are not relicensed under MIT. Public availability does not establish redistribution rights. Downloaded timetable caches stay local; source metadata is in data/sources.json.
This independent project is unaffiliated with Trenitalia or Italo.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found