catalog-agent
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@catalog-agentFind books with 5 or fewer in stock, lowest stock first."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
catalog-agent
An MCP server for a product catalogue: it lets an MCP client over stdio (tested with Claude Code and MCP Inspector) search products and change their price and stock, safely. It's TypeScript on the official MCP SDK v2, over the catalogue API from my sister repo product-catalog at its v1.1.0 tag. Phase 2 will add my own tool-calling agent loop on top, with OpenRouter models and real-model evals.
It's also a record of how I work with an AI coding assistant (Claude Code): what it wrote, what I decided and checked, and where it got things wrong.

Claude Code finds low-stock books, dry-runs a restock, applies it after I confirm, then hits a change someone else made in between (STALE_VERSION) and asks me before overwriting it. Full transcript.
At a glance
Who I am: a backend engineer (about 5.5 years: NestJS/TypeScript, Go, PostgreSQL, Redis, OpenSearch). I'd used MCP servers but never built one. This is a personal project.
Status: Phase 1, the MCP server, is released as
v0.1.0(milestones M0–M4). Phase 2, the agent loop and its evals, comes next.What it shows:
six tools designed for a model as the reader: bounded inputs, small outputs, errors that say how to recover
least privilege in two layers: write tools exist only when configured, and the API key's scope limits every call; delete and reindex are never exposed
writes that are never blindly retried: version-checked updates, dry runs, and a confirm-after-timeout path that can't apply a write twice
tests without an LLM: 327 unit and MCP-level tests, and 61 integration tests against the real API, about half of them through the spawned stdio server
Who did what:
The AI (Claude Code)
Me
Spec
Wrote the brief, REQUIREMENTS.md
Design
Read the official docs and the code; researched how well-known MCP servers solve the same problems; proposed the options
Made every decision (ADRs); chose against its recommendation where I disagreed
Build
Wrote all the code, tests, CI and docs, one planned milestone at a time
Reviewed every milestone: the tour, the files, the reviewer's findings
Checks
Ran every suite and mutation check; a separate AI reviewer checked each milestone's whole diff
Ran the demos in Claude Code and MCP Inspector
Proof: a plan and a note per milestone in docs/milestones/, six ADRs, what the review loop caught, and a co-author trailer on every commit made with the AI.
Related MCP server: inventory-mcp
Architecture
Claude Code / MCP Inspector / any stdio host the MCP host and client
│ MCP over stdio: JSON-RPC on stdin/stdout, logs on stderr
▼
┌───────────────────────────────────────────────┐
│ catalog-agent MCP server (Node 24, this repo) │ 6 tools; CATALOG_ACCESS=read|write
│ tools → CatalogClient: timeouts, read │
│ retries, conditional writes │
└──────────────────────┬────────────────────────┘
│ HTTP, Authorization: Bearer <key> (read or write scope)
▼
catalog-api v1.1.0 (NestJS) ──── PostgreSQL, Redis
│
search-service (Go) ──────────── OpenSearchHow it works, in detail (the MCP basics, the tools, errors, reliability, tests): docs/how-it-works.md.
Run it
Windows 11 with Docker Desktop (WSL2, at least 8 GB), Node 24, PowerShell. Every command, with what to expect, is in AGENTS.md under "Commands".
Create
.envfirst:Copy-Item .env.example .env. It holds the read key andCATALOG_ACCESS=read: the three read tools. For the write tools, change both lines:CATALOG_ACCESS=writeand the write key,dev-write-key-not-secret-000000000000000. The dev keys are public, from product-catalog, and not secret.Start the catalogue and seed it (the first build takes about 3 minutes):
docker compose up --build -d --wait docker compose run --rm -e CATALOG_API_URL=http://catalog-api:3000 -e CATALOG_API_KEY=dev-admin-key-not-secret-000000000000000 catalog-api node dist/seed/main.jsBuild the server:
npm ci, thennpm run build.Claude Code: run
claudein this folder and approve thecatalogserver (.mcp.json); check it with/mcp. Then ask, for example: "Find books with 5 or fewer in stock, lowest stock first." After editing.env, reconnect from/mcp.MCP Inspector (no LLM):
npx -y @modelcontextprotocol/inspector@2.12.0 --cli --config .mcp.json --server catalog --method tools/call --tool-name search_products --tool-arg category=books maxStock=5 sort=stock_asc size=3Leave out
--clifor the web UI.Tests:
npm test(no stack needed) andnpm run test:int(against the running stack, about 2 minutes).
The tools
Tool | Access | What it does |
| read | Filtered search (text, category, brand, price, |
| read | One product in full, with the |
| read | Categories, brands and price buckets with counts, so the model learns valid filters |
| write | Adds a product; never retried |
| write | Sets an absolute value with |
Errors are results the model can act on: a code, whether to retry, and a hint, often naming the next tool call. A stale version is
STALE_VERSIONwith the current version.Reliability: reads retry with jittered backoff; writes never retry blindly. After a timeout, a set call re-reads the product and decides from its version whether the write landed. ADR-0004.
Design decisions
ADR | Decision |
A tiered context system for the AI assistant | |
Toolchain and pins: MCP SDK v2, TypeScript 7, Vitest 5 | |
catalog-api | |
Read retries, conditional writes, confirm after a timeout | |
Tool results: text and structured content, errors, pagination, protocol eras | |
Write tools: access mode, annotations, dry runs, no-op writes |
What I'd change in production
A remote server over Streamable HTTP with OAuth 2.1 (no token passthrough to the API); a lookup by SKU or idempotency keys for create; a cache-bypassing read before a write; a deadline for a whole set call; an error schema once the MCP spec has one; OpenTelemetry traces and per-caller rate limits. Details: how-it-works.md.
How the AI was used
The loop, per milestone: the AI read the code and docs and asked me the real decisions; it wrote an ADR and a plan, built test-first with nothing committed, and a fresh AI reviewer checked the whole diff before I reviewed it. The context system behind it: docs/ai-workflow.md.
Its mistakes are recorded, with who caught them, in what the review loop caught. For example:
it missed a key-leak path its sister repo had already closed (found by the reviewer)
it built error results on the SDK's behaviour without checking a second client; my demo in Inspector showed they broke the spec
a cancelled write call still wrote (found by the reviewer)
License
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted MCP for e-commerce: live product catalog, stock, and pricing for AI agents.
Merchant product catalogs for AI agents: price, availability, specs, variants, buy links. Read-only.
MCP server for Product Management
Agent-native marketplace. Bootstrap, list inventory, search, negotiate, and trade via MCP.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server exposing Shopify commerce backend with ~22 typed tools for orders, inventory, logistics, and fulfillment, including read/write separation and structured errors.ISC
- FlicenseNot gradedqualityCmaintenanceA read-only MCP server for querying product inventory, providing tools to retrieve product details and stock quantities.-
- AlicenseBqualityCmaintenanceEnables MCP clients to manage an e-commerce product catalog in MySQL, including creating, reading, updating, deleting, and searching products, plus AI-generated descriptions and low-stock monitoring.49 npmMIT
- AlicenseAqualityBmaintenanceEnables MCP clients to search and inspect a catalog of 125 commerce, inventory, and data skills, invoke them with explicit spending limits, and check wallet balances and receipts.5MIT