Calling a Tariff API or MCP Server From an AI Agent
2026-11-12
If you're building a quoting tool, a checkout that shows landed cost, or an AI agent that answers "what will this cost to import?", you'll eventually want duty data in code rather than in a browser tab. This post covers the two main ways to get it, a REST API and an MCP server, what to send, and what to check in the answer before you show it to anyone.
I built DutyCite's API and MCP server around one rule: every rate comes back with its official source and an as-of date. For an agent, that's the difference between an answer someone can check and a guess.
Disclaimer: This post is general information, not customs brokerage, legal advice or a binding classification. That applies to what your agent tells users, too. For a classification you can rely on, use a CBP binding ruling or a licensed customs broker.
Why duty data is a hard API problem
US duty in 2026 isn't a single lookup. A correct answer has to combine:
- the base rate on the 8-digit HTS line (HTS lookup guide),
- Chapter 99 duties that depend on origin and product: Section 301 (overview) and Section 232 (how they stack),
- the exemptions between them. For example, the July 2026 forced-labor Section 301 duty doesn't apply to Section 232 goods (USITC HTS),
- and fees: MPF and HMF, with limits that change every October 1 (fees guide).
And it changes. This year alone, IEEPA duties ended in February (CBP CSMS #67834313), a Section 122 surcharge ran from February to July (Federal Register), and new Section 301 duties started on July 24 (Federal Register). A model's training data can't keep up with that. Your agent should fetch rates, not remember them.
Option 1: REST API
A REST call fits ordinary backend code: checkout, ERP sync, batch quoting.
Inputs a duty calculation needs. These are DutyCite's field names, from /docs and its OpenAPI spec:
hts: the HTS code, ideally all 10 digits (required)origin: country of origin as an ISO 3166-1 alpha-2 code, e.g.VN(required)customs_value: customs value in US dollars (required; DutyCite works in USD only)mode:ocean,air,truck,rail,mailorother. This matters because HMF applies to ocean cargo.entry_date: rates depend on the date. DutyCite estimates current entries; historical entry dates aren't covered.quantityandunit(orquantities), for specific-rate lines (cents per kg, per dozen, and so on)
Shape of a call. Here's DutyCite's endpoint. Replace YOUR_API_KEY with your key; the docs also accept an x-api-key header. Field names match /docs, and the docs take precedence if they change:
curl -X POST "https://dutycite.com/v1/duty" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "hts": "6109.10.00.12", "origin": "VN", "customs_value": 20000, "mode": "ocean", "entry_date": "2026-11-12" }'
Other optional fields:
claim_preference: set to true to claim an FTA special rate.entry_type:formal,informalorauto.options:metal_weight_pct,auto_part,mhd_vehicle_partanduk_melted, for Section 232 tests.
The response contains:
lines: each withprogram,heading,rate,amount,effective_dateand asourceobject (title,url)possible_additional: duties that depend on facts the API can't see, such as end usetotals,warnings,not_in_force,as_ofanddisclaimer
A call that fails validation returns HTTP 422 and isn't charged. A missing key or an empty balance returns HTTP 402. For up to 100 lines on one entry, there's POST /v1/duty/bulk.
What to check in any tariff API's response, whichever provider you use:
- One line per duty layer, not just a total, so you can show and audit the stack (why that matters).
- A source on each line. That means the HTS heading, Federal Register notice or regulation it came from.
- An as-of date on each line or on the whole response.
- Explicit exemptions. If a layer was dropped, the response should say why.
- What isn't covered. Antidumping and countervailing duties aren't in the HTS rate column (CBP AD/CVD), so a response that doesn't flag them is quietly incomplete.
Option 2: MCP server
The Model Context Protocol (MCP) is a standard way for AI applications to discover and call tools. Its data layer is "JSON-RPC based." Clients discover tools with tools/list and run them with tools/call. The protocol supports both a local stdio transport and Streamable HTTP for remote servers (MCP architecture).
In practice, you add a remote MCP server to your agent or client, the model sees a tool with a description and an input schema, and it calls that tool when a user asks about import costs. You write no glue code for the call itself.
To connect DutyCite's server, use the values in /docs:
- Server URL: https://dutycite.com/mcp (Streamable HTTP)
- Tool name(s): calculate_duty (paid), plus free hts_search and hts_lookup
- Auth: an
Authorization: Bearer YOUR_API_KEYheader in your client's server config, for example:
{
"mcpServers": {
"dutycite": {
"url": "https://dutycite.com/mcp",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}
}
}
I'm not listing the tool's parameters here because the schema in /docs is the source of truth, and your client reads it from tools/list anyway.
Guardrails I'd put on any agent that quotes duty
- Make the agent cite. Tell it to show the source and as-of date for each rate it reports. If a line has no source, it shouldn't present that line as fact.
- Ask for missing inputs. Origin and entry date change the answer. A good agent asks for them and doesn't assume.
- Don't let it classify silently. If the user gives a product description instead of an HTS code, the agent should say the code is its best guess and point to /hts or a binding ruling.
- Keep the disclaimer. An agent's duty estimate is still an estimate. Say so in the answer.
- Re-fetch, don't cache forever. Tie any cache to the as-of date and refresh it often. Rates changed several times in 2026.
- Watch the cost of loops. Agents can call tools repeatedly. Set a cap per conversation.
A worked prompt-to-answer flow
- User: "What would 500 cotton T-shirts from Vietnam, $20,000 total, by ocean, cost in duty?"
- Agent checks the inputs. It has origin, value and mode, and it asks for or confirms the entry date and HTS code (6109.10.00 is a likely candidate, but the agent says so and doesn't assume).
- Agent calls the tool.
- Agent reports each line with its source. I worked the same example by hand in how to calculate US import duty, where the stack as of Nov 12, 2026 was 16.5% base plus 12.5% Section 301, plus MPF and HMF.
- Agent adds the disclaimer and the as-of date.
Pricing, briefly
DutyCite's API and MCP calls are prepaid. Packs cost $11.45 for 500 calls ($10 credits + $1.45 processing fee), $28.13 for 1,400 calls ($25 + $3.13) or $111.49 for 6,000 calls ($100 + $11.49), plus sales tax or VAT where it applies. Before tax, that works out to about 2.29¢, 2.01¢ or 1.86¢ per duty calculation, as listed on /pricing. There's also a free 10-call trial key. The web calculator (5 free calculations a day) and the HTS lookup are free.
Facts about tariffs in this post were checked Nov 12, 2026. API details live in /docs and take precedence over anything here.
References
- USITC, Harmonized Tariff Schedule (live search; heading 9903.05.90 and U.S. note 52). https://hts.usitc.gov/
- CBP, CSMS #67834313, "Ending Collection of International Emergency Economic Powers Act Duties." https://content.govdelivery.com/accounts/USDHSCBP/bulletins/40b11c9
- Federal Register, Proclamation 11012, 91 FR 9339 (Feb 25, 2026). https://www.federalregister.gov/documents/2026/02/25/2026-03824/imposing-a-temporary-import-surcharge-to-address-fundamental-international-payments-problems
- Federal Register, USTR, "Notice of Actions in Section 301 Investigations ... Forced Labor," 91 FR 47318 (Jul 28, 2026). https://www.federalregister.gov/documents/2026/07/28/2026-15181/notice-of-actions-in-section-301-investigations-of-acts-policies-and-practices-of-various-economies
- CBP, Antidumping and Countervailing Duties. https://www.cbp.gov/trade/priority-issues/adcvd
- Model Context Protocol, "Architecture overview." https://modelcontextprotocol.io/docs/learn/architecture