AI Interfaces

Public, read-only endpoints that expose each company's published catalog — as schema.org JSON-LD for search engines, as an MCP server for AI agents, and as a WebMCP embed for in-browser agents.

Every endpoint is keyed by the company's pluginKey — the stable public key issued by the platform the catalog is sourced from. Unknown keys return 404. All data is a read-only mirror of the company's published catalog — no customer data or internal pricing is ever exposed. Examples below use Tudi Mechanical Systems.

1 · JSON-LD feed

GET/companies/{pluginKey}.jsonld

Returns the company's complete schema.org graph as application/ld+json, ready to embed verbatim in a <script type="application/ld+json"> tag. The @graph contains:

NodeContents
LocalBusinessBusiness name, postal address, geo coordinates, website.
Product (system type)One per system type (e.g. HP & Air Handler, Water Heater). The AggregateOffer spans the type's lowest and highest fully-installed price, nests up to three Good/Better/Best tier offers, and carries a configurable note describing what the price covers. Disable per deployment by removing system from CONCOM_OFFERABLE_ITEM_TYPES.
Product / ServiceOne per remaining offer group (by category, plus one per uncategorized item), typed by its member items. Each carries an AggregateOffer with lowPrice/highPrice/offerCount.
Up to 50 offers per company. The feed emits at most 50 offer nodes — the most representative first (largest categories, then highest-priced individual items) — so the embedded JSON-LD stays a sensible size for large catalogs.

Example

curl http://ai-interfaces.toolbox.contractorcommerce.com/companies/000qeNvgDSrmHEbIejt1beAWureP3Z5HrsB3NZFq.jsonld

Abbreviated response:

{
  "@context": "https://schema.org",
  "@graph": [
    { "@type": "LocalBusiness", "name": "Tudi Mechanical Systems",
      "address": { "@type": "PostalAddress", "addressLocality": "…" } },
    { "@type": "Product", "name": "HP & Air Handler",
      "offers": { "@type": "AggregateOffer", "priceCurrency": "USD",
                  "lowPrice": "8500.00", "highPrice": "15200.00", "offerCount": 24,
                  "description": "Fully-installed price. Includes installation and permits.",
                  "offers": [
                    { "@type": "Offer", "name": "Good",   "price": "8500.00"  },
                    { "@type": "Offer", "name": "Better", "price": "10200.00" },
                    { "@type": "Offer", "name": "Best",   "price": "12750.00" } ] } },
    { "@type": "Product", "name": "Air Filters",
      "offers": { "@type": "AggregateOffer", "priceCurrency": "USD",
                  "lowPrice": "60.05", "highPrice": "186.04", "offerCount": 3 } }
  ]
}

Embedding on a website

<script type="application/ld+json">
  …paste the response body verbatim…
</script>

2 · MCP server (for AI agents)

POST/companies/{pluginKey}/mcp

A per-company Model Context Protocol server using the Streamable HTTP transport (JSON-RPC 2.0, protocol 2025-06-18). It is stateless: every request is answered with a single application/json body, notifications return 202, and GET returns 405 (no server-initiated stream). Point any MCP client at the URL and it will discover the tools.

Tools

ToolArgumentsReturns
get_business_profileName, address, geo coordinates.
list_offersOffer groups with USD price ranges and offer counts.
search_catalogquery (required), limit (≤ 25)Matching items with SKU, type and price.
check_service_areapostal_code (required)Whether the company serves that postal code.
get_faqsCommon questions with their answer options.

Connect from Claude Code

claude mcp add --transport http tudi-mechanical-systems \
  "http://ai-interfaces.toolbox.contractorcommerce.com/companies/000qeNvgDSrmHEbIejt1beAWureP3Z5HrsB3NZFq/mcp"

Then ask things like “do they serve zip 63376, and what do air filters cost?” — the agent discovers and calls the tools itself.

Raw JSON-RPC examples

Handshake:

curl http://ai-interfaces.toolbox.contractorcommerce.com/companies/000qeNvgDSrmHEbIejt1beAWureP3Z5HrsB3NZFq/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{
        "protocolVersion":"2025-06-18","capabilities":{},
        "clientInfo":{"name":"demo","version":"1"}}}'

List tools:

curl http://ai-interfaces.toolbox.contractorcommerce.com/companies/000qeNvgDSrmHEbIejt1beAWureP3Z5HrsB3NZFq/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

Call a tool — search the catalog:

curl http://ai-interfaces.toolbox.contractorcommerce.com/companies/000qeNvgDSrmHEbIejt1beAWureP3Z5HrsB3NZFq/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{
        "name":"search_catalog","arguments":{"query":"Lennox","limit":5}}}'

Check service-area coverage:

curl http://ai-interfaces.toolbox.contractorcommerce.com/companies/000qeNvgDSrmHEbIejt1beAWureP3Z5HrsB3NZFq/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{
        "name":"check_service_area","arguments":{"postal_code":"63376"}}}'
Errors. Unknown methods return JSON-RPC -32601; unknown tools -32602; invalid tool arguments return a result with isError: true and an explanatory message, per the MCP tool-error convention.

3 · WebMCP embed (in-browser agents)

GET/webmcp.js

A drop-in script that exposes the same catalog tools to AI agents running inside the visitor's browser via the emerging WebMCP (navigator.modelContext) API. Add one tag to the company's site — the script discovers the tools from the MCP endpoint above and registers them; no keys or server calls on the contractor's part:

<script type="module"
        src="https://ai-interfaces.toolbox.contractorcommerce.com/webmcp.js"
        data-plugin-key="000qeNvgDSrmHEbIejt1beAWureP3Z5HrsB3NZFq"></script>
Experimental. WebMCP is a W3C Community Group draft; today it runs only in Chrome 146+ behind the enable-webmcp-testing flag (origin trial in 149). The tag is a safe no-op in browsers without it. The tools, arguments and behavior are identical to the MCP server above — this is just a browser-native delivery of the same catalog.

4 · Source tracking

Any endpoint accepts an optional source query parameter. When present, the request is recorded — the source label, the endpoint path, the HTTP method, and a timestamp — so you can attribute traffic to a campaign, referrer, or integration. It is optional, never changes the response body or status, and is ignored when omitted or empty.

GET/companies/{pluginKey}.jsonld?source=your-label

Append ?source= (any short label) to any endpoint URL — for example:

curl "http://ai-interfaces.toolbox.contractorcommerce.com/companies/000qeNvgDSrmHEbIejt1beAWureP3Z5HrsB3NZFq.jsonld?source=newsletter"
Optional & non-intrusive. The parameter only adds an attribution record; requests without a source are not tracked. Use a stable label per channel (e.g. newsletter, partner-acme) so hits group cleanly.

5 · Data freshness

The mirror is synchronized from the source platform's API on a recurring incremental schedule; offer groups and price ranges are rebuilt after each sync. Prices reflect the company's published catalog at the time of the last sync.