Skip to main content
Glama

CatalogMCP

CI

Setting up a digital product catalog today is either slow (click through a UI for every attribute and rule) or expensive (script it against an API, which turns labor cost into engineering cost for every future change). This is a spike proving a third option: an agent talking to a governed MCP tool surface can replace both. A catalog admin describes what they want in plain language — "add a Weight attribute in kg, required for all Industrial-line products" — and an agent executes it through tools that preview, log, and gate every change. Setup becomes a conversation instead of a UI marathon or an engineering ticket.

Demo

šŸŽ„ Watch the recorded demo — screen recording of the exact run described below.

The scripted client in demo/client.ts drives this server through a real Claude tool-use loop (Anthropic Messages API, no mocking) and walks through:

  1. Browsing the empty catalog.

  2. A natural-language request to set up the catalog from an attached file of products and their attribute values — including the schema (attributes, a required-for-industrial-line rule) the import depends on.

  3. A dry-run preview surfacing two rows that fail validation, a back-and-forth to fix them, then a real commit of all five products.

  4. Reading the audit log the commit produced.

  5. Browsing the catalog again, now populated — closing the loop the same way it opened, via the agent, not a human refreshing a UI.

  6. A destructive request — delete the material attribute — held for confirmation with a data-aware blast-radius disclosure (5 affected products, by name), then confirmed.

  7. A closing beat: the same request attempted against a read-only instance, cleanly refused.

The full text transcript of that same run is in demo/transcript.txt — reproducible yourself by running npm run demo.

Related MCP server: Salesforce-to-Glider MCP Server

What makes this MCP (not just an API)

MCP is a wire protocol — JSON-RPC 2.0 messages over a transport (stdio here; HTTP/SSE elsewhere) — not a coding convention. A small, fixed set of method names is standardized by the spec itself, so any compliant client (Claude Desktop, this repo's own demo/client.ts, any other agent framework) can talk to this server without knowing anything about catalogs, attributes, or rules ahead of time.

The protocol methods

Method

Direction

Purpose

initialize

client → server

Handshake: exchange protocol versions, negotiate capabilities

notifications/initialized

client → server

Client confirms it's ready

tools/list

client → server

Discovery — "what can you do?" Returns every tool's name, description, and JSON Schema input shape

tools/call

client → server

Invocation — "do this one, with these arguments"

That's the entire surface an agent needs to know in advance. There's no POST /create_attribute endpoint — an agent calls tools/call with {"name": "create_attribute", "arguments": {...}}. A trimmed real exchange with this server:

// → client
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05", ...}}

// ← server
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{"listChanged":true}},"serverInfo":{"name":"catalog-mcp","version":"0.1.0"}}}

// → client
{"jsonrpc":"2.0","id":2,"method":"tools/list"}

// ← server — every tool below, as name + description + JSON Schema
{"jsonrpc":"2.0","id":2,"result":{"tools":[{"name":"list_attributes", ...}, ...]}}

How it works in this codebase

We never wrote a tools/list or tools/call handler. Every call to server.registerTool(name, config, handler) in src/tools/ appends to an internal registry inside @modelcontextprotocol/sdk's McpServer. The SDK answers tools/list by dumping that registry (converting our Zod schemas to JSON Schema along the way) and answers tools/call by looking the requested name up in the same registry and invoking its handler — none of that is our code. It's also why the governance layer (src/governance/governed-registration.ts) wraps registerTool itself rather than hooking into some HTTP middleware layer: that single call is the only seam every tool invocation is guaranteed to pass through.

The tools

12 tools, grouped by what they operate on. Every mutating tool accepts dryRun: true for a no-persist preview; full argument shapes are in src/tools/.

Schema (catalog structure — attributes, rules)

Tool

Args

Mutating?

list_attributes

—

no

get_attribute

name

no

create_attribute

name, type, enumValues?, unit?, dryRun?

yes

update_attribute

name, type?, enumValues?, unit?, dryRun?

yes

delete_attribute

name, confirmToken?

yes — destructive, two-phase

list_rules

—

no

create_rule

attributeName, productLines, dryRun?

yes

Content (actual products)

Tool

Args

Mutating?

list_products

—

no

get_product

sku

no

import_products

rows, dryRun?

yes — bulk, upsert, partial-commit

set_attribute_value

sku, attributeName, value, dryRun?

yes

Governance

Tool

Args

Mutating?

list_audit_log

—

no

Why the guardrails aren't optional

Nobody hands an ungoverned agent write access to a live product catalog. The preview/audit/approval layer isn't a safety feature bolted on afterward — it's the precondition that makes "just describe what you want" viable for something you can't afford to get wrong. Concretely, this server never lets a mutation happen blind:

  • Dry-run preview — every mutating tool accepts dryRun: true and returns the exact outcome without persisting anything.

  • Audit log — every tool call is recorded (timestamp, tool, args, actor, outcome) and readable via its own tool, not just claimed to exist.

  • Two-phase confirm on destructive ops — deleting an attribute first returns a blast-radius disclosure (a count and a sample of affected products) and a token; only a second call with that token executes, and if the catalog changed in between, the stale token is refused rather than honored.

  • Policy mode — the server can run fully read-only, refusing every mutating tool at the gate, for a locked-down deployment.

See CONTEXT.md for the domain glossary and CLAUDE.md for the full scope, tool surface, and explicit non-goals.

Setup

npm install
npm test     # domain, tool, and governance tests, plus the 6-step demo acceptance test
npm run dev  # start the MCP server over stdio (add --read-only to lock it down)
npm run demo # run the scripted Claude-driven demo client (needs ANTHROPIC_API_KEY)

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Enables managing Google Tag Manager and Google Analytics 4 through natural language, with tiered read/write/destructive safety controls including dry-run writes and two-phase confirmations for destructive actions.
    8
    1
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables conversational CRUD management of a service catalog and service orders, including item manipulation, search, and business-rule validation through natural language.
    -