Catalog Attribute Normalizer

com.acjlabsPublished by acjlabs.comOfficial publisherv0.1.2Updated Oct 24, 2026

Catalog attribute normalizer, taxonomy-grounded — no fabricated Google/Shopify category IDs.

VerifiedStreamable HTTPWeb executableData & AnalyticsBusiness & Commerce

Overview

AI-generated overview

Hosted MCP server that normalizes product catalog attributes and maps products to Google, Shopify and Amazon category taxonomies.

What you can do
  • Normalize a batch of raw products (title, description, raw attributes) into canonical sizes, colors, materials, gender and sleeve length, with provenance marking whether a value was cleaned up or inferred.
  • Map each product to category paths and leaf IDs for the Google, Shopify or Amazon taxonomies you request, with a confidence score per path.
  • Return one result per input product in the same order, with per-product errors instead of failing the whole batch.
When to use it
Useful when merging messy multi-source product data — a Shopify export, a supplier CSV, a marketplace scrape — into consistent attributes and grounded category mappings for feed or merchant-ops work.
Requirements
Remote streamable HTTP endpoint; no local install needed. Calling the tool requires an API key sent as an Authorization Bearer header, obtained by self-serve signup with an email address. Tool discovery works without a key. An optional npm client package exists for typed calls.
Before you install
The API key is shown once at signup and cannot be recovered, so store it immediately. Usage is metered per product, not per call: the free tier covers 500 products per month, and a batch larger than the remaining balance is refused entirely with a 402. Paid plans are listed as opening soon. Extracted attribute values and low-confidence or null leaf IDs should be checked. Amazon mapping is best-effort rather than taxonomy-verified. Product data is sent to a third-party hosted service that is…

Installation

In SourceWeft

  1. Open Catalog Attribute Normalizer in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/com.acjlabs%2Fcatalog-normalizer/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "catalog-attribute-normalizer": {
      "type": "http",
      "url": "https://catalog-normalizer.acjlabs.com/mcp"
    }
  }
}

README

Catalog Attribute Normalizer

Taxonomy-grounded catalog attribute normalizer — verified against the real Google Product Taxonomy, so it catches the plausible-but-wrong category IDs a generic LLM invents. Messy multi-source catalogs — titles, descriptions, images — in; consistent attributes, units, and grounded category mappings out. For merchant-ops teams and feed-tool developers wrangling a Shopify export, a supplier CSV, and a marketplace scrape that each spell "size" or "material" differently.

What it does

  • Accepts a batch of raw products (title, description, raw_attributes), returns normalized attributes (canonicalized sizes/colors/units) plus category mappings for whichever taxonomies you request (Google Product Taxonomy, Shopify, Amazon).
  • Works as an MCP server (normalize_catalog tool) or a plain HTTPS API.

Example (MCP tool call)

json
{  "tool": "normalize_catalog",  "input": {    "products": [{ "title": "...", "description": "...", "raw_attributes": { "size": "Lrg", "Color": "Navy Blue" } }],    "target_taxonomies": ["google", "shopify"]  }}
json
{  "results": [    {      "schema_version": "2.0",      "source_title": "...",      "category_paths": {        "google": { "path": ["Apparel & Accessories", "Clothing", "Shirts & Tops"], "leaf_id": null, "confidence": 0.9 },        "shopify": { "path": ["Apparel & Accessories", "Clothing", "Tops"], "leaf_id": "aa-3-1", "confidence": 0.85 }      },      "attributes": {        "size": { "value": "L", "provenance": "canonicalized" },        "color": { "value": "navy", "provenance": "canonicalized" }      }    }  ]}

attributes is keyed by a controlled vocabulary (size, color, material, gender, sleeve_length — unrecognized keys are dropped, not passed through under a model-chosen name). Each value's provenance is "canonicalized" when it came from your own raw_attributes input for that product (deterministic cleanup only, no recall) or "extracted" when the model inferred it from the title/description and it wasn't in your input — treat "extracted" values as a suggestion, the same way you'd treat a low-confidence category_paths entry.

Attributes are reliable by construction — canonicalizing values already in your input, not recall. Category classification is retrieval-grounded, not recalled from memory: candidates are retrieved from the real, current Google and Shopify taxonomy files and offered to the model as suggestions, so a leaf_id almost always names a node that actually exists — measured against a 12-product evaluation set, each product checked against both the Google and Shopify taxonomies: 22 of 24 checks (91.7%) exact path + leaf-ID matches. Still treat confidence and a null leaf_id as "worth a quick check," not a guarantee — a leaf_id is only ever returned when the path independently verifies against the real taxonomy file, so a null there is an honest "check this" signal, never a fabricated ID. Amazon has no comprehensive public taxonomy reference file to retrieve candidates from, so it stays best-effort (recall from memory) rather than retrieval-grounded.

Pricing

The free tier is self-serve today; paid plans are opening soon.

  • Free — 500 products/month, no card required. Self-serve today.
  • Pay-as-you-go (opening soon) — $0.01/product, no minimum.
  • Pro (opening soon) — $29/month for 5,000 products (~$0.0058/product effective).

Want a paid plan now? Register your interest and we'll set you up first.

What counts as one unit: one product, not one call. A normalize_catalog call carrying 40 products uses 40 of your monthly allowance; batching is a convenience, not a discount. A batch is all-or-nothing — if it is larger than your remaining balance, the whole call is refused with 402 (the body names required and remaining) and nothing is classified, so you are never billed for a partial result that looks complete. A call that fails outright costs nothing.

Getting a key

The MCP server is live at https://catalog-normalizer.acjlabs.com/mcp (the alternate https://acjlabs-catalog-normalizer.acjlabs.workers.dev/mcp address reaches the same deployment and keeps working, so existing configurations need no change). Free-tier keys self-serve — POST /v1/signup with { "email": "[email protected]" } returns your key directly in the response, good for 500 products/month, no card required. Store it immediately — it is shown once and cannot be recovered if lost (re-signup for a new one). See https://acjlabs-catalog.pages.dev for the same steps plus pricing and a comparison against alternatives. Paid keys provision the same way via a one-time claim link once Pro/pay-as-you-go billing is live.

Connecting it to an MCP client

With Claude Code:

bash
claude mcp add --transport http catalog-normalizer \  https://catalog-normalizer.acjlabs.com/mcp \  --header "Authorization: Bearer YOUR_API_KEY"

Any other MCP client that supports a remote HTTP server with a custom header (Cursor, Cline, VS Code, etc.) works the same way: point it at the URL above with an Authorization: Bearer YOUR_API_KEY header. A gateway or scanner that can only forward the raw key value (no Bearer prefix) also works — both forms authenticate. Tool discovery (initialize/tools/list) doesn't require a key at all; only calling normalize_catalog does.

See docs/quickstart.md for a full copy-paste walkthrough (getting a key, per-client configs, confirming the connection with curl) if you'd rather follow one linear guide.

npm client

Prefer a typed function over hand-rolling MCP JSON-RPC calls? @acjlabs/catalog-attribute-normalizer-client (live on npm) wraps the normalize_catalog tool call:

sh
npm install @acjlabs/catalog-attribute-normalizer-client
ts
import { createCatalogNormalizerClient } from "@acjlabs/catalog-attribute-normalizer-client";
const client = createCatalogNormalizerClient({  baseUrl: "https://catalog-normalizer.acjlabs.com",  apiKey: "...",});const results = await client.normalizeCatalog(products, ["google", "shopify"]);

Why not just use a category classifier?

Category-classification APIs tell you what a product is. They don't touch the messier problem: standardizing attributes across sources that each spell them differently. The vendors that do take on the broader job are enterprise sales-led — demo request, annual contract, no self-serve signup and no public price. See the full comparison, or read why "clean product data" is actually two different problems (canonicalization vs. classification, and why they fail differently).

Source availability & support

This repository hosts the documentation for the hosted service. The service implementation is not open source. Bug reports and feature requests are welcome in this repo's Issues; you can also reach us at [email protected].

Source: README.md at commit 0307ab0

Tools

1

normalize_catalog

Normalize Catalog

Normalizes a batch of catalog products (attribute canonicalization/extraction + category-path mapping into the requested target taxonomies: google, shopify, amazon). Returns one result per input product, same order: a NormalizedProduct on success, or { error, source_title } if that specific product's classification failed — one product's failure never voids the rest of the batch. attributes is keyed by a controlled vocabulary (size, color, material, gender, sleeve_length — unrecognized keys are dropped, not passed through under a model-chosen name) and each value carries provenance: "canonicalized" means it came from your own raw_attributes input for that product (deterministic cleanup only, no recall); "extracted" means the model inferred it from the title/description and it wasn't in your input — treat extracted values as a suggestion, not a confirmed fact about the product, the same way you'd treat a low-confidence category_paths entry. category_paths for google and shopify is retrieval-grounded against the real, current taxonomy files (not recalled from memory) — measured at 22/24 (91.7%) exact path+leaf_id matches on a 12-product evaluation set; amazon has no comparable public reference file, so it stays best-effort. Each entry's confidence (0-1) and leaf_id (null when not confident it matches a real node) are the honest signal regardless of taxonomy — treat a low-confidence or null-leaf_id result as a suggestion worth a quick human check, not a confirmed classification.

Parametersproductsrequiredtarget_taxonomiesrequired

Version history

1
  1. v0.1.2LatestSep 16, 2026

Score

90% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts

    Declare a license in the repository or the registry entry.

Other Acjlabs integrations