Developer docs

Tariff Code Compliance MCP Server

Hosted MCP access to the Tariff Code Compliance knowledge graph for tariff-system discovery, native node lookup, search, and bounded graph traversal.

For product-classification workflow and private ChatGPT or Claude installation instructions, see the ChatGPT and Claude guide. These integrations are currently private/custom and have not been approved for public directory listing.

Endpoint

The MCP server is an Auth0 OAuth-protected remote Streamable HTTP endpoint. It does not expose the Explorer's public preview contract.

https://api.prod.tariffcodecompliance.com/tariff-code-compliance/v1/mcp

The exact endpoint URL is also the OAuth resource and token audience. Access requires scope tcc.knowledge_graph.read plus the current Explorer product entitlement explorer.mcp.read.

The endpoint supports MCP protocol version 2026-07-28 over stateless JSON Streamable HTTP. Every request is independent: the server does not issue or require Mcp-Session-Id, and ignores that header if an older client sends it. Clients using earlier supported protocol versions can continue to use the legacy initialize flow.

Protected-resource metadata:

https://api.prod.tariffcodecompliance.com/.well-known/oauth-protected-resource

ChatGPT and Claude quick start

Claude

Add the endpoint as a private custom connector. Claude discovers Auth0 from the protected-resource metadata, registers the connector client, and opens the Auth0 sign-in and consent flow. After consent, call list_tariff_systems before selecting an explicit system and version for deeper tools.

ChatGPT

In developer mode, create an app for the endpoint above. ChatGPT discovers the OAuth configuration, registers the connector client, and opens the Auth0 sign-in and consent flow. After consent, call list_tariff_systems and then one of the version-scoped read tools.

Both clients use Auth0 Dynamic Client Registration, authorization code with PKCE, and renewable credentials. A new Auth0 identity receives its Explorer identity and initial MCP entitlement automatically; an existing identity keeps its current grant state.

New accounts currently use the internal explorer-beta-free plan. Accepted MCP calls produce usage records in Metronome. That beta plan does not currently charge or enforce a customer usage limit, but the records may support usage-based pricing, limits, or enforcement under a future or different plan and applicable terms. Although tariff graph reads do not change product or tariff data, an accepted tool call enqueues a usage record; the tools therefore advertise readOnlyHint: false, openWorldHint: false, and destructiveHint: false.

The client sends only selected MCP tool inputs to TCC. TCC does not automatically receive the full conversation or full product description. See the Privacy Policy for the data and analytics boundary.

For protocol troubleshooting after completing OAuth, an Auth0-issued MCP access token can be sent as a standard Bearer token:

export AUTH0_MCP_ACCESS_TOKEN="<Auth0-issued MCP access token>"

curl -sS https://api.prod.tariffcodecompliance.com/tariff-code-compliance/v1/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer ${AUTH0_MCP_ACCESS_TOKEN}" \
  -H "Mcp-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: server/discover" \
  --data '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "server/discover",
    "params": {
      "_meta": {
        "io.modelcontextprotocol/protocolVersion": "2026-07-28",
        "io.modelcontextprotocol/clientInfo": {
          "name": "tcc-protocol-test",
          "version": "1.0.0"
        },
        "io.modelcontextprotocol/clientCapabilities": {}
      }
    }
  }'

server/discover returns the supported protocol versions and server capabilities without a legacy initialization handshake. Discovery and list responses include resultType: "complete", ttlMs, and cacheScope metadata so clients can apply the protocol's cache semantics.

For a modern tool call, the HTTP headers must match the JSON-RPC body:

curl -sS https://api.prod.tariffcodecompliance.com/tariff-code-compliance/v1/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer ${AUTH0_MCP_ACCESS_TOKEN}" \
  -H "Mcp-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/call" \
  -H "Mcp-Name: list_tariff_systems" \
  --data '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "_meta": {
        "io.modelcontextprotocol/protocolVersion": "2026-07-28",
        "io.modelcontextprotocol/clientInfo": {
          "name": "tcc-protocol-test",
          "version": "1.0.0"
        },
        "io.modelcontextprotocol/clientCapabilities": {}
      },
      "name": "list_tariff_systems",
      "arguments": {}
    }
  }'

For protocol 2026-07-28, Mcp-Method is required and must equal the JSON-RPC method. Mcp-Name is also required for tools/call and must equal params.name; a mismatch fails with HTTP 400. The current TCC tool schemas do not declare parameter headers, so clients should not send Mcp-Param-* headers.

Legacy protocol clients can continue to initialize and call the same stateless endpoint without the new method/name headers. For example:

curl -sS https://api.prod.tariffcodecompliance.com/tariff-code-compliance/v1/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer ${AUTH0_MCP_ACCESS_TOKEN}" \
  --data '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "list_tariff_systems",
      "arguments": {}
    }
  }'

The raw HTTP response is an MCP JSON-RPC response. Tool payloads are returned inside the MCP result object; the examples below show the parsed JSON payload for the called tool.

Tools

  • list_tariff_systems
  • describe_tariff_system
  • resolve_nodes
  • search_nodes
  • get_node
  • list_node_edges
  • traverse_nodes

These tools expose the native KGv3 node and edge contract. Start with list_tariff_systems, then use the returned system and version for the remaining tools. Node IDs are opaque: resolve or search for a node before fetching or traversing it.

Paged tools return at most 25 items. Pagination is continuation-only: when page.has_more is true, pass page.next_page_token back as page_token; paged tools do not return exact totals. Traversal is bounded by max_depth, max_nodes, and max_edges_per_node; if truncated is true, narrow the traversal instead of treating it as complete.

Searches must be specific enough to complete within the service bound. An over-broad search fails with a bad-request error and the message Search is too broad. Narrow your search and try again. Narrow the query rather than retrying it unchanged.

Example traversal

All calls are JSON-RPC requests sent to the MCP endpoint. The examples below use the sandbox knowledge graph output shape with US_HTS version 2026-rev-4; production clients should first call list_tariff_systems and use the returned version.

List tariff systems

Input:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_tariff_systems",
    "arguments": {}
  }
}

Output:

{
  "systems": [
    {
      "system": "US_HTS",
      "version": "2026-rev-4",
      "system_version_id": "sysv:US_HTS:US:2026-rev-4",
      "enabled": true,
      "default_version": "2026-rev-4",
      "default_system_version_id": "sysv:US_HTS:US:2026-rev-4",
      "versions": [
        {
          "version": "2026-rev-4",
          "system_version_id": "sysv:US_HTS:US:2026-rev-4",
          "is_default": true
        }
      ]
    }
  ]
}

Describe the selected system

Input:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "describe_tariff_system",
    "arguments": {
      "system": "US_HTS",
      "version": "2026-rev-4"
    }
  }
}

The output contains the exact system_version_id, the system profile, and a guide_markdown field describing the node kinds, identifier schemes, relations, and properties available for that version. Treat that guide as authoritative rather than assuming a fixed schema across tariff systems.

Resolve a code to a native node

Input:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "resolve_nodes",
    "arguments": {
      "system": "US_HTS",
      "version": "2026-rev-4",
      "selector": {
        "source_key": {
          "scheme": "us_hts.code",
          "value": "9506"
        },
        "kinds": ["classification"]
      }
    }
  }
}

The result contains up to 25 node summaries. A unique result's ref.node_id is the opaque ID to use with get_node, list_node_edges, and traverse_nodes. If the selector is ambiguous, refine it with the system guide's identifier schemes or kinds.

Search native nodes

Input:

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "search_nodes",
    "arguments": {
      "system": "US_HTS",
      "version": "2026-rev-4",
      "query": "sports equipment",
      "kinds": ["classification"],
      "locales": ["en"]
    }
  }
}

Search matches an HTS code prefix or an existing related tariff term. It does not scan arbitrary classification descriptions. It currently accepts only US_HTS classifications with kinds set to ["classification"], locales set to ["en"], and no effective_at. Unsupported search shapes fail with INVALID_ARGUMENT and guidance to correct the request.

Fetch one native node

Input:

{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "get_node",
    "arguments": {
      "system": "US_HTS",
      "version": "2026-rev-4",
      "node_id": "<node id returned by resolve_nodes or search_nodes>"
    }
  }
}

The native node includes its source key, identifiers, labels, texts, properties, validity, and provenance.

Traverse hierarchy and related nodes

Input:

{
  "jsonrpc": "2.0",
  "id": 6,
  "method": "tools/call",
  "params": {
    "name": "traverse_nodes",
    "arguments": {
      "system": "US_HTS",
      "version": "2026-rev-4",
      "start_node_ids": ["<resolved node id>"],
      "direction": "both",
      "relations": ["parent_of", "applies_to", "references", "defines"],
      "max_depth": 2,
      "max_nodes": 100,
      "max_edges_per_node": 50
    }
  }
}

Use direction: "outgoing" with relations: ["parent_of"] for children. Use direction: "incoming" with the same relation for ancestors. Tariff rates are nodes connected with applies_to; notes and definitions use the relations described by the selected system's guide.

Page through direct edges

Input:

{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/call",
  "params": {
    "name": "list_node_edges",
    "arguments": {
      "system": "US_HTS",
      "version": "2026-rev-4",
      "node_id": "<resolved node id>",
      "direction": "outgoing",
      "relations": ["parent_of"],
      "related_kinds": ["classification"]
    }
  }
}

This returns native edge records plus an opaque continuation token when another page exists.

Markdown

The canonical source for this page is available as Markdown at /docs/mcp.md.