Skip to main content
Glama

Add TfL journeys from a contactless statement

add_tfl_journeys
Idempotent

Adds TfL contactless journeys to the person’s Untap account, up to 500 rows per call, and checks everything they have saved for incomplete journeys, missed Hopper fares and other overcharges. Each row carries flags for an incomplete journey, a revenue-inspection maximum fare, a free Hopper fare, a TfL correction and the daily or weekly cap, as shown on the statement. Journeys already saved are skipped. Refunds follow the same rule as the TfL check: an incomplete journey without a destination is an upper limit equal to the whole charge, and one with intended_destination is an estimate. Requires sign-in to Untap.

Input Schema

NameRequiredDescriptionDefault
journeysYesEvery journey on the statement. Up to 500 per call.
card_last4YesLast 4 digits of the contactless card, if shown.
period_endYesStatement period end date YYYY-MM-DD.
period_startYesStatement period start date YYYY-MM-DD.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changed
    • changedInput schema / properties / journeys / items / properties / is_incomplete / description
      Previous value: -"True if this journey has no tap-out recorded (e.g. label \"Incomplete\" or \"No exit\")."New value: +"True if this journey has no tap-out recorded (e.g. label \"Incomplete\" or \"No exit\"), including when it was charged the maximum fare for that reason."
    • addedInput schema / properties / journeys / items / properties / is_inspection_penalty
      Added value: +{
      +  "description": "Optional. True only when the statement shows a penalty for failing a ticket inspection, which TfL does not refund. A maximum fare for a missing touch out counts as is_incomplete, not this.",
      +  "type": [
      +    "boolean",
      +    "null"
      +  ]
      +}
    • changedInput schema / properties / journeys / items / properties / is_max_fare / description
      Previous value: -"True if the statement labels this as a max-fare charge for a failed revenue inspection."New value: +"Deprecated. Replaced by is_incomplete and is_inspection_penalty."
    • changedInput schema / properties / journeys / items / properties / is_max_fare / type
      Previous value: -"boolean"New value: +[
      +  "boolean",
      +  "null"
      +]
    • changedInput schema / properties / journeys / items / required
      Previous value: -[
      -  "date",
      -  "start_time",
      -  "end_time",
      -  "mode",
      -  "from_location",
      -  "to_location",
      -  "bus_route",
      -  "fare_pence",
      -  "is_max_fare",
      -  "is_incomplete"
      -]New value: +[
      +  "date",
      +  "start_time",
      +  "end_time",
      +  "mode",
      +  "from_location",
      +  "to_location",
      +  "bus_route",
      +  "fare_pence",
      +  "is_incomplete"
      +]
  2. Changed6 schema fields changed
    • addedInput schema / properties / journeys / items / properties / intended_destination
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maxLength": 80,
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Optional, for an incomplete journey with no touch out: the station the person was travelling to. With it, the refund is estimated as the fare charged minus the usual fare to that station. Without it, the figure is an upper limit equal to the whole charge."
      +}
    • changedInput schema / properties / journeys / items / properties / is_auto_corrected / description
      Previous value: -"OPTIONAL. True if the statement says TfL already auto-corrected this journey (e.g. \"Auto-completed\", \"Adjusted\")."New value: +"Optional. True when the statement says TfL has already corrected this journey (for example \"Auto-completed\" or \"Adjusted\")."
    • changedInput schema / properties / journeys / items / properties / is_daily_cap_hit / description
      Previous value: -"OPTIONAL. True if the statement explicitly marks this row as the daily-cap-reached entry."New value: +"Optional. True when the statement marks this row as the one where the daily cap was reached."
    • changedInput schema / properties / journeys / items / properties / is_hopper_free / description
      Previous value: -"OPTIONAL. True if the statement marks this fare as a free Hopper fare (second bus/tram tap within 60 min)."New value: +"Optional. True when the statement shows this fare as a free Hopper fare (a second bus or tram within 60 minutes)."
    • changedInput schema / properties / journeys / items / properties / is_weekly_cap_hit / description
      Previous value: -"OPTIONAL. True if the statement marks this row as a weekly-cap-reached entry."New value: +"Optional. True when the statement marks this row as the one where the weekly cap was reached."
    • changedInput schema / properties / journeys / items / properties / mode / description
      Previous value: -"Transport mode for this row. Use \"unknown\" only if the statement does not say."New value: +"Transport mode for this row, or \"unknown\" when the statement does not say."
  3. First observed

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare readOnly=false, idempotent=true and destructiveHint=false; the description earns credit for adding the auth prerequisite, the batching limit, and the duplicate-skip rule that explains the idempotency hint. It also discloses refund estimation semantics, which is real behavioural context an agent would otherwise lack.

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?

Front-loaded with the core action and limit, then flags, dedupe and refund rules in a tight sequence. Dense but each sentence carries information; the refund-rule sentence is the only one that could be trimmed given the schema already covers it.

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?

With no output schema, the description still covers safety-relevant behaviour via annotations, auth requirement, batch cap and duplicate handling. Minor gaps remain around what happens on partial failures or how rows beyond 500 should be submitted, but nothing critical is missing for correct invocation.

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 coverage is 100% and every field, including the flag booleans and the deprecated is_max_fare, is documented inline. The description's discussion of flags and intended_destination largely restates what the schema already says, so it adds only marginal meaning beyond the structured fields; baseline 3 applies.

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?

States a specific verb and resource ('Adds TfL contactless journeys to the person's Untap account') plus the per-call limit and the post-save checking behaviour. It never names check_tfl_journeys explicitly – only alludes to 'the TfL check' – so an agent must infer how this differs from that sibling, which keeps it below a 5.

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

Usage Guidelines3/5

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

Gives useful operating context: sign-in requirement, 500-row ceiling and that already-saved journeys are skipped, which implies safe re-running. It does not say when to prefer this over check_tfl_journeys or what to do with statements larger than 500 rows, so usage is implied rather than prescribed.

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.