Skip to main content
Glama

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és

Avec 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 Paris

1. Obtenir une clé PRIM (5 min)

  1. Créer un compte gratuit sur https://prim.iledefrance-mobilites.fr.

  2. Générer une clé dans « Mes jetons ».

  3. 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 test

Claude 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.js

Sans 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 inspector

3. Configuration

Variable

Défaut

Rôle

IDFM_API_KEY

Obligatoire. Clé PRIM.

IDFM_HOME_STOP

47046 (La Hacquinière)

Gare de départ par défaut.

IDFM_WORK_STOP

473890 (Denfert-Rochereau)

Ce que « Paris » veut dire.

IDFM_CACHE_TTL

25

Cache par URL, en secondes.

IDFM_TIMEOUT_MS

10000

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

next_trains_to_paris

Le principal. Départ, retard, heure d'arrivée, durée, mission, terminus, perturbations.

Navitia journeys

departures_board

Tableau de gare : heure attendue, voie, train à quai, trains supprimés. Pas d'heure d'arrivée.

SIRI stop-monitoring

line_status

Perturbations en cours et à venir sur la B.

Navitia line_reports, repli SIRI general-message

plan_journey

Itinéraire quelconque, tous modes, avec arrive_by. Accepte une adresse postale.

Navitia journeys + BAN

find_stop

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_journey avec arrive_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_board sens saint-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.sh

Quelques 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 test

Le 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.sh

Il 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

  • 401 sur 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épondre no_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 des lon;lat : lui passer un stop_area:IDFM:47046 répond invariablement no_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 dans allowed_id[], où ils sont indispensables. En repli, le serveur retente en identifiants, puis sur /v2/navitia/coverage/{coverage}/journeys si cette coverage existe (/v2/navitia/coverage répond 404 sur au moins une clé PRIM, et l'ancienne fr-idf a é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_board bascule 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:22193 est un quai, IDFM:monomodalStopPlace:470540 une station : seul le second existe comme stop_area côté calculateur. Le premier donnait un no_origin_nor_destination trè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 tools
departures_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
stopNoArrêt (id ou nom). Défaut : La Hacquinière (47046).
countNoNombre de départs (défaut 5).
directionNoSens : « paris » = vers Paris (défaut), « saint-remy » = sens opposé (banlieue), « all » = les deux.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden. It discloses what the tool returns (departure times, delays, platforms, at-platform status, cancellations), what it intentionally omits (arrival time), and its default behavior (La Hacquinière, direction Paris). It does not mention data freshness or output format, but the core behavior is well covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: it opens with what the tool does and the exact kind of information returned, then handles exclusions and usage context, and ends with defaults. Every sentence earns its place without unnecessary filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description needs to communicate return content; it does so by listing expected departure fields and explicitly excluding arrival time. It also covers defaults and fallback usage. A small gap is the lack of any statement about output structure or count behavior, but the description is largely sufficient for a real-time board tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 stop, count, and direction with defaults and enums. The description adds a default-stop reminder and direction default, but little new parameter meaning beyond what the schema provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as a real-time departure board for a stop, listing specific fields like expected time, delay, platform, at-platform status, and cancellations. It also explicitly distinguishes itself from next_trains_to_paris by stating it does NOT provide arrival times, which removes ambiguity between siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives concrete use cases: 'il est où le train ?', 'sur quelle voie ?', and as a fallback if the journey planner is down. It also explicitly routes the agent to next_trains_to_paris when arrival time is needed, providing clear when-to-use versus when-to-use-an-alternative guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoNombre de résultats (défaut 10).
queryYesNom, même approximatif : « hacquini », « denfert ».

TDQS

A4.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries the full burden of behavioral disclosure. It usefully notes that no API key is required and that results are grouped by station, but it does not describe response format details, error behavior, or pagination. The description adds some behavioral value but leaves several operational details unstated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences long, front-loads the core purpose, and each sentence earns its place: what it does, when to use it, and what it does not do. There is no redundant or vague wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple, has only two parameters, and both are fully documented in the schema. The description covers the main use case, the alternative for addresses, and the nature of the returned data. It would benefit from a mention of the response shape or what happens when no stop is found, but it is complete enough for effective selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by emphasizing that the query can be approximate and providing concrete examples like 'hacquini' and 'denfert'. This helps the agent understand the intended fuzzy matching behavior of the query parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: searching for an Île-de-France stop by name, returning identifier, lines, and modes grouped by station. It also distinguishes itself from plan_journey by clarifying that postal addresses are not handled here. This makes the tool's purpose immediately clear and differentiated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use this tool: when a stop name is unknown or when there is doubt. It also gives an exclusion case, postal addresses, and names the alternative tool, plan_journey, that should be used instead. This is strong routing guidance for an agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
include_pastNoInclure les perturbations terminées (défaut : non).

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Aucune annotation n'est fournie, donc la description doit porter la transparence comportementale. Elle précise le périmètre (perturbations en cours et à venir), ce qui est utile, mais elle ne décrit pas le format de retour, la fraîcheur des données, ni la couverture temporelle exacte (par exemple l'horizon des perturbations annoncées). C'est un niveau de transparence correct mais non exhaustif.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

La description est courte, en deux phrases, avec l'information principale en tête puis des exemples d'utilisation pertinents. Chaque phrase apporte une valeur ajoutée : la première définit le contenu, la seconde indique quand l'utiliser. Aucun mot superflu.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Pour un outil simple avec un seul paramètre optionnel et aucune annotation, la description est globalement complète : elle précise le contenu, le périmètre temporel et les cas d'usage. Il manque juste une description plus explicite de ce que recevra l'agent (format de sortie), mais cela reste mineur au vu de la simplicité de l'outil.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Le seul paramètre, include_past, est entièrement documenté dans le schéma (100 % de couverture). La description n'ajoute rien de spécifique sur ce paramètre, mais la mention des perturbations « en cours et à venir » sous-entend que le passé est exclu par défaut. Le schéma faisant déjà le travail, la note de base de 3 est appropriée.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

La description indique clairement l'objet de l'outil : l'état de la ligne RER B avec les perturbations en cours et à venir. Elle précise les types de perturbations (travaux, incidents, grèves, interruptions, suppressions), ce qui la distingue implicitement des outils de prochains départs ou d'itinéraires, même si elle n'emploie pas un verbe d'action explicite comme « retourner » ou « fournir ».

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

La description donne des cas d'usage concrets et explicites : répondre à « il y a un problème sur la B ? » ou expliquer un trajet anormalement long. Elle ne mentionne toutefois pas explicitement quand ne pas utiliser cet outil par rapport aux outils frères, même si le contexte d'utilisation est suffisamment clair.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoArrivée : gare, adresse postale ou coordonnées. Défaut : Denfert-Rochereau (473890).
fromNoGare de départ (id ou nom). Défaut : La Hacquinière (47046).
whenNoHoraire souhaité : "18:30", "18h30", "demain 08:15" ou une date ISO. Par défaut : maintenant.
countNoNombre de trains (défaut 3).

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations available, the description carries the full transparency burden and performs well: it discloses real-time behavior ('Temps réel'), delay reporting, exact output fields, and the RER B/no-shuttle-bus scope. It also explains that default stations are configuration-driven. For a read-only schedule lookup, there are no hidden side effects or auth requirements left undisclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The definition is a compact set of sentences that front-loads the primary use case and then efficiently lists returned fields, scope restrictions, and default-station guidance. Every sentence contributes operational information with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with four optional parameters, no output schema, and no annotations, the description provides the essential information: what is returned, real-time behavior, exclusions, and default handling. Count and when semantics are covered by the schema, so nothing critical an agent needs to select or invoke the tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents all four optional parameters, so the baseline is 3. The description adds valuable guidance beyond the schema by stating that the default stations come from configuration and should only be overridden when the user mentions another station, which directly informs how the agent should populate from/to.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states exactly what the tool does: for each next train from La Hacquinière to Denfert-Rochereau it gives real departure time and delay, arrival time, duration, mission code, terminus, and disruptions. It also marks itself as the tool for the specific question 'quand est le prochain RER pour Paris et j'arrive à quelle heure?' and limits scope to RER B, distinguishing it from board or journey tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly identifies when to use the tool via the quoted user question and gives exclusions: RER B only and no shuttle buses. It also instructs that default stations come from configuration and should only be specified when the user mentions another station. However, it does not explicitly name sibling tools such as departures_board or plan_journey as alternatives, so some disambiguation remains implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toYesArrivée : nom d'arrêt, adresse postale complète, identifiant, ou coordonnées « lon;lat ». Donner l'adresse telle quelle — inutile de chercher la station la plus proche soi-même.
fromYesDépart : nom d'arrêt (« Massy-Palaiseau »), adresse postale complète (« 43 rue Saint-Dominique, Paris »), identifiant, ou coordonnées « lon;lat ».
whenNoHoraire souhaité : "18:30", "18h30", "demain 08:15" ou une date ISO. Par défaut : maintenant.
countNoNombre d'itinéraires (défaut 3).
arrive_byNoSi vrai, `when` est l'heure d'ARRIVÉE souhaitée et non de départ.
rer_b_onlyNoLimiter le calcul au RER B (pas de bus ni d'autre ligne).

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden of behavioral disclosure. It reveals that results are real-time, multimodal, include connections, and that endpoints accept postal addresses directly without requiring nearest-stop lookup. It does not cover response format or rate limits, but those are not critical for this routing use case.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each earning its place: the core scope, the key address-input behavior, and the sibling routing preference. It is front-loaded and contains no redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers scope, input flexibility, arrival-time handling, and the main alternative, which is enough for common calls. Since there is no output schema and no annotations, it could have briefly described the returned itinerary shape, but the core invocation context is complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value beyond the schema by giving a concrete address example and by connecting user intent ('je dois être à X à 9 h') to the when/arrive_by combination, which is a helpful semantic bridge not explicitly in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear function: real-time itinerary computation in Île-de-France, with all modes and connections included. It differentiates itself from siblings by emphasizing multimodal routing and explicitly names next_trains_to_paris as the alternative for a specific commute case.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit routing rule: prefer next_trains_to_paris for habitual home → Paris trips. It also translates a natural-language arrival requirement ('je dois être à X à 9 h') into the correct parameter usage, which helps an agent select and invoke the tool correctly.

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.

  1. 5 tool updatesv1.0.0
    • First observeddepartures_board
    • First observedfind_stop
    • First observedline_status
    • First observednext_trains_to_paris
    • First observedplan_journey

TDQS

A4.1/5.0

Scored across 5 tools

Disambiguation4/5

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.

Naming Consistency3/5

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.

Tool Count5/5

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.

Completeness4/5

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.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An 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
  • A
    license
    C
    quality
    C
    maintenance
    MCP server for the UK Bus Open Data Service, enabling timetable queries, stop search, route discovery, journey planning, and real-time bus tracking.
    16
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server for real-time German public transport data (HAFAS/VBN network). Enables querying departures, arrivals, journeys, and nearby stops using natural language.
    -