db-fahrplan
This server gives live Deutsche Bahn timetable, journey planning, fare, and station information to MCP clients like Claude or Cursor.
Plan journeys with live times, delays, duration, changes, and prices
Get fare options and cheapest time bands for a travel day
Show live departure and arrival boards with cancellations and platform changes
Retrieve full trip details: all stops, live status, amenities, running days
Get coach sequence and platform sectors for long-distance trains
Search stations by name or find stations near GPS coordinates
Filter journeys by BahnCard, children, bike, max transfers, via stations, first class, or Deutschlandticket
Return results as compact text or structured JSON
Provides access to live Deutsche Bahn timetable data, including station search, journey planning, departure and arrival boards, platforms, delays, Flexpreis fares, and disruption notices.
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., "@db-fahrplan Show me trains from Munich to Frankfurt tomorrow morning."
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.
db-fahrplan-mcp
Status, 2026-10-13: currently blocked by bahn.de. bahn.de answers this tool's requests (station search, departure boards, journeys) with HTTP 403
OPS_BLOCKED, from a residential connection too. The tool reports the block with bahn.de's reference and does not work around it: this project stays an honest client (see Legal, honestly). Until bahn.de lets it through again, use bahn.de or the DB Navigator app.
Live Deutsche Bahn timetables for Claude, Cursor, and any MCP client: connections, every fare option, cheapest time of day, departure boards, delays, platform changes, all stops of a train, coach sequence, stations near you.
It talks directly to the JSON endpoints behind bahn.de — the same ones the website uses. No API key. No proxy. No third-party mirror to go down. You get what bahn.de shows, including real-time data.
uvx db-fahrplan-mcpWhat it can answer
Question | Tool |
"Krefeld to Köln Messe, there by 8 on Sunday" |
|
"…with my BahnCard 50, two kids, bike, max one change, via Düsseldorf" |
|
"Only Deutschlandticket trains" |
|
"What tickets exist for that 09:35, and what do they cost?" |
|
"When is it cheapest to go to Berlin on the 12th?" |
|
"What leaves Köln Hbf in the next 30 min?" |
|
"Where is ICE 555 right now? Does it still stop at Hagen?" |
|
"Which sector do I stand in for 1st class on ICE 109?" |
|
"Stations near 50.94, 6.96" |
|
"Is 'Frankfurt Flughafen' the Fernbahnhof or Regionalbahnhof?" |
|
Every journey carries a recon_token (→ fares), every leg and board row a journey_id (→ stops).
Times are Europe/Berlin wherever the server runs; (+7) means 7 minutes late; (+1d) means
after midnight. Occupancy (load), amenities (WiFi, bike, step-free, quiet zone…), real-time
platforms and disruption notes are included.
Related MCP server: webharvest
Install
Claude Code
claude mcp add db-fahrplan -s user -- uvx db-fahrplan-mcpClaude Desktop / Cursor / any MCP client — claude_desktop_config.json:
{
"mcpServers": {
"db-fahrplan": {
"command": "uvx",
"args": ["db-fahrplan-mcp"]
}
}
}No uv? pipx install db-fahrplan-mcp or pip install db-fahrplan-mcp, then use
"command": "db-fahrplan-mcp".
Remote / HTTP
db-fahrplan-mcp --transport streamable-http --host 127.0.0.1 --port 8000Binds to localhost by default. Put it behind a reverse proxy with auth before exposing it.
Example
Krefeld Hbf → Köln Messe/Deutz, arrive by 08:00 Sunday
db_journeys("Krefeld Hbf", "Köln Messe/Deutz", "2026-08-30 08:00", arrive_by=true, format="text")
Krefeld Hbf → Köln Messe/Deutz, arrive by 2026-08-30 08:00 (Europe/Berlin)
06:35 → 07:23 · 48 min · 0× change · 25.80 €
RE7 Krefeld Hbf 06:35 Gl.5 → Köln Messe/Deutz 07:23 Gl.1…and on a bad day (real output, signal-box failure at Montabaur):
15:53 → 17:09 · 76 min · 0× change
ICE 125 Köln Hbf 15:53 Gl.2 A-C → Frankfurt(Main)Hbf 17:09 Gl.1 CANCELLED
! Ein defektes Stellwerk im Raum Montabaur beeinträchtigt den Bahnverkehr …
! Verbindung fällt ausformat="text" is compact and cheap in tokens; format="json" (default) is structured.
Configuration
Env var | Default | |
|
| Token-bucket limit on requests to bahn.de |
|
| HTTP timeout, seconds |
|
| Log level (stderr) |
|
| For testing against a mock |
How it compares
db-fahrplan-mcp | DB API Marketplace servers¹ | transport.rest wrappers² | |
API key | none | client id + secret | none (shared 100 req/min) |
Journey planning | ✅ | ❌ (timetables only) | ✅ |
Prices, fare breakdown, best-price day | ✅ | ❌ | ❌ |
BahnCard / children / via / bike / max changes | ✅ | ❌ | partial |
Occupancy, amenities, coach sequence | ✅ | ❌ | ❌ |
Real-time delays, platform changes, cancellations | ✅ | ✅ | ✅ |
Runs offline tests, weekly live canary | ✅ | – | – |
¹ e.g. PaulvonBerg/db-mcp-server, jorekai/db-timetable-mcp. ² e.g. AnythingMCP's DB connector.
Development
git clone https://github.com/capraCoder/db-fahrplan-mcp && cd db-fahrplan-mcp
python -m pip install -e ".[dev]"
pytest # offline, replays recorded bahn.de responses (tests/fixtures)
pytest -m live # hits bahn.de — Krefeld→Garmisch multi-modal trip, fares, best price, boards
ruff check . && mypyCI runs on Linux + Windows, Python 3.10–3.13, on both MCP SDK 1.x and 2.x. A weekly canary runs the live tests and opens an issue if bahn.de changes something.
Legal, honestly
Full text: DISCLAIMER.md. The short version:
Unofficial. Not affiliated with, endorsed by, or supported by Deutsche Bahn AG. "Deutsche Bahn" and "DB" are trademarks of Deutsche Bahn AG. The software ships no DB data and performs no systematic extraction — each query fetches only what the user asked for.
Undocumented endpoints. bahn.de can change or block them at any time. The canary will notice within a week; please open an issue with the raw response if you hit it first.
bahn.de's terms of use restrict automated access. This is a personal, non-commercial tool with an honest
User-Agentand a rate limiter (30 req/min by default). Use it for yourself; do not build a scraping farm on it. bahn.de can refuse requests (HTTP 403) from cloud/VPN addresses or from this tool itself, on any network. The tool reports the block with bahn.de's reference and stops; it does not work around blocks.Prices are informational, as bahn.de quotes them for the given travellers at that moment. Booking happens on bahn.de.
Timetable changes (mid-December, mid-June) can make far-future queries temporarily odd.
No liability for missed connections or wrong fares — see DISCLAIMER.md.
Citing
If this server is part of published work, cite it (metadata in CITATION.cff; GitHub's
"Cite this repository" button renders it):
capraCoder (2026). db-fahrplan-mcp: Deutsche Bahn timetables as an MCP server (Version 1.0.1) [Software]. https://github.com/capraCoder/db-fahrplan-mcp
@software{capracoder_db_fahrplan_mcp_2026,
author = {{capraCoder}},
title = {db-fahrplan-mcp: Deutsche Bahn timetables as an MCP server},
version = {1.0.1},
year = {2026},
url = {https://github.com/capraCoder/db-fahrplan-mcp}
}Release artifacts carry OpenTimestamps proofs (*.ots, Bitcoin-anchored): existence and
integrity are provable without any third-party archive.
Licence
MIT.
Available Tools
9 toolsdb_arrivalsArrival boardCRead-onlyIdempotent
Live arrival board, same shape as db_departures (direction = origin).
Inputs: station (required), when, format, minutes, +1 more. Returns: result
db_best_priceCheapest fares across a dayARead-onlyIdempotent
Bestpreissuche: the cheapest available fare in each time band of a day (00–07, 07–10, 10–13, 13–16, 16–19, 19–24) with the connection it applies to. Use for 'when is it cheapest to go'. Typically only meaningful for long-distance routes booked in advance.
Inputs: date (required), to_station (required), from_station (required), adults, +4 more. Returns: result
db_departuresDeparture boardARead-onlyIdempotent
Live departure board: time (real-time, with delay), line, destination, platform (real-time,
platform_changed flag), cancellation, disruption notes, and journey_id for db_trip_details.
Inputs: station (required), when, format, minutes, +1 more. Returns: result
db_journey_offersFare options for one journeyARead-onlyIdempotent
All fares bahn.de offers for ONE specific connection (Super Sparpreis, Sparpreis, Flexpreis, regional day tickets…) with price and class, re-checked live. Use after db_journeys when the user asks 'how much' or 'cheapest ticket'. Prices are informational, not a booking.
Inputs: recon_token (required), adults, bahncard, first_class, +1 more. Returns: result
db_journeysPlan a journeyARead-onlyIdempotent
Plan train connections between two stations with live bahn.de data.
Each connection: dep/arr (real-time; '(+7)' = 7 min late, '(+1d)' = next day), duration,
changes, price in EUR for the given travellers/BahnCard (None with Deutschlandticket), load
(occupancy) per class, recon_token (pass to db_journey_offers for Sparpreis/Flexpreis
breakdown), and per leg: line, platforms (real-time, with *_platform_changed), stops count,
amenities (WiFi, bike, step-free…), cancellations, journey_id (pass to db_trip_details),
and disruption notes. A journey flagged alternative is DB's re-route around a disruption.
Inputs: to_station (required), from_station (required), via, bike, +13 more. Returns: result
db_nearbyStations near coordinatesARead-onlyIdempotent
Stations and stops around a GPS position — 'stations near me'. Returns name, EVA number,
products, and the bahn.de id usable in every other tool.
Inputs: latitude (required), longitude (required), radius_m, rail_only, +1 more. Returns: result
db_search_stationSearch stationsARead-onlyIdempotent
Find Deutsche Bahn stations by name. Call this only when a name is ambiguous or another
tool rejected it; the other tools accept plain station names directly. Returns name, EVA
number (eva), products served, and the full bahn.de id (also accepted by other tools).
Inputs: query (required), include_stops. Returns: result
db_train_formationCoach sequence (Wagenreihung)ARead-onlyIdempotent
Coach order and platform sectors for a long-distance train at a station: which sector (A–G) 1st class, bistro, bike and quiet coaches stop at, and the real-time platform. Answers 'where do I stand on the platform'. ICE/IC/EC only; not available for regional trains.
Inputs: when (required), train (required), station (required). Returns: result
db_trip_detailsTrip details (all stops, live)ARead-onlyIdempotent
Every stop of one specific train run with scheduled and real-time arrival/departure, platform (real-time), load, and notes — i.e. 'where is this train now, is my stop still served, which platform at my stop'. Also returns train amenities and running days.
Inputs: journey_id (required), format. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 9 tools
Each tool targets a distinct task: station search, journey planning, fare offers, best-price search, departures, arrivals, trip details, nearby stations, and train formation. The only mild overlap is between db_journey_offers and db_best_price (both fare-related), but their specific purposes and usage cues keep them distinguishable.
All tools consistently use the `db_` prefix and clear domain vocabulary. Minor inconsistency: `db_search_station` is verb-based while most others are noun phrases (`db_journeys`, `db_departures`), but the overall pattern is still predictable and readable.
Nine tools is well-scoped for a rail travel information server. Each tool covers a distinct user need without unnecessary duplication or overwhelming breadth.
The tool set covers the full journey information workflow: station discovery by name or GPS, journey planning, fare comparison, live departures/arrivals, per-trip stop details, and train formation. There are no obvious dead ends or significant missing operations for the stated domain.
Maintenance
Related MCP Connectors
One MCP for the Web. Easily search, crawl, navigate, and extract websites without getting blocked.…
One MCP server for 180+ live web-data APIs returning clean JSON from sites that block scrapers.
Official MCP server for MAQAMI, a hotel and flight booking platform with 3M+ hotels. Search live hotel rates and flights, look up places, airports and hotel details, then prebook and book. Remote Streamable HTTP endpoint, no API key required.
Stealth web browser for agents: search, fetch, click, download and type in persistent MCP sessions.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables MCP-compatible clients to scrape and extract data from live websites using a headless Chromium browser, with support for CSS selectors, link extraction, table extraction, and Amazon product pages.-
- AlicenseNot gradedqualityBmaintenanceEnables web search and scraping through MCP, running locally with courtesy rate limiting and caching.17 npmMIT
- AlicenseBqualityBmaintenanceEnables MCP clients to run live web searches, fetch and navigate readable web pages, search images, capture PDF screenshots, and retrieve finance, weather, sports, and world-time data through a zero-configuration authenticated backend.118 npmMIT
- AlicenseAqualityCmaintenanceEnables MCP-compatible clients to search the web and fetch HTTP/HTTPS pages as Markdown, returning result metadata such as titles, URLs, dates, relevance, and summaries.219 npm1MIT