Skip to main content
Glama

UK Duty & VAT Calculator

uk_duty_calculator
Read-onlyIdempotent

Estimate UK import duty and VAT for a commodity code using the LIVE GOV.UK Trade Tariff — rates are fetched per request, not from a static table. The CIF value is composed from customs_value + freight_cost + insurance_cost; duty = CIF x the duty rate for the origin country; VAT (typically 20%) applies on the duty-inclusive value.

Provide commodity_code (a declarable 10-digit code), origin_country (ISO-2) and customs_value in GBP; freight_cost, insurance_cost and incoterm are optional refinements.

Behavior: live lookup plus deterministic arithmetic on the returned rate; a 6- or 8-digit code is refused — never padded with zeros to a code you did not send — with declarable_codes, the 10-digit codes beneath it in the UK Trade Tariff (610910 → 6109100010, 6109100090); an origin that is not an ISO 3166-1 country is refused; origin-dependent measures the tariff cannot resolve automatically surface in warnings. Rate-limited: a limit error carries reset_at, the UTC time the allowance resets.

Returns: commodity_code and description, origin country, cif_value, duty_rate (+ percent), duty_amount, vat_rate, vat_amount, total_import_taxes, total_landed_cost and warnings under result (amounts in GBP); validity.as_of marks the live-rate timestamp; plus confidence, _source and citation (the FreightUtils v1 response envelope). Field names as this package serves them (snake_case); the hosted /api/mcp endpoint serves the same fields in camelCase (e.g. total_cbm → totalCbm).

Limitations: an estimate, not a customs ruling — excise, quotas, anti-dumping measures, reliefs and origin-proof requirements can change the outcome; confirm with a customs broker or HMRC before relying on it.

Related: hs_code_lookup (find the 6-digit code first), incoterms_lookup (who actually pays these costs).

Input Schema

NameRequiredDescriptionDefault
linesNoBatch: up to 10 lines, each { commodity_code, origin_country, customs_value, freight_cost?, insurance_cost?, incoterm? } — answered as results[] in input order, each as its own call (each line its own receipt). Send alone; the UK Trade Tariff is read live per line.
incotermNoIncoterm basis
freight_costNoFreight cost in GBP, 0 or more (default 0)
customs_valueNoCustoms value in GBP. Required unless lines[] is sent.
commodity_codeNoUK tariff commodity code — a declarable 10 digits, spaces allowed (a 6- or 8-digit code is refused with the declarable codes beneath it)
insurance_costNoInsurance cost in GBP, 0 or more (default 0)
origin_countryNoISO 2-letter country of origin (e.g. "CN", "US"). Required unless lines[] is sent.

Output Schema

NameRequiredDescriptionDefault
okYes
_metaNo
as_ofNo
resultYes
statusNo
_sourceYes
editionNo
citationYes
validityNo
warningsNo
confidenceYes
missing_inputsNo
blocking_errorsNo
envelope_versionYes
normalized_inputNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedOutput schema / properties / _meta / properties / upstream
      Added value: +{
      +  "additionalProperties": {},
      +  "properties": {
      +    "datasets": {
      +      "additionalProperties": {
      +        "additionalProperties": {},
      +        "properties": {
      +          "kind": {
      +            "anyOf": [
      +              {
      +                "enum": [
      +                  "watched",
      +                  "checksum-only",
      +                  "manual"
      +                ],
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "last_success": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "reason": {
      +            "type": "string"
      +          },
      +          "stale": {
      +            "type": "boolean"
      +          },
      +          "state": {
      +            "enum": [
      +              "in_step",
      +              "changed_upstream",
      +              "schema_drift",
      +              "unreachable",
      +              "window_missed",
      +              "unknown"
      +            ],
      +            "type": "string"
      +          },
      +          "window_days": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          }
      +        },
      +        "required": [
      +          "state",
      +          "kind",
      +          "last_success",
      +          "window_days",
      +          "stale"
      +        ],
      +        "type": "object"
      +      },
      +      "propertyNames": {
      +        "type": "string"
      +      },
      +      "type": "object"
      +    },
      +    "stale": {
      +      "type": "boolean"
      +    },
      +    "state": {
      +      "enum": [
      +        "in_step",
      +        "changed_upstream",
      +        "schema_drift",
      +        "unreachable",
      +        "window_missed",
      +        "unknown"
      +      ],
      +      "type": "string"
      +    },
      +    "state_read_at": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    }
      +  },
      +  "required": [
      +    "state",
      +    "stale",
      +    "state_read_at",
      +    "datasets"
      +  ],
      +  "type": "object"
      +}
  2. Changed1 schema field changed
    • addedOutput schema / properties / _meta / properties / ids
      Added value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "pattern": {
      +      "type": "string"
      +    },
      +    "scheme": {
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "scheme",
      +    "pattern"
      +  ],
      +  "type": "object"
      +}
  3. Changed2 schema fields changed
    • removedOutput schema / properties / _meta / properties / receipt / properties / reason / const
      Removed value: -"key_required"
    • addedOutput schema / properties / _meta / properties / receipt / properties / reason / enum
      Added value: +[
      +  "key_required",
      +  "quota"
      +]
  4. Changed1 schema field changed
    • addedOutput schema / properties / _meta / properties / receipt
      Added value: +{
      +  "additionalProperties": {},
      +  "properties": {
      +    "created_at": {
      +      "type": "string"
      +    },
      +    "dataset_version": {
      +      "additionalProperties": {
      +        "type": "string"
      +      },
      +      "propertyNames": {
      +        "type": "string"
      +      },
      +      "type": "object"
      +    },
      +    "engine_version": {
      +      "type": "string"
      +    },
      +    "inputs": {},
      +    "reason": {
      +      "const": "key_required",
      +      "type": "string"
      +    },
      +    "receipt_hash": {
      +      "type": "string"
      +    },
      +    "result": {
      +      "additionalProperties": {},
      +      "propertyNames": {
      +        "type": "string"
      +      },
      +      "type": "object"
      +    },
      +    "schema_version": {
      +      "type": "string"
      +    },
      +    "stored": {
      +      "const": false,
      +      "type": "boolean"
      +    },
      +    "tool": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "stored",
      +    "reason",
      +    "schema_version",
      +    "receipt_hash",
      +    "created_at",
      +    "tool",
      +    "inputs",
      +    "dataset_version",
      +    "engine_version",
      +    "result"
      +  ],
      +  "type": "object"
      +}
  5. Changed1 schema field changed
    • addedOutput schema / properties / _meta / properties / edition_basis
      Added value: +{
      +  "type": "string"
      +}
  6. Changed4 schema fields changed
    • changedInput schema / properties / customs_value / description
      Previous value: -"Customs value in GBP"New value: +"Customs value in GBP. Required unless lines[] is sent."
    • addedInput schema / properties / lines
      Added value: +{
      +  "description": "Batch: up to 10 lines, each { commodity_code, origin_country, customs_value, freight_cost?, insurance_cost?, incoterm? } — answered as results[] in input order, each as its own call (each line its own receipt). Send alone; the UK Trade Tariff is read live per line.",
      +  "items": {
      +    "additionalProperties": {},
      +    "propertyNames": {
      +      "type": "string"
      +    },
      +    "type": "object"
      +  },
      +  "maxItems": 10,
      +  "minItems": 1,
      +  "type": "array"
      +}
    • changedInput schema / properties / origin_country / description
      Previous value: -"ISO 2-letter country of origin (e.g. \"CN\", \"US\")"New value: +"ISO 2-letter country of origin (e.g. \"CN\", \"US\"). Required unless lines[] is sent."
    • removedInput schema / required
      Removed value: -[
      -  "commodity_code",
      -  "origin_country",
      -  "customs_value"
      -]
  7. Changed1 schema field changed
    • addedOutput schema / properties / _meta
      Added value: +{
      +  "additionalProperties": {},
      +  "properties": {
      +    "check_id": {
      +      "type": "string"
      +    },
      +    "receipt_url": {
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
  8. Changed5 schema fields changed
    • addedOutput schema / properties / as_of
      Added value: +{
      +  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +  "type": "string"
      +}
    • addedOutput schema / properties / edition
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "applies_from": {
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "may_apply_until": {
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "name": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "name",
      +        "applies_from",
      +        "may_apply_until"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • changedOutput schema / properties / envelope_version / enum
      Previous value: -[
      -  "1",
      -  "1.1"
      -]New value: +[
      +  "1",
      +  "1.1",
      +  "1.2"
      +]
    • addedOutput schema / properties / missing_inputs
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / status
      Added value: +{
      +  "enum": [
      +    "ok",
      +    "partial",
      +    "not_found",
      +    "unsupported",
      +    "ambiguous"
      +  ],
      +  "type": "string"
      +}
  9. Changed2 schema fields changed
    • removedOutput schema / properties / validity / properties / effective_to / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / validity / properties / effective_to / type
      Added value: +[
      +  "string",
      +  "null"
      +]
  10. Changed1 schema field changed
    • addedInput schema / additionalProperties
      Added value: +false
  11. Changed2 schema fields changed
    • changedInput schema / properties / commodity_code / description
      Previous value: -"UK tariff commodity code (6-10 digits)"New value: +"UK tariff commodity code — a declarable 10 digits, spaces allowed (a 6- or 8-digit code is refused with the declarable codes beneath it)"
    • changedInput schema / properties / commodity_code / pattern
      Previous value: -"^\\d{6,10}$"New value: +"^[\\d\\s]{6,14}$"
  12. Changed4 schema fields changed
    • changedInput schema / properties / freight_cost / description
      Previous value: -"Freight cost in GBP (default 0)"New value: +"Freight cost in GBP, 0 or more (default 0)"
    • addedInput schema / properties / freight_cost / minimum
      Added value: +0
    • changedInput schema / properties / insurance_cost / description
      Previous value: -"Insurance cost in GBP (default 0)"New value: +"Insurance cost in GBP, 0 or more (default 0)"
    • addedInput schema / properties / insurance_cost / minimum
      Added value: +0
  13. 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"
      +]
  14. 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"
      +}
  15. Changed2 schema fields changed
    • addedInput schema / properties / commodity_code / pattern
      Added value: +"^\\d{6,10}$"
    • addedInput schema / properties / origin_country / pattern
      Added value: +"^[A-Za-z]{2}$"
  16. Changed11 schema fields changed
    • removedInput schema / properties / commodityCode
      Removed value: -{
      -  "description": "UK tariff commodity code (6-10 digits)",
      -  "type": "string"
      -}
    • addedInput schema / properties / commodity_code
      Added value: +{
      +  "description": "UK tariff commodity code (6-10 digits)",
      +  "type": "string"
      +}
    • removedInput schema / properties / customsValue
      Removed value: -{
      -  "description": "Customs value in GBP",
      -  "exclusiveMinimum": 0,
      -  "type": "number"
      -}
    • addedInput schema / properties / customs_value
      Added value: +{
      +  "description": "Customs value in GBP",
      +  "exclusiveMinimum": 0,
      +  "type": "number"
      +}
    • removedInput schema / properties / freightCost
      Removed value: -{
      -  "description": "Freight cost in GBP (default 0)",
      -  "type": "number"
      -}
    • addedInput schema / properties / freight_cost
      Added value: +{
      +  "description": "Freight cost in GBP (default 0)",
      +  "type": "number"
      +}
    • removedInput schema / properties / insuranceCost
      Removed value: -{
      -  "description": "Insurance cost in GBP (default 0)",
      -  "type": "number"
      -}
    • addedInput schema / properties / insurance_cost
      Added value: +{
      +  "description": "Insurance cost in GBP (default 0)",
      +  "type": "number"
      +}
    • removedInput schema / properties / originCountry
      Removed value: -{
      -  "description": "ISO 2-letter country of origin (e.g. \"CN\", \"US\")",
      -  "type": "string"
      -}
    • addedInput schema / properties / origin_country
      Added value: +{
      +  "description": "ISO 2-letter country of origin (e.g. \"CN\", \"US\")",
      +  "type": "string"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "commodityCode",
      -  "originCountry",
      -  "customsValue"
      -]New value: +[
      +  "commodity_code",
      +  "origin_country",
      +  "customs_value"
      +]
  17. First observed

TDQS

A4.6/5.0
Behavior4/5

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

Goes well beyond the annotations: live per-request rate fetch, refusal behavior for short codes with declarable_codes returned, ISO-3166 validation of origin, unresolved origin-dependent measures surfacing in warnings, and rate limiting with reset_at. It also enumerates the returned monetary fields. Minor tension: live remote fetching sits awkwardly with openWorldHint=false, though that hint is usually read as 'no arbitrary external entities', so this is a nuance rather than a contradiction.

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

Conciseness4/5

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

Front-loaded with the purpose and inputs, then behavior, returns, limitations and related tools in a clean order. It is longer than needed, and one sentence is off-target for this tool: the FreightUtils v1 / camelCase envelope note references total_cbm, a shipping field this tool does not return.

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?

Despite an output schema existing, the description summarizes the key result fields and the as_of timestamp, and covers refusals, rate limits, warnings, and the estimator caveat with a broker/HMRC check. The only gap is batching via lines[], which the schema documents at 100%.

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; the description earns a 4 by explaining how customs_value, freight_cost and insurance_cost compose CIF and by stressing that origin_country must be an ISO-2 country. It omits the lines[] batch parameter entirely, which is the main alternate input mode, so the prose alone would leave an agent unaware of batching.

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 specific verb and resource: 'Estimate UK import duty and VAT for a commodity code using the LIVE GOV.UK Trade Tariff'. It also states the calculation basis (CIF = customs_value + freight + insurance) and names the sibling it does not replace (hs_code_lookup), so an agent can distinguish it from lookup/conversion siblings 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?

Explicitly states the minimum inputs (commodity_code, origin_country, customs_value), which fields are optional refinements, and routes the agent to hs_code_lookup 'find the 6-digit code first' and incoterms_lookup. It also states a hard exclusion (6- or 8-digit codes are refused, never zero-padded) and closes with what it is not (an estimate, not a customs ruling).

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.