Skip to main content
Glama

Klassio — EU customs tariff (CN/HS) classification + EUDR

klassio_classify_article

Read-onlyIdempotent

Single-product classification. Accepts a free-text description plus optional structured hints (materials, intended_use, category, origin/destination country). POPULATE EVERY HINT YOU HAVE — materials/intended_use/category materially improve retrieval and candidate quality vs a description-only call (e.g. description:"Funko POP Vinyl", category:"Figurines", materials:["PVC plastic"], intended_use:"decorative collectible figure" reliably surfaces ch. 95). Returns top-3 CN candidates, EUDR scope, MFN duty, a bilingual reasoning_md narrative, a gap_analysis flagging missing inputs, and a tri-state status (confident / review_recommended / manual_review_required). Trust status for review-routing — do not re-derive your own confidence threshold. PAT-authed callers also receive prior_decisions[] from the org dictionary history.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
langNoReturn reasoning in a single language: drops the redundant rationale_* field for the other and (with compact_rules) collapses the shared rule pool to this language. Absent = bilingual (default).
dry_runNoFirst half of the BYOM eval loop: with dry_run:true retrieval + prompt-build run but the judge is NOT called — returns candidates_top10 + request_token only, no judge spend. Judge with your own model (e.g. fan out across subagents to parallelise), then call klassio_submit_classification_verdict. Prefer this over the inline judge for bulk eval/scoring.
includeNoL3 opt-ins. 'compact_rules' hoists per-candidate rule bodies into a shared top-level classification_rules pool (candidates carry rule_ids[] instead). 'truncate_rules' truncates the pool bodies to ~240 chars (use with compact_rules). Default = master shape (per-candidate bilingual classification_rules, no pool).
categoryNoYour internal product-taxonomy label, e.g. "Figurines", "Vacuum Cleaner Accessories". Folded into the retrieval query to anchor the right chapter (e.g. "Figurines" pulls ch. 95 toys instead of ch. 39 raw polymer). Populate whenever you have one.
materialsNoConstituent materials, e.g. ["PVC plastic","vinyl"] or ["wood","MDF"]. Strongly improves retrieval — a material-poor description retrieves weaker candidates. Populate whenever known.
current_cnNo
descriptionYes
origin_iso2NoCountry of origin (ISO 3166-1 alpha-2, e.g. "CN"). Improves duty/FTA and EUDR country-risk context and disambiguates origin-sensitive headings.
intended_useNoFunction / end use, e.g. "decorative collectible figure" or "kitchen cabinet door panel". Disambiguates products whose bare name misleads (a "Funko POP Vinyl" reads as raw vinyl without it). Populate whenever known.
destination_iso2NoImport destination country (ISO 3166-1 alpha-2, e.g. "SE"). Adds destination-specific measure/declaration context.
omit_system_promptNoDry-run only: omit the re-sent judge system prompt from dry_run_prompt.system (set null) to save ~3k tokens per call. prompt_version is still returned so a caller can validate a system cached via klassio_get_judge_system_prompt. Does NOT change request_token. Default false (system included).
omit_raw_candidatesNoDry-run only: omit the diagnostic dry_run_prompt.raw_candidates pool. Default false (raw_candidates included). The BYOM submit path re-runs retrieval, so omitting this does not affect request_token.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
statusYes
taric_gapNo
candidatesYes
confidenceYes
query_usedYes
result_refYes
taric_codeNo
gri_appliedYes
judge_debugYes
taric_basisNo
gap_analysisYes
judge_winnerYes
rationale_enYes
rationale_svYes
reasoning_mdYes
dry_run_promptNo
taric_measuresNo
judge_runner_upYes
prior_decisionsNo
taric_candidatesNo
mfn_across_leavesNo
retrieval_qualityNo
recommended_actionNo
classification_rulesNo
judge_quota_remainingNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedOutput schema / properties / judge_debug / properties / deciding_notes
      Added value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "chapters": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "chars": {
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "clause_keys": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "status": {
      +      "enum": [
      +        "rendered",
      +        "not_triggered",
      +        "no_clauses",
      +        "loader_error"
      +      ],
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "status",
      +    "clause_keys",
      +    "chars",
      +    "chapters"
      +  ],
      +  "type": "object"
      +}
  2. Changed11 schema fields changed
    • addedOutput schema / properties / judge_debug / properties / heading_proposal_injected
      Added value: +{
      +  "maximum": 9007199254740991,
      +  "minimum": -9007199254740991,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / judge_debug / properties / normalize_ms
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / judge_debug / properties / normalize_outcome
      Added value: +{
      +  "enum": [
      +    "off",
      +    "cache_hit",
      +    "ok",
      +    "timeout",
      +    "parse_fail",
      +    "refused",
      +    "error"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / judge_debug / properties / normalize_prompt_version
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / judge_debug / properties / proposed_headings
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / judge_debug / properties / proposed_headings_valid
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / judge_debug / properties / retrieval_ms
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / judge_debug / properties / rewrite_dense_n
      Added value: +{
      +  "maximum": 9007199254740991,
      +  "minimum": -9007199254740991,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / judge_debug / properties / rewrite_only_codes
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / judge_debug / properties / rewrite_only_in_pool
      Added value: +{
      +  "maximum": 9007199254740991,
      +  "minimum": -9007199254740991,
      +  "type": "integer"
      +}
    • addedOutput schema / properties / judge_debug / properties / tariff_rewrite
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
  3. Changed7 schema fields changed
    • addedOutput schema / properties / judge_debug / properties / chapter_hint_source
      Added value: +{
      +  "enum": [
      +    "normalised",
      +    "raw",
      +    "bti"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / judge_debug / properties / judge_flagged_missing
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / judge_debug / properties / off_list_cn_code
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / judge_debug / properties / off_list_reason
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / judge_debug / properties / off_list_rejected
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / judge_debug / properties / rationale_winner_mismatch
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / judge_debug / properties / rerank_error
      Added value: +{
      +  "type": "string"
      +}
  4. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare read-only/idempotent safety, so the description rightly spends its budget on behavior the schema can't convey: the tri-state status contract ('Trust status for review-routing — do not re-derive your own confidence threshold'), PAT-auth prior_decisions behavior, and dry_run's judge-spend avoidance. This is rich, non-redundant disclosure.

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 purpose, then inputs, then outputs, then the status caveat. Dense but nearly every sentence earns its place; the hint-emphasis slightly overlaps the schema descriptions but is defensible given retrieval stakes.

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

Completeness5/5

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

An output schema exists so return values needn't be explained in depth, yet the description still summarizes the key return fields and the review-routing rule. For a 12-parameter tool with a sibling lookup tool, an agent has everything needed to call it correctly.

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 already 83%, so the baseline is 3, but the description adds genuine meaning: it explains why materials/intended_use/category matter (retrieval quality) and reinforces the description-only vs hinted comparison, supplementing the schema's own field docs.

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+resource phrase ('Single-product classification') and immediately states the accepted inputs and the concrete outputs (top-3 CN candidates, EUDR scope, MFN duty, status). The sibling klassio_lookup_cn_code is a code lookup, so this classification tool is clearly distinguished without opening either schema.

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

Usage Guidelines4/5

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

Gives strong when-to-use guidance: 'POPULATE EVERY HINT YOU HAVE' with a worked example showing how hints change chapter retrieval, and routes bulk eval to dry_run. It does not explicitly state when to prefer klassio_lookup_cn_code over this tool, so it stops short of full alternative routing.

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