Skip to main content
Glama

comtrade_get_trade_balance

Read-onlyIdempotent

Retrieve UN Comtrade trade balance records for a reporter and partner, showing exports, imports, and the X-M balance by product, procedure, transport, and period.

Instructions

Fetch UN Comtrade trade data with a reporter's exports and imports side by side.

Upstream's getTradeBalance, which its spec marks "EXPERIMENTAL - USE SPARINGLY": one keyed call, no count first. Each row, a TradeBalanceRecord, holds a reporter's exports (*_x: primary_value_x, qty_x, net_wgt_x, ...) and imports (*_m) with one partner, second partner, product code, customs procedure, mode of transport and period, and primary_value_bal, which the spec defines as "X - M": upstream's value, passed through (54550055814.504944 for Switzerland and the World in 2023). Without breakdown_mode upstream answers every breakdown (48 rows for Switzerland and the World, 2023, all goods); breakdown_mode="classic" returns the total row alone. A query nothing matches returns an empty list. meta.total is upstream's count. The query must name reporter_code or partner_code, and cmd_code: upstream offers no count to check a query's size before the call (countOnly answered 0 for those 48 rows), so a broader query is refused before it is sent. Arguments are checked before the call; an unknown reporter, partner, customs or transport code raises UnknownCode, an InvalidRequestError naming the packaged list and the closest code, another mistake InvalidRequestError naming the closest valid value. The spec says a free-tier key that is not on UN Comtrade's allow-list is refused with HTTP 403 "User not allowed" (AuthError); the key the package was recorded with was answered (2026-10-28).

Args: type_code: "C" goods or "S" services. freq_code: "A" annual or "M" monthly. cl_code: Product classification, checked against the package's list: "HS" (all HS editions as reported, the one recorded here; rows name the edition in classification_code, e.g. "H6"), an edition "H0" to "H6", SITC "SS", "S1" to "S4", BEC "B4", "B5", "BE", "TM", for services EBOPS "EB", "EB02", "EB10", "EB10S". The Tools spec lists HS, S1 to S4, BE4, BE5, EB, EB02, EB10 and EBSDMX; BE4, BE5 and EBSDMX are not in the package's list (upstream refused BE5 on data/v1/get and EBSDMX on getDa) and are refused before the call. reporter_code: Reporting areas as UN Comtrade's numeric codes, comma-separated, e.g. "757" Switzerland, "842" USA, "276" Germany, "156" China, "757,842", as list_reporters lists them. Some differ from ISO numeric codes: Switzerland is 757, not 756. Required unless partner_code is given. period: Years "2023" (annual) or months "202305" (monthly), at most 12 comma-separated, e.g. "2021,2022,2023". partner_code: Partner areas, comma-separated, as list_partners lists them: "0" World (the total over all partners), "276" Germany. Required unless reporter_code is given; omitted, upstream's default applies, which on get_data is every partner, one row each. partner2_code: Second partner (consignment) areas, comma-separated, codes of list_partners; "0" is the total. cmd_code: Product codes of cl_code, comma-separated, as list_commodities(cl_code) lists them: "TOTAL" for all goods, "AG2" for every chapter, codes such as "27", "0901" or "090111", wildcards such as "27??". customs_code: Customs procedures, comma-separated: "C00" the total, "C01" clearance for home use, "C03" outright exportation. Omit for every procedure, one row each. mot_code: Modes of transport, comma-separated: "0" the total, "1000" air, "2100" sea, "3100" railway, "3200" road, "9100" pipelines and cables. Omit for every mode, one row each. aggregate_by: Upstream parameters to aggregate the results over, comma-separated from cmdCode, period, partnerCode, partner2Code, reporterCode, customsCode, motCode, e.g. "cmdCode"; sent on as given (not recorded on this operation; on get_data the aggregated parameters come back as -2). breakdown_mode: Omitted, upstream's default: every customs procedure, mode of transport and second partner, one row each. "classic": the total row only (customs_code "C00", mot_code 0, partner2_code 0). "plus", the spec's other value, gives every breakdown on get_data. include_desc: Upstream's includeDesc, "Include descriptions of data variables": with it the recorded rows have reporter_iso/reporter_desc, the partner and second partner ones, cmd_desc, customs_desc, mot_desc, the quantity unit abbreviations, aggr_level and is_leaf filled; no answer with rows was recorded without it.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "type_code": "<type_code>",
      "freq_code": "<freq_code>",
      "cl_code": "<cl_code>"
    },
    "name": "comtrade_get_trade_balance"
  }
}

Input Schema

NameRequiredDescriptionDefault
periodNo
cl_codeYes
cmd_codeNo
mot_codeNo
freq_codeYes
type_codeYes
aggregate_byNo
customs_codeNo
include_descNo
partner_codeNo
partner2_codeNo
reporter_codeNo
breakdown_modeNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already establish read-only, idempotent, open-world, non-destructive behavior, yet the description still adds substantial context the annotations can't convey: default `breakdown_mode` yields every breakdown (48 rows for the Switzerland/World example) while `"classic"` returns only the total row, a non-matching query returns an empty list, `meta.total` mirrors upstream `count`, and `countOnly` gave a useless answer. It also documents the failure surface in detail — `UnknownCode` for bad area/customs/transport codes, `InvalidRequestError` naming the closest valid value, and HTTP 403 `AuthError` for keys outside the free-tier allow-list.

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?

The purpose is front-loaded correctly and the argument list is organized, but the prose is substantially bloated: verbatim upstream spec quotes, a stray literal value (`54550055814.504944`), and the recording date of the package key (2026-10-28) add no decision value. Dense nested backtick/parenthetical constructions make several sentences harder to parse than the underlying fact warrants.

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 13-parameter tool with no output schema, the description covers everything an agent needs: what a row contains, how breakdown defaults change row counts, how to shrink results, error classes raised before and during the call, and the auth constraint. Return-value semantics are described inline, which compensates for the absent output schema.

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

Parameters5/5

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

With 13 parameters and 0% schema description coverage, the description carries the entire documentation burden, and it does so parameter by parameter: code formats and examples for `reporter_code` (757 = Switzerland, not ISO 756), `period` ("202305", max 12 values), `partner_code` ("0" = World), `cmd_code` including wildcards like "27??", plus enumerated values for `customs_code`, `mot_code`, `aggregate_by` and `include_desc`. It also explains which classification codes are accepted versus which the upstream spec lists but the package refuses (BE4, BE5, EBSDMX).

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

Purpose4/5

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

The opening sentence names a specific verb and resource (fetch UN Comtrade trade data) and pins down the distinctive shape of the result: a reporter's exports and imports side by side with `primary_value_bal`. It also identifies the upstream operation (`getTradeBalance`), which lets an agent map it against sibling `comtrade_get_data` and `comtrade_get_bilateral_data`. It stops short of explicitly stating which sibling to choose in which situation, so it is clear but not fully self-differentiating.

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?

The description gives real usage context: it flags the upstream "EXPERIMENTAL - USE SPARINGLY" marking, states hard preconditions (the query must name `reporter_code` or `partner_code`, and `cmd_code`), and warns that broad queries are refused because no count can be checked first. That tells the agent when this call will and won't go through. What is missing is an explicit redirection to a sibling tool for cases this one rejects, so it falls short of a full 5.

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