Skip to main content
Glama

comtrade_get_bilateral_data

Read-onlyIdempotent

Compare a reporter's trade figures with partners' mirror data row by row to analyse bilateral trade asymmetries and spot data gaps.

Instructions

Compare a reporter's trade figures with its partners' mirror figures, row by row.

Upstream's getBilateralData, which its spec marks "EXPERIMENTAL - USE SPARINGLY": one keyed call, "basic trade data joined with mirror partner data", useful to analyse bilateral trade asymmetries. Its result is not a list, nor is get_mirror_flows': data is a BilateralData holding upstream's note, its timestamp_requested and the rows, data.data, because the note qualifies the mirror values. It counts the partners with a data gap and gives their share of world trade without naming them ("a data gap for 2 partner(s) ... approximately 0.015% of the accumulated world's share"). Each row, a BilateralDataRecord, is one reporter, partner, product code, flow and period at the total of every breakdown (customs_code "C00", mot_code 0): the reporter's figures (primary_value, qty, net_wgt, ...) beside the mirror (mirror_primary_value, mirror_qty, ...), for a reporter's exports "the import data reported by" its partners, as UN Comtrade's Help Center puts it. It warns that "the outcome of the mirror data depends on the availability of other reporters rather than no-trade": a mirror of 0 is no evidence of no trade. For Switzerland's 2023 exports Afghanistan's mirror of 0 showed which partner the gap was, inferred from the counts (DPRK alone: 1, the USA alone: none, the three together: 2), not stated. That is no general rule: the note speaks of a gap "during specific periods" and says "the calculation of mirror data may be incomplete", and a mirror of 0 can also be a partner that reported no such imports. primary_value_disc is upstream's, its meaning not stated; in every recorded row it equals (mirror_primary_value - primary_value) / primary_value, a relative difference (-0.16 for Switzerland's 2023 exports to the USA, -1.0 where the mirror is 0). The mirror2_* fields are not described upstream and were None or 0 in every recorded row. A pair upstream holds nothing for has no row. meta.total is upstream's count. Over MCP the rows are not cut to the result cap one by one: an answer above it (about 40 rows) comes as a preview of its text, so name a few partners or periods per call. 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 (it ignores countOnly), so a broader query is refused before it is sent. Arguments are checked before the call; an unknown reporter or partner code raises UnknownCode, an InvalidRequestError naming the packaged list and the closest area, another mistake InvalidRequestError naming the closest valid value.

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), comma-separated, e.g. "2021,2022,2023"; unlike get_data, more than 12 are accepted (13 answered 13 rows). partner_code: Partner areas, comma-separated, as list_partners lists them: "842" USA, "276" Germany, "842,276", one row each. Required unless reporter_code is given. 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??". flow_code: One trade flow: "X" exports or "M" imports; upstream refuses both in one call ("M,X"), so call once per flow. include_desc: Upstream's includeDesc, sent on as given: the recorded answers carry no descriptions with or without it (the *_iso and *_desc fields stay None); list_reporters and list_partners name the codes.

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_bilateral_data"
  }
}

Input Schema

NameRequiredDescriptionDefault
periodNo
cl_codeYes
cmd_codeNo
flow_codeNo
freq_codeYes
type_codeYes
include_descNo
partner_codeNo
reporter_codeNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A4.2/5.0
Behavior3/5

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

Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description then adds substantial context the annotations cannot: the `BilateralData` wrapper with `note`/`timestamp_requested`, the caveat that a mirror of 0 is not evidence of no trade, the meaning of `primary_value_disc`, undocumented `mirror2_*` fields, `meta.total` = `count`, truncation to a text preview above ~40 rows, and specific error types (`UnknownCode`, `InvalidRequestError`). That is well beyond the annotation bar and warrants more than a 3 – it is a 5 for added behavioral context.

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?

Purpose and output shape are front-loaded before the Args block, which is good structure. But the prose is very long for a tool description and includes narrative digressions, notably the extended Switzerland/Afghanistan/DPRK example and reasoning about inferring gaps, which are illustrative but not essential to invoking the tool. The density is justified by the tool's complexity, yet it could be trimmed without losing call-critical information.

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

Completeness4/5

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

With no output schema and 9 parameters, the description must explain returns and it does: wrapper structure, row fields, the detail codes, the total row convention, truncation behavior, and error handling. Nothing an agent needs to call correctly appears missing, though the `mirror2_*` fields remain admittedly unexplained upstream, a minor residual gap.

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 0%, so the description carries the full burden and does so: every one of the 9 parameters is explained with syntax, examples, and constraints (comma-separated lists, month format `"202305"`, `cl_code` valid values plus the `BE4`/`BE5`/`EBSDMX` discrepancies, `reporter_code` non-ISO numbering like 757 vs 756, wildcard forms for `cmd_code`). It is thorough and compensates fully for the empty schema, well above the baseline for low coverage.

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 opening sentence names a specific verb and resource: compare a reporter's figures with its partners' mirror figures, row by row. It explicitly distinguishes the result from `get_mirror_flows` ("Its result is not a list, nor is ``get_mirror_flows``'") and from `get_data`, so an agent can tell the siblings apart without opening a 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?

It relays upstream's "EXPERIMENTAL - USE SPARINGLY" warning, names the analytical use case (bilateral trade asymmetries), states the practical constraint "name a few partners or periods per call", and notes flow must be one per call. It also contrasts against `get_data` on the period limit, giving an agent clear grounds to choose between them.

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