MCP server for querying Indonesian customs tariff and harmonized system codes via the INSW API
This server has critical gaps across all dimensions. Both tools lack proper parameter descriptions, have minimal descriptions (<20 chars would trigger floor), missing input schema detail, and no output schema documentation. The tools are read-only but lack annotations to signal this to clients. No error handling strategy is evident, the code returns bare strings on failure ('Unable to fetch commodity data for this location') with no guidance for LLM recovery. Parameter validation is absent, hscode and query accept any string, inviting malformed requests. The implementation is functional but falls far short of production-grade tool design.
Get detail of commodity code in indonesia. Args: hscode: should be strictly in string format, should not contain dot, space, or any special character. commodity code or harmonized system code for import product categorization
Get list of all possible Indonesia commodity code search by commodity name or code. Args: query: goods or commodity query to search for its commodity code and custom tariff
Parameter descriptions are missing or minimal. 'hscode' parameter has a long description embedded in the tool docstring, but it's not properly formatted as a parameter annotation. 'query' parameter has only 11 words of guidance. Neither parameter specifies format constraints, allowed character sets, or length limits in machine-parseable form (e.g., minLength, maxLength, pattern in JSON Schema).
No input schema field definitions visible in the tool registration. Both tools register parameters with type and description, but the source code does not show explicit minLength, maxLength, pattern, or enum constraints. The rubric requires 'params lack type definitions → schema score CANNOT exceed 30'. While types ARE present (string), constraints are absent, limiting score to 40.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 38 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 29 | - | v1 |
No output schema documented. Both tools return unstructured JSON strings (raw API responses wrapped in json.dumps). The rubric requires 'Document the output schema. LLMs need to know what fields to expect.' Currently, an LLM calling get_hscode_detail has no definition of what fields the response contains, their types, or which fields are guaranteed vs optional.
Error handling is bare-bones and provides no recovery guidance. Both tools return the string 'Unable to fetch commodity data for this location.' on failure. The rubric requires 'Error responses must tell the LLM what to do next.' Current behavior gives the LLM no actionable guidance, should it retry? Call a different tool? Ask the user? The error also conflates location and commodity, which is misleading.
No input validation or constraint enforcement. The hscode parameter claims it 'should not contain dot, space, or any special character', but this is not enforced in code, the string is passed directly to the API URL. A malformed input like 'HS-CODE' or '1234 5678' will reach the API and fail cryptically. LLMs cannot be trusted to follow natural-language constraints, they need regex patterns or validation logic.
Tool descriptions are under 50 characters and lack context. 'Get detail of commodity code in indonesia.' (45 chars) and 'Get list of all possible Indonesia commodity code search by commodity name or code.' (82 chars) lack WHAT happens, WHEN to use it vs the other tool, and what the response structure is. The rubric specifies 'Keep descriptions between 10 - 1024 characters' and emphasizes 'Write descriptions as if prompt-engineering.' These are bare-bones stubs.
No readOnlyHint or other tool annotations. The description states 'Risk: READ_ONLY' in the metadata, but the tool definition itself lacks the readOnlyHint annotation that MCP clients expect (tool metadata with 'readOnly': true). Without this hint, clients may incorrectly assume these tools can modify state or may not apply safety guardrails.
No pagination support. search_commodity_description hardcodes size=10&from=0 in the API call. If results can exceed 10 items, the LLM cannot retrieve additional pages. The rubric requires 'Tools returning lists should accept page/offset and limit parameters and return a total count or next_cursor.' A production tool must expose these as tool parameters so agents can iterate through results.
Raw API response returned without stripping unnecessary fields. Both tools return response['data'] or response['data'][0]['result'] wrapped in JSON, which may include internal metadata, timestamps, or verbose structures irrelevant to the LLM. The rubric notes 'APIs return verbose metadata irrelevant to chat interactions. Strip pagination internals, audit fields, and raw IDs the user never sees.' This wastes tokens and risks context window exhaustion.
Tool naming is verb-based but could be more specific. 'get_hscode_detail' is clear, but 'search_commodity_description' is ambiguous, does it search by name, code, or both? The rubric requires 'When multiple tools operate on the same resource, their names must make the distinction obvious.' Renaming to 'search_hscode_by_commodity_name' or splitting into 'search_hscode_by_name' and 'search_hscode_by_code' would improve clarity.