Skip to main content
Glama

ADR 1.1.3.6 Exemption Calculator

adr_exemption_calculator
Read-onlyIdempotent

Calculate ADR 1.1.3.6 "small load" exemption points for a dangerous-goods load and say whether it qualifies. Each substance's transport category (Table A column (15), 0-4) sets a points multiplier (1.1.3.6.4: category 1 x50, 2 x3, 3 x1, 4 x0; the nine ADR 1.1.3.6.3 note-a entries UN 0081/0082/0084/0241/0331/0332/0482/1005/1017 are x20); points = quantity x multiplier. The rule (1.1.3.6.2), for dangerous goods carried in packages: goods of ONE transport category qualify when their TOTAL on the transport unit stays within that category's 1.1.3.6.3 column (3) maximum — category 1: 20, 2: 333, 3: 1,000 (kg or L); note-a entries 50 kg; category 4 unlimited; category 0: 0 — however it is split across lines; goods of DIFFERENT categories qualify when the 1.1.3.6.4 points sum does not exceed 1,000. This calculator also holds every line, and every substance summed across its lines, to its category maximum — on a mixed load that is stricter than 1.1.3.6.4 (the conservative side). Transport category 0 substances can NEVER use this exemption — has_category_zero flags them.

Provide un_number + quantity for a single substance, OR items[] for a load — never both: every field of the single-substance form (un_number, quantity, packing_group, variant_index, unit, basis) sent beside items[] is refused (the API answers 400 naming the field), never dropped — put it on the item it belongs to, a substance as an item of its own. Quantities are in kg or litres per the substance's ADR unit. un_number also takes an ID-prefixed air-only number (e.g. "ID8000") — see Routing.

Multi-variant UNs: a UN number with more than one ADR Table A row (packing group / concentration variant — e.g. UN 1789 PG II vs PG III have different transport categories) needs packing_group (I|II|III) or variant_index (from adr_lookup) to pin one row. A packing_group that still leaves several rows is enough when those rows agree on class, transport category, scope and the 1.1.3.6.3 counted dimension (UN 1790 PG I: two concentration bands, both category 1) — the verdict is returned with items[].equivalent_variants + variant_note naming the rows it holds for; only when the rows DISAGREE (UN 2215 PG III: MOLTEN is category 0, the solid category 3) does it still ask for variant_index, and candidates[] then lists only that packing group's rows. With no disambiguator at all: a single-line call, or a load where EVERY line is ambiguous, returns blocking_errors[AMBIGUOUS_UN_VARIANT] + human_review_required + candidates[] (each candidate's item_index, un_number, variant_index, packing_group, proper_shipping_name, transport_category, multiplier) and NO verdict — blocking_errors is in the text content as well as structuredContent; a MIXED load withholds only the ambiguous line (items[].withheld true, points null, row fields null) while every other line keeps its points; total_points is null (1.1.3.6.4 sums every line, one term is unknown) and exempt is null UNLESS the resolved lines alone already disqualify the load — a CARRIAGE PROHIBITED entry, a category 0 entry, a per-substance maximum exceeded, or a partial sum already over 1,000 — in which case exempt is false with the ladder message (and carriage_prohibited true where that is the reason), because no packing group can undo those. warnings state the resolved lines' partial sum, candidates[] carry expected_unit (the 1.1.3.6.3 counted dimension — the only difference for UN 3375 PG II, liquid in L vs solid in kg), and the envelope carries human_review_required + candidates[] plus one AMBIGUOUS_UN_VARIANT warning per withheld line. Never a silently guessed row. Single-row UNs are unchanged.

Scope verdicts: Table A rows listed "NOT SUBJECT TO ADR" or "CARRIAGE PROHIBITED" never enter the points math. An all-not-subject load (e.g. UN 1845 dry ice) returns not_subject_to_adr true with a dedicated message ("Not subject to ADR (road). Section 5.5.3 applies: ...") and, for dry ice, conditions[] quoting the ADR 2025 section 5.5.3 requirements verbatim (ventilation, package marking, warning mark, documentation, training). A load containing a CARRIAGE PROHIBITED entry returns exempt false with carriage_prohibited true. In a mixed load, not-subject items are excluded from the points and the exclusion is stated in warnings.

Routing: every returned line carries state, in the words the FreightUtils document check uses — COUNTED (evaluated on one Table A row: its points, or a category 0 / CARRIAGE PROHIBITED row that settles the load), AIR_ONLY_ID, NOT_SUBJECT_TO_ADR, or BLOCKED (no points from the line as sent — withheld, basis_mismatch or category_unresolved; the line's own flag says which). AIR_ONLY_ID: an ID-prefixed number such as ID 8000 (consumer commodity) is an air-only identifier with no ADR Table A entry, so it gives no transport category and nothing is counted for it (items[].air_only_id true, row fields null). Each such line carries a warning stating the condition that 0 rests on: it is the ADR answer when the packages are limited quantities to the ICAO Technical Instructions (3.4.9 and 3.4.10 deem them to meet 3.4.1-3.4.4; goods exempted under 1.1.3.4.2 are not taken into account by 1.1.3.6.5) — goods not in such packages must be entered under their own UN numbers. Only the ID prefix makes a line air-only — an ID number is never read as the UN number with the same digits — and an all-air-only load returns total_points 0, exempt true with its own message, never "1.1.3.6 exemption applies" and never not_subject_to_adr.

Behavior: deterministic points arithmetic over ADR 2025 reference data; a UN that cannot be found returns blocking_errors (NOT_FOUND); exempt is the overall verdict. Fields are checked by name: a field the tool does not read is refused with a tool error naming it and listing the accepted ones, never ignored. Rate-limited: a limit error carries reset_at, the UTC time the allowance resets.

Returns: items[] (each with state, packing_group, variant_index, transport_category, multiplier, points, air_only_id on an ID-prefixed line, quantity_unit/quantity_basis/expected_unit when a unit or basis was declared, scope flags where applicable, withheld + ambiguity_reason on an unpinned multi-variant line, and equivalent_variants + variant_note when a packing group resolved by equivalence), total_points (NULL when no verdict was reached), threshold (1000), exempt (NULL when no verdict was reached — never false as a stand-in), has_category_zero, has_quantity_exceedance, warnings, message, human_review_required + candidates[] when any line is withheld, and — on scope verdicts — not_subject_to_adr/conditions_ref/conditions[]/carriage_prohibited under result — or, when every line is ambiguous, human_review_required + candidates[] with blocking_errors, plus confidence, _source and citation (the FreightUtils v1 response envelope).

Limitations: a deterministic calculation over reference data, not legal advice — 1.1.3.6 relieves goods carried in packages only (not in bulk or in tanks), and this calculator takes no packaging input; even exempt loads keep core duties (packaging, marking, documentation), and mixed-packing rules still apply; verify against the current UNECE ADR text.

Related: adr_lookup (per-substance data incl. transport category + variant_index), adr_lq_eq_check (the LQ/EQ relief routes instead of 1.1.3.6).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
unitNoOPTIONAL. The dimension `quantity` is stated in — 'L' or 'kg'. Omit it and the number is taken as already on the ADR 1.1.3.6.3 basis (the historical contract). Supply it and it is CHECKED against the dimension 1.1.3.6.3 counts for the row: litres for liquids and for compressed or adsorbed gases, kilograms for solids, liquefied/refrigerated/dissolved gases and articles. A mismatch returns no points and says which dimension the entry is counted in. Single-substance form only: sent beside items[] it is refused (INVALID_INPUT) — set it on each item.
basisNoOPTIONAL. 'net' or 'gross'. ADR 1.1.3.6.3 counts the dangerous goods themselves, never the packaging, so a figure declared 'gross' returns no points in ANY unit — send the net quantity instead. Single-substance form only: sent beside items[] it is refused (INVALID_INPUT) — set it on each item.
itemsNoArray of items for mixed-load check
quantityNoQuantity on the ADR 1.1.3.6.3 basis: net kg for solids and liquefied, refrigerated or dissolved gases; litres for liquids; receptacle water capacity in litres for compressed or adsorbed gases and chemicals under pressure; articles as the mass of the articles without their packagings, in kg.
un_numberNoUN number for single check (4 digits, optionally "UN"-prefixed) — or an ID-prefixed air-only number such as "ID8000", which has no ADR Table A entry and is routed AIR_ONLY_ID (nothing counted under 1.1.3.6 — the ADR answer for limited-quantity packages to the ICAO Technical Instructions, 3.4.9 / 3.4.10 / 1.1.3.6.5, as the warning on that line states). Single-substance form only: sent beside items[] it is refused (INVALID_INPUT) — send the substance as an item.
packing_groupNoPacking group (I, II or III) — only needed to disambiguate a UN that has more than one ADR Table A row (e.g. UN 1789). Ignored for single-row UNs. Single-substance form only: sent beside items[] it is refused (INVALID_INPUT) — set it on each item.
variant_indexNoADR Table A variant index (as returned by adr_lookup) — pins one row when a UN has several variants that share a packing group (e.g. concentration bands). Ignored for single-row UNs. Single-substance form only: sent beside items[] it is refused (INVALID_INPUT) — set it on each item.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
okYes
resultYes
_sourceYes
citationYes
validityNo
warningsNo
confidenceYes
blocking_errorsNo
envelope_versionYes
normalized_inputNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / items / items / properties / un_number / pattern
      Previous value: -"^(?:(?:UN)?\\d{4}|\\s*ID\\s*[-:.]?\\s*\\d{4}\\s*)$"New value: +"^(?:\\s*(?:UN\\s*)?\\d{4}\\s*|\\s*ID\\s*[-:.]?\\s*\\d{4}\\s*)$"
    • changedInput schema / properties / un_number / pattern
      Previous value: -"^(?:(?:UN)?\\d{4}|\\s*ID\\s*[-:.]?\\s*\\d{4}\\s*)$"New value: +"^(?:\\s*(?:UN\\s*)?\\d{4}\\s*|\\s*ID\\s*[-:.]?\\s*\\d{4}\\s*)$"
  2. Changed3 schema fields changed
    • addedInput schema / properties / items / items / properties / quantity / maximum
      Added value: +1000000000
    • addedInput schema / properties / items / minItems
      Added value: +1
    • addedInput schema / properties / quantity / maximum
      Added value: +1000000000
  3. Changed2 schema fields changed
    • addedInput schema / additionalProperties
      Added value: +false
    • addedInput schema / properties / items / items / additionalProperties
      Added value: +false
  4. Changed8 schema fields changed
    • changedInput schema / properties / basis / description
      Previous value: -"OPTIONAL. 'net' or 'gross'. ADR 1.1.3.6.3 counts the dangerous goods themselves, never the packaging, so a figure declared 'gross' returns no points in ANY unit — send the net quantity instead."New value: +"OPTIONAL. 'net' or 'gross'. ADR 1.1.3.6.3 counts the dangerous goods themselves, never the packaging, so a figure declared 'gross' returns no points in ANY unit — send the net quantity instead. Single-substance form only: sent beside items[] it is refused (INVALID_INPUT) — set it on each item."
    • changedInput schema / properties / items / items / properties / un_number / description
      Previous value: -"UN number (4 digits, optionally \"UN\"-prefixed)"New value: +"UN number (4 digits, optionally \"UN\"-prefixed) — or an ID-prefixed air-only number such as \"ID8000\" (routed AIR_ONLY_ID; the warning on that line states the limited-quantity condition the 0 rests on)"
    • changedInput schema / properties / items / items / properties / un_number / pattern
      Previous value: -"^(UN)?\\d{4}$"New value: +"^(?:(?:UN)?\\d{4}|\\s*ID\\s*[-:.]?\\s*\\d{4}\\s*)$"
    • changedInput schema / properties / packing_group / description
      Previous value: -"Packing group (I, II or III) — only needed to disambiguate a UN that has more than one ADR Table A row (e.g. UN 1789). Ignored for single-row UNs."New value: +"Packing group (I, II or III) — only needed to disambiguate a UN that has more than one ADR Table A row (e.g. UN 1789). Ignored for single-row UNs. Single-substance form only: sent beside items[] it is refused (INVALID_INPUT) — set it on each item."
    • changedInput schema / properties / un_number / description
      Previous value: -"UN number for single check (4 digits, optionally \"UN\"-prefixed)"New value: +"UN number for single check (4 digits, optionally \"UN\"-prefixed) — or an ID-prefixed air-only number such as \"ID8000\", which has no ADR Table A entry and is routed AIR_ONLY_ID (nothing counted under 1.1.3.6 — the ADR answer for limited-quantity packages to the ICAO Technical Instructions, 3.4.9 / 3.4.10 / 1.1.3.6.5, as the warning on that line states). Single-substance form only: sent beside items[] it is refused (INVALID_INPUT) — send the substance as an item."
    • changedInput schema / properties / un_number / pattern
      Previous value: -"^(UN)?\\d{4}$"New value: +"^(?:(?:UN)?\\d{4}|\\s*ID\\s*[-:.]?\\s*\\d{4}\\s*)$"
    • changedInput schema / properties / unit / description
      Previous value: -"OPTIONAL. The dimension `quantity` is stated in — 'L' or 'kg'. Omit it and the number is taken as already on the ADR 1.1.3.6.3 basis (the historical contract). Supply it and it is CHECKED against the dimension 1.1.3.6.3 counts for the row: litres for liquids and for compressed or adsorbed gases, kilograms for solids, liquefied/refrigerated/dissolved gases and articles. A mismatch returns no points and says which dimension the entry is counted in."New value: +"OPTIONAL. The dimension `quantity` is stated in — 'L' or 'kg'. Omit it and the number is taken as already on the ADR 1.1.3.6.3 basis (the historical contract). Supply it and it is CHECKED against the dimension 1.1.3.6.3 counts for the row: litres for liquids and for compressed or adsorbed gases, kilograms for solids, liquefied/refrigerated/dissolved gases and articles. A mismatch returns no points and says which dimension the entry is counted in. Single-substance form only: sent beside items[] it is refused (INVALID_INPUT) — set it on each item."
    • changedInput schema / properties / variant_index / description
      Previous value: -"ADR Table A variant index (as returned by adr_lookup) — pins one row when a UN has several variants that share a packing group (e.g. concentration bands). Ignored for single-row UNs."New value: +"ADR Table A variant index (as returned by adr_lookup) — pins one row when a UN has several variants that share a packing group (e.g. concentration bands). Ignored for single-row UNs. Single-substance form only: sent beside items[] it is refused (INVALID_INPUT) — set it on each item."
  5. Changed4 schema fields changed
    • addedInput schema / properties / basis
      Added value: +{
      +  "description": "OPTIONAL. 'net' or 'gross'. ADR 1.1.3.6.3 counts the dangerous goods themselves, never the packaging, so a figure declared 'gross' returns no points in ANY unit — send the net quantity instead.",
      +  "enum": [
      +    "net",
      +    "gross"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / items / items / properties / basis
      Added value: +{
      +  "description": "OPTIONAL. 'net' or 'gross'. ADR 1.1.3.6.3 counts the dangerous goods themselves, never the packaging, so a figure declared 'gross' returns no points in ANY unit — send the net quantity instead.",
      +  "enum": [
      +    "net",
      +    "gross"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / items / items / properties / unit
      Added value: +{
      +  "description": "OPTIONAL. The dimension `quantity` is stated in — 'L' or 'kg'. Omit it and the number is taken as already on the ADR 1.1.3.6.3 basis (the historical contract). Supply it and it is CHECKED against the dimension 1.1.3.6.3 counts for the row: litres for liquids and for compressed or adsorbed gases, kilograms for solids, liquefied/refrigerated/dissolved gases and articles. A mismatch returns no points and says which dimension the entry is counted in.",
      +  "enum": [
      +    "L",
      +    "kg"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / unit
      Added value: +{
      +  "description": "OPTIONAL. The dimension `quantity` is stated in — 'L' or 'kg'. Omit it and the number is taken as already on the ADR 1.1.3.6.3 basis (the historical contract). Supply it and it is CHECKED against the dimension 1.1.3.6.3 counts for the row: litres for liquids and for compressed or adsorbed gases, kilograms for solids, liquefied/refrigerated/dissolved gases and articles. A mismatch returns no points and says which dimension the entry is counted in.",
      +  "enum": [
      +    "L",
      +    "kg"
      +  ],
      +  "type": "string"
      +}
  6. Changed2 schema fields changed
    • addedInput schema / properties / items / items / properties / quantity / description
      Added value: +"Quantity on the ADR 1.1.3.6.3 basis: net kg for solids and liquefied, refrigerated or dissolved gases; litres for liquids; receptacle water capacity in litres for compressed or adsorbed gases and chemicals under pressure; articles as the mass of the articles without their packagings, in kg."
    • changedInput schema / properties / quantity / description
      Previous value: -"Quantity in kg/L"New value: +"Quantity on the ADR 1.1.3.6.3 basis: net kg for solids and liquefied, refrigerated or dissolved gases; litres for liquids; receptacle water capacity in litres for compressed or adsorbed gases and chemicals under pressure; articles as the mass of the articles without their packagings, in kg."
  7. Changed5 schema fields changed
    • addedOutput schema / properties / _source / properties / authority_current_edition
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / _source / properties / checked_at
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / _source / properties / dataset_edition
      Added value: +{
      +  "type": "string"
      +}
    • removedOutput schema / properties / envelope_version / const
      Removed value: -"1"
    • addedOutput schema / properties / envelope_version / enum
      Added value: +[
      +  "1",
      +  "1.1"
      +]
  8. Changed4 schema fields changed
    • addedInput schema / properties / items / items / properties / packing_group
      Added value: +{
      +  "description": "Packing group for a multi-variant UN.",
      +  "enum": [
      +    "I",
      +    "II",
      +    "III"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / items / items / properties / variant_index
      Added value: +{
      +  "description": "ADR Table A variant index for a multi-variant UN.",
      +  "maximum": 9007199254740991,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedInput schema / properties / packing_group
      Added value: +{
      +  "description": "Packing group (I, II or III) — only needed to disambiguate a UN that has more than one ADR Table A row (e.g. UN 1789). Ignored for single-row UNs.",
      +  "enum": [
      +    "I",
      +    "II",
      +    "III"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / variant_index
      Added value: +{
      +  "description": "ADR Table A variant index (as returned by adr_lookup) — pins one row when a UN has several variants that share a packing group (e.g. concentration bands). Ignored for single-row UNs.",
      +  "maximum": 9007199254740991,
      +  "minimum": 0,
      +  "type": "integer"
      +}
  9. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "_source": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "checked": {
      +          "type": "string"
      +        },
      +        "name": {
      +          "type": "string"
      +        },
      +        "provenance_status": {
      +          "enum": [
      +            "verified",
      +            "pending-verification",
      +            "computed",
      +            "live"
      +          ],
      +          "type": "string"
      +        },
      +        "source_url": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "name",
      +        "checked",
      +        "provenance_status"
      +      ],
      +      "type": "object"
      +    },
      +    "blocking_errors": {
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "code": {
      +            "type": "string"
      +          },
      +          "message": {
      +            "type": "string"
      +          },
      +          "recovery": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "action": {
      +                "type": "string"
      +              },
      +              "params": {
      +                "additionalProperties": {},
      +                "propertyNames": {
      +                  "type": "string"
      +                },
      +                "type": "object"
      +              },
      +              "tool": {
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "action"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "code",
      +          "message",
      +          "recovery"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "citation": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "qualifier": {
      +          "type": "string"
      +        },
      +        "text": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "text"
      +      ],
      +      "type": "object"
      +    },
      +    "confidence": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "basis": {
      +          "enum": [
      +            "deterministic",
      +            "provenance",
      +            "match_quality",
      +            "freshness"
      +          ],
      +          "type": "string"
      +        },
      +        "level": {
      +          "enum": [
      +            "high",
      +            "medium",
      +            "low"
      +          ],
      +          "type": "string"
      +        },
      +        "score": {
      +          "maximum": 1,
      +          "minimum": 0,
      +          "type": "number"
      +        }
      +      },
      +      "required": [
      +        "level",
      +        "basis"
      +      ],
      +      "type": "object"
      +    },
      +    "envelope_version": {
      +      "const": "1",
      +      "type": "string"
      +    },
      +    "normalized_input": {
      +      "additionalProperties": {},
      +      "propertyNames": {
      +        "type": "string"
      +      },
      +      "type": "object"
      +    },
      +    "ok": {
      +      "type": "boolean"
      +    },
      +    "result": {
      +      "additionalProperties": {},
      +      "propertyNames": {
      +        "type": "string"
      +      },
      +      "type": "object"
      +    },
      +    "validity": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "as_of": {
      +          "type": "string"
      +        },
      +        "effective_from": {
      +          "type": "string"
      +        },
      +        "effective_to": {
      +          "anyOf": [
      +            {
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        }
      +      },
      +      "required": [
      +        "as_of"
      +      ],
      +      "type": "object"
      +    },
      +    "warnings": {
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "code": {
      +            "type": "string"
      +          },
      +          "details": {
      +            "additionalProperties": {},
      +            "propertyNames": {
      +              "type": "string"
      +            },
      +            "type": "object"
      +          },
      +          "message": {
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "code",
      +          "message"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    }
      +  },
      +  "required": [
      +    "envelope_version",
      +    "ok",
      +    "result",
      +    "confidence",
      +    "_source",
      +    "citation"
      +  ],
      +  "type": "object"
      +}
  10. Changed4 schema fields changed
    • addedInput schema / properties / items / items / properties / un_number / description
      Added value: +"UN number (4 digits, optionally \"UN\"-prefixed)"
    • addedInput schema / properties / items / items / properties / un_number / pattern
      Added value: +"^(UN)?\\d{4}$"
    • changedInput schema / properties / un_number / description
      Previous value: -"UN number for single check"New value: +"UN number for single check (4 digits, optionally \"UN\"-prefixed)"
    • addedInput schema / properties / un_number / pattern
      Added value: +"^(UN)?\\d{4}$"
  11. First observed

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, and the description adds far more: field-name rejection with a tool error, 400 on single+items mix, rate limiting with reset_at, that exempt/total_points are NULL (never false as a stand-in) when no verdict is reached, that ambiguity is never silently guessed, and the exact conditions producing carriage_prohibited/not_subject_to_adr. This is unusually rich behavioral disclosure 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.

Conciseness3/5

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

Front-loaded and sectioned (Behavior, Scope verdicts, Routing, Returns, Limitations, Related), but it is extremely long and dense, and the Returns paragraph largely restates what the output schema already provides. For a tool this complex some length is warranted, yet several passages (variant handling is described three times) could be tightened.

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?

Given a complex compliance calculator with 7 parameters, no required fields, and a rich output schema, the description covers the full decision space: input forms, ambiguity, scope verdicts, air-only routing, rate limits, and legal limitations. An agent has everything needed to call it and interpret the verdict correctly; 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 coverage is 100%, so the baseline is 3, but the description adds meaning the schema does not: the mutual-exclusivity contract between the single-substance fields and items[], why packing_group/variant_index exist (multi-variant UNs), and the equivalence fallback. The narrative explains the cross-field rules that the per-property schema descriptions leave implicit.

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?

Opens with a precise verb+resource+outcome: 'Calculate ADR 1.1.3.6 "small load" exemption points for a dangerous-goods load and say whether it qualifies.' It names the exact regulation, the points model (quantity x multiplier), and positions itself against siblings in the Related section (adr_lookup for source data, adr_lq_eq_check for the alternative relief route), so an agent can distinguish it immediately.

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 when-to-use routing: single-substance form vs items[] (and that mixing them is a 400), packing_group vs variant_index for multi-variant UNs, and the disambiguation ladder (equivalent variants returned vs blocking_errors). It also states when NOT to use it, pointing to adr_lookup for per-substance data and adr_lq_eq_check as the alternative relief route, plus limitations (packages only, not bulk/tanks).

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.