idf-mcp
Provides real-time RER B transit information from Île-de-France Mobilités, including next train departures, arrival times, delays, platform/boarding info, line status disruptions, and journey planning with addresses or stop names.
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., "@idf-mcp c'est quand le prochain RER pour Paris ?"
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.
idf-mcp — « c'est quand le prochain RER ? »
Serveur MCP local qui branche Claude (Code et Desktop) sur le temps réel du RER B, via les API publiques d'Île-de-France Mobilités (plateforme PRIM).
> c'est quand le prochain RER pour Paris, et j'arrive à quelle heure ?
La Hacquinière → Denfert-Rochereau · lun. 7 sept. 20:38
• EKLI 20:42 → Denfert-Rochereau 21:19 · 37 min · direct · terminus Aéroport Charles de Gaulle 2 · dans 4 min
• DEFI 20:57 (+3) → Denfert-Rochereau 21:34 (+3) · 37 min · direct · terminus Mitry-Claye · dans 19 min ⚠ retards annoncésAvec une correspondance ou une adresse, chaque étape est détaillée :
> je dois être au 43 rue Saint-Dominique à 10 h
La Hacquinière → 43 Rue Saint-Dominique 75007 Paris · mar. 8 sept. 08:50
• EPAF 08:59 → 43 Rue Saint-Dominique 75007 Paris 09:48 · 49 min · 1 corresp. · dans 9 min
↳ marche 2 min → La Hacquinière
↳ RER B (EPAF) · La Hacquinière 08:59 → Saint-Michel Notre-Dame 09:32 · 12 arrêts · dir. Aéroport CDG 2
↳ marche 4 min → Saint-Michel Notre-Dame
↳ attente 2 min
↳ RER C (ELBA) · Saint-Michel Notre-Dame 09:38 → Invalides 09:44 · 2 arrêts · dir. Versailles Rive Gauche
↳ marche 4 min → 43 Rue Saint-Dominique 75007 Paris1. Obtenir une clé PRIM (5 min)
Créer un compte gratuit sur https://prim.iledefrance-mobilites.fr.
Générer une clé dans « Mes jetons ».
Souscrire aux API — une clé ne donne accès qu'à ce à quoi on a souscrit, c'est la cause n°1 de
401:« Prochains passages (requête unitaire) » →
departures_board« Calculateur – accès générique v2 » →
next_trains_to_paris,plan_journey« Messages info trafic v2 » →
line_status
Quota : environ 20 000 requêtes par jour et par API. Le serveur met en cache chaque URL 25 s, donc une rafale de questions ne coûte qu'un appel.
Related MCP server: openbusdata
2. Installer
npm install
npm run build # optionnel : évite de dépendre de tsx au lancement
npm testClaude Code
claude mcp add --scope user idfm \
-e IDFM_API_KEY=ta_cle \
-e IDFM_WORK_STOP=473890 \
-- node /chemin/vers/idf-mcp/dist/index.jsSans npm run build, remplacer la dernière ligne par
-- npx tsx /chemin/vers/idf-mcp/src/index.ts.
Claude Desktop
Dans ~/Library/Application Support/Claude/claude_desktop_config.json :
{
"mcpServers": {
"idfm": {
"command": "node",
"args": ["/chemin/vers/idf-mcp/dist/index.js"],
"env": {
"IDFM_API_KEY": "ta_cle",
"IDFM_WORK_STOP": "473890"
}
}
}
}Vérifier sans Claude
IDFM_API_KEY=ta_cle npm run inspector3. Configuration
Variable | Défaut | Rôle |
| — | Obligatoire. Clé PRIM. |
|
| Gare de départ par défaut. |
|
| Ce que « Paris » veut dire. |
|
| Cache par URL, en secondes. |
|
| Timeout HTTP. |
Autres gares parisiennes de la B : 45102 Châtelet - Les Halles ·
462394 Gare du Nord · 43833 Luxembourg · 44877 Saint-Michel Notre-Dame ·
44500 Port Royal · 473843 Cité Universitaire.
Voir .env.example. Ces variables se passent au serveur via la
config MCP (-e ou le bloc env), pas par un fichier .env lu au démarrage.
4. Les tools
Tool | Ce qu'il donne | Source |
| Le principal. Départ, retard, heure d'arrivée, durée, mission, terminus, perturbations. | Navitia |
| Tableau de gare : heure attendue, voie, train à quai, trains supprimés. Pas d'heure d'arrivée. | SIRI |
| Perturbations en cours et à venir sur la B. | Navitia |
| Itinéraire quelconque, tous modes, avec | Navitia |
| Recherche d'arrêt par nom → identifiant + lignes. Sans clé. | Open data IDFM |
Prompt /prochain-rer : déclenche next_trains_to_paris avec les valeurs par défaut.
Les gares s'écrivent par identifiant (473890), par nom (Denfert-Rochereau),
sans accent (hacquiniere) ou par alias (denfert, chatelet, cdg, st remy).
plan_journey accepte en plus une adresse postale (43 rue Saint-Dominique, Paris)
et des coordonnées (2.317444;48.859821) — inutile de chercher la station la plus
proche à la main. Les horaires acceptent 18:30, 18h30, demain, demain 08:15
ou une date ISO.
Exemples de questions
« c'est quand le prochain RER pour Paris ? »
« je pars dans 20 min, j'arrive à quelle heure à Châtelet ? »
« il y a des retards sur la B ? »
« le train est à quai ? sur quelle voie ? »
« pour être à Denfert à 9 h, je pars à quelle heure ? » →
plan_journeyavecarrive_by« je dois être au 43 rue Saint-Dominique demain à 9 h » →
plan_journey, adresse telle quelle« le dernier train pour Saint-Rémy ce soir ? » →
departures_boardsenssaint-remy
5. Ce que fait le code
src/
index.ts bootstrap MCP (stdio), les 5 tools et le prompt
config.ts lecture de l'environnement
time.ts Europe/Paris : Navitia rend du local sans offset, SIRI de l'ISO
format.ts rendu texte compact (« EKLI 20:42 (+2) → … · dans 4 min »)
idfm/client.ts fetch + apikey + cache TTL + erreurs traduites (401/404/429/5xx/timeout)
idfm/siri.ts stop-monitoring, general-message
idfm/navitia.ts journeys, line_reports
idfm/stops.ts les 47 gares de la B en dur (ids + coordonnées) + ordre de la ligne
idfm/geocode.ts adresse → coordonnées (Base Adresse Nationale, sans clé)
tests/ 99 tests, dont un test d'intégration qui démarre le serveur
scripts/ capture-fixtures.shQuelques décisions qui méritent une phrase :
L'heure d'arrivée vient de Navitia, pas de SIRI. SIRI ne sait dire que « ce train part d'ici à telle heure » ; toutes les missions de la B ne desservent pas les mêmes gares, donc SIRI seul ne permet pas de conclure.
Le sens « vers Paris » est calculé, pas deviné. Les 47 gares portent une position le long de la ligne (branches comprises), et Paris intra-muros est un intervalle sur le tronc commun. Depuis La Hacquinière « vers Paris » exclut Saint-Rémy ; depuis Le Bourget il exclut CDG et Mitry. Depuis une gare parisienne, la question n'a pas de sens et le tool le dit au lieu de filtrer.
Les trains supprimés sont affichés, marqués
⛔ SUPPRIMÉ. Les masquer serait le plus sûr moyen de rater une info importante.L'heure d'arrivée est celle à destination, marche finale comprise, pas celle du dernier train : sur « je dois y être à 10 h », c'est l'écart qui compte. Le détail des étapes donne l'heure exacte de chaque train.
Le détail n'apparaît que s'il sert : correspondance à faire, ou marche d'au moins trois minutes. Un RER direct reste sur une seule ligne.
Une réponse vide n'est pas une erreur : la nuit, il n'y a simplement plus de train, et le message le dit.
Les identifiants et coordonnées des gares sont en dur (vérifiés contre l'open data IDFM le 2026-09-07) : pas d'appel réseau pour résoudre « denfert ».
Une station, une entrée. Le référentiel expose un identifiant par quai et par ligne : « Invalides » y figure 24 fois. Les résultats sont regroupés par nom et commune, ce qui évite de déclarer ambiguë chaque gare parisienne.
On tranche au lieu d'échouer. Quand plusieurs arrêts collent encore, le mieux classé est retenu (nom exact, puis mode lourd, puis nombre de lignes) et les autres sont affichés — refuser de choisir rendait le calcul inutilisable.
6. Développement
npm test # suite complète
npm run test:watch
npm run typecheck
npm run dev # lance le serveur en stdio (pour l'inspecteur)Les fixtures livrées sont synthétiques : elles reproduisent la forme documentée des API, pas une capture réelle. Avec une clé en main :
IDFM_API_KEY=ta_cle ./scripts/capture-fixtures.sh
npm testLe script écrase tests/fixtures/*.json avec de vraies réponses. Si un test
casse à ce moment-là, c'est une bonne nouvelle : il a trouvé un écart entre la
documentation PRIM et la réalité, et l'endroit exact à corriger.
Si le calculateur refuse les itinéraires :
IDFM_API_KEY=ta_cle ./scripts/diagnose.shIl teste une par une les causes possibles (filtre de ligne, identifiants d'arrêt, chemin appelé, souscription) et dit laquelle est la bonne.
7. Pièges connus
401sur Navitia alors que SIRI marche → l'API « Calculateur » n'est pas souscrite sur cette clé. Le message d'erreur du serveur le dit explicitement.allowed_id[]est une liste blanche, pas un filtre. Tout ce qui n'y figure pas est interdit — y compris l'origine et la destination du trajet, ce qui fait répondreno_origin_nor_destination. Les deux gares sont donc toujours ajoutées à la liste ; et si le calculateur refuse malgré tout le filtre, il est abandonné et la réponse le signale plutôt que de ne rien rendre.Le calculateur veut des coordonnées, pas des identifiants d'arrêt. PRIM n'expose que l'endpoint global de Navitia (
/v2/navitia/journeys), et celui-ci ne sait résoudre que deslon;lat: lui passer unstop_area:IDFM:47046répond invariablementno_origin_nor_destination, quel que soit le couple de gares. Les trajets sont donc demandés en coordonnées — embarquées pour les 47 gares de la B, cherchées dans l'open data sinon — tandis que les identifiants restent utilisés dansallowed_id[], où ils sont indispensables. En repli, le serveur retente en identifiants, puis sur/v2/navitia/coverage/{coverage}/journeyssi cette coverage existe (/v2/navitia/coveragerépond 404 sur au moins une clé PRIM, et l'anciennefr-idfa été décommissionnée : elle est donc demandée, jamais devinée). La combinaison qui marche est mémorisée — les appels suivants coûtent une seule requête.La Hacquinière a 3 points d'arrêt (ZDE) pour 1 zone d'arrêt (ZDA) — on travaille toujours au niveau ZDA (
47046). Si SIRI ne renvoie rien pour une ZDA,departures_boardbascule automatiquement sur les quais.Changement d'heure : Navitia renvoie de l'heure locale sans offset. La conversion est testée sur la nuit du 25 octobre.
Un identifiant de quai n'est pas une zone d'arrêt.
IDFM:22193est un quai,IDFM:monomodalStopPlace:470540une station : seul le second existe commestop_areacôté calculateur. Le premier donnait unno_origin_nor_destinationtrès trompeur.Le géocodage est bridé à l'Île-de-France. « Denfert » seul renvoie une avenue à La Rochelle avec un score honorable ; hors des départements 75 à 95, le résultat est rejeté.
Ne pas boucler depuis un hook : le cache de 25 s protège le quota d'une rafale, pas d'une boucle.
8. Sources
Available Tools
5 toolsdepartures_boardTableau de gare (temps réel)A
Tableau des prochains départs à un arrêt, comme les écrans sur le quai : heure attendue, retard, voie, train à quai ou non, trains supprimés. Ne donne PAS l'heure d'arrivée (utiliser next_trains_to_paris pour ça). Utile pour « il est où le train ? », « sur quelle voie ? », ou en repli si le calculateur est en panne. Défaut : La Hacquinière (47046), sens Paris.
Inputs: stop, count, direction.
find_stopRecherche d'arrêtA
Cherche un arrêt d'Île-de-France par nom : identifiant, lignes et modes desservis, regroupés par station. À utiliser quand un nom est inconnu ou pour lever un doute. Inutile pour une adresse postale : plan_journey la prend directement. N'utilise pas de clé API (données ouvertes).
Inputs: query (required), limit.
line_statusPerturbations du RER BA
État de la ligne : perturbations en cours et à venir (travaux, incidents, grèves, interruptions, suppressions). À utiliser quand l'utilisateur demande « il y a un problème sur la B ? » ou pour expliquer un trajet anormalement long.
Inputs: include_past.
next_trains_to_parisProchains RER vers ParisA
LE tool à utiliser pour « c'est quand le prochain RER pour Paris et j'arrive à quelle heure ? ». Donne, pour chaque prochain train La Hacquinière (47046) → Denfert-Rochereau (473890) : heure de départ réelle et retard, heure d'arrivée, durée, code mission, terminus et perturbations. Temps réel, RER B uniquement (pas de bus de rabattement). Les gares par défaut viennent de la configuration ; les préciser seulement si l'utilisateur parle d'une autre gare.
Inputs: to, from, when, count.
plan_journeyCalcul d'itinéraireA
Itinéraire temps réel en Île-de-France, tous modes et correspondances incluses. Les extrémités acceptent un nom d'arrêt MAIS AUSSI une adresse postale : passer « 43 rue Saint-Dominique, Paris » directement, sans chercher la station la plus proche. Pour « je dois être à X à 9 h », utiliser when avec arrive_by: true. Préférer next_trains_to_paris pour le trajet domicile → Paris habituel.
Inputs: to (required), from (required), when, count, +2 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 5 tools
Most tools have clearly distinct jobs: departures_board handles live platform/departure info, line_status handles disruptions, find_stop handles stop lookup, and plan_journey handles multimodal itineraries. next_trains_to_paris overlaps somewhat with plan_journey for the habitual commute, but the descriptions explicitly explain when to prefer each.
All names are readable and use snake_case, but they mix noun-phrase resource names (departures_board, line_status, next_trains_to_paris) with verb-first command names (plan_journey, find_stop). There is no consistent verb_noun pattern across the set.
Five tools is a well-scoped size for a transit information server. Each tool covers a distinct layer of functionality—next trains, live departures, line status, journey planning, and stop lookup—without unnecessary duplication.
The set covers the core transit domain well: departures, arrivals via next_trains_to_paris, disruptions, stop search, and full journey planning. Minor gaps exist, such as no dedicated tool for return-trip RER B status or line status for non-B lines, but plan_journey and line_status can work around these.
Related MCP Connectors
MCP server for the Seline Analytics API
MCP server for French (BOAMP) + EU (TED) public procurement data via TenderAPI.
MCP server for Travel & Transportation
MCP server providing attendance data queries via the CloudTime API.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP server for interacting with the Berlin Public Transport (BVG) API to search for locations and plan journeys. It provides real-time access to departures, arrivals, trip details, and vehicle tracking within Berlin's transit network.MIT
- AlicenseCqualityCmaintenanceMCP server for the UK Bus Open Data Service, enabling timetable queries, stop search, route discovery, journey planning, and real-time bus tracking.1622 PyPIMIT
- AlicenseNot gradedqualityDmaintenanceMCP server for real-time German public transport data (HAFAS/VBN network). Enables querying departures, arrivals, journeys, and nearby stops using natural language.ISC
- FlicenseNot gradedqualityDmaintenanceMCP server for querying French railway services (SNCF) via the Navitia API, enabling station search, journey planning, and departure board retrieval.-