Skip to main content
Glama

Server Details

Search language schools abroad, compare courses, dates and prices, and request bookings.

Ownership verified
Status
Healthy
Uptime
99.9% over 22 days
Last Tested
Transport
Streamable HTTP · MCP 2025-06-18
URL

TDQS

A3.8/5.0

Scored across 17 tools

Disambiguation4/5

Most tools target distinct resources and actions (search_, get_, list_, calculate_, save_, create_). However ask_school_question, request_quote, and request_discussion all cover contacting the school, and request_discussion's description even bundles the definitions of the other two, creating some genuine overlap. Descriptions do help disambiguate, so the boundaries are workable.

Naming Consistency5/5

Every tool follows a clean snake_case verb_noun convention (search_destinations, get_school, list_courses, create_booking, calculate_trip_price, save_trip). Verbs are used consistently and predictably across the whole set.

Tool Count4/5

17 tools is on the heavier side but largely justified by a multi-step domain (search, school details, courses, accommodations, dates, pricing, trip draft, booking, contact). The three school-contact tools could arguably be consolidated, leaving slight redundancy.

Completeness4/5

The surface covers the full workflow from destination/school search through course and accommodation details, starting dates, pricing, trip save, booking, and follow-up email/contact. Gaps are minor (no booking cancellation or modification, no payment-status tool), but no dead ends in the core booking journey.

Available Tools

17 tools
ask_school_questionAInspect

Send a question to the school without a full trip configuration. Requires OAuth requests scope. Optional idempotency_key.

NameRequiredDescriptionDefault
contactNoOptional first_name, last_name. Email always comes from the verified account.
messageYesStudent message to the school.
trip_idNoOptional trip_id from save_trip.
currencyNoISO 4217 currency for prices in this call. Usually EUR.EUR
school_idYesCraft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID.
configurationNoSame shape as the Extralingo school-page configurator: startDate (YYYY-MM-DD), students[] with courseId, weeks, optional accommodationGroupId, mealType, extras.
idempotencyKeyNoOptional alias of idempotency_key.
idempotency_keyNoOptional. Same semantics as create_booking (24 hour replay window).

Output Schema

NameRequiredDescription
kindNoLead type on success.
messageNoHuman-readable confirmation (not a booking confirmation).
successYes
redirectUrlNoExtralingo /my URL for the student to follow the request, when available.
newBookingIdNoCraft newBookings entry id when created.

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already declare non-read-only, open-world, non-destructive behavior, so the safety profile is covered. The description adds a genuinely useful non-schema fact — the required OAuth "requests" scope — plus the availability of an idempotency key, though it says nothing about what happens downstream (whether the school is emailed, expected response latency, rate limits).

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?

Three short clauses, front-loaded with the action and scoping constraint, then auth, then the idempotency note. Nothing is padded, though the trailing idempotency_key mention largely duplicates the schema and slightly dilutes the front-loading.

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?

An output schema exists, so return values need not be described, and the schema fully documents the complex nested configuration. But for a tool with 8 parameters, nested objects, and relationships to save_trip/trip_id, the description does not explain how trip_id or configuration interact with the "without a full trip configuration" framing, leaving a meaningful 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 all 8 parameters including the nested configuration object. The description only restates that idempotency_key is optional, adding no semantics beyond what the schema provides — the correct baseline of 3.

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 ("Send a question to the school") and adds a scoping qualifier ("without a full trip configuration") that separates it from booking/quote flows. It does not name a sibling explicitly, so differentiation is inferred rather than stated.

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 phrase "without a full trip configuration" implies this is the lightweight path when no trip exists, which hints at when to prefer it over create_booking or request_quote. However, no alternative is named and no when-not conditions are given, so the agent must infer the routing against 16 siblings.

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

calculate_trip_priceA
Read-onlyIdempotent
Inspect

Live checkout quote for a configuration. Not a booking. Call before create_booking and before telling the student a final price.

NameRequiredDescriptionDefault
localeNoResponse language and site context. One of en, nl, da, sv.
trip_idNoOptional saved trip id; when set, the quote may be stored on that trip.
currencyNoISO 4217 currency for prices in this call. Usually EUR.EUR
school_idNoCraft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID.
country_codeNoVisitor country ISO 3166-1 alpha-2 (e.g. NL). Affects fee display where applicable.
discountCodeNoOptional promotion or discount code.
configurationNoSame shape as the Extralingo school-page configurator: startDate (YYYY-MM-DD), students[] with courseId, weeks, optional accommodationGroupId, mealType, extras.

Output Schema

NameRequiredDescription
dataNoFull pricing breakdown from the booking engine.
quoteNoHuman-oriented price summary.
successYes

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description usefully reinforces that this is not a booking, but adds no detail on rate limits, auth, or the fact that a quote may be persisted when trip_id is supplied (which sits in the schema, not the description).

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, front-loaded sentences with zero filler; the disambiguation and the ordering constraint are stated immediately and nothing is redundant.

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 a rich nested input schema and an existing output schema, the description need not explain returns or fields. It supplies the workflow context an agent needs; only a note on quote persistence/rate behavior would improve it further.

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 every parameter including the nested configuration is already documented in the schema. The description adds no parameter-level meaning beyond the word 'configuration,' so the baseline 3 is appropriate.

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 operation (a live checkout quote for a configuration) and explicitly distinguishes itself from create_booking with 'Not a booking.' It clarifies scope and non-mutation, though the word 'quote' alone leaves slight ambiguity about whether it computes prices or retrieves a previously stored one.

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 concrete sequencing guidance: call before create_booking and before quoting a final price to the student. That is strong context, but it does not mention an alternative for non-live/exploratory pricing or reference siblings like request_quote.

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

create_bookingAInspect

Submit an unpaid booking for a bookings_live school (same path as the website Book now flow). The school still confirms availability; Extralingo emails the student; down payment is due within 5 days of school confirmation via Extralingo only. Never tell the user they are confirmed or paid. Requires OAuth bookings scope (Bearer token). Optional idempotency_key replays the same payload within 24 hours.

NameRequiredDescriptionDefault
phoneNoStudent phone number (required).
contactNoOptional first_name, last_name, phone. Email always comes from the verified account; contact.email must match or be omitted.
trip_idNoOptional trip_id from save_trip linking this booking to a draft.
currencyNoISO 4217 currency for prices in this call. Usually EUR.EUR
school_idNoCraft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID.
phoneCountryNoISO 3166-1 alpha-2 country for the phone (e.g. NL).
configurationNoSame shape as the Extralingo school-page configurator: startDate (YYYY-MM-DD), students[] with courseId, weeks, optional accommodationGroupId, mealType, extras.
termsAcceptedNoMust be true when not using OAuth (OAuth grants record acceptance).
idempotencyKeyNoOptional alias of idempotency_key.
studentDetailsNoPer-student details aligned with configuration.students (names, dates of birth, etc.).
idempotency_keyNoOptional. Same key + same payload within 24 hours replays the original response; conflicting payload returns validation_failed.
privacyAcceptedNoMust be true when not using OAuth.
specialRequestsNoFree-text notes for the school.

Output Schema

NameRequiredDescription
statusNoe.g. awaiting_school_confirmation.
successYes
bookingIdNoCraft booking id when returned by the booking engine.
redirectUrlNo
studentMessageNo
bookingReferenceNo
agent_must_tell_the_userNo

TDQS

A4.5/5.0
Behavior5/5

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

Goes well beyond the annotations: discloses OAuth bookings scope/Bearer token requirement, the school-confirmation email and 5-day down-payment flow, an explicit instruction never to tell the user they are confirmed or paid, and 24-hour idempotency replay semantics. This is exactly the operational context annotations cannot convey.

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?

Front-loads the core action in the first clause, then layers workflow, warning, auth, and idempotency in tight sentences with no filler. Every sentence carries distinct, actionable information.

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?

With an output schema present and 100% schema coverage, the description's job is to supply the non-structural context, and it does: auth requirements, downstream timeline, user-facing messaging constraint, and idempotency behavior. Nothing an agent needs to call it correctly 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 100%, so the schema already documents every parameter thoroughly, including the nested configuration object. The description only restates idempotency behavior that the schema's idempotency_key description already covers, adding no new parameter-level meaning.

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 ('Submit an unpaid booking for a bookings_live school') and anchors it to a known workflow ('same path as the website Book now flow'). This is clearly distinguishable from sibling tools like request_quote or save_trip.

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 clear context for when this tool applies (live school booking, school still must confirm availability, trip_id can link a saved draft), but never names an alternative or a when-not condition, e.g. request_quote vs create_booking or what to do if the school is not bookings_live.

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

email_tripAInspect

Email continue_url (/s/{id}) to the verified account inbox. Requires OAuth trips scope. Rate-limited. Not a booking; you can share continue_url without emailing.

NameRequiredDescriptionDefault
emailNoOptional. Must match the verified OAuth account email if sent. The link is always sent to that account.
localeNoResponse language and site context. One of en, nl, da, sv.
trip_idYestrip_id from save_trip.
lastNameNoOptional salutation for the email body.
firstNameNoOptional salutation for the email body.

Output Schema

NameRequiredDescription
urlNoLegacy alias of continue_url.
messageNo
successYes
trip_idNo
trip_urlNo
emailed_toNoVerified account inbox that received the email.
continue_urlNo

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already mark this as a non-read-only, non-idempotent, open-world action, and the description adds real context: OAuth trips scope requirement, rate limiting, and that the link always goes to the verified account inbox regardless of the email field. It does not describe failure modes when the scope is missing, but the disclosure goes meaningfully beyond 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?

Four short, front-loaded sentences with no filler; the core action leads and constraints follow. The telegraphic '/s/{id}' and 'OAuth trips scope' phrasing is dense but still parseable, costing only a little readability.

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?

An output schema exists, so return values need no explanation here. For a 5-parameter, non-idempotent side-effecting tool, the description covers auth, rate limits, recipient constraint, and the non-booking caveat well; only error/retry behavior is left unaddressed.

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 baseline is 3; the schema already documents email, locale, lastName, firstName and trip_id sources. The description adds only indirect meaning (the payload is continue_url, the inbox is the verified account) without clarifying parameter behavior beyond what the schema states.

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+resource ('Email continue_url (/s/{id}) to the verified account inbox') with the exact recipient and payload. An agent can distinguish this from siblings like save_trip or create_booking without opening any schema, and the '/s/{id}' detail pins the artifact being sent.

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 an explicit exclusion and a decision rule: 'Not a booking; you can share continue_url without emailing.' This tells the agent when not to call it and implies a no-email alternative workflow. It stops short of naming the specific sibling tool to use instead of emailing.

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

get_accommodation_detailsA
Read-onlyIdempotent
Inspect

One group from list_accommodations (group_id): type, room_types, meal/board options, distance, amenities, age and min-stay rules, and week prices for startDate and currency. Use after list_accommodations, before save_trip or calculate_trip_price, or to answer questions about one option. Week prices are indicative; call calculate_trip_price for a checkout total.

NameRequiredDescriptionDefault
localeNoResponse language and site context. One of en, nl, da, sv.
currencyNoISO 4217 currency for prices in this call. Usually EUR.EUR
group_idYesAccommodation group id from list_accommodations.
startDateNoCourse start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates.

Output Schema

NameRequiredDescription
groupNoAccommodation group from GET /v3/accommodations/{id} (v2 grouping): labels, classification, room and meal options, facilities, rules, and pricing hints for the requested start date.
successYes

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, non-destructive and closed-world, so the safety profile is covered. The description adds a genuinely non-obvious behavioral caveat: week prices are indicative only and a real checkout total requires calculate_trip_price. It does not cover auth/permission needs or response volume, so it stops short of a 5.

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 tight sentences, front-loaded with what is returned, then the sequencing and the price caveat. Every clause carries information; no filler or restatement of the name.

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?

An output schema exists, so return-structure explanation is unnecessary, and the description still supplies the one thing outside structured fields an agent needs: trust level of prices and where to get the authoritative total. Combined with 100% schema coverage, nothing material 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?

Schema description coverage is 100%, so 3 is the baseline. The description goes slightly beyond it by tying specific parameters to output semantics ('week prices for startDate and currency'), clarifying that startDate and currency key the price figures returned. No extra syntax or format detail (e.g., valid date range) is added.

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 (get) and resource (details of one accommodation group) and enumerates the returned facets: type, room_types, board options, distance, amenities, age/min-stay rules, week prices. It explicitly positions itself as 'One group from list_accommodations (group_id)', distinguishing it from the sibling that lists many.

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?

Gives explicit sequencing: 'Use after list_accommodations, before save_trip or calculate_trip_price, or to answer questions about one option.' It names both the prerequisite sibling and the downstream siblings, plus the disambiguating condition (questions about a single option).

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

get_course_detailsA
Read-onlyIdempotent
Inspect

Details for one course id from list_courses (pricing rows, supplements, metadata).

NameRequiredDescriptionDefault
localeNoResponse language and site context. One of en, nl, da, sv.
currencyNoISO 4217 currency for prices in this call. Usually EUR.EUR
course_idYesCourse product id from list_courses.
school_idYesCraft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID.
startDateNoCourse start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates.

Output Schema

NameRequiredDescription
courseNoSingle course product with pricing rows and supplements for the requested start date.
successYes

TDQS

A3.5/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered structurally. The description adds a small amount of content context (that pricing rows and supplements come back), but says nothing about auth needs, rate limits, or behavior when the id is invalid.

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?

A single compact sentence with the identifying scope ('one course id') front-loaded and the returned content types in a trailing parenthetical. Nothing is wasted, though the fragment style makes it slightly clipped rather than fully self-explanatory.

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 an output schema covering return values and annotations covering the safety profile, the description only needs to fix scope and provenance, which it does. It is marginally thin on whether optional parameters like startDate or currency change the result, 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?

Schema description coverage is 100% and an output schema exists, so locale, currency, course_id, school_id and startDate are already fully documented, including the Craft CMS vs CRM id distinction. The description adds no syntax, default, or format detail beyond the schema; 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?

Names the resource (course details) and ties it to the sibling that supplies the id ('one course id from list_courses'), which separates it from list_courses and the other detail tools. It also enumerates the payload (pricing rows, supplements, metadata), though the verb is implied rather than stated.

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 phrase 'from list_courses' implies the prerequisite step of enumerating courses first, and 'one course id' signals single-item scope. There is no explicit when-not guidance or comparison to alternatives such as get_trip or calculate_trip_price, so usage is only inferred.

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

get_schoolA
Read-onlyIdempotent
Inspect

School briefing: profile, cancellation policy, reviews, image URLs, bookings_live flag, and optional hero image for chat UI. Requires school_id from search_language_schools.

NameRequiredDescriptionDefault
localeNoResponse language and site context. One of en, nl, da, sv.
school_idYesCraft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID.
include_hero_imageNoWhen true, structuredContent may include a compressed JPEG in MCP image content; hero_image is stripped from structuredContent after attach.

Output Schema

NameRequiredDescription
dataNoSchool profile (title, url, city, country, bookings_live, reviews, images[]).
successYes

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare read-only, idempotent, non-destructive, closed-world behavior, so the safety burden is covered. The description adds context the annotations lack: the optional chat-UI hero image behavior and the instructional booking flag, which matter for how the result is consumed.

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 tight sentences with zero filler; the returned payload is front-loaded and the prerequisite follows. Nothing is redundant or padding.

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?

An output schema exists, so return shape need not be spelled out, and the description still enumerates the payload for quick routing. Only minor absence is any note on permissions or failure modes, which is acceptable given the complete annotations and output schema.

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 all three parameters (locale, school_id, include_hero_image) are fully documented in the schema, including the Craft CMS id sourcing and hero-image stripping. The description repeats the school_id requirement rather than adding syntax or format detail beyond it, so the baseline 3 applies.

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 the resource (school briefing) and enumerates exactly what it returns: profile, cancellation policy, reviews, image URLs, bookings_live flag, and hero image. Distinguishes it from sibling getters like get_course_details and get_accommodation_details by naming school-specific content.

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?

Explicitly states the prerequisite sourcing: 'Requires school_id from search_language_schools,' which tells the agent it must call the search tool first. No explicit when-not or alternative-tool routing is given, but the ordering guidance is clear.

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

get_school_filtersA
Read-onlyIdempotent
Inspect

Valid filter values for search_language_schools (languages, countries, cities, course types, and other facets).

NameRequiredDescriptionDefault
localeNoResponse language and site context. One of en, nl, da, sv.

Output Schema

NameRequiredDescription
dataNoFacet lists keyed by filter name.
successYes

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is clear. The description adds useful context that this is a filter-value lookup for a specific search tool, but does not add behavioral details such as auth needs or caching/rate-limit 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?

One tightly written sentence with no filler, front-loading the tool's purpose and the sibling it supports.

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 simple one-parameter schema, rich annotations, and an existing output schema, the description is nearly complete. It could be slightly stronger by explicitly saying to call this tool before search_language_schools, but an agent has enough information to select it 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 100%, and the single locale parameter is fully documented in the schema. The description does not add any parameter-level meaning beyond the schema, so the 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?

States a specific verb and resource: provides valid filter values for search_language_schools, and enumerates the facets (languages, countries, cities, course types). This distinguishes it from search_language_schools, which performs the actual search.

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?

Clearly ties the tool to search_language_schools as the source of filter values, giving strong implied context for when to call it. However, it does not state exclusions or explicitly instruct an agent to call this before search_language_schools.

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

get_tripA
Read-onlyIdempotent
Inspect

Load a saved trip by trip_id from save_trip. Returns continue_url for website handoff with configuration restored.

NameRequiredDescriptionDefault
trip_idYestrip_id returned by save_trip.

Output Schema

NameRequiredDescription
urlNoLegacy alias of continue_url.
noteNo
successYes
summaryNoHuman-readable configuration summary for agents.
trip_idNoShareable trip id (/s/{id}).
trip_urlNo
school_idNoCraft school entry id.
school_urlNo
school_nameNo
continue_urlNoShareable Extralingo URL that restores configuration.
configurationNo

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already establish the safety profile (readOnly, idempotent, non-destructive, closed-world). The description adds genuine context beyond them: the return payload is a continue_url intended for website handoff with configuration restored, telling the agent what the call actually yields and why.

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 sentences, zero waste, with the primary action and its key output front-loaded. Every clause 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?

An output schema exists so return-value documentation isn't strictly required, yet the description still flags the continue_url handoff, which is the practically important part. Nothing critical is missing for a one-param, read-only, idempotent retrieval 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 coverage is 100% and the description's only parameter statement ("by trip_id") merely restates the schema's own "trip_id returned by save_trip." With a single well-documented parameter, baseline 3 applies; no added syntax or format detail.

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 ("Load") and resource ("saved trip") and ties it to the producing tool, save_trip, so an agent can distinguish it from the save_trip sibling. It stops short of differentiating itself from the other get_* siblings, but the pairing with save_trip makes the 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 Guidelines3/5

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

"by trip_id from save_trip" implies the round-trip workflow (save first, then load), which is useful implied usage guidance. However there is no explicit when-to-use/when-not statement and no named alternative for a similar retrieval need.

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

list_accommodationsB
Read-onlyIdempotent
Inspect

Accommodation groups for a school. Use group ids in save_trip configuration (accommodationGroupId).

NameRequiredDescriptionDefault
localeNoResponse language and site context. One of en, nl, da, sv.
currencyNoISO 4217 currency for prices in this call. Usually EUR.EUR
school_idYesCraft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID.
startDateNoCourse start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates.
country_codeNoVisitor country ISO 3166-1 alpha-2 (e.g. NL). Affects fee display where applicable.

Output Schema

NameRequiredDescription
schoolNo
successYes
currencyNo
start_dateNo
location_discountNo
busy_school_monthsNo
accommodation_groupsNoFlat list of accommodation groups (id for get_accommodation_details / configuration).
has_location_discountsNo
accommodation_categoriesNoSame groups nested by category for display.
allows_double_room_individual_bookingsNo

TDQS

B3.1/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description adds the scoping fact that results are per-school and that the ids feed save_trip, but says nothing about pagination, filtering, or how many groups to expect. With annotations carrying the safety burden, this is an adequate 3.

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?

Two short sentences with zero padding, and the resource is stated before the downstream integration tip. It is appropriately sized, though the first sentence is a fragment rather than a complete statement of what the call returns.

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?

With an output schema present and 100% schema coverage, the description does not need to describe return values or parameter formats. What is missing is the when-to-use boundary against sibling tools like get_accommodation_details and how this fits with get_school, leaving the definition adequate but not complete for a 17-tool catalog.

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% and every parameter (school_id, locale, currency, startDate, country_code) is documented in the schema, including cross-tool references like search_language_schools and list_starting_dates. The description adds no parameter-level information whatsoever, so the baseline 3 applies.

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

Purpose3/5

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

The description names the resource ('Accommodation groups for a school'), which is enough to distinguish it from get_accommodation_details (single accommodation details), but it never states the action verb. It's a noun phrase where 'list' is only implied by the tool name, so the purpose is clear but not crisply stated.

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 second sentence is a downstream usage hint: 'Use group ids in save_trip configuration (accommodationGroupId).' That tells the agent why/when to call this (to obtain ids for save_trip), which is genuinely useful. However, it gives no exclusion or comparison against get_accommodation_details or get_school, so the routing guidance is only partial.

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

list_coursesA
Read-onlyIdempotent
Inspect

Live course catalogue for a bookings_live school (course ids, weeks, prices). Use returned course ids inside save_trip configuration.

NameRequiredDescriptionDefault
localeNoResponse language and site context. One of en, nl, da, sv.
currencyNoISO 4217 currency for prices in this call. Usually EUR.EUR
school_idYesCraft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID.
startDateNoCourse start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates.
country_codeNoVisitor country ISO 3166-1 alpha-2 (e.g. NL). Affects fee display where applicable.

Output Schema

NameRequiredDescription
schoolNoSchool metadata from the booking API.
successYes
currencyNo
start_dateNoEffective start date used for pricing (YYYY-MM-DD).
course_typesNoCourse types with nested courses[] (course ids, weeks, week prices).
pricing_ruleNo
location_discountNo
busy_school_monthsNo
has_location_discountsNo

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and a closed world, so the safety profile is covered. The description adds that the catalogue is 'live' and lists the returned fields, but says nothing about pagination, filtering behavior, or auth needs.

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, zero filler, with the resource and its returned fields front-loaded before the chaining instruction. 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?

With an output schema present the description need not explain return values, and the schema fully documents all five parameters. The only missing piece is how this list relates to get_course_details, which the description leaves implicit.

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 every parameter is documented in the schema (locale, currency, school_id source, startDate, country_code). The description adds no syntax or format meaning beyond what the schema already provides, so the 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 ('Live course catalogue for a bookings_live school') and even names the fields returned (course ids, weeks, prices). It does not explicitly distinguish itself from the sibling get_course_details, so it falls just short of 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 Guidelines4/5

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

Gives explicit downstream context: the returned course ids are meant to be fed into save_trip configuration, which tells an agent when this tool belongs in a workflow. It names no exclusion or alternative (e.g. get_course_details for a single course), so it is clear context without routing guidance.

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

list_starting_datesA
Read-onlyIdempotent
Inspect

Allowed course start dates (typically Mondays) for a school. Use startDate values in list_courses and configuration.startDate.

NameRequiredDescriptionDefault
localeNoResponse language and site context. One of en, nl, da, sv.
school_idYesCraft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID.

Output Schema

NameRequiredDescription
datesNoBookable course start dates (typically Mondays, YYYY-MM-DD strings).
successYes

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=false and destructiveHint=false, so the safety profile is fully covered without the description. The description adds only the 'typically Mondays' domain caveat; no auth, rate-limit, or pagination details are given.

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 tight sentences, with the resource definition and the 'typically Mondays' caveat front-loaded before the downstream consumption hint. 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 simple read-only lookup with a fully documented 2-param schema and an output schema, the description covers purpose, value semantics, and cross-tool usage adequately. Only minor gaps (e.g., ordering of returned dates) remain.

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%, and the schema already explains locale enum values and that school_id is the Craft CMS entry id (not the CRM UUID). The description adds no parameter meaning beyond the schema, so the baseline 3 applies.

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+resource ('Allowed course start dates ... for a school') and scopes it to a single school, which cleanly distinguishes it from the broader sibling list_courses. The cross-reference to where these values are consumed makes the tool's role 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?

Explicitly tells the agent what to do with the result: 'Use startDate values in list_courses and configuration.startDate,' which is real chaining guidance. It does not, however, name an alternative tool or state when *not* to call this one.

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

request_discussionAInspect

Trip discussion: trip_id or school_id+configuration plus message. ask_school_question: question without a trip. request_quote: personal quote (comments) when not booking. School gets the config; Extralingo emails the verified account and coordinates replies. Returns kind, newBookingId, redirectUrl, message (not a booking). OAuth scope requests. Optional idempotency_key.

NameRequiredDescriptionDefault
contactNoOptional first_name, last_name. Email always comes from the verified account.
messageNoStudent message to the school.
trip_idNoOptional trip_id from save_trip.
currencyNoISO 4217 currency for prices in this call. Usually EUR.EUR
school_idNoCraft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID.
configurationNoSame shape as the Extralingo school-page configurator: startDate (YYYY-MM-DD), students[] with courseId, weeks, optional accommodationGroupId, mealType, extras.
idempotencyKeyNoOptional alias of idempotency_key.
idempotency_keyNoOptional. Same semantics as create_booking (24 hour replay window).

Output Schema

NameRequiredDescription
kindNoLead type on success.
messageNoHuman-readable confirmation (not a booking confirmation).
successYes
redirectUrlNoExtralingo /my URL for the student to follow the request, when available.
newBookingIdNoCraft newBookings entry id when created.

TDQS

A3.6/5.0
Behavior4/5

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

Beyond the annotations, it discloses meaningful behavior: the school receives the config, Extralingo emails the verified account and coordinates replies, and the call returns kind/newBookingId/redirectUrl and is 'not a booking'. That 'not a booking' clarification is exactly the kind of side-effect context annotations don't convey.

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

Conciseness3/5

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

It is compact but written as a string of colon-delimited fragments that are hard to parse and not front-loaded around the primary action. Every clause carries some information, but the telegraphic structure reduces readability.

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 an 8-parameter, nested-object tool with an output schema, the description covers the modes, side effects, key return fields, OAuth scope, and idempotency. The main gap is the unresolved overlap with the ask_school_question/request_quote siblings.

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%, so the schema already documents every parameter; baseline is 3. The description adds only the 'trip_id or school_id+configuration' either/or relationship, which the schema does not express, but it omits the message/contact/currency semantics and does not compensate meaningfully.

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 names a concrete action (send a discussion/message to a school) and enumerates the input shapes for its modes (trip_id, or school_id+configuration, plus message). However, it overlaps awkwardly with sibling tools ask_school_question and request_quote by describing those modes inside this tool rather than cleanly distinguishing request_discussion from them.

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?

It gives partial conditions ('ask_school_question: question without a trip', 'request_quote: personal quote (comments) when not booking'), which imply when each mode applies. But it never states when to call request_discussion versus the standalone ask_school_question/request_quote siblings, so routing is left to inference.

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

request_quoteAInspect

Ask the school for a personal quote when bookings_live is false or the student is not ready to book. Requires OAuth requests scope. Optional idempotency_key.

NameRequiredDescriptionDefault
contactNoOptional first_name, last_name. Email always comes from the verified account.
trip_idNoOptional trip_id from save_trip.
commentsNoStudent message to the school.
currencyNoISO 4217 currency for prices in this call. Usually EUR.EUR
school_idNoCraft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID.
configurationNoSame shape as the Extralingo school-page configurator: startDate (YYYY-MM-DD), students[] with courseId, weeks, optional accommodationGroupId, mealType, extras.
idempotencyKeyNoOptional alias of idempotency_key.
idempotency_keyNoOptional. Same semantics as create_booking (24 hour replay window).

Output Schema

NameRequiredDescription
kindNoLead type on success.
messageNoHuman-readable confirmation (not a booking confirmation).
successYes
redirectUrlNoExtralingo /my URL for the student to follow the request, when available.
newBookingIdNoCraft newBookings entry id when created.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations declare the mutation/safety profile (readOnlyHint=false, openWorldHint=true, destructiveHint=false), and the description usefully adds the OAuth 'requests' scope requirement, which annotations do not convey. Idempotency-key behavior is deferred to the schema, so it adds only moderate extra behavioral context.

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 sentences, no waste, and the critical call condition is front-loaded before the incidental scope/idempotency notes. Nothing needs trimming.

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 an output schema present and full schema coverage on 8 parameters, the description only needs to carry the when-to-call and auth context, which it does. It is slightly thin on how the quote is delivered or whether the request is free/side-effecting, but not enough to mislead.

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% and every parameter, including the nested configuration object, is documented richly in the schema. The description adds nothing beyond noting idempotency_key is optional, so the baseline 3 applies.

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+resource ('Ask the school for a personal quote') and immediately bounds the scenario ('when bookings_live is false or the student is not ready to book'), which distinguishes it from the booking/creating siblings. An agent can tell this apart from create_booking without opening either 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 a clear trigger condition (bookings_live false, student not ready to book) rather than terse context. It stops short of naming the closest siblings it should be chosen over — request_discussion, ask_school_question, create_booking — so the boundary with those is left to inference.

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

save_tripAInspect

Create or update a server-side trip draft. Returns trip_id, url, trip_url, and continue_url (/s/{id}) so the student can restore selections on Extralingo.com. Not a booking. Requires OAuth trips scope (Bearer token).

NameRequiredDescriptionDefault
emailNoOptional student email for anonymous drafts. With OAuth, the verified account email is used.
localeNoResponse language and site context. One of en, nl, da, sv.
trip_idNoOmit to create a new trip. Pass an existing trip_id from save_trip to update the same continue_url.
school_idNoCraft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID.
configurationNoSame shape as the Extralingo school-page configurator: startDate (YYYY-MM-DD), students[] with courseId, weeks, optional accommodationGroupId, mealType, extras.

Output Schema

NameRequiredDescription
urlNoLegacy alias of continue_url.
noteNo
successYes
summaryNoHuman-readable configuration summary for agents.
trip_idNoShareable trip id (/s/{id}).
trip_urlNo
school_idNoCraft school entry id.
school_urlNo
school_nameNo
continue_urlNoShareable Extralingo URL that restores configuration.
configurationNo

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare the non-readOnly, non-idempotent, non-destructive, closed-world profile, and the description adds real context on top: the required OAuth trips scope (Bearer token) and that anonymous drafts can use an email instead. It does not say whether an update replaces or merges existing selections, which is the main behavioral ambiguity left for an upsert.

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 sentences, front-loaded with the action, then the return contract, then the auth requirement. Nothing is redundant or padded.

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?

With a full output schema, complete annotations, and 100% schema coverage, the description only needs to supply the auth scope, the non-booking boundary, and the restore-on-Extralingo purpose — all of which it does. Nothing an agent needs to call this correctly 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 100% and the parameters are richly documented (school_id provenance, courseId from list_courses, startDate format), so the schema does the heavy lifting. The description adds no parameter-level detail of its own, which is the expected baseline of 3 at full coverage.

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 ('Create or update a server-side trip draft') and immediately scopes it against the obvious sibling with 'Not a booking', so an agent can distinguish it from create_booking and get_trip without opening a 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 the create-vs-update rule via trip_id and an explicit exclusion ('Not a booking'), which routes the agent away from booking tools. It does not, however, name a specific sibling to use instead or state prerequisites beyond the OAuth scope, so it stops short of a full when/when-not/alternative statement.

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

search_destinationsA
Read-onlyIdempotent
Inspect

Search cities, countries, and school names. Use before search_language_schools to resolve place names to slugs.

NameRequiredDescriptionDefault
limitNoMaximum results (1–20).
queryNoDestination or school name prefix. Empty returns popular destinations.
localeNoResponse language and site context. One of en, nl, da, sv.
languageNoOptional language slug to restrict destinations (e.g. spanish).

Output Schema

NameRequiredDescription
hitsNoDestination matches.
queryNo
localeNo
schoolsNoOptional school name fallback hits.
successYes

TDQS

A4.2/5.0
Behavior3/5

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

Annotations already declare readOnly, idempotent, non-destructive, and closed-world, so the safety profile is covered. The description adds the useful hint that output is intended as slugs for a downstream call, but says nothing about result format, empty-query behavior, or ranking beyond what the schema states. Adequate, not rich.

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, zero waste, with the primary purpose front-loaded and the sequencing hint second. Nothing to trim.

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?

An output schema exists and the input schema is fully documented, so return values and parameter meanings need not be restated. The description covers what it searches and when to call it; only minor context (e.g. how many slugs to resolve or that locale controls response language) is left implicit.

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 all four parameters (query, locale, language, limit) are already documented in the schema, including the empty-query fallback and the language-slug filter. The description adds no parameter detail, so the baseline of 3 applies.

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 (Search) over concrete resources (cities, countries, school names), and explicitly distinguishes itself from the sibling search_language_schools. An agent can tell what this does 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 Guidelines5/5

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

Gives an explicit ordering rule: use this before search_language_schools to resolve place names to slugs. Names the alternative tool and the condition that selects it, so the routing decision is unambiguous.

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

search_language_schoolsA
Read-onlyIdempotent
Inspect

Search and rank language schools. Returns school_id, url, indicative from-price, and reviews. Prices are not a booking quote; call calculate_trip_price before quoting a total.

NameRequiredDescriptionDefault
cityNoSingle city slug filter. Prefer cities[] for multiple.
limitNoMaximum schools to return (1–20).
queryNoFree-text search (school name, city, or keyword). Empty returns popular matches for the other filters.
citiesNoCity slug filters from get_school_filters.
localeNoResponse language and site context. One of en, nl, da, sv.
countryNoCountry slug or name filter from get_school_filters.
languageNoLanguage slug filter from get_school_filters (e.g. spanish, english).
course_typeNoCourse type slug from get_school_filters (e.g. intensive, private).

Output Schema

NameRequiredDescription
dataNoMeilisearch-style payload with hits[] (school_id, title, url, city, country, pricing hints).
successYes

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the safety profile is covered by structured data. The description adds value by disclosing the return fields (school_id, url, indicative from-price, reviews) and the critical caveat that prices are not a booking quote. That caveat is genuinely useful behavioral context not present in annotations. Still, it doesn't cover pagination, ranking logic, or empty-result 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 front-loaded sentences with zero waste: the first declares purpose and return shape, the second delivers the critical pricing caveat and points to the correct sibling. 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?

With an output schema present, the description correctly avoids re-explaining return structure, and the annotations cover safety hints. The pricing caveat and sibling routing are the key missing pieces an agent needs, so the essential behavioral guidance is there. Minor gaps remain around filter-selection strategy given the eight optional parameters, but nothing critical for correct invocation is absent.

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%, so every parameter already has a description in the schema, including city vs cities preference and limit bounds. The description adds no filter syntax, slug source, or example usage beyond what the schema provides. Baseline 3 is appropriate when the schema does all the parameter work.

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+resource (search and rank language schools) and immediately distinguishes itself from the related pricing sibling by disclaiming that prices are not a booking quote and directing to calculate_trip_price. An agent can tell exactly what this tool does relative to get_school, list_courses, and calculate_trip_price.

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 routes the agent to calculate_trip_price for totals, which is a clear when-to-use-nothing-else signal. However, it does not explain when to prefer this tool over get_school or search_destinations, nor how city vs cities vs query filters should be chosen. Usage is implied but not fully specified.

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. 12 tool updates
    • Changedask_school_question5 fields changed
      • addedOutput schema / properties / kind
        Added value: +{
        +  "description": "Lead type on success.",
        +  "enum": [
        +    "question"
        +  ],
        +  "type": "string"
        +}
      • removedOutput schema / properties / lead
        Removed value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}
      • addedOutput schema / properties / message / description
        Added value: +"Human-readable confirmation (not a booking confirmation)."
      • addedOutput schema / properties / newBookingId
        Added value: +{
        +  "description": "Craft newBookings entry id when created.",
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / redirectUrl
        Added value: +{
        +  "description": "Extralingo /my URL for the student to follow the request, when available.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
    • Changedcreate_booking5 fields changed
      • removedOutput schema / properties / booking
        Removed value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}
      • addedOutput schema / properties / bookingId
        Added value: +{
        +  "description": "Craft booking id when returned by the booking engine.",
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / bookingReference
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / redirectUrl
        Added value: +{
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / status
        Added value: +{
        +  "description": "e.g. awaiting_school_confirmation.",
        +  "type": "string"
        +}
    • Changedemail_trip4 fields changed
      • addedOutput schema / properties / emailed_to
        Added value: +{
        +  "description": "Verified account inbox that received the email.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / trip_id
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / trip_url
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / url
        Added value: +{
        +  "description": "Legacy alias of continue_url.",
        +  "type": "string"
        +}
    • Changedget_accommodation_details2 fields changed
      • removedOutput schema / properties / data
        Removed value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}
      • addedOutput schema / properties / group
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Accommodation group from GET /v3/accommodations/{id} (v2 grouping): labels, classification, room and meal options, facilities, rules, and pricing hints for the requested start date.",
        +  "properties": {
        +    "amenities": {
        +      "description": "Facilities and highlighted amenities.",
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "classification": {
        +      "additionalProperties": true,
        +      "description": "Accommodation type, class, and room metadata.",
        +      "type": "object"
        +    },
        +    "distance": {
        +      "additionalProperties": true,
        +      "description": "Distance-to-school summary (string or structured object from the API).",
        +      "type": [
        +        "string",
        +        "object",
        +        "null"
        +      ]
        +    },
        +    "group_name": {
        +      "description": "Grouped title when room-type grouping is enabled.",
        +      "type": "string"
        +    },
        +    "id": {
        +      "description": "Group id (matches group_id).",
        +      "type": "string"
        +    },
        +    "location": {
        +      "additionalProperties": true,
        +      "description": "Address, distance_to_school, and travel-time hints.",
        +      "type": "object"
        +    },
        +    "meal_options": {
        +      "description": "Board/meal plans with pricing_for_requested_weeks when not split by room_types.",
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "name": {
        +      "description": "Display name of the accommodation group.",
        +      "type": "string"
        +    },
        +    "occupancy": {
        +      "additionalProperties": true,
        +      "description": "Minimum/maximum age and occupancy limits.",
        +      "type": "object"
        +    },
        +    "room_types": {
        +      "description": "Room variants, each with meal_options, stay_length, and week pricing.",
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "stay_length": {
        +      "additionalProperties": true,
        +      "description": "Minimum and maximum stay in weeks.",
        +      "type": "object"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedget_course_details2 fields changed
      • addedOutput schema / properties / course
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Single course product with pricing rows and supplements for the requested start date.",
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • removedOutput schema / properties / data
        Removed value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}
    • Changedget_trip7 fields changed
      • addedOutput schema / properties / school_id
        Added value: +{
        +  "description": "Craft school entry id.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / school_name
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / school_url
        Added value: +{
        +  "type": "string"
        +}
      • removedOutput schema / properties / summary / additionalProperties
        Removed value: -true
      • addedOutput schema / properties / summary / description
        Added value: +"Human-readable configuration summary for agents."
      • changedOutput schema / properties / summary / type
        Previous value: -"object"New value: +"string"
      • addedOutput schema / properties / trip_id / description
        Added value: +"Shareable trip id (/s/{id})."
    • Changedlist_accommodations10 fields changed
      • addedOutput schema / properties / accommodation_categories
        Added value: +{
        +  "description": "Same groups nested by category for display.",
        +  "items": {
        +    "additionalProperties": true,
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / accommodation_groups
        Added value: +{
        +  "description": "Flat list of accommodation groups (id for get_accommodation_details / configuration).",
        +  "items": {
        +    "additionalProperties": true,
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / allows_double_room_individual_bookings
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / busy_school_months
        Added value: +{
        +  "additionalProperties": true,
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / currency
        Added value: +{
        +  "type": "string"
        +}
      • removedOutput schema / properties / data
        Removed value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}
      • addedOutput schema / properties / has_location_discounts
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / location_discount
        Added value: +{
        +  "additionalProperties": true,
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / school
        Added value: +{
        +  "additionalProperties": true,
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / start_date
        Added value: +{
        +  "type": "string"
        +}
    • Changedlist_courses9 fields changed
      • addedOutput schema / properties / busy_school_months
        Added value: +{
        +  "additionalProperties": true,
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / course_types
        Added value: +{
        +  "description": "Course types with nested courses[] (course ids, weeks, week prices).",
        +  "items": {
        +    "additionalProperties": true,
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / currency
        Added value: +{
        +  "type": "string"
        +}
      • removedOutput schema / properties / data
        Removed value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}
      • addedOutput schema / properties / has_location_discounts
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / location_discount
        Added value: +{
        +  "additionalProperties": true,
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / pricing_rule
        Added value: +{
        +  "additionalProperties": true,
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / school
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "School metadata from the booking API.",
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / start_date
        Added value: +{
        +  "description": "Effective start date used for pricing (YYYY-MM-DD).",
        +  "type": "string"
        +}
    • Changedlist_starting_dates2 fields changed
      • removedOutput schema / properties / data
        Removed value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}
      • addedOutput schema / properties / dates
        Added value: +{
        +  "description": "Bookable course start dates (typically Mondays, YYYY-MM-DD strings).",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
    • Changedrequest_discussion5 fields changed
      • addedOutput schema / properties / kind
        Added value: +{
        +  "description": "Lead type on success.",
        +  "enum": [
        +    "discussion"
        +  ],
        +  "type": "string"
        +}
      • removedOutput schema / properties / lead
        Removed value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}
      • addedOutput schema / properties / message / description
        Added value: +"Human-readable confirmation (not a booking confirmation)."
      • addedOutput schema / properties / newBookingId
        Added value: +{
        +  "description": "Craft newBookings entry id when created.",
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / redirectUrl
        Added value: +{
        +  "description": "Extralingo /my URL for the student to follow the request, when available.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
    • Changedrequest_quote5 fields changed
      • addedOutput schema / properties / kind
        Added value: +{
        +  "description": "Lead type on success.",
        +  "enum": [
        +    "quote"
        +  ],
        +  "type": "string"
        +}
      • removedOutput schema / properties / lead
        Removed value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}
      • addedOutput schema / properties / message / description
        Added value: +"Human-readable confirmation (not a booking confirmation)."
      • addedOutput schema / properties / newBookingId
        Added value: +{
        +  "description": "Craft newBookings entry id when created.",
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / redirectUrl
        Added value: +{
        +  "description": "Extralingo /my URL for the student to follow the request, when available.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
    • Changedsave_trip7 fields changed
      • addedOutput schema / properties / school_id
        Added value: +{
        +  "description": "Craft school entry id.",
        +  "type": "integer"
        +}
      • addedOutput schema / properties / school_name
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / school_url
        Added value: +{
        +  "type": "string"
        +}
      • removedOutput schema / properties / summary / additionalProperties
        Removed value: -true
      • addedOutput schema / properties / summary / description
        Added value: +"Human-readable configuration summary for agents."
      • changedOutput schema / properties / summary / type
        Previous value: -"object"New value: +"string"
      • addedOutput schema / properties / trip_id / description
        Added value: +"Shareable trip id (/s/{id})."
  2. 17 tool updates
    • Changedask_school_question12 fields changed
      • removedInput schema / properties / auth_token
        Removed value: -{
        -  "type": "string"
        -}
      • addedInput schema / properties / configuration
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Same shape as the Extralingo school-page configurator: startDate (YYYY-MM-DD), students[] with courseId, weeks, optional accommodationGroupId, mealType, extras.",
        +  "properties": {
        +    "accommodationGroupId": {
        +      "description": "Accommodation group id from list_accommodations (optional).",
        +      "type": "string"
        +    },
        +    "mealType": {
        +      "description": "Meal plan key when accommodation is selected.",
        +      "type": "string"
        +    },
        +    "startDate": {
        +      "description": "Course start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates.",
        +      "examples": [
        +        "2026-09-07"
        +      ],
        +      "type": "string"
        +    },
        +    "students": {
        +      "description": "One object per traveller. courseId comes from list_courses.",
        +      "items": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "courseId": {
        +            "description": "Course product id from list_courses for this school.",
        +            "type": "string"
        +          },
        +          "weeks": {
        +            "description": "Course duration in weeks.",
        +            "minimum": 1,
        +            "type": "integer"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / contact / additionalProperties
        Added value: +true
      • changedInput schema / properties / contact / description
        Previous value: -"Optional first_name, last_name. Email always comes from the verified account. A different contact.email is rejected."New value: +"Optional first_name, last_name. Email always comes from the verified account."
      • addedInput schema / properties / currency / description
        Added value: +"ISO 4217 currency for prices in this call. Usually EUR."
      • addedInput schema / properties / currency / examples
        Added value: +[
        +  "EUR"
        +]
      • addedInput schema / properties / idempotencyKey / description
        Added value: +"Optional alias of idempotency_key."
      • addedInput schema / properties / message / description
        Added value: +"Student message to the school."
      • addedInput schema / properties / school_id / description
        Added value: +"Craft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID."
      • addedInput schema / properties / school_id / examples
        Added value: +[
        +  12345
        +]
      • addedInput schema / properties / trip_id
        Added value: +{
        +  "description": "Optional trip_id from save_trip.",
        +  "type": "string"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "lead": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "message": {
        +      "type": "string"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedcalculate_trip_price14 fields changed
      • addedInput schema / properties / configuration / additionalProperties
        Added value: +true
      • changedInput schema / properties / configuration / description
        Previous value: -"Same shape as the V2 school-page configurator: startDate, students[].courseId, weeks, accommodationGroupId, mealType, extras."New value: +"Same shape as the Extralingo school-page configurator: startDate (YYYY-MM-DD), students[] with courseId, weeks, optional accommodationGroupId, mealType, extras."
      • addedInput schema / properties / configuration / properties
        Added value: +{
        +  "accommodationGroupId": {
        +    "description": "Accommodation group id from list_accommodations (optional).",
        +    "type": "string"
        +  },
        +  "mealType": {
        +    "description": "Meal plan key when accommodation is selected.",
        +    "type": "string"
        +  },
        +  "startDate": {
        +    "description": "Course start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates.",
        +    "examples": [
        +      "2026-09-07"
        +    ],
        +    "type": "string"
        +  },
        +  "students": {
        +    "description": "One object per traveller. courseId comes from list_courses.",
        +    "items": {
        +      "additionalProperties": true,
        +      "properties": {
        +        "courseId": {
        +          "description": "Course product id from list_courses for this school.",
        +          "type": "string"
        +        },
        +        "weeks": {
        +          "description": "Course duration in weeks.",
        +          "minimum": 1,
        +          "type": "integer"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "type": "array"
        +  }
        +}
      • addedInput schema / properties / country_code / description
        Added value: +"Visitor country ISO 3166-1 alpha-2 (e.g. NL). Affects fee display where applicable."
      • addedInput schema / properties / country_code / examples
        Added value: +[
        +  "NL",
        +  "DE"
        +]
      • addedInput schema / properties / currency / description
        Added value: +"ISO 4217 currency for prices in this call. Usually EUR."
      • addedInput schema / properties / currency / examples
        Added value: +[
        +  "EUR"
        +]
      • addedInput schema / properties / discountCode / description
        Added value: +"Optional promotion or discount code."
      • addedInput schema / properties / locale / description
        Added value: +"Response language and site context. One of en, nl, da, sv."
      • addedInput schema / properties / locale / examples
        Added value: +[
        +  "en",
        +  "nl",
        +  "da",
        +  "sv"
        +]
      • addedInput schema / properties / school_id / description
        Added value: +"Craft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID."
      • addedInput schema / properties / school_id / examples
        Added value: +[
        +  12345
        +]
      • addedInput schema / properties / trip_id / description
        Added value: +"Optional saved trip id; when set, the quote may be stored on that trip."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "data": {
        +      "additionalProperties": true,
        +      "description": "Full pricing breakdown from the booking engine.",
        +      "type": "object"
        +    },
        +    "quote": {
        +      "additionalProperties": true,
        +      "description": "Human-oriented price summary.",
        +      "type": "object"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedcreate_booking21 fields changed
      • removedInput schema / properties / auth_token
        Removed value: -{
        -  "type": "string"
        -}
      • addedInput schema / properties / configuration / additionalProperties
        Added value: +true
      • addedInput schema / properties / configuration / description
        Added value: +"Same shape as the Extralingo school-page configurator: startDate (YYYY-MM-DD), students[] with courseId, weeks, optional accommodationGroupId, mealType, extras."
      • addedInput schema / properties / configuration / properties
        Added value: +{
        +  "accommodationGroupId": {
        +    "description": "Accommodation group id from list_accommodations (optional).",
        +    "type": "string"
        +  },
        +  "mealType": {
        +    "description": "Meal plan key when accommodation is selected.",
        +    "type": "string"
        +  },
        +  "startDate": {
        +    "description": "Course start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates.",
        +    "examples": [
        +      "2026-09-07"
        +    ],
        +    "type": "string"
        +  },
        +  "students": {
        +    "description": "One object per traveller. courseId comes from list_courses.",
        +    "items": {
        +      "additionalProperties": true,
        +      "properties": {
        +        "courseId": {
        +          "description": "Course product id from list_courses for this school.",
        +          "type": "string"
        +        },
        +        "weeks": {
        +          "description": "Course duration in weeks.",
        +          "minimum": 1,
        +          "type": "integer"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "type": "array"
        +  }
        +}
      • addedInput schema / properties / contact / additionalProperties
        Added value: +true
      • changedInput schema / properties / contact / description
        Previous value: -"Optional first_name, last_name, phone. Email always comes from the verified account. A different contact.email is rejected."New value: +"Optional first_name, last_name, phone. Email always comes from the verified account; contact.email must match or be omitted."
      • addedInput schema / properties / currency / description
        Added value: +"ISO 4217 currency for prices in this call. Usually EUR."
      • addedInput schema / properties / currency / examples
        Added value: +[
        +  "EUR"
        +]
      • changedInput schema / properties / idempotencyKey / description
        Previous value: -"Optional. Alias of idempotency_key."New value: +"Optional alias of idempotency_key."
      • changedInput schema / properties / idempotency_key / description
        Previous value: -"Optional. Same key + same payload within 24 hours replays the original response. A different payload with the same key fails."New value: +"Optional. Same key + same payload within 24 hours replays the original response; conflicting payload returns validation_failed."
      • addedInput schema / properties / phone / description
        Added value: +"Student phone number (required)."
      • changedInput schema / properties / phoneCountry / description
        Previous value: -"ISO2, e.g. NL"New value: +"ISO 3166-1 alpha-2 country for the phone (e.g. NL)."
      • changedInput schema / properties / privacyAccepted / description
        Previous value: -"Only needed for legacy auth_token sessions. OAuth grants already include privacy acceptance."New value: +"Must be true when not using OAuth."
      • addedInput schema / properties / school_id / description
        Added value: +"Craft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID."
      • addedInput schema / properties / school_id / examples
        Added value: +[
        +  12345
        +]
      • addedInput schema / properties / specialRequests / description
        Added value: +"Free-text notes for the school."
      • addedInput schema / properties / studentDetails / description
        Added value: +"Per-student details aligned with configuration.students (names, dates of birth, etc.)."
      • addedInput schema / properties / studentDetails / items
        Added value: +{
        +  "additionalProperties": true,
        +  "type": "object"
        +}
      • changedInput schema / properties / termsAccepted / description
        Previous value: -"Only needed for legacy auth_token sessions. OAuth grants already include terms acceptance."New value: +"Must be true when not using OAuth (OAuth grants record acceptance)."
      • addedInput schema / properties / trip_id / description
        Added value: +"Optional trip_id from save_trip linking this booking to a draft."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "agent_must_tell_the_user": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "booking": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "studentMessage": {
        +      "type": "string"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedemail_trip7 fields changed
      • changedInput schema / properties / email / description
        Previous value: -"Optional. Must match the verified account email if sent. The link is always emailed to that account."New value: +"Optional. Must match the verified OAuth account email if sent. The link is always sent to that account."
      • addedInput schema / properties / firstName / description
        Added value: +"Optional salutation for the email body."
      • addedInput schema / properties / lastName / description
        Added value: +"Optional salutation for the email body."
      • addedInput schema / properties / locale / description
        Added value: +"Response language and site context. One of en, nl, da, sv."
      • addedInput schema / properties / locale / examples
        Added value: +[
        +  "en",
        +  "nl",
        +  "da",
        +  "sv"
        +]
      • addedInput schema / properties / trip_id / description
        Added value: +"trip_id from save_trip."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "continue_url": {
        +      "type": "string"
        +    },
        +    "message": {
        +      "type": "string"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedget_accommodation_details8 fields changed
      • addedInput schema / properties / currency / description
        Added value: +"ISO 4217 currency for prices in this call. Usually EUR."
      • addedInput schema / properties / currency / examples
        Added value: +[
        +  "EUR"
        +]
      • addedInput schema / properties / group_id / description
        Added value: +"Accommodation group id from list_accommodations."
      • addedInput schema / properties / locale / description
        Added value: +"Response language and site context. One of en, nl, da, sv."
      • addedInput schema / properties / locale / examples
        Added value: +[
        +  "en",
        +  "nl",
        +  "da",
        +  "sv"
        +]
      • addedInput schema / properties / startDate / description
        Added value: +"Course start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates."
      • addedInput schema / properties / startDate / examples
        Added value: +[
        +  "2026-09-07"
        +]
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "data": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedget_course_details10 fields changed
      • addedInput schema / properties / course_id / description
        Added value: +"Course product id from list_courses."
      • addedInput schema / properties / currency / description
        Added value: +"ISO 4217 currency for prices in this call. Usually EUR."
      • addedInput schema / properties / currency / examples
        Added value: +[
        +  "EUR"
        +]
      • addedInput schema / properties / locale / description
        Added value: +"Response language and site context. One of en, nl, da, sv."
      • addedInput schema / properties / locale / examples
        Added value: +[
        +  "en",
        +  "nl",
        +  "da",
        +  "sv"
        +]
      • addedInput schema / properties / school_id / description
        Added value: +"Craft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID."
      • addedInput schema / properties / school_id / examples
        Added value: +[
        +  12345
        +]
      • addedInput schema / properties / startDate / description
        Added value: +"Course start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates."
      • addedInput schema / properties / startDate / examples
        Added value: +[
        +  "2026-09-07"
        +]
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "data": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedget_school6 fields changed
      • changedInput schema / properties / include_hero_image / description
        Previous value: -"Include a compressed JPEG for display in chat. Default true."New value: +"When true, structuredContent may include a compressed JPEG in MCP image content; hero_image is stripped from structuredContent after attach."
      • addedInput schema / properties / locale / description
        Added value: +"Response language and site context. One of en, nl, da, sv."
      • addedInput schema / properties / locale / examples
        Added value: +[
        +  "en",
        +  "nl",
        +  "da",
        +  "sv"
        +]
      • addedInput schema / properties / school_id / description
        Added value: +"Craft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID."
      • addedInput schema / properties / school_id / examples
        Added value: +[
        +  12345
        +]
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "data": {
        +      "additionalProperties": true,
        +      "description": "School profile (title, url, city, country, bookings_live, reviews, images[]).",
        +      "type": "object"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedget_school_filters3 fields changed
      • addedInput schema / properties / locale / description
        Added value: +"Response language and site context. One of en, nl, da, sv."
      • addedInput schema / properties / locale / examples
        Added value: +[
        +  "en",
        +  "nl",
        +  "da",
        +  "sv"
        +]
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "data": {
        +      "additionalProperties": true,
        +      "description": "Facet lists keyed by filter name.",
        +      "type": "object"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedget_trip2 fields changed
      • addedInput schema / properties / trip_id / description
        Added value: +"trip_id returned by save_trip."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "configuration": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "continue_url": {
        +      "description": "Shareable Extralingo URL that restores configuration.",
        +      "type": "string"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "success": {
        +      "const": true
        +    },
        +    "summary": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "trip_id": {
        +      "type": "string"
        +    },
        +    "trip_url": {
        +      "type": "string"
        +    },
        +    "url": {
        +      "description": "Legacy alias of continue_url.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_accommodations11 fields changed
      • addedInput schema / properties / country_code / description
        Added value: +"Visitor country ISO 3166-1 alpha-2 (e.g. NL). Affects fee display where applicable."
      • addedInput schema / properties / country_code / examples
        Added value: +[
        +  "NL",
        +  "DE"
        +]
      • addedInput schema / properties / currency / description
        Added value: +"ISO 4217 currency for prices in this call. Usually EUR."
      • addedInput schema / properties / currency / examples
        Added value: +[
        +  "EUR"
        +]
      • addedInput schema / properties / locale / description
        Added value: +"Response language and site context. One of en, nl, da, sv."
      • addedInput schema / properties / locale / examples
        Added value: +[
        +  "en",
        +  "nl",
        +  "da",
        +  "sv"
        +]
      • addedInput schema / properties / school_id / description
        Added value: +"Craft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID."
      • addedInput schema / properties / school_id / examples
        Added value: +[
        +  12345
        +]
      • addedInput schema / properties / startDate / description
        Added value: +"Course start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates."
      • addedInput schema / properties / startDate / examples
        Added value: +[
        +  "2026-09-07"
        +]
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "data": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_courses11 fields changed
      • addedInput schema / properties / country_code / description
        Added value: +"Visitor country ISO 3166-1 alpha-2 (e.g. NL). Affects fee display where applicable."
      • addedInput schema / properties / country_code / examples
        Added value: +[
        +  "NL",
        +  "DE"
        +]
      • addedInput schema / properties / currency / description
        Added value: +"ISO 4217 currency for prices in this call. Usually EUR."
      • addedInput schema / properties / currency / examples
        Added value: +[
        +  "EUR"
        +]
      • addedInput schema / properties / locale / description
        Added value: +"Response language and site context. One of en, nl, da, sv."
      • addedInput schema / properties / locale / examples
        Added value: +[
        +  "en",
        +  "nl",
        +  "da",
        +  "sv"
        +]
      • addedInput schema / properties / school_id / description
        Added value: +"Craft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID."
      • addedInput schema / properties / school_id / examples
        Added value: +[
        +  12345
        +]
      • changedInput schema / properties / startDate / description
        Previous value: -"YYYY-MM-DD Monday"New value: +"Course start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates."
      • addedInput schema / properties / startDate / examples
        Added value: +[
        +  "2026-09-07"
        +]
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "data": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedlist_starting_dates5 fields changed
      • addedInput schema / properties / locale / description
        Added value: +"Response language and site context. One of en, nl, da, sv."
      • addedInput schema / properties / locale / examples
        Added value: +[
        +  "en",
        +  "nl",
        +  "da",
        +  "sv"
        +]
      • addedInput schema / properties / school_id / description
        Added value: +"Craft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID."
      • addedInput schema / properties / school_id / examples
        Added value: +[
        +  12345
        +]
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "data": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedrequest_discussion14 fields changed
      • removedInput schema / properties / auth_token
        Removed value: -{
        -  "type": "string"
        -}
      • addedInput schema / properties / configuration / additionalProperties
        Added value: +true
      • addedInput schema / properties / configuration / description
        Added value: +"Same shape as the Extralingo school-page configurator: startDate (YYYY-MM-DD), students[] with courseId, weeks, optional accommodationGroupId, mealType, extras."
      • addedInput schema / properties / configuration / properties
        Added value: +{
        +  "accommodationGroupId": {
        +    "description": "Accommodation group id from list_accommodations (optional).",
        +    "type": "string"
        +  },
        +  "mealType": {
        +    "description": "Meal plan key when accommodation is selected.",
        +    "type": "string"
        +  },
        +  "startDate": {
        +    "description": "Course start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates.",
        +    "examples": [
        +      "2026-09-07"
        +    ],
        +    "type": "string"
        +  },
        +  "students": {
        +    "description": "One object per traveller. courseId comes from list_courses.",
        +    "items": {
        +      "additionalProperties": true,
        +      "properties": {
        +        "courseId": {
        +          "description": "Course product id from list_courses for this school.",
        +          "type": "string"
        +        },
        +        "weeks": {
        +          "description": "Course duration in weeks.",
        +          "minimum": 1,
        +          "type": "integer"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "type": "array"
        +  }
        +}
      • addedInput schema / properties / contact / additionalProperties
        Added value: +true
      • changedInput schema / properties / contact / description
        Previous value: -"Optional first_name, last_name. Email always comes from the verified account. A different contact.email is rejected."New value: +"Optional first_name, last_name. Email always comes from the verified account."
      • addedInput schema / properties / currency / description
        Added value: +"ISO 4217 currency for prices in this call. Usually EUR."
      • addedInput schema / properties / currency / examples
        Added value: +[
        +  "EUR"
        +]
      • addedInput schema / properties / idempotencyKey / description
        Added value: +"Optional alias of idempotency_key."
      • addedInput schema / properties / message / description
        Added value: +"Student message to the school."
      • addedInput schema / properties / school_id / description
        Added value: +"Craft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID."
      • addedInput schema / properties / school_id / examples
        Added value: +[
        +  12345
        +]
      • addedInput schema / properties / trip_id / description
        Added value: +"Optional trip_id from save_trip."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "lead": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "message": {
        +      "type": "string"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedrequest_quote14 fields changed
      • removedInput schema / properties / auth_token
        Removed value: -{
        -  "type": "string"
        -}
      • addedInput schema / properties / comments / description
        Added value: +"Student message to the school."
      • addedInput schema / properties / configuration / additionalProperties
        Added value: +true
      • addedInput schema / properties / configuration / description
        Added value: +"Same shape as the Extralingo school-page configurator: startDate (YYYY-MM-DD), students[] with courseId, weeks, optional accommodationGroupId, mealType, extras."
      • addedInput schema / properties / configuration / properties
        Added value: +{
        +  "accommodationGroupId": {
        +    "description": "Accommodation group id from list_accommodations (optional).",
        +    "type": "string"
        +  },
        +  "mealType": {
        +    "description": "Meal plan key when accommodation is selected.",
        +    "type": "string"
        +  },
        +  "startDate": {
        +    "description": "Course start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates.",
        +    "examples": [
        +      "2026-09-07"
        +    ],
        +    "type": "string"
        +  },
        +  "students": {
        +    "description": "One object per traveller. courseId comes from list_courses.",
        +    "items": {
        +      "additionalProperties": true,
        +      "properties": {
        +        "courseId": {
        +          "description": "Course product id from list_courses for this school.",
        +          "type": "string"
        +        },
        +        "weeks": {
        +          "description": "Course duration in weeks.",
        +          "minimum": 1,
        +          "type": "integer"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "type": "array"
        +  }
        +}
      • addedInput schema / properties / contact / additionalProperties
        Added value: +true
      • changedInput schema / properties / contact / description
        Previous value: -"Optional first_name, last_name. Email always comes from the verified account. A different contact.email is rejected."New value: +"Optional first_name, last_name. Email always comes from the verified account."
      • addedInput schema / properties / currency / description
        Added value: +"ISO 4217 currency for prices in this call. Usually EUR."
      • addedInput schema / properties / currency / examples
        Added value: +[
        +  "EUR"
        +]
      • addedInput schema / properties / idempotencyKey / description
        Added value: +"Optional alias of idempotency_key."
      • addedInput schema / properties / school_id / description
        Added value: +"Craft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID."
      • addedInput schema / properties / school_id / examples
        Added value: +[
        +  12345
        +]
      • addedInput schema / properties / trip_id / description
        Added value: +"Optional trip_id from save_trip."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "lead": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "message": {
        +      "type": "string"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedsave_trip10 fields changed
      • addedInput schema / properties / configuration / additionalProperties
        Added value: +true
      • addedInput schema / properties / configuration / description
        Added value: +"Same shape as the Extralingo school-page configurator: startDate (YYYY-MM-DD), students[] with courseId, weeks, optional accommodationGroupId, mealType, extras."
      • addedInput schema / properties / configuration / properties
        Added value: +{
        +  "accommodationGroupId": {
        +    "description": "Accommodation group id from list_accommodations (optional).",
        +    "type": "string"
        +  },
        +  "mealType": {
        +    "description": "Meal plan key when accommodation is selected.",
        +    "type": "string"
        +  },
        +  "startDate": {
        +    "description": "Course start calendar date (YYYY-MM-DD). Typically a Monday from list_starting_dates.",
        +    "examples": [
        +      "2026-09-07"
        +    ],
        +    "type": "string"
        +  },
        +  "students": {
        +    "description": "One object per traveller. courseId comes from list_courses.",
        +    "items": {
        +      "additionalProperties": true,
        +      "properties": {
        +        "courseId": {
        +          "description": "Course product id from list_courses for this school.",
        +          "type": "string"
        +        },
        +        "weeks": {
        +          "description": "Course duration in weeks.",
        +          "minimum": 1,
        +          "type": "integer"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "type": "array"
        +  }
        +}
      • addedInput schema / properties / email / description
        Added value: +"Optional student email for anonymous drafts. With OAuth, the verified account email is used."
      • addedInput schema / properties / locale / description
        Added value: +"Response language and site context. One of en, nl, da, sv."
      • addedInput schema / properties / locale / examples
        Added value: +[
        +  "en",
        +  "nl",
        +  "da",
        +  "sv"
        +]
      • addedInput schema / properties / school_id / description
        Added value: +"Craft CMS school entry id from search_language_schools hits (field school_id). Not the CRM UUID."
      • addedInput schema / properties / school_id / examples
        Added value: +[
        +  12345
        +]
      • changedInput schema / properties / trip_id / description
        Previous value: -"Omit to create. Pass to update the same URL."New value: +"Omit to create a new trip. Pass an existing trip_id from save_trip to update the same continue_url."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "configuration": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "continue_url": {
        +      "description": "Shareable Extralingo URL that restores configuration.",
        +      "type": "string"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "success": {
        +      "const": true
        +    },
        +    "summary": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "trip_id": {
        +      "type": "string"
        +    },
        +    "trip_url": {
        +      "type": "string"
        +    },
        +    "url": {
        +      "description": "Legacy alias of continue_url.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedsearch_destinations6 fields changed
      • addedInput schema / properties / language / description
        Added value: +"Optional language slug to restrict destinations (e.g. spanish)."
      • addedInput schema / properties / limit / description
        Added value: +"Maximum results (1–20)."
      • addedInput schema / properties / locale / description
        Added value: +"Response language and site context. One of en, nl, da, sv."
      • addedInput schema / properties / locale / examples
        Added value: +[
        +  "en",
        +  "nl",
        +  "da",
        +  "sv"
        +]
      • addedInput schema / properties / query / description
        Added value: +"Destination or school name prefix. Empty returns popular destinations."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "hits": {
        +      "description": "Destination matches.",
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "locale": {
        +      "enum": [
        +        "en",
        +        "nl",
        +        "da",
        +        "sv"
        +      ],
        +      "type": "string"
        +    },
        +    "query": {
        +      "type": "string"
        +    },
        +    "schools": {
        +      "description": "Optional school name fallback hits.",
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
    • Changedsearch_language_schools13 fields changed
      • addedInput schema / properties / cities / description
        Added value: +"City slug filters from get_school_filters."
      • addedInput schema / properties / cities / items / description
        Added value: +"City slug."
      • addedInput schema / properties / city / description
        Added value: +"Single city slug filter. Prefer cities[] for multiple."
      • addedInput schema / properties / country / description
        Added value: +"Country slug or name filter from get_school_filters."
      • addedInput schema / properties / course_type / description
        Added value: +"Course type slug from get_school_filters (e.g. intensive, private)."
      • changedInput schema / properties / language / description
        Previous value: -"Language slug, e.g. spanish"New value: +"Language slug filter from get_school_filters (e.g. spanish, english)."
      • addedInput schema / properties / language / examples
        Added value: +[
        +  "spanish"
        +]
      • addedInput schema / properties / limit / description
        Added value: +"Maximum schools to return (1–20)."
      • addedInput schema / properties / locale / description
        Added value: +"Response language and site context. One of en, nl, da, sv."
      • addedInput schema / properties / locale / examples
        Added value: +[
        +  "en",
        +  "nl",
        +  "da",
        +  "sv"
        +]
      • addedInput schema / properties / query / description
        Added value: +"Free-text search (school name, city, or keyword). Empty returns popular matches for the other filters."
      • addedInput schema / properties / query / examples
        Added value: +[
        +  "Barcelona intensive Spanish"
        +]
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "additionalProperties": true,
        +  "properties": {
        +    "data": {
        +      "additionalProperties": true,
        +      "description": "Meilisearch-style payload with hits[] (school_id, title, url, city, country, pricing hints).",
        +      "type": "object"
        +    },
        +    "success": {
        +      "const": true
        +    }
        +  },
        +  "required": [
        +    "success"
        +  ],
        +  "type": "object"
        +}
  3. 4 tool updates
    • Changedask_school_question2 fields changed
      • addedInput schema / properties / idempotencyKey
        Added value: +{
        +  "type": "string"
        +}
      • addedInput schema / properties / idempotency_key
        Added value: +{
        +  "description": "Optional. Same semantics as create_booking (24 hour replay window).",
        +  "type": "string"
        +}
    • Changedcreate_booking3 fields changed
      • changedInput schema / properties / idempotencyKey / description
        Previous value: -"Required. Reuse only to retry the same payload."New value: +"Optional. Alias of idempotency_key."
      • addedInput schema / properties / idempotency_key
        Added value: +{
        +  "description": "Optional. Same key + same payload within 24 hours replays the original response. A different payload with the same key fails.",
        +  "type": "string"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "idempotencyKey"
        -]
    • Changedrequest_discussion2 fields changed
      • addedInput schema / properties / idempotencyKey
        Added value: +{
        +  "type": "string"
        +}
      • addedInput schema / properties / idempotency_key
        Added value: +{
        +  "description": "Optional. Same semantics as create_booking (24 hour replay window).",
        +  "type": "string"
        +}
    • Changedrequest_quote2 fields changed
      • addedInput schema / properties / idempotencyKey
        Added value: +{
        +  "type": "string"
        +}
      • addedInput schema / properties / idempotency_key
        Added value: +{
        +  "description": "Optional. Same semantics as create_booking (24 hour replay window).",
        +  "type": "string"
        +}
  4. 17 tool updates
    • First observedask_school_question
    • First observedcalculate_trip_price
    • First observedcreate_booking
    • First observedemail_trip
    • First observedget_accommodation_details
    • First observedget_course_details
    • First observedget_school
    • First observedget_school_filters
    • First observedget_trip
    • First observedlist_accommodations
    • First observedlist_courses
    • First observedlist_starting_dates
    • First observedrequest_discussion
    • First observedrequest_quote
    • First observedsave_trip
    • First observedsearch_destinations
    • First observedsearch_language_schools

Publisher details

Operator
Extralingo B.V. · Publisher source
Vendor relationship
First-party
Trust center
Not applicable
Restrictions
No paid plan, API key or admin approval required. Search and catalogue tools (schools, courses, dates, accommodation, prices) are open without sign-in. Write tools (save/email trip, quote requests, school questions, discussions, bookings) require OAuth 2.1 sign-in with a free Extralingo account; the user verifies with a one-time code emailed by extralingo.com, no password. Dynamic client registration is supported, so no custom OAuth app is needed. Requests are rate-limited. Bookings are unpaid until the school confirms availability. Responses are available in English, Dutch, Danish and Swedish. · Publisher source

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    A
    maintenance
    Official MCP server for MAQAMI, a hotel and flight booking platform with 3M+ hotels. Search live hotel rates and flights, look up places, airports and hotel details, then prebook and book. Remote Streamable HTTP endpoint, no API key required.
    12
    41
    56 npm
    2
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Vacation rental software. A signed stay offer on the host's own domain. Agents discover a host domain, verify an Ed25519-signed offer (VRP), and send the guest to that domain to book and pay the host. Do not compare hosts or prices. HemmaBo + VRP, 6 runtime tools: 2 HemmaBo tools, 2 host onboarding tools, and 2 VRP verification tools. Not an OTA. Not a marketplace.
    7
    6
    280 npm
    4
    Apache 2.0
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources