Skip to main content
Glama

Add a train booking

add_train_journey

Adds a UK train booking to the person’s Untap account and works out Delay Repay for it. One booking per call, with each journey in legs (one for a single, two for a return, in travel order). Untap checks National Rail’s Historical Service Performance records for each journey; the delay, actual arrival and cancellation fields are optional, and when left out Untap looks them up. Operators accept one journey per claim form, so a return with both directions late means two claims. A train journey that is already saved is returned as it is, not saved twice. Requires sign-in to Untap.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
legsYesEach journey on this booking, in travel order: one for a single, two for a return (outward first), more for a multi-stop booking. Untap works out Delay Repay for each journey and adds them up.
season_typeNoSeason tickets only: how long the season runs. The operator divides the season price into single journeys (for example annual 464, monthly 40, weekly 10, flexi 16) and pays a share of one journey. When left out, the result gives the percentage and the method but no amount.
ticket_typeYesTicket type as printed. For "return" and "open_return" the single fare is half the price paid; for "season" the amount is a share of one journey value (see season_type); every other type uses the full price as the single fare.
booking_referenceYesBooking reference if available, otherwise null.
ticket_price_penceYesTotal fare paid in pence for the whole booking. £62.00 = 6200.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • addedInput schema / properties / season_type
      Added value: +{
      +  "anyOf": [
      +    {
      +      "enum": [
      +        "weekly",
      +        "monthly",
      +        "quarterly",
      +        "six_monthly",
      +        "annual",
      +        "flexi"
      +      ],
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Season tickets only: how long the season runs. The operator divides the season price into single journeys (for example annual 464, monthly 40, weekly 10, flexi 16) and pays a share of one journey. When left out, the result gives the percentage and the method but no amount."
      +}
    • changedInput schema / properties / ticket_type / description
      Previous value: -"Ticket type as printed. For \"return\" and \"open_return\" the single fare is half the price paid; every other type uses the full price as the single fare."New value: +"Ticket type as printed. For \"return\" and \"open_return\" the single fare is half the price paid; for \"season\" the amount is a share of one journey value (see season_type); every other type uses the full price as the single fare."
  2. Changed6 schema fields changed
    • changedInput schema / properties / legs / description
      Previous value: -"Every leg of this booking. Single ticket = 1 leg. Return = 2 legs (outbound first, then return). Multi-stop bookings can have more legs in journey order. Untap runs Delay Repay eligibility per leg and sums the entitlements."New value: +"Each journey on this booking, in travel order: one for a single, two for a return (outward first), more for a multi-stop booking. Untap works out Delay Repay for each journey and adds them up."
    • changedInput schema / properties / legs / items / properties / actual_arrival / description
      Previous value: -"OPTIONAL. Per-leg actual arrival as ISO 8601 datetime if the user told you. Leave undefined to auto-check."New value: +"Optional. Actual arrival for this journey as an ISO 8601 datetime, if known. When left out, Untap looks it up."
    • changedInput schema / properties / legs / items / properties / delay_minutes / description
      Previous value: -"OPTIONAL. Per-leg delay in minutes if the user told you. Leave undefined to auto-check via HSP."New value: +"Optional. Delay at arrival for this journey, in minutes, if known. When left out, Untap looks it up in National Rail records."
    • changedInput schema / properties / legs / items / properties / operator_toc_code / description
      Previous value: -"TOC code for this leg. Must match one of the National Rail two-letter codes: VT=Avanti West Coast, CC=c2c, CH=Chiltern Railways, EM=East Midlands Railway, GX=Gatwick Express, GN=Great Northern, GW=Great Western Railway, LE=Greater Anglia, NT=Northern Trains, SW=South Western Railway, SE=Southeastern, SN=Southern, TL=Thameslink, TP=TransPennine Express, AW=Transport for Wales, LM=West Midlands Railway, LN=London Northwestern Railway, XC=CrossCountry, GR=LNER, SR=ScotRail, LD=Lumo, HT=Hull Trains, CS=Caledonian Sleeper"New value: +"National Rail two-letter operator code for this journey: VT=Avanti West Coast, CC=c2c, CH=Chiltern Railways, EM=East Midlands Railway, GX=Gatwick Express, GN=Great Northern, GW=Great Western Railway, LE=Greater Anglia, NT=Northern Trains, SW=South Western Railway, SE=Southeastern, SN=Southern, TL=Thameslink, TP=TransPennine Express, AW=Transport for Wales, LM=West Midlands Railway, LN=London Northwestern Railway, XC=CrossCountry, GR=LNER, SR=ScotRail, LD=Lumo, HT=Hull Trains, CS=Caledonian Sleeper"
    • changedInput schema / properties / legs / items / properties / was_cancelled / description
      Previous value: -"OPTIONAL. True if the user said this leg was cancelled. Skips the HSP lookup."New value: +"Optional. True when this journey was cancelled. When set, no National Rail lookup is made."
    • changedInput schema / properties / ticket_type / description
      Previous value: -"Ticket type as printed. \"return\" or \"open_return\" trigger half-fare-per-leg compensation; everything else uses the full ticket as the single-fare basis."New value: +"Ticket type as printed. For \"return\" and \"open_return\" the single fare is half the price paid; every other type uses the full price as the single fare."
  3. First observed

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare a non-readonly, open-world, non-destructive write, and the description adds real context beyond them: Untap queries National Rail Historical Service Performance per journey, omitted delay/arrival/cancellation fields trigger lookups, and an already-saved journey is returned as-is rather than duplicated. The dedup statement sits in mild tension with idempotentHint=false, though it plausibly describes content-level dedup rather than same-argument idempotency. Auth requirement ('Requires sign-in') is a useful addition.

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

Conciseness4/5

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

Purpose is front-loaded in the first sentence and the remaining clauses are dense but purposeful (leg ordering, optional-field lookups, dedup, one-claim-per-journey, auth). A few items duplicate the schema descriptions, so there is minor redundancy, but no 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?

For a mutation tool with a nested legs array, no output schema and no return-value documentation, the description covers prerequisites (sign-in), cardinality rules per claim, dedup, and the external lookup dependency. It gives a hint about result shape for season_type but does not otherwise characterize what the call returns, leaving a modest gap.

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 ticket_type fare math, season_type proration, operator codes and every leg field. The description largely restates this (optional lookup fields, single-vs-return leg count), adding only the 'travel order' framing for legs. Correct to sit at the baseline when the schema does the heavy lifting.

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?

States a specific verb and resource ('Adds a UK train booking to the person's Untap account') and adds the secondary outcome ('works out Delay Repay for it'), which separates it cleanly from siblings like add_flight, add_parking_fine and add_tfl_journeys. An agent can identify it as the UK-rail booking creator without opening the schema.

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?

Gives concrete operating context: one booking per call, legs in travel order (one single / two return), and the rule that operators accept one journey per claim form so a late return means two claims. It also states the sign-in prerequisite. It stops short of naming an alternative sibling (e.g. check_train_delay vs this add path), so it is not a full when/when-not routing statement.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.