DEV Community

Cover image for 15 deterministic tools your AI agent should call instead of guessing
hexadata
hexadata

Posted on Edited on

15 deterministic tools your AI agent should call instead of guessing

Ask an LLM whether EKU9003173C9 is a valid Mexican RFC, what the German VAT rate was on a given date, or which HTS code applies to a stainless steel sink, and you get a confident answer. Sometimes it is right. For an invoicing, KYC or customs agent, "sometimes" is not good enough: a check digit is either correct or not, a tariff code is either in the official schedule or not, and a payroll withholding comes from a published table, not from a model's memory.

This post is about the class of work an agent should delegate to deterministic tools and how we packaged 15 of them as one MCP server on Apify. Everything runs against official or open sources, has no LLM inside, stores nothing, and costs half a cent per call.

The 15 Hexadata Tools grouped by validate, look up and calculate, with the agent → MCP server → official sources flow and prices

What belongs in a tool, not in a prompt

Three tests. If the answer (1) has a published algorithm or table, (2) is needed many times per task (one call per invoice, supplier, shipment or employee) and (3) is expensive to get wrong, it belongs in a tool. Business validation passes all three:

Tool Use this when… Official source
validate_tax_id checking a company or taxpayer ID from MX, ES, AR, CL, CO, BR, GB, US, IT, FR, DE, PE, CA, AU or IN check-digit algorithms published by each tax authority
validate_vat_eu confirming an EU VAT number is registered (reverse charge) VIES, European Commission
validate_iban validating an IBAN and splitting bank, branch and account ISO 13616 + IBAN registry
lookup_lei finding the legal entity behind an LEI, or the LEI of a name GLEIF
lookup_postal_code resolving a postal code to city/region/coordinates in 120+ countries GeoNames (CC BY)
validate_bank_account checking a Mexican CLABE, a US ABA routing number or a SWIFT/BIC Banxico SPEI list, ABA rules, ISO 9362
normalize_phone storing a phone as E.164 with country and line type libphonenumber
validate_email_domain checking syntax and whether the domain receives mail (MX, disposable) DNS + open blocklist
get_fx_rate converting with an official rate for a date ECB reference rates, Banxico FIX
business_days adding business days or listing holidays in 200+ countries Nager.Date, Mexican LFT art. 74
lookup_industry_code classifying an activity with NAICS, NACE, CPV or SCIAN Census, Eurostat, EU Publications Office, INEGI
lookup_hs_code finding a customs tariff code and the US duty rate USITC HTS, EU Combined Nomenclature
get_vat_rates getting standard and reduced VAT/GST rates of 35 countries for a date TEDB + national laws
lookup_sat_catalog picking a Mexican CFDI 4.0 catalog value (product key, unit, CFDI use, regime) SAT official workbook
calc_payroll_mx computing Mexican ISR, subsidy, IMSS, Infonavit and net pay DOF, INEGI, Ley del Seguro Social

Every answer carries the same envelope: ok, the result, source, sourceUrl, sourceDate or tableVersion, and scrapedAt. Items that cannot be answered (INVALID_INPUT, UNSUPPORTED_COUNTRY, SOURCE_UNAVAILABLE) come back with ok: false and are never charged.

Three design rules

  1. Deterministic. No model inside. The same input always gives the same output, except market data (FX rates) that carries its date.
  2. Stateless. A tax ID or a phone number is validated and forgotten. Logs contain counts and error codes only. No lists of people.
  3. Explicit coverage. Every multi-country tool declares its supported countries in its description and returns UNSUPPORTED_COUNTRY (free) for the rest, so the agent knows when not to trust it.

Call it from an MCP client

The Actor runs as a Streamable HTTP MCP server. Add it to Claude Desktop, Cursor, VS Code or any MCP client:

{
  "mcpServers": {
    "hexadata-validation": {
      "url": "https://hexadatalabs--business-validation-tools-mcp.apify.actor/mcp",
      "headers": { "Authorization": "Bearer <APIFY_TOKEN>" }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Then ask: "Validate these supplier tax IDs: MX EKU9003173C9, ES B12345674 and BR 11.222.333/0001-81, and tell me which are malformed." The agent calls validate_tax_id once with three items and reports the valid and reason fields instead of guessing.

Call it from n8n, Make or plain HTTP

Batch mode takes { tool, items[], params } and writes one dataset row per item. One HTTP call, synchronous:

curl -s -X POST "https://api.apify.com/v2/acts/hexadatalabs~business-validation-tools-mcp/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tool":"validate_iban","items":[{"iban":"DE89 3704 0044 0532 0130 00"},{"iban":"DE89370400440532013001"}]}'
Enter fullscreen mode Exit fullscreen mode

The second IBAN comes back with valid: false, reason: "INVALID_CHECK_DIGITS". In n8n or Make, use the Apify node with "Run an Actor and get dataset items" and the same JSON.

Python

from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("hexadatalabs/business-validation-tools-mcp").call(run_input={
    "tool": "calc_payroll_mx",
    "items": [{"monthlyGross": 20000, "riskClass": "I", "year": 2026}],
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["isr"], item["imssEmployee"]["total"], item["net"], item["employerCost"], item["tableVersion"])
Enter fullscreen mode Exit fullscreen mode

Agents without an account: USDC via x402

The Actor runs with limited permissions, so an agent can buy a prepaid Apify token with USDC through a Coinbase Agentic Wallet (x402) and call it with no Apify account. $1 USDC ≈ 200 single calls or 500 batch items.

What it costs

$0.005 per single-item call, $0.002 per item when a call carries 2–500 items. 1,000 IBAN checks ≈ $2; 5,000 supplier tax IDs across 12 countries ≈ $10; 100 Mexican payroll calculations ≈ $0.20. Invalid input is free.

What it does not do

It checks formats and check digits, not registries (except VIES and GLEIF, which are live). It does not return bank names for ABA or BIC (those directories forbid commercial redistribution). Text search over code systems is a deterministic word match, not semantic search. It is a calculation aid, not tax advice.

Full documentation, the per-tool input and output fields and the legal notes are on the Actor page. Missing a country or a catalog? Open an issue with the official source and we add it.

Top comments (0)