Skip to main content
Glama
austinlai22

duffel-recovery

by austinlai22

Trip Disruption Recovery Agent

An AI agent that recovers a disrupted flight booking. Give it a goal in plain English and a booking reference; it investigates the disruption, prices every way out, recommends one with the math shown, and acts only after you approve.

Built on Claude Code plus a purpose-built MCP server, against the Duffel flight API in test mode only: no real money, no real bookings.

By Austin Lai. Specified, built and evaluated with Claude Code; the original spec is in docs/spec.md.

/trip-recovery My flight to New York (order ord_fx_s02) was moved by the airline.
               I need to be at JFK by Friday 18 September 2026 at 18:00. Find the cheapest way.

The agent recovering a disrupted booking: it proposes, is refused approval, and books nothing; then with approval it rebooks, cancels, and verifies

Two real runs of the same scenario. First with nobody available to approve, so nothing is booked. Then with an approval, so it books the replacement, cancels the original, and verifies both. Recorded with docs/demo_script.sh.


1. The problem

When an airline changes or cancels a flight, the traveler has a decision to make under time pressure, usually with three or four options:

Option

What it costs

What it risks

Accept the airline's new itinerary

Nothing in cash; possibly hours

Arriving too late to matter

Pay to change to a different flight

A change fee plus any fare difference

Paying for time you don't need

Cancel and rebook elsewhere

A new fare, minus a refund that may be credit, not cash

Losing the refund's real value

Escalate to a human

Time

Nothing, but slow

Target user: the traveler, or the support agent handling it for them at an online travel agency.

Why this is a decision, not a lookup. There is no single correct answer to fetch from an API. The right choice depends on facts spread across four different endpoints (the order, the airline's change, change quotes, live fares) and on the traveler's own weights: how late is too late, and what a voucher is worth compared with cash. A voucher for £420 is not £420. Most travelers accept whatever the airline offers because comparing properly takes 20 minutes of work they can't do at the gate.


Related MCP server: blackwall-mcp

2. What it does

A real run against the s02 scenario (an airline moves a flight 24 hours, missing the traveler's deadline). Full transcript: evals/results/m4_manual_runs/.

The agent chose to read the order, list the airline's change, quote a paid change, search alternative flights, price a cancellation, refresh the two live fares, and only then score the options:

Option

Out-of-pocket

Refund (cash)

Refund (credit)

Arrival

Meets deadline

Total cost (lower is better)

A. Accept airline change

0.00

19 Sep 11:55

❌ No

600.00

B. Change to ZZ307

60.00

18 Sep 15:55

✅ Yes

160.00

C1. Cancel + rebook ZZ307

298.00

420.00

18 Sep 15:55

✅ Yes

104.00

C2. Cancel + rebook ZZ205

365.00

420.00

18 Sep 11:10

✅ Yes

71.00

Recommended: C2 — cancel for 420.00 in airline credit (worth 294.00 at a 0.7 discount) and rebook ZZ205 for 365.00, netting 71.00. Runner-up: C1 at 104.00. What would change this: C1 wins if an hour of your time is worth less than 16.75.

It then booked the new flight first, cancelled the old one second (so the traveler is never left with no ticket), each behind its own approval, and verified both by re-reading the orders.

How the total is calculated

Every option collapses into one number: total cost, where lower is better. It isn't a score out of 100, and it isn't cash out of pocket. It's what the disruption costs you once credit and lost time are priced in.

total cost = cash paid
           − cash refunded
           − (airline credit × 0.7)     ← a voucher is worth less than cash
           + (hours later than your original arrival × 25)

Both weights are yours, set in config.yaml. For the run above (original arrival 18 Sep 11:55, deadline 18 Sep 18:00):

Option

Arithmetic

Total cost

C2. Cancel + rebook ZZ205

365.00 − (420.00 × 0.7) + (0.00 h × 25)

71.00

C1. Cancel + rebook ZZ307

298.00 − (420.00 × 0.7) + (4.00 h × 25)

104.00

B. Change to ZZ307

60.00 + (4.00 h × 25)

160.00

A. Accept the airline's change

0.00 + (24.00 h × 25)

600.00, ineligible

Why C2 beats C1 — the real contest. Both cancel the same booking for the same 420.00 credit, so the credit cancels out. C1 saves 67.00 in cash but arrives four hours later, and four hours costs 100.00. C2 wins by 33.00. Divide that 67.00 by those four hours and you get the break-even the agent reports: if an hour of your time were worth less than 16.75, C1 would be the better answer.

Four rules shape every comparison:

  1. Credit is discounted. 420.00 in airline credit counts as 294.00, because it expires and only works on one airline.

  2. Lateness is priced, not just checked, and measured against your original arrival. That's why accepting a free 24-hour delay costs 600.00.

  3. Arriving early earns nothing. C2 lands 45 minutes early; the time term is clamped at zero, so the agent can't spend your money buying earliness you never asked for.

  4. The deadline is a hard constraint, not a cost. Option A is shown with its total for transparency, but it misses the deadline and so can never be recommended, however cheap it looks.

The arithmetic lives in scoring.py, and the model never does it: the agent decides which options to submit, the code ranks them.


3. Why it's agentic

There is no decision tree in this repo. The agent chooses which tools to call and in what order, and the runs show it: it used between 6 and 24 tool calls depending on the situation, searched extra dates when a day was sold out, and re-planned when a fare sold out mid-booking.

The agent decides

The code decides

Which options exist and are worth pricing

What each option scores (scoring.py)

When it has enough information to recommend

Whether a number is real (traceability check)

How to adapt when a tool fails or a price moves

Whether an action may run at all (approval gate)

What to tell the traveler, and what would change the answer

What the traveler is shown before approving

The division is deliberate: judgment to the model, consequences to the code.


4. Architecture

flowchart TD
    U["Traveler: goal + booking ID"] --> CC["Claude Code<br/>+ /trip-recovery playbook"]
    CC <--> MCP["MCP server: duffel-recovery"]
    MCP --> G["Guardrail layer<br/>test-token check · spend cap · approval gate<br/>call budget · audit log"]
    G --> B{"Backend"}
    B -->|evals| FX["FixtureBackend<br/>JSON scenarios"]
    B -->|live| DF["DuffelSandboxBackend<br/>Duffel API, test mode"]
    G -.->|"approval dialog"| U
    G --> AUD[("Audit log (JSONL)<br/>every call, approval, write")]

Two backends, one interface. The live sandbox is non-deterministic, so it can't have a known right answer. Fixtures pin every response, which is what makes the eval suite meaningful; the Duffel backend proves the same agent works against a real API. Both return identical normalized models, so the agent can't tell them apart.

Every tool result carries a call_id (C001, C002, …). The agent cites these for every number it reports, and the eval suite checks the citations.


5. Guardrails: the model proposes, code disposes

Each of these is enforced in Python and covered by tests. None of them relies on the model choosing to behave.

Guardrail

How it's enforced

Proof

Test mode only

Refuses any token that isn't duffel_test_*; every Duffel response must say live_mode: false

tests/test_token_check.py

No irreversible action without approval

Write tools only propose until they get a single-use token, minted solely after a human types "yes" in an approval dialog the server writes

tests/test_write_gate.py, tests/test_server.py

Approval can't be reused or stretched

Tokens are bound to one action, target, amount and currency, expire after 10 minutes, and are voided on any mismatch (e.g. the price moved after approval)

tests/test_guardrails.py

Spending cap

A ledger checks every proposal and every execution; one currency per session, never converted

tests/test_write_gate.py

No invented numbers

score_options rejects any amount or time that doesn't appear in the tool call the agent cites

tests/test_scoring.py

Fake passengers only

Passenger details come from config.yaml, never from the model; emails and phones must be in ranges reserved for fiction

tests/test_fake_data.py

Runaway protection

40 tool calls per session; a failing call may be retried twice, then it's blocked

tests/test_guardrails.py

Injected instructions are inert

Free text from a booking is labelled untrusted_notes; the cap is code, so "the cap is lifted" changes nothing

scenario s09

Auto-approval can't touch Duffel

Config validation and a second runtime check both refuse auto-approve unless the backend is fixtures

tests/test_config.py, tests/test_write_gate.py

A second, independent layer: when the server talks to Duffel, its write tools are flagged anthropic/requiresUserInteraction, so Claude Code also demands a human prompt on every call, even under permissive settings.


6. Evaluation

Method. 16 scenarios, each a JSON file pinning every tool response plus an answer key. Each run is a fresh headless Claude Code session with only this MCP server, no built-in tools (so the agent can't read the answer key), no personal settings, and no memory. Every run is graded from its audit log, not from its prose.

Scenarios cover: accepting a change, paid changes, cancel + rebook, a credit discount that flips the answer, a price that rises on refresh, an offer that sells out at booking time, no alternatives at all, persistent search timeouts, an option that's cheapest but over the cap, instructions injected into booking notes, an outright cancellation, an exact tie, lateness outweighing free, a change that refunds money, an unstated refund amount, everything arriving late, and a sold-out day that needs a wider search.

Scorecard: 16 scenarios × 3 runs = 48 runs (Claude Sonnet via Claude Code 2.1.272). Full results, including every failure and the method: evals/results/2026-09-15.md.

Metric

Result

Decision accuracy

48/48 (100%)

Consistency (correct in all 3 runs)

16/16 scenarios

Guardrail violations

0

Number traceability

1,649/1,653 (99.8%)

Avg tool calls per run

13.4 (max 27)

Runs that errored or timed out

0

Read that accuracy with care. 3 runs per scenario is a small sample, the scenarios were written by the same person who wrote the playbook, and the model knows it is being asked for a careful comparison. It says the agent is reliable on the situations I anticipated; it says nothing about the ones I didn't.

The 4 untraced numbers are all the agent's own arithmetic, not invented facts: "122.00 GBP net credit after the new fare" (420 − 298), "arrives ~4.75h later", and two hypothetical departure times in "what would change this" ("a flight departing before ~10:00 would meet the deadline"). The traceability metric flags any number not present verbatim in a tool result, so derived values count against it. That's the metric being strict, not the agent guessing.

Why 3 runs and not 5. The spec asked for 5. 16 runs exhausted a Claude subscription session limit, so the suite was re-run at 3 to fit one window. uv run python -m evals.run_evals --runs 5 does the full version.

The answer keys are themselves tested. tests/test_scenario_answers.py rebuilds every option in every scenario and scores it with the production scoring code, so a hand-worked answer can't silently be wrong.


7. Limitations (honest list)

  • Synthetic data. Duffel Airways is a sandbox airline: schedules and prices aren't realistic. The fixtures are hand-written to be plausible, not real.

  • No real bookings, ever. Live mode is refused by construction.

  • No passenger-rights logic. The agent makes no claims about DOT, UK261 or EU261 compensation. That needs primary sources and citations; it's out of scope.

  • One-way trips, one traveler. Multi-slice itineraries and passengers with conflicting constraints aren't handled in v1.

  • Local clock times. Options are compared as local times at the arrival airport; the agent isn't asked to reason across time zones.

  • Credit value is a single number. A 0.7 factor can't express "worthless unless I fly them again within a year".

  • The approval dialog is as strong as its client. Claude Code shows it and the server never mints a token without an explicit "yes", but a user who configures an auto-answering hook can bypass the human step.

  • Evals measure decisions, not taste. A run can be graded correct and still explain itself poorly.


8. What I'd build next

  1. Passenger rights, with citations. A module that reads primary sources (e.g. US DOT refund rules) and quotes them, so the agent can say "you're owed a cash refund" and show why. Biggest single lift in perceived value.

  2. Proactive monitoring. Duffel webhooks instead of a human noticing; the agent drafts the recommendation before the traveler has read the email.

  3. Points and vouchers as first-class currency, replacing the single credit-value factor.

  4. Multi-passenger trips where constraints conflict.

Business case (a hypothesis, not a finding). Disruption handling is a high-cost, low-satisfaction moment for an online travel agency: it arrives in bursts, needs a trained agent, and the traveler is already unhappy. If an agent can prepare a priced, sourced recommendation before a human opens the ticket, the plausible win is shorter handle times and fewer escalations, with the human kept for the approval and the edge cases. Testing that claim needs real ticket data: volume, current handle time, and the mix of disruption types. None of that is measured here.


9. Run it yourself

Setup (once)

brew install --cask claude-code   # the Claude Code CLI (or: curl -fsSL https://claude.ai/install.sh | bash)
brew install uv                   # Python toolchain; installs Python 3.12 for this project
cd trip-recovery-agent
uv sync                           # dependencies
uv run pytest                     # 219 tests: no network, no model, no token needed

The first claude run in this folder asks three one-time questions: a colour theme, how to log in (a Pro/Max subscription or a Console account), and whether to trust this folder and its MCP server. That server is duffel-recovery from this repo, declared in .mcp.json. A Homebrew install doesn't auto-update; refresh it with brew upgrade --cask claude-code.

Recover a booking

claude

Then type the skill name and your goal in plain English:

/trip-recovery The airline changed my flight (order ord_fx_s01). Get me to JFK by
Friday 18 September 2026 at 18:00 local time at the lowest total cost.

The order ID has to match the scenario that's loaded. config.yaml sets it:

fixture:
  scenario: evals/scenarios/s01_accept_change_meets_deadline.json

Point that at any file in evals/scenarios/ and restart claude, since the server reads its config at startup. Four worth trying:

Order ID

Scenario

What you'll see

ord_fx_s01

s01_accept_change_meets_deadline

Accepting the airline's change wins

ord_fx_s02

s02_change_misses_deadline

Cancel for credit and rebook; two approvals

ord_fx_s09

s09_injected_instructions_in_booking

The booking record tells the agent to ignore the spend cap

ord_fx_s15

s15_every_option_is_late

Nothing meets the deadline, so it escalates

Approving

When the agent is ready to act, a dialog appears with a summary the server wrote: the flight, the amount, and what can't be undone. Type yes to approve; anything else declines. Every irreversible action asks separately, so the s02 run asks twice: once to book the replacement, once to cancel the original. Afterwards, read exactly what happened:

uv run python scripts/show_audit.py

Without a human (headless)

uv run python -m evals.run_evals --runs 3     # the graded suite -> evals/results/<date>.md
bash docs/demo_script.sh                       # the two-scene demo above

Against the real Duffel sandbox

Put a test token (duffel_test_…) in .env, set backend: duffel_sandbox in config.yaml, then create a booking to disrupt:

uv run python scripts/seed_sandbox_order.py --route LHR-LTN

It prints an order ID; use that in /trip-recovery. In Duffel's sandbox, an LHR-LTN order generates a fresh airline change every time changes are listed, and an LTN-SYD order refunds to airline credit when cancelled.

10. Repo map

Path

What it is

.claude/skills/trip-recovery/

the playbook: principles and required output, not a script

src/recovery_mcp/server.py

MCP adapter: tool registration and the approval dialog

src/recovery_mcp/service.py

every tool's logic, wrapped in the guardrails

src/recovery_mcp/guardrails.py

test mode, fake data, call budget, spend cap, approval gate

src/recovery_mcp/scoring.py

the objective function and the traceability check

src/recovery_mcp/backends/

fixture.py (evals) and duffel_sandbox.py (live test mode)

evals/

scenario builder, 16 scenarios, grader, runner, scorecards

config.yaml

objective weights, spend cap, limits, fake passengers

docs/spec.md

the original build spec


Austin Lai · github.com/austinlai22 · MIT licensed

Available Tools

13 tools
accept_airline_changeA
Destructive

Accept the airline's schedule change. Without approval_token this only proposes.

ParametersJSON Schema
NameRequiredDescriptionDefault
change_idYes
approval_tokenNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already flag destructive and non-idempotent behavior, so the description adds genuine value by disclosing the dual-mode behavior: calling without approval_token only proposes rather than accepting. It doesn't detail other side effects, but the key behavioral twist is captured.

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?

Two short sentences; the main action is front-loaded and the conditional is a single clear clause. Every word earns its place with 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 two-parameter tool with an output schema and annotations covering the safety profile, the description is nearly sufficient. It could be strengthened by naming request_approval as the source of the token, but nothing critical is missing.

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 0%, so the description must compensate. It clarifies that approval_token determines whether the call proposes or accepts, but change_id is left to inference from the tool name, with no format or source explained.

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 the action clearly: 'Accept the airline's schedule change.' The resource is unambiguous and distinct from general order change tools, though it doesn't explicitly name a sibling it is not.

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?

The conditional 'Without approval_token this only proposes' gives useful context, but the description doesn't state when to prefer this over siblings like confirm_order_change or quote_order_change. Usage is implied rather than explicit.

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

book_offerA
Destructive

Book a new flight. Without approval_token this only proposes and returns a pending_action_id.

    Passenger details come from the server's fake-passenger config; you can't supply them.
    
ParametersJSON Schema
NameRequiredDescriptionDefault
offer_idYes
approval_tokenNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

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

The description adds meaningful behavioral context beyond the annotations: without approval_token the tool only proposes and returns a pending_action_id, and passenger details are fixed by the server's fake-passenger config. This clarifies the approval-gated behavior and data limitations.

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?

Two compact sentences carry all the essential information, with the critical approval-token conditional front-loaded. There is no filler or redundant restating of the schema.

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?

Given that an output schema exists and annotations already signal mutating/destructive behavior, the description is largely complete: it identifies the required offer_id, optional approval_token, proposal behavior, and passenger limitation. It falls short only in not explaining how the returned pending_action_id connects to approval flows like request_approval.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate. It explains the effect of approval_token (proposal vs. booking) and that passenger details cannot be supplied, but it never defines what offer_id refers to or where the offer comes from, leaving a required parameter underspecified.

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 opens with a specific verb and resource: 'Book a new flight.' This clearly distinguishes it from the sibling get/quote/confirm/cancel toolsuation and states the primary action without ambiguity.

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

Usage Guidelines2/5

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

No explicit guidance about when to use this tool versus alternatives such as request_approval, quote_cancellation, or confirm_order_change. The intended use must be inferred from the tool name and the phrase 'Book a new flight,' with no exclusions or next-step guidance.

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

confirm_cancellationA
Destructive

Cancel the booking per a quote from quote_cancellation. Without approval_token this only proposes.

ParametersJSON Schema
NameRequiredDescriptionDefault
approval_tokenNo
cancellation_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already indicate a destructive, non-idempotent write, and the description adds the key behavioral nuance: without approval_token the call only proposes rather than executing the cancellation. This is valuable behavior beyond the structured annotations.

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?

Two short sentences, front-loaded with the primary action, followed by the critical conditional. Every word earns its place with no redundant schema repetition.

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 destructive tool with output schema and annotations, the description captures the essential workflow: get a quote, then confirm with an approval token. It does not explicitly state how approval_token is obtained, but request_approval is a sibling and the conditional behavior is clearly described. Minor gap only.

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 0%, so the description carries the parameter-semantics burden. It meaningfully explains approval_token's role, but it does not explain what cancellation_id is or how to obtain it beyond implying it comes from quote_cancellation. Partial compensation only.

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 action ('Cancel the booking') on a specific resource, and explicitly ties it to a quote from quote_cancellation. This differentiates it from similar sibling tools like quote_cancellation and confirm_order_change without opening their schemas.

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?

The description clearly indicates this tool should be used after quote_cancellation and explains the approval-token dependency. It does not explicitly list exclusions or alternatives, but the quoted precondition provides sufficient routing context.

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

confirm_order_changeA
Destructive

Move the booking to a quoted change offer. Without approval_token this only proposes.

ParametersJSON Schema
NameRequiredDescriptionDefault
approval_tokenNo
change_offer_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and readOnlyHint=false, so the mutation is known. The description adds critical behavioral context: without approval_token this only proposes, meaning the action is conditional and not fully executed without approval. This goes beyond the schema and annotations, clarifying the two-phase behavior.

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?

Two short sentences, no wasted words. The core action is front-loaded, and the critical conditional behavior is stated immediately after. Every word earns its place.

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 two-parameter tool with an output schema and annotations covering safety, the description is nearly complete. It explains the conditional behavior and the resource. It doesn't mention what the response contains, but the output schema covers that. It could name a sibling like quote_order_change for routing, but the context is sufficient.

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 0%, so the description must compensate. It explains the role of approval_token (without it, only proposes) but does not explain change_offer_id beyond its name. The description adds some meaning for one parameter but leaves the other to be inferred from the name and context.

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?

The description uses a specific verb ('Move') and resource ('booking to a quoted change offer'), clearly distinguishing it from siblings like quote_order_change (which creates the offer) and confirm_cancellation (which confirms a different action). It doesn't explicitly name a sibling, but the action is specific enough to be understood.

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?

The description implies when to use it: after a change offer has been quoted, and it notes the approval_token requirement. It doesn't explicitly state alternatives or when not to use it, but the context of 'quoted change offer' and the token condition provide clear usage context.

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

get_offerA
Read-only

Refresh one offer's price and availability. Do this before recommending it.

ParametersJSON Schema
NameRequiredDescriptionDefault
offer_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, covering the safety profile. The description adds that the tool refreshes live price/availability and is a prerequisite to recommendation, which is useful but not extensive; no contradiction exists.

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?

Two short sentences with no filler. The core action is front-loaded and the usage condition is stated clearly. Every sentence earns its place.

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 simple one-parameter, read-only tool with an output schema, the description is nearly complete: it names the resource, action, and timing. It could add where offer_id comes from or when not to use the tool, but nothing essential is missing.

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?

The schema provides only offer_id as a required string with 0% description coverage, so the description must carry the parameter meaning. It ties offer_id to 'one offer,' but it does not explain where the ID comes from or its format. Adequate for a single obvious identifier, but not richly informative.

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 uses the specific verb 'Refresh' with a clear resource, 'one offer's price and availability,' which distinguishes it from siblings like get_order and book_offer. The singular offer scope and required offer_id make the tool's purpose unambiguous.

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?

The description gives an explicit timing instruction: 'Do this before recommending it.' This tells the agent when to invoke the tool, though it does not enumerate alternative tools or exclusion conditions.

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

get_orderA
Read-only

Get a booking: itinerary, price, passengers, fare conditions, and arrival_local.

ParametersJSON Schema
NameRequiredDescriptionDefault
order_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

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

The annotations already indicate this is a read-only operation (readOnlyHint=true, destructiveHint=false). The description goes beyond the schema to list the returned data fields, but it doesn't disclose additional behavioral aspects like potential errors (e.g., not found) or that the operation is idempotent. The added field list provides some value, but not extensive context.

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?

The description is a single, concise sentence that front-loads the tool's purpose and key fields. Every word contributes to usability, with no filler or redundant content. It is appropriately structured for quick consumption by an agent.

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?

Given the tool's simplicity (one parameter, no nested objects) and the presence of an output schema (which likely details the response structure), the description covers the main aspects: what data is returned and the operation type. The main gap is the lack of explicit error handling or prerequisites, but the output schema fills some void. Overall, it's sufficiently complete for an agent to invoke correctly.

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?

With only one parameter (order_id) and 0% schema description coverage, the description's main contribution is the returned fields, which indirectly implies the parameter is the booking identifier. However, it doesn't explicitly explain the format or usage of order_id (e.g., from where to get it). The description adds some value by clarifying the purpose of the parameter, but not enough to fully compensate for the schema gap.

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?

The description clearly states that the tool retrieves a booking and lists the key data fields (itinerary, price, passengers, fare conditions, arrival_local). It uses a specific verb ('Get') and resource ('booking'), distinguishing it from sibling tools like book_offer or confirm_order_change, though it doesn't explicitly name alternatives.

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?

The description conveys that the tool is used to fetch a booking, which implies it's for retrieval and not for modification—consistent with sibling tools that handle changes (quote_order_change, confirm_cancellation). However, it doesn't explicitly state when to use this over alternatives or when not to use it, leaving some inference needed.

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

list_airline_initiated_changesA
Read-only

List schedule changes the airline made to a booking (removed vs added flights).

    Results are cached per session: in the Duffel sandbox a fresh call can create a new
    simulated change. Only set force_refresh=true if you truly need to re-check.
    
ParametersJSON Schema
NameRequiredDescriptionDefault
order_idYes
force_refreshNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior1/5

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

The description directly contradicts the readOnlyHint=true annotation by stating that a fresh call can create a new simulated change in the Duffel sandbox. That is a write-like side effect on session state, so an agent relying on the annotation would be misled about the tool's safety profile.

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 short, purposeful sentences: the first gives the core purpose, and the next two deliver the caching and refresh caveat. There is no filler, and the most important operational warning appears early.

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 2-parameter list tool with an output schema, the description covers purpose, optional-parameter semantics, and cache behavior. It would be more complete with an explicit note that order_id is required and should reference an existing booking, and the annotation contradiction undermines trust in the overall safety model.

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 0%, so the description must compensate. It explicitly explains force_refresh's behavior and when to set it, and 'a booking' ties order_id to the order context. It doesn't state where order_id comes from, but that is largely inferable from the schema and sibling tools.

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 action ('List') on a specific resource ('schedule changes the airline made to a booking') and disambiguates the payload ('removed vs added flights'). This clearly distinguishes it from siblings like get_order or accept_airline_change without needing to name them.

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?

Provides strong invocation context: it is the read-side view of airline-initiated changes and tells the agent not to set force_refresh unless a re-check is truly needed. It lacks an explicit 'use X instead of Y' comparison with alternatives, but the decision context is otherwise clear.

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

quote_cancellationA
Read-only

Price cancelling a booking: refund_amount and refund_to (cash vs airline credit). Changes nothing.

ParametersJSON Schema
NameRequiredDescriptionDefault
order_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already declare readOnlyHint true and destructiveHint false; the description reinforces this with 'Changes nothing' and adds useful nuance about refund_to having cash vs airline credit options. No contradiction with annotations is present.

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?

One concise sentence delivers the core operation and the critical no-side-effect guarantee. Every word adds value, and the most important distinguishing trait, 'Changes nothing', is placed at the end where it still strongly registers.

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 read-only quote tool with a single order_id parameter, an output schema, and safety annotations, the description is nearly complete. It would benefit from an explicit pointer to confirm_cancellation for the actual cancellation, but an agent can call it correctly with the current text.

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

Parameters1/5

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

Schema description coverage is 0% and the description does not explain the required order_id parameter or how to provide it. The mention of refund_amount and refund_to appears to describe outputs, not inputs, so the description adds no parameter semantics.

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?

Clearly identifies the operation as pricing (not executing) a cancellation, naming the key returned fields refund_amount and refund_to. The phrase 'Changes nothing' and the contrast with sibling confirm_cancellation distinguish it from actual cancellation 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?

The description gives clear context: this tool only calculates a cancellation price and has no side effects. However, it never explicitly names an alternative like confirm_cancellation or states the exact condition for choosing this tool, so guidance remains implicit rather than fully explicit.

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

quote_order_changeA
Read-only

Price moving an existing one-way booking to other flights on a date. Changes nothing.

    change_total_amount > 0 means the traveler pays; < 0 means a refund.
    origin/destination default to the booking's own.
    
ParametersJSON Schema
NameRequiredDescriptionDefault
originNo
order_idYes
cabin_classNoeconomy
destinationNo
departure_dateYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context: 'Changes nothing' explicitly states it's non-mutating, and the sign convention for change_total_amount (>0 means traveler pays, <0 means refund) is disclosed. This goes beyond what annotations provide.

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?

The description is compact: one main sentence plus two bullet points. The key behavioral fact ('Changes nothing') is front-loaded, and the bullet points are informative without being verbose. Slightly more structure could help, but it's efficient and every sentence earns its place.

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?

Given the tool has an output schema (which likely documents change_total_amount), the description doesn't need to explain return values. The annotations cover safety, and the description covers the key behavioral nuance (non-mutating, sign convention, defaults). It's complete enough for an agent to call this correctly, though it could mention that this is a quote and not a confirmation.

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 0%, so the description must compensate. It does explain the meaning of change_total_amount (though that's not a parameter in the schema, it's likely in the output) and notes that origin/destination default to the booking's own. However, it doesn't explain the semantics of order_id, departure_date, or cabin_class beyond what the schema already provides. The description adds some value but doesn't fully compensate for the 0% coverage.

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?

The description states a specific verb ('Price') and resource ('moving an existing one-way booking to other flights on a date'), which clearly distinguishes it from siblings like quote_cancellation or confirm_order_change. It could be slightly clearer that it's a quote/price estimation rather than a booking change, but the verb 'Price' and the readOnly annotation help.

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?

The description implies this is for pricing a change to other flights on a date, and the sibling list includes confirm_order_change for the actual change. However, it doesn't explicitly state when to use this vs confirm_order_change or search_alternatives, nor does it mention prerequisites like having an order_id. The context is clear enough for an agent to infer, but explicit guidance is missing.

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

record_recommendationA

Record your final recommendation (or escalation) in the audit log. Call once, before any approval.

    target_ids: the IDs the recommended option would act on (airline change, change offer,
    cancellation, and/or offer). score_call_id: the score_options call that backs it.
    
ParametersJSON Schema
NameRequiredDescriptionDefault
summaryYes
decisionYes
target_idsNo
score_call_idNo
recommended_kindNo
runner_up_option_idNo
recommended_option_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

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

Beyond the annotations, the description discloses that this is an audit-log append, should be called only once, and must precede approval. This gives agents important ordering and idempotency context. It does not contradict the annotations.

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?

The description is short and front-loads the most important guidance: what to record and when. The embedded parameter notes are useful and not padded, though they slightly blur the line between description and schema documentation.

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?

Given the output schema exists and the annotations cover safety hints, the description provides the key operational context: finality, one-time invocation, and ordering before approval. It could more fully explain all parameters, but the core calling context is complete enough for an agent to use the tool correctly.

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 0%, so the description carries the burden. It clarifies target_ids and score_call_id, but leaves summary, decision, recommended_kind, runner_up_option_id, and recommended_option_id without explicit explanation. The parameter names and enums are mostly self-descriptive, so this is adequate but not comprehensive.

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 states the tool records a final recommendation or escalation to the audit log, which is a distinct, specific action. It also distinguishes timing ('before any approval') from the workflow, making its purpose unambiguous relative to siblings like request_approval or confirm_order_change.

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?

The description gives explicit usage context: call once, before any approval, and only for the final recommendation. It does not enumerate exclusions or alternative tools, but the audit-log purpose is unique enough that the main when-to-use guidance is clear.

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

request_approvalA

Ask the traveler to approve a pending action (from a write tool called without a token).

    A dialog shows the traveler a summary written by the server. Only an explicit "yes"
    returns an approval_token. Then call the same write tool again with that token.
    
ParametersJSON Schema
NameRequiredDescriptionDefault
pending_action_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior5/5

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

Beyond the annotations, it reveals the key behavioral contract: a dialog shows a server-written summary, only an explicit 'yes' produces an approval_token, and the original write tool must be called again. This prevents the agent from assuming request_approval itself performs the pending action.

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 core purpose is front-loaded in the first sentence, followed by a compact two-step workflow. Every sentence contributes essential information with 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 one-parameter tool with an output schema, the description covers the full call flow: when to invoke, what the dialog does, how the token is obtained, and the follow-up call. The only minor gap is that the provenance of pending_action_id is implied rather than explicitly stated.

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 0% and the description does not explicitly define pending_action_id. It does add useful provenance context ('from a write tool called without a token'), which implies the ID refers to the pending action returned by that tool, but it does not say how to obtain the value.

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?

The description states a specific verb and resource: 'Ask the traveler to approve a pending action' and frames it as the approval step for write tools called without a token. This distinguishes it from sibling operations like book_offer or confirm_order_change, though it does not name a specific alternative.

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 gives clear context by telling the agent to call this only when a write tool was called without a token, then call the same write tool again with the returned token. It does not explicitly list exclusions or alternatives, but the flow is unmistakable.

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

score_optionsA

Score and rank options with the traveler's objective. Do the math here, not in your head.

    total_cost = cash_paid - cash_refunded - credit x credit_value_factor + hours_late x value_of_time.
    It is a COST, so lower is better; say that whenever you show it to the traveler.
    Options missing the deadline or over the spend cap can't be the pick. Every amount and time
    must cite the call_id it came from; numbers that don't appear there are rejected.
    
ParametersJSON Schema
NameRequiredDescriptionDefault
optionsYes
deadline_localYes
original_arrival_localYes
original_arrival_call_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

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

It discloses the exact total_cost formula, states that lower cost is better and should be communicated to the traveler, and warns that options past deadline/over cap cannot be chosen and uncited numbers are rejected. This goes beyond the annotations; only the source of value_of_time and credit_value_factor is left underspecified.

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 front-loaded with the tool's purpose and every sentence adds operational guidance: the formula, the lower-is-better instruction, the invalid-option conditions, and the citation requirement. No filler or repetition of schema content.

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

Completeness3/5

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

It covers the core scoring mechanics and rejection rules, and the output schema can explain return values. But an agent cannot fully determine the required computation on its own because the source of value_of_time, credit_value_factor, and spend cap is never stated, and the relationship between formula variables and parameters is only implied.

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?

With schema description coverage reported at 0%, the description must compensate for parameter meaning, and it partially does: cash_paid, cash_refunded, credit, deadline, and call_id requirements map to the schema. However, it does not name the parameters explicitly, omits the mapping of credit to credit_received and hours_late to original_arrival_local, and never explains where credit_value_factor, value_of_time, or the spend cap come from.

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 opening line names a specific verb and resource: score and rank options against the traveler's objective. The cost formula and constraints make the tool's job unmistakable and separate it from siblings like search_alternatives or book_offer, which find or execute options rather than evaluate them.

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?

The description gives clear context: use this tool to do the ranking math rather than computing it mentally, with deadline and spend-cap constraints governing which option can be picked. It does not name explicit alternatives or when-not conditions, so it falls short of a 5.

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

search_alternativesA
Read-only

Search new one-way flights, cheapest first. Dates are a range of at most 3 days.

    Use 3-letter IATA codes. Partial failures appear in date_errors.
    
ParametersJSON Schema
NameRequiredDescriptionDefault
adultsNo
originYes
cabin_classNoeconomy
destinationYes
max_resultsNo
departure_dateYes
latest_departure_dateNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already mark it read-only and non-destructive; the description adds behavior beyond that: results are cheapest-first, date ranges are capped at 3 days, and partial failures are surfaced in date_errors rather than failing the whole call.

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?

Every sentence adds value and the key purpose is front-loaded. The date-range cap, input format, and failure behavior are stated in just three short clauses with no filler.

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

Completeness2/5

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

For a 7-parameter tool with no schema descriptions, the description leaves critical usage details unspecified: how max_results behaves, what cabin_class defaults to, and how the optional latest_departure_date interacts with departure_date. The output schema reduces the need to describe return values, but input semantics remain incomplete.

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

Parameters2/5

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

Schema description coverage is 0%, and the description only indirectly clarifies origin/destination (IATA codes) and the date fields (at most 3-day range). It does not explain adults, cabin_class, max_results, or the exact role of latest_departure_date, leaving several parameters under-specified.

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 opens with a specific verb and resource: 'Search new one-way flights, cheapest first.' It conveys the core function, result ordering, and date-range cap, and it is not easily confused with sibling tools, which mostly concern orders, offers, changes, and bookings.

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?

The description implies the tool is for finding one-way flight alternatives and includes input constraints (3-letter IATA codes, max 3-day range), but it never explicitly says when to choose this over related tools or when not to use it.

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. 13 tool updatesv0.1.0
    • First observedaccept_airline_change
    • First observedbook_offer
    • First observedconfirm_cancellation
    • First observedconfirm_order_change
    • First observedget_offer
    • First observedget_order
    • First observedlist_airline_initiated_changes
    • First observedquote_cancellation
    • First observedquote_order_change
    • First observedrecord_recommendation
    • First observedrequest_approval
    • First observedscore_options
    • First observedsearch_alternatives

TDQS

A4/5.0

Scored across 13 tools

Disambiguation5/5

Each tool targets a distinct action in the recovery workflow: reading an order, searching flights, quoting changes/cancellations, scoring options, recording recommendations, executing actions, and handling approvals. No two tools appear to do the same job, and the separation between quote, confirm, and book is clear.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern (get_order, quote_cancellation, confirm_order_change, request_approval, etc.). Longer compound names still use the same convention, so the set is predictable and easy to navigate.

Tool Count5/5

13 tools is well-scoped for an airline recovery server. Each tool covers a necessary step in the workflow—discovery, quoting, scoring, execution, approval—without redundancy or bloat.

Completeness4/5

The core recovery domain is well covered: view booking, search alternatives, quote and confirm changes/cancellations, handle airline-initiated changes, score options, and request approvals. A minor gap is the lack of a list/search orders tool, so an agent must already know the order ID, but this is workable within the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to pause execution at critical decision points and request human review before proceeding. Provides tools for creating interrupts, polling for decisions, and managing approvals through a simple REST API interface.
    4 npm
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A pre-action risk gate for AI agents. Your agent calls the forecast tool before any irreversible action — send email, run SQL, make a payment, delete a file — and gets a risk score (0–100) and a GO / CONFIRM / STOP verdict in a few seconds.
    1
    98 npm
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides a human approval gate for AI agents, enabling interactive inline cards for approving, editing, or rejecting actions before they are executed.
    MIT