Skip to main content
Glama

Quote a shipment

quote_shipment

Quote a shipment: create a quotation with carrier rates for an origin, a destination and parcel(s). It buys nothing. Each call creates a quotation record, except that an identical request from the same user within 10 minutes returns the earlier one with mcp_repeat; asked for another quote with nothing new, ask in one question what changes (origin, destination, parcel, carrier) instead of resending the same payload. Send address_from, address_to and either parcel or parcels. A postal_code per address is enough: estado, municipio and colonia are filled from the CP catalog and reported in mcp_autofilled, so do not ask for the colonia; mention the one picked. To insure the goods (SOS Protección), set package_protected and declared_value on the parcel and report the priced mcp_protection.protection_total as-is, never a computed percentage. order_id quotes an existing order; constraints / objective add mcp_ranking. Rates price asynchronously: while mcp_next_step.status is pending, poll get_quotation with the id. Missing address data answers status: "needs_input" naming the fields to ask for. Each rate carries pickup (the carrier collects at the origin), pickup_automatic and pickup_ocurre (drop-off at a branch): answer pickup questions from them. Entrega en sucursal / ocurre (the recipient collects at a carrier branch) is a purchase option of the rates whose office_delivery is true: mcp_office lists them and how to buy that way (list_office_points, then create_shipment with office_delivery). Offer it when the user mentions sucursal, ocurre or branch pickup; a rate with office_delivery_only is sold only that way. Only after the user picks a rate, buy it with create_shipment (that rate's id as rate_id); protect_shipment is for a label already bought. Returns the quotation with rates[] and mcp_* keys (mcp_office among them), or the needs_input payload.

Tool call template

This tool declares no required parameters. Add optional parameters from the input schema as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {},
    "name": "quote_shipment"
  }
}

Input Schema

NameRequiredDescriptionDefault
waitNoWait server-side for carrier prices before returning (default true). Set false to return the raw pending quotation immediately.
parcelNoSingle parcel (cm/kg)
parcelsNoMultiple parcels (alternative to `parcel`)
order_idNoOptional. Id of an existing order of this account to quote instead of inline addresses (from list_orders, get_order or create_order in this conversation). Never pass a shipment or quotation id.
productsNoLine items, needed for customs on international routes. Ignored when `parcels` is sent: put them in the first parcel's `products` instead.
objectiveNoHow to rank eligible rates (default balanced). Adds `mcp_ranking` to the result.
address_toNoDestination = who receives (destinatario/cliente). Same keys as address_from. In a return (devolución), the customer becomes address_from and the merchant address_to.
overweightNoMarks the quotation as an overweight re-quote (no quotation webhook, rates priced for the whole quotation, not per package). Leave unset for a normal quote; false is the default.
constraintsNoStructured requirements to rank rates against. Rates that violate any are moved to `mcp_ranking.unmet_constraints`.
address_fromNoOrigin = who sends (remitente/bodega del merchant). Never swap with address_to: 'mándale X a Juan' means Juan is address_to, not address_from. Map the user's words to these exact keys: estado→area_level1, municipio/alcaldía→area_level2, colonia→area_level3.
items_quantityNoStore-integration quotes only: number of items, packed into boxes from the connected store's package settings in place of `parcel`/`parcels`. Ignored without a connected store.
declared_amountNoAmount to COLLECT on delivery (cash on delivery). NOT the insured value: insure with the parcel's `package_protected` + `declared_value`.
timeout_secondsNoMax seconds to wait for prices when wait=true (default 20, capped at 30).
cash_on_deliveryNoQuote cash on delivery: the carrier collects `declared_amount` from the recipient. The purchase keeps what is set here.
requested_carriersNoRestrict to these carrier names
poll_interval_secondsNoSeconds between internal polls when wait=true (default 2).
recipient_pays_shippingNoWith cash_on_delivery, adds the shipping cost to the amount collected from the recipient

Output Schema

NameRequiredDescriptionDefault
idNoQuotation id: pass it to get_quotation
ratesNoOne entry per carrier service
reasonNoneeds_input only: address_fields_absent
statusNoneeds_input when address fields are missing (no quotation made)
messageNoneeds_input only: what went wrong
missingNoneeds_input only: missing fields per address
order_idNoOrder quoted, when order_id was given
packagesNoParcels as quoted
providedNoneeds_input only: the addresses as received
field_helpNoneeds_input only: what each missing field means
mcp_repeatNoquote_shipment only: present when an identical request from the same user within 10 minutes returned the earlier quotation
mcp_rankingNoPresent only when constraints or objective were given
is_completedNoTrue once no rate is pending
mcp_next_stepNoServer-added hint naming the next tool to call; absent when there is no next step
how_to_resolveNoneeds_input only: how to obtain the missing values
mcp_autofilledNoAddress fields completed from the postal code catalog, per address_from / address_to ({ filled, alternatives }); absent when nothing was filled
mcp_protectionNoquote_shipment only: the protection priced in this quotation
quotation_scopeNonational or international
ambiguous_fieldsNoneeds_input only
field_provenanceNoneeds_input only: low-confidence fields to confirm
retry_instructionNoneeds_input only: when to call quote_shipment again
suggested_questionNoneeds_input only: question to relay to the user

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed14 schema fields changed
    • changedInput schema / properties / address_from / properties / apartment_number / description
      Previous value: -"Número interior / apartment or suite (optional)"New value: +"Número interior / apartment or suite (optional), 10 characters max"
    • changedInput schema / properties / address_from / properties / area_level3 / description
      Previous value: -"Colonia / neighborhood. OPTIONAL — do NOT ask the user for it upfront: it is auto-resolved from postal_code (auto-picks when the CP has one colonia; picks the first and reports alternatives otherwise). Provide it only if the user already said it."New value: +"Colonia / neighborhood. OPTIONAL — do NOT ask the user for it upfront: it is auto-resolved from postal_code (auto-picks when the CP has one colonia; picks the first and reports alternatives otherwise). Provide it only if the user already said it. At least 2 characters."
    • changedInput schema / properties / address_from / properties / company / description
      Previous value: -"Company name when the party is a business (optional)"New value: +"Company name when the party is a business (optional), 60 characters max"
    • changedInput schema / properties / address_from / properties / name / description
      Previous value: -"Contact full name"New value: +"Contact full name, 3 to 30 characters"
    • changedInput schema / properties / address_from / properties / phone / description
      Previous value: -"Not needed to quote, but REQUIRED later to buy the label — include it whenever the user already gave it"New value: +"Not needed to quote, but REQUIRED later to buy the label (10 digits MX) — include it whenever the user already gave it"
    • changedInput schema / properties / address_from / properties / reference / description
      Previous value: -"Delivery reference/notes. MAX 30 chars origin / 40 destination — truncate proactively."New value: +"Delivery reference/notes. MAX 30 chars origin / 40 destination — truncate proactively. Not needed to quote, but REQUIRED on both origin and destination to buy the label (except BR) — include it whenever the user already gave it."
    • changedInput schema / properties / address_from / properties / street1 / description
      Previous value: -"Calle y número / street incl. number"New value: +"Calle y número / street incl. number, 45 characters max in MX, e.g. 'Av. Insurgentes Sur 100'. Never the colonia, municipio/alcaldía/city or estado here: they have their own fields (area_level3 / area_level2 / area_level1) and resolve from postal_code. Collect the address in pieces (street + number, CP); never ask the user for 'calle, número, colonia y ciudad' as one field."
    • changedInput schema / properties / address_to / properties / apartment_number / description
      Previous value: -"Número interior / apartment or suite (optional)"New value: +"Número interior / apartment or suite (optional), 10 characters max"
    • changedInput schema / properties / address_to / properties / area_level3 / description
      Previous value: -"Colonia / neighborhood. OPTIONAL — do NOT ask the user for it upfront: it is auto-resolved from postal_code (auto-picks when the CP has one colonia; picks the first and reports alternatives otherwise). Provide it only if the user already said it."New value: +"Colonia / neighborhood. OPTIONAL — do NOT ask the user for it upfront: it is auto-resolved from postal_code (auto-picks when the CP has one colonia; picks the first and reports alternatives otherwise). Provide it only if the user already said it. At least 2 characters."
    • changedInput schema / properties / address_to / properties / company / description
      Previous value: -"Company name when the party is a business (optional)"New value: +"Company name when the party is a business (optional), 60 characters max"
    • changedInput schema / properties / address_to / properties / name / description
      Previous value: -"Contact full name"New value: +"Contact full name, 3 to 30 characters"
    • changedInput schema / properties / address_to / properties / phone / description
      Previous value: -"Not needed to quote, but REQUIRED later to buy the label — include it whenever the user already gave it"New value: +"Not needed to quote, but REQUIRED later to buy the label (10 digits MX) — include it whenever the user already gave it"
    • changedInput schema / properties / address_to / properties / reference / description
      Previous value: -"Delivery reference/notes. MAX 30 chars origin / 40 destination — truncate proactively."New value: +"Delivery reference/notes. MAX 30 chars origin / 40 destination — truncate proactively. Not needed to quote, but REQUIRED on both origin and destination to buy the label (except BR) — include it whenever the user already gave it."
    • changedInput schema / properties / address_to / properties / street1 / description
      Previous value: -"Calle y número / street incl. number"New value: +"Calle y número / street incl. number, 45 characters max in MX, e.g. 'Av. Insurgentes Sur 100'. Never the colonia, municipio/alcaldía/city or estado here: they have their own fields (area_level3 / area_level2 / area_level1) and resolve from postal_code. Collect the address in pieces (street + number, CP); never ask the user for 'calle, número, colonia y ciudad' as one field."
  2. Changed34 schema fields changed
    • addedInput schema / properties / address_from / properties / apartment_number / description
      Added value: +"Número interior / apartment or suite (optional)"
    • addedInput schema / properties / address_from / properties / company / description
      Added value: +"Company name when the party is a business (optional)"
    • addedInput schema / properties / address_to / properties / apartment_number / description
      Added value: +"Número interior / apartment or suite (optional)"
    • addedInput schema / properties / address_to / properties / company / description
      Added value: +"Company name when the party is a business (optional)"
    • addedInput schema / properties / cash_on_delivery / description
      Added value: +"Quote cash on delivery: the carrier collects `declared_amount` from the recipient. The purchase keeps what is set here."
    • addedInput schema / properties / items_quantity / description
      Added value: +"Store-integration quotes only: number of items, packed into boxes from the connected store's package settings in place of `parcel`/`parcels`. Ignored without a connected store."
    • addedInput schema / properties / overweight / description
      Added value: +"Marks the quotation as an overweight re-quote (no quotation webhook, rates priced for the whole quotation, not per package). Leave unset for a normal quote; false is the default."
    • changedInput schema / properties / parcel / properties / height / description
      Previous value: -"cm"New value: +"Height in cm"
    • changedInput schema / properties / parcel / properties / length / description
      Previous value: -"cm"New value: +"Length in cm"
    • addedInput schema / properties / parcel / properties / package_type / description
      Added value: +"Packaging code from list_packagings (optional to quote; create_shipment needs one)"
    • changedInput schema / properties / parcel / properties / weight / description
      Previous value: -"kg"New value: +"Weight in kg"
    • changedInput schema / properties / parcel / properties / width / description
      Previous value: -"cm"New value: +"Width in cm"
    • addedInput schema / properties / parcels / items / properties / consignment_note / description
      Added value: +"Carta-porte SAT code from list_consignment_notes (optional to quote; create_shipment needs one)"
    • changedInput schema / properties / parcels / items / properties / height / description
      Previous value: -"cm"New value: +"Height in cm"
    • changedInput schema / properties / parcels / items / properties / length / description
      Previous value: -"cm"New value: +"Length in cm"
    • changedInput schema / properties / parcels / items / properties / package_protected / description
      Previous value: -"Insure this parcel (SOS Protección). The cost is priced by the account's configuration and returned in the quotation; never compute it."New value: +"Insure this parcel (SOS Protección); never compute its cost. In `parcels`, an omitted value quotes protection by default with the account's suggested declared value: send false to quote without it."
    • addedInput schema / properties / parcels / items / properties / package_type / description
      Added value: +"Packaging code from list_packagings (optional to quote; create_shipment needs one)"
    • addedInput schema / properties / parcels / items / properties / products / description
      Added value: +"Items packed in this parcel. Only the first parcel's products are read, and they replace the top-level `products`."
    • addedInput schema / properties / parcels / items / properties / products / items / properties / country_code / description
      Added value: +"Country of origin of the item, ISO-3166-1 alpha-2 (e.g. 'MX')"
    • addedInput schema / properties / parcels / items / properties / products / items / properties / description_en / description
      Added value: +"What the item is, in English, for customs on international routes"
    • changedInput schema / properties / parcels / items / properties / products / items / properties / hs_code / description
      Previous value: -"Harmonized System code (international)"New value: +"Harmonized System tariff code, for customs on international routes"
    • addedInput schema / properties / parcels / items / properties / products / items / properties / price / description
      Added value: +"Unit price in the account's currency (multiplied by quantity)"
    • changedInput schema / properties / parcels / items / properties / products / items / properties / product_id / description
      Previous value: -"Catalog product id: data[].id from list_products"New value: +"Catalog product id: data[].id from list_products. When it resolves, hs_code, description_en, country_code and price come from the catalog; send only quantity."
    • addedInput schema / properties / parcels / items / properties / products / items / properties / quantity / description
      Added value: +"Units of this item"
    • changedInput schema / properties / parcels / items / properties / weight / description
      Previous value: -"kg"New value: +"Weight in kg"
    • changedInput schema / properties / parcels / items / properties / width / description
      Previous value: -"cm"New value: +"Width in cm"
    • changedInput schema / properties / products / description
      Previous value: -"Line items"New value: +"Line items, needed for customs on international routes. Ignored when `parcels` is sent: put them in the first parcel's `products` instead."
    • addedInput schema / properties / products / items / properties / country_code / description
      Added value: +"Country of origin of the item, ISO-3166-1 alpha-2 (e.g. 'MX')"
    • addedInput schema / properties / products / items / properties / description_en / description
      Added value: +"What the item is, in English, for customs on international routes"
    • changedInput schema / properties / products / items / properties / hs_code / description
      Previous value: -"Harmonized System code (international)"New value: +"Harmonized System tariff code, for customs on international routes"
    • addedInput schema / properties / products / items / properties / price / description
      Added value: +"Unit price in the account's currency (multiplied by quantity)"
    • changedInput schema / properties / products / items / properties / product_id / description
      Previous value: -"Catalog product id: data[].id from list_products"New value: +"Catalog product id: data[].id from list_products. When it resolves, hs_code, description_en, country_code and price come from the catalog; send only quantity."
    • addedInput schema / properties / products / items / properties / quantity / description
      Added value: +"Units of this item"
    • addedInput schema / properties / recipient_pays_shipping / description
      Added value: +"With cash_on_delivery, adds the shipping cost to the amount collected from the recipient"
  3. Changed8 schema fields changed
    • changedInput schema / properties / address_from / description
      Previous value: -"ORIGIN = who SENDS (remitente/bodega del merchant). Never swap with address_to: 'mándale X a Juan' means Juan is address_to, not address_from. Map the user's words to these EXACT keys: estado→area_level1, municipio/alcaldía→area_level2, colonia→area_level3."New value: +"Origin = who sends (remitente/bodega del merchant). Never swap with address_to: 'mándale X a Juan' means Juan is address_to, not address_from. Map the user's words to these exact keys: estado→area_level1, municipio/alcaldía→area_level2, colonia→area_level3."
    • changedInput schema / properties / address_from / properties / address_template_id / description
      Previous value: -"Use a saved template instead of inline fields"New value: +"Use a saved address instead of inline fields: data[].id from list_address_templates or data.id from create_address_template"
    • changedInput schema / properties / address_to / description
      Previous value: -"DESTINATION = who RECEIVES (destinatario/cliente). Same keys as address_from. In a return (devolución), the customer becomes address_from and the merchant address_to."New value: +"Destination = who receives (destinatario/cliente). Same keys as address_from. In a return (devolución), the customer becomes address_from and the merchant address_to."
    • changedInput schema / properties / address_to / properties / address_template_id / description
      Previous value: -"Use a saved template instead of inline fields"New value: +"Use a saved address instead of inline fields: data[].id from list_address_templates or data.id from create_address_template"
    • changedInput schema / properties / order_id / description
      Previous value: -"Quote an existing order instead of inline addresses"New value: +"Optional. Id of an existing order of this account to quote instead of inline addresses (from list_orders, get_order or create_order in this conversation). Never pass a shipment or quotation id."
    • addedInput schema / properties / parcels / items / properties / products / items / properties / product_id / description
      Added value: +"Catalog product id: data[].id from list_products"
    • addedInput schema / properties / products / items / properties / product_id / description
      Added value: +"Catalog product id: data[].id from list_products"
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "description": "A quotation, or a needs_input payload when address fields are missing",
      +  "properties": {
      +    "ambiguous_fields": {
      +      "description": "needs_input only",
      +      "items": {},
      +      "type": "array"
      +    },
      +    "field_help": {
      +      "description": "needs_input only: what each missing field means"
      +    },
      +    "field_provenance": {
      +      "description": "needs_input only: low-confidence fields to confirm"
      +    },
      +    "how_to_resolve": {
      +      "description": "needs_input only: how to obtain the missing values"
      +    },
      +    "id": {
      +      "description": "Quotation id: pass it to get_quotation"
      +    },
      +    "is_completed": {
      +      "description": "True once no rate is pending"
      +    },
      +    "mcp_autofilled": {
      +      "description": "Address fields completed from the postal code catalog, per address_from / address_to ({ filled, alternatives }); absent when nothing was filled"
      +    },
      +    "mcp_next_step": {
      +      "description": "Server-added hint naming the next tool to call; absent when there is no next step",
      +      "properties": {
      +        "arguments": {
      +          "description": "Arguments to pass to that tool, when known"
      +        },
      +        "collect_if_missing": {
      +          "description": "Inputs still to gather from the user before calling that tool, when any",
      +          "items": {},
      +          "type": "array"
      +        },
      +        "message": {
      +          "description": "Instruction for the agent"
      +        },
      +        "status": {
      +          "description": "State that motivated the hint, e.g. 'pending' or 'priced'"
      +        },
      +        "tool": {
      +          "description": "Name of the tool to call next"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "mcp_protection": {
      +      "description": "quote_shipment only: the protection priced in this quotation",
      +      "properties": {
      +        "declared_value": {
      +          "description": "Insured value across the parcels; 0 when unprotected"
      +        },
      +        "hint": {
      +          "description": "How to report (never compute) the protection cost"
      +        },
      +        "protected": {
      +          "description": "Whether any parcel was quoted with protection"
      +        },
      +        "protection_total": {
      +          "description": "Protection cost, as priced by the account's configuration"
      +        },
      +        "source": {
      +          "description": "Who priced the protection"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "mcp_ranking": {
      +      "description": "Present only when constraints or objective were given",
      +      "properties": {
      +        "objective": {
      +          "description": "cheapest, fastest, most_reliable or balanced"
      +        },
      +        "ranked": {
      +          "description": "Eligible rates, best first, with rank_reason",
      +          "items": {
      +            "properties": {
      +              "amount": {
      +                "description": "Carrier price before fees, as a numeric string"
      +              },
      +              "currency_code": {
      +                "description": "Currency of the amounts, e.g. MXN"
      +              },
      +              "days": {
      +                "description": "Estimated delivery days"
      +              },
      +              "error_messages": {
      +                "description": "Why the rate is unavailable; empty when it priced"
      +              },
      +              "id": {
      +                "description": "Rate id: the rate_id for create_shipment and list_office_points"
      +              },
      +              "insurable": {
      +                "description": "Whether protection can be added to this rate"
      +              },
      +              "office_delivery": {
      +                "description": "Recipient can collect at a carrier office (list_office_points delivery)"
      +              },
      +              "office_delivery_only": {
      +                "description": "Office delivery is the only route for this destination"
      +              },
      +              "office_pickup": {
      +                "description": "Sender can drop off at a carrier office (list_office_points pickup)"
      +              },
      +              "pickup": {
      +                "description": "Whether the service offers a carrier pickup (see schedule_pickup)"
      +              },
      +              "pickup_automatic": {
      +                "description": "Whether the carrier pickup is booked automatically with the label"
      +              },
      +              "pickup_ocurre": {
      +                "description": "Whether the sender drops the package off at a carrier branch (ocurre)"
      +              },
      +              "protection_value_total": {
      +                "description": "Protection this rate charges, priced by the account's configuration"
      +              },
      +              "provider_display_name": {
      +                "description": "Carrier name to show the user"
      +              },
      +              "provider_name": {
      +                "description": "Carrier name, e.g. fedex or estafeta"
      +              },
      +              "provider_service_code": {
      +                "description": "Carrier service code"
      +              },
      +              "provider_service_name": {
      +                "description": "Carrier service (e.g. Express, Terrestre)"
      +              },
      +              "rank_reason": {
      +                "description": "Only inside mcp_ranking.ranked: why it ranks there"
      +              },
      +              "status": {
      +                "description": "Pricing state; pending while the carrier is still pricing"
      +              },
      +              "success": {
      +                "description": "False when the carrier could not price it (see error_messages)"
      +              },
      +              "total": {
      +                "description": "Price the purchase charges, as a numeric string (coupon already applied)"
      +              },
      +              "total_value_with_protection": {
      +                "description": "total including declared protection"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "unmet_constraints": {
      +          "description": "Rates that violate a constraint",
      +          "items": {
      +            "properties": {
      +              "rate_id": {
      +                "description": "Rate that violates a constraint"
      +              },
      +              "violations": {
      +                "description": "Constraints it misses",
      +                "items": {},
      +                "type": "array"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "type": "array"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "mcp_repeat": {
      +      "description": "quote_shipment only: present when an identical request from the same user within 10 minutes returned the earlier quotation",
      +      "properties": {
      +        "hint": {
      +          "description": "Ask the user what changes before quoting again"
      +        },
      +        "quotation_id": {
      +          "description": "The earlier quotation returned again"
      +        },
      +        "repeated": {
      +          "description": "true: no new quotation was created"
      +        },
      +        "seconds_ago": {
      +          "description": "How long ago it was created"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "needs_input only: what went wrong"
      +    },
      +    "missing": {
      +      "description": "needs_input only: missing fields per address"
      +    },
      +    "order_id": {
      +      "description": "Order quoted, when order_id was given"
      +    },
      +    "packages": {
      +      "description": "Parcels as quoted",
      +      "items": {},
      +      "type": "array"
      +    },
      +    "provided": {
      +      "description": "needs_input only: the addresses as received"
      +    },
      +    "quotation_scope": {
      +      "description": "national or international"
      +    },
      +    "rates": {
      +      "description": "One entry per carrier service",
      +      "items": {
      +        "properties": {
      +          "amount": {
      +            "description": "Carrier price before fees, as a numeric string"
      +          },
      +          "currency_code": {
      +            "description": "Currency of the amounts, e.g. MXN"
      +          },
      +          "days": {
      +            "description": "Estimated delivery days"
      +          },
      +          "error_messages": {
      +            "description": "Why the rate is unavailable; empty when it priced"
      +          },
      +          "id": {
      +            "description": "Rate id: the rate_id for create_shipment and list_office_points"
      +          },
      +          "insurable": {
      +            "description": "Whether protection can be added to this rate"
      +          },
      +          "office_delivery": {
      +            "description": "Recipient can collect at a carrier office (list_office_points delivery)"
      +          },
      +          "office_delivery_only": {
      +            "description": "Office delivery is the only route for this destination"
      +          },
      +          "office_pickup": {
      +            "description": "Sender can drop off at a carrier office (list_office_points pickup)"
      +          },
      +          "pickup": {
      +            "description": "Whether the service offers a carrier pickup (see schedule_pickup)"
      +          },
      +          "pickup_automatic": {
      +            "description": "Whether the carrier pickup is booked automatically with the label"
      +          },
      +          "pickup_ocurre": {
      +            "description": "Whether the sender drops the package off at a carrier branch (ocurre)"
      +          },
      +          "protection_value_total": {
      +            "description": "Protection this rate charges, priced by the account's configuration"
      +          },
      +          "provider_display_name": {
      +            "description": "Carrier name to show the user"
      +          },
      +          "provider_name": {
      +            "description": "Carrier name, e.g. fedex or estafeta"
      +          },
      +          "provider_service_code": {
      +            "description": "Carrier service code"
      +          },
      +          "provider_service_name": {
      +            "description": "Carrier service (e.g. Express, Terrestre)"
      +          },
      +          "rank_reason": {
      +            "description": "Only inside mcp_ranking.ranked: why it ranks there"
      +          },
      +          "status": {
      +            "description": "Pricing state; pending while the carrier is still pricing"
      +          },
      +          "success": {
      +            "description": "False when the carrier could not price it (see error_messages)"
      +          },
      +          "total": {
      +            "description": "Price the purchase charges, as a numeric string (coupon already applied)"
      +          },
      +          "total_value_with_protection": {
      +            "description": "total including declared protection"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "reason": {
      +      "description": "needs_input only: address_fields_absent"
      +    },
      +    "retry_instruction": {
      +      "description": "needs_input only: when to call quote_shipment again"
      +    },
      +    "status": {
      +      "description": "needs_input when address fields are missing (no quotation made)"
      +    },
      +    "suggested_question": {
      +      "description": "needs_input only: question to relay to the user"
      +    }
      +  },
      +  "type": "object"
      +}
  4. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only declare readOnlyHint=false, openWorldHint=true, idempotentHint=false and destructiveHint=false; the description adds the non-obvious traits: a quotation record is created per call, an identical request from the same user within 10 minutes returns the earlier one with `mcp_repeat`, and prices arrive asynchronously requiring polling of get_quotation while status is pending. It further discloses the `needs_input` failure mode and the autofill reporting via `mcp_autofilled`, none of which appear in 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?

Purpose and the key 'it buys nothing / use create_shipment to buy' contrast are front-loaded, and nearly every sentence carries operational instruction. Some paragraphs are dense run-ons packing repeat handling, insurance, order_id, async polling and needs_input into one block, which makes it slower to scan than it needs to be.

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

Completeness5/5

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

For a 17-parameter, nested-object tool with async pricing, the description covers the essential runtime story: async pending status and polling, needs_input recovery, repeat dedupe, autofill behavior, insurance pricing rules, and the office-delivery branch. With an output schema present it correctly avoids describing return shapes in detail, only naming `rates[]` and the mcp_* keys.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, and the description genuinely rises above it by telling the agent how to use the parameters: 'A postal_code per address is enough ... do not ask for the colonia,' and 'set `package_protected` and `declared_value` on the parcel.' It also explains that `order_id` quotes an existing order and that `constraints`/`objective` add `mcp_ranking`; it does not, however, touch several other notable params such as wait, timeout_seconds, or requested_carriers, leaving those to the schema.

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

Purpose5/5

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

The first sentence states a specific verb and resource — 'create a quotation with carrier rates for an origin, a destination and parcel(s)' — and immediately bounds it with 'It buys nothing,' which separates it from create_shipment. Later sentences name create_shipment and protect_shipment as the alternatives, so the agent can distinguish siblings without opening their schemas.

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

Usage Guidelines5/5

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

Explicit routing is given: quote here, and 'Only after the user picks a rate, buy it with create_shipment (that rate's id as rate_id); protect_shipment is for a label already bought.' It also prescribes the repeat-request path (ask one question about what changes rather than resending) and when to offer office delivery ('when the user mentions sucursal, ocurre or branch pickup').

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources