Skip to main content
Glama
Thethirdone3

merchant-catalog-mcp

by Thethirdone3

merchant-catalog-mcp

A small, production-quality MCP (Model Context Protocol) server in TypeScript. It exposes a mock merchant catalog to any MCP-compatible client (Claude Desktop, the MCP Inspector, IDE agents, etc.) through three tools — search, availability, and ordering. The data is intentionally in-memory: this project is a clear, readable demonstration of the protocol, not a data layer.


What it does

The server exposes three tools over the MCP stdio transport:

Tool

Input

What it returns

search_products

query (string, required), category (enum, optional)

Products whose name/description match the query, optionally filtered by category.

check_availability

productId (string, required)

Stock status (in_stock / low_stock / out_of_stock) and on-hand quantity.

place_order

productId (string), quantity (positive integer)

Validates against stock, decrements it, and returns a mock order confirmation. Errors (bad id, not enough stock) come back as tool results flagged isError.

Every tool also declares an outputSchema and returns structuredContent, so clients receive typed objects, not just text.

It also exposes the other two MCP primitives:

Primitive

Name

What it is

Resource

catalog://products

The full catalog as a read-only JSON resource the host can pull into context.

Prompt

gift_finder

A user-invoked template (occasion, budget) that composes a catalog gift-recommendation request.


Related MCP server: UCP MCP Storefront

How the MCP pieces fit (the 60-second tour)

  • Host / client / server. A host app (Claude Desktop, the Inspector) runs an MCP client that connects to one or more servers. This repo is one server.

  • A server exposes three kinds of things. Tools (model-callable actions), resources (read-only data the app pulls by URI), and prompts (user-invoked templates). This server demonstrates all three: three tools, a catalog://products resource, and a gift_finder prompt.

  • Transport = the pipe. Messages are JSON-RPC 2.0. With the stdio transport, the client launches this server as a subprocess and exchanges messages over stdin/stdout. (Because stdout is the protocol channel, all diagnostics in this server go to stderr.)

  • Input schema = the contract. Each tool declares its arguments with a zod schema. The SDK converts it to JSON Schema, advertises it during discovery, and validates every incoming call against it before the handler runs. The schema is what tells the model exactly how it's allowed to call the tool.

  • Output schema = the response contract. Each tool also declares an outputSchema and returns structuredContent — a typed object the client gets directly, validated by the SDK — instead of only stringified JSON in text.

  • Lifecycle. initialize (capability handshake) → tools/list (discovery) → tools/call (invocation) → structured result. State (stock levels) persists for the life of the process, so an order visibly reduces availability.


Project structure

src/
  catalog.ts   Domain layer: Product type, in-memory data, pure lookup/search/mutate helpers.
               No MCP imports — this is the "swap-in-a-database-here" seam.
  index.ts     Protocol layer: creates the McpServer, registers the three tools
               (input + output schema + handler), the catalog resource, and the
               gift_finder prompt, then connects the stdio transport.

The split is deliberate: business logic in catalog.ts, protocol wiring in index.ts. The tools are thin adapters over logic that could just as easily sit behind a real API or database.


Requirements

  • Node.js 18+ (developed on Node 24 LTS)

Install

npm install

Run

# Dev: run the TypeScript directly, no build step
npm run dev

# Production: compile to dist/ then run the compiled server
npm run build
npm start

On startup the server prints merchant-catalog-mcp running on stdio to stderr and then waits for JSON-RPC messages on stdin. (Running it in a bare terminal and seeing it "hang" is correct — it's waiting for a client to speak to it.)


Verify it works

Option A — MCP Inspector, UI mode

npm run inspect

This launches the official MCP Inspector and opens a browser panel. Steps:

  1. It auto-connects to this server over stdio.

  2. Open the Tools tab and click List Tools — you'll see all three, each with a form generated from its input schema.

  3. Select search_products, enter a query (e.g. speaker), and Run Tool.

  4. Try place_order with productId=sku-003, quantity=2, then run check_availability on the same id to watch stock drop.

Option B — MCP Inspector, CLI mode (scriptable)

# Discover tools
npx @modelcontextprotocol/inspector --cli node dist/index.js --method tools/list

# Call a tool
npx @modelcontextprotocol/inspector --cli node dist/index.js \
  --method tools/call --tool-name search_products --tool-arg query=speaker

# Place an order
npx @modelcontextprotocol/inspector --cli node dist/index.js \
  --method tools/call --tool-name place_order \
  --tool-arg productId=sku-002 --tool-arg quantity=1

Option C — raw JSON-RPC (what a client does under the hood)

{
  printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"raw","version":"1.0.0"}}}'
  printf '%s\n' '{"jsonrpc":"2.0","method":"notifications/initialized"}'
  printf '%s\n' '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
  printf '%s\n' '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_products","arguments":{"query":"headphones"}}}'
  sleep 0.5
} | node dist/index.js

Use it from Claude Desktop

Build first (npm run build), then add this server to your Claude Desktop MCP config. The file lives at:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "merchant-catalog": {
      "command": "/absolute/path/to/node",
      "args": ["/absolute/path/to/merchant-catalog-mcp/dist/index.js"]
    }
  }
}

Then fully quit and reopen Claude Desktop (it loads MCP servers only at startup). The three tools will appear in the tools menu.

Gotcha — use absolute paths for both command and args. Claude Desktop is a GUI app, so it launches this server with the system environment, not your shell's — it does not read ~/.zshrc/~/.bashrc and therefore may not find node on its PATH. Pointing command at the absolute path of your Node binary (find it with which node) avoids a "spawn node ENOENT" failure.


Catalog

Eight products across four categories (audio, wearables, home, accessories), including deliberately low-stock (sku-003, sku-008) and out-of-stock (sku-004) items so you can exercise the availability and validation paths. See src/catalog.ts.


Possible next steps

  • Swap catalog.ts for a real database — the protocol layer wouldn't change.

  • Add an HTTP/SSE transport for remote hosting (only the transport lines in index.ts change).

  • Add unit tests over catalog.ts and a CI workflow that runs tsc + tests.

License

MIT

Available Tools

3 tools
check_availabilityCheck availabilityA

Check the stock status and on-hand quantity for a single product, given its product id.

ParametersJSON Schema
NameRequiredDescriptionDefault
productIdYesThe product id to check, e.g. "sku-001".

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
statusYesCoarse stock status derived from the on-hand quantity.
quantityYesUnits currently on hand.

TDQS

A3.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided. The description only states the action, lacking disclosure of behavioral traits such as being read-only, authentication needs, or any limitations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no superfluous words, effectively communicating the tool's purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no annotations, output schema present), the description sufficiently covers the purpose, though it omits any non-obvious constraints.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the description adds no additional meaning beyond 'given its product id', aligning with the baseline for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses specific verb 'Check' and resource 'stock status and on-hand quantity for a single product', clearly distinguishing from siblings 'place_order' and 'search_products'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implicitly specifies use for a single product by requiring productId, but does not explicitly state when to avoid this tool or mention alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

place_orderPlace orderA

Place an order for a given quantity of a product. Validates the product exists and that enough stock is available, decrements stock, and returns a mock order confirmation.

ParametersJSON Schema
NameRequiredDescriptionDefault
quantityYesHow many units to order. Must be a positive integer.
productIdYesThe product id to order, e.g. "sku-001".

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameYes
totalYes
statusYes
orderIdYes
quantityYes
productIdYes
unitPriceYes
remainingStockYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description discloses key behaviors: product existence validation, stock availability check, stock decrement, and return of a mock confirmation. However, it does not mention idempotency, error handling, or whether the operation is reversible.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, using one sentence to state the purpose and two to describe behaviors. It is front-loaded and contains no fluff, though a more structured format could enhance readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema existence, the description does not need to detail return values. It covers purpose, validation, mutation, and mock return. However, missing details about error conditions and side effects slightly reduce completeness for a mutation tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters have descriptions. The description adds behavioral context about validation but does not provide additional syntax or format details beyond the schema. Therefore, a baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'place an order' and identifies the resource as an order for a product. It distinguishes from sibling tools like check_availability and search_products by detailing the full order process including validation, stock decrement, and confirmation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implicitly indicates when to use the tool (to place an order) but lacks explicit guidance on when not to use it or alternatives. Mentioning that check_availability should be used first for stock verification would improve clarity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_productsSearch productsA

Search the merchant catalog by keyword, with an optional category filter. Returns matching products with id, name, price, and stock.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesKeyword to match against product name and description.
categoryNoOptional category to restrict results to.

Output Schema

ParametersJSON Schema
NameRequiredDescription
countYesNumber of products matched.
productsYesThe matching products.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries full burden. It discloses return fields (id, name, price, stock) but omits details like pagination, sorting, rate limits, or whether the operation is read-only.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no redundancy. First sentence presents the purpose, second summarizes the output. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple search tool with an output schema, the description is sufficient. It covers the main functionality and output fields, though it could mention pagination or error handling for completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the description adds minimal meaning beyond the schema. It mentions the return fields but does not elaborate on parameter usage beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches the merchant catalog by keyword with an optional category filter, distinguishing it from sibling tools like check_availability and place_order.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like check_availability or place_order, nor any prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A4/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: searching products, checking stock, and placing orders. There is no overlap or ambiguity.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (search_products, check_availability, place_order), making them predictable.

Tool Count5/5

Three tools is well-scoped for a simple merchant catalog server, covering the core search, stock check, and order operations without excess.

Completeness4/5

The tool set covers search, stock inquiry, and ordering. A minor gap is the lack of a dedicated get_product_details tool, but search can compensate.

Maintenance

ActivityStale
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    A UCP-compliant MCP storefront server that exposes product catalog operations (search, cart, checkout) as MCP tools, following UCP schema version 2026-04-08.
    5
    MIT
  • F
    license
    A
    quality
    B
    maintenance
    An MCP server that enables natural language catalog search, cart management, and checkout workflows against the Fake Store API, with strict schemas and session-persistent carts.
    8

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Thethirdone3/merchant-catalog-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server