inventory-doctor
Reads Amazon-style seller-sku/quantity TSV inventory exports for cross-source sync diagnostics, including SKU mismatches and oversell risk.
Compares inventory from Shopify product/inventory CSV exports or live Shopify Admin API stores, detecting SKU mismatches, oversell risk, blank-vs-zero quantities, barcode conflicts, and location-level drift.
Click on "Install 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., "@inventory-doctordiff these two CSV exports and flag any oversell risks"
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.
inventory-doctor
Multi-source inventory sync diagnostics — find the SKUs you're overselling without knowing it.
Compare two inventory snapshots (CSV exports or live Shopify stores) and get a report of everything that doesn't line up: SKU mismatches, oversell risk, blank cells masquerading as zeros, barcode conflicts, and more.
Your data never leaves your machine. CSV files are parsed locally; Shopify API calls go directly from your computer to your own stores over HTTPS. There is no server, no telemetry, no upload.
Install & run
npm install # or: pnpm install
npm run build # produces dist/cli.js (with shebang)
# zero-credential path: two CSV exports
npx tsx src/cli.ts diff fixtures/shopify-store-a.csv fixtures/shopify-store-b.csv
# or after build / npm link:
inventory-doctor diff a.csv b.csvRelated MCP server: DataClaw MCP Server
What it looks like
Running inventory-doctor diff fixtures/shopify-store-a.csv fixtures/shopify-store-b.csv against the bundled sample files (which deliberately contain one of every problem):
inventory-doctor — sync diagnosis
============================================================
Sources: shopify-store-a vs shopify-store-b
shopify-store-a: 13 records
shopify-store-b: 12 records
Sync health score: 33/100
exact match: 5 · minor drift: 0 · severe drift: 4 · unmatched: 6 (of 15)
CRITICAL (8)
------------------------------------------------------------
[CRITICAL] SKU "DUP-100" appears 2 times in shopify-store-a with different quantities
[CRITICAL] SKU "ORPHAN-A" exists in shopify-store-a but is missing from shopify-store-b
[CRITICAL] "OVER-1" is out of stock in shopify-store-a (0) but shows 8 available in
shopify-store-b — you may be selling stock you don't have
[CRITICAL] "BLANK-1" has a BLANK quantity cell in shopify-store-a (not "0") while
shopify-store-b tracks a real quantity — an import may read this as 0
[CRITICAL] Barcode 9999999 maps to 2 different SKUs across sources
("BC-A" in shopify-store-a vs "BC-B" in shopify-store-b)
...
WARNING (5)
------------------------------------------------------------
[WARN] SKU differs only by letter case: "ABC-123" (a) vs "abc-123" (b)
[WARN] SKU matches only after removing whitespace/invisible characters
[WARN] "CONT-1" allows overselling ("continue selling when out of stock") with quantity 0
...
INFO (3)
------------------------------------------------------------
[INFO] Possible prefix/suffix variant: "GHI-789" (a) vs "SHOP-GHI-789" (b)
[INFO] Sync health score: 33/100 — 5 exact, 0 minor drift, 4 severe drift, 6 unmatched
[INFO] "UNTRACKED-1" has inventory tracking OFF in shopify-store-a but is
stock-managed in shopify-store-bThe full output is checked in as fixtures/expected-report.md — it's a living document verified by the test suite.
The exit code is 1 when critical findings exist, so you can wire this into CI or a cron job.
The six diagnostic rules
Rule | What it catches | Severity |
| Case-only / whitespace / prefix-suffix SKU variants, orphan SKUs, one-to-many duplicates within one source | info → critical |
| Quantity ≤ 0 on one side but > 0 on the other; "continue selling when out of stock" with empty stock; drift beyond threshold | warning → critical |
| A blank quantity cell vs an explicit | critical |
| Same barcode, different SKUs across sources — silent mapping misconfiguration | critical |
| Overall sync health: % exact / minor drift / severe drift / unmatched → health score 0–100 | info |
| Inventory tracking disabled in one source while another manages stock | info |
Blank vs "0" is a first-class distinction. CSV parsers love turning empty cells into 0; this tool keeps quantity: null strictly separate from quantity: 0 all the way through.
Supported inputs
Shopify product CSV — both header generations are recognized (
Variant SKUand the currentSKU,Variant Inventory QtyandInventory quantity, etc.)Shopify inventory CSV — both layouts: the long "All states" table (one row per variant × location) and the wide "Available" table (location names as column headers, inferred automatically)
Anything else — alias-based column probing (Amazon-style
seller-sku/quantityTSVs work out of the box), plus explicit mapping when guessing fails:
inventory-doctor diff shopify.csv erp.csv --map sku="Item Code" --map quantity="Stock Count"SKU normalization (trim, case folding, full-width → half-width, zero-width character removal) is used only for comparison — reports always show your raw SKU values.
Multi-location aware. When both sources carry a location dimension (inventory CSV long/wide, or the API), quantities are compared per (SKU, location): a location-level stockout or drift is reported at that location and never hidden by summing across locations, and a SKU stocked at two locations is not mistaken for a duplicate. When one side has no location dimension (product CSV), its per-SKU quantity is compared against the other side's cross-location sum. See fixtures/shopify-inventory-c.csv / -d.csv (long format) and fixtures/shopify-inventory-wide-e.csv / -f.csv (wide format) for worked examples.
Shopify Admin API (optional)
Pull live snapshots instead of exporting CSVs. Create inventory-doctor.json in the project directory (or ~/.config/inventory-doctor/config.json):
{
"stores": [
// Mode 1: existing static token (shpat_... — still works if you already have one)
{ "name": "store-a", "domain": "a.myshopify.com", "accessToken": "env:STORE_A_TOKEN" },
// Mode 2: client credentials grant (the current way to create app credentials)
{ "name": "store-b", "domain": "b.myshopify.com",
"clientId": "env:STORE_B_CLIENT_ID", "clientSecret": "env:STORE_B_SECRET" }
]
}Credentials support "env:VAR_NAME" references so secrets stay out of files. Then:
inventory-doctor diff --store store-a --store store-b # store vs store
inventory-doctor diff --store store-a --csv b.csv # mixed modeDetails that matter:
API version pinned to 2026-07 (
/admin/api/2026-07/graphql.json).Inventory is read via
quantities(names: [...])— the oldInventoryLevel.availablefield no longer exists.Tokens from client credentials live 24h; they're cached and refreshed 60s early, not re-requested per call.
Rate limiting is adaptive: every response's
extensions.cost.throttleStatus.currentlyAvailabledrives a slow-down before the bucket empties; HTTP 429 /THROTTLEDbacks off 1s and retries. No plan-specific rate numbers are hardcoded.Read-only scopes only:
read_inventory,read_products,read_locations.
Client credentials limitation: the app and the store must belong to the same Shopify org. That covers "a merchant building a tool for their own store". Agencies managing client stores will get shop_not_permitted and need full OAuth — which this tool does not implement (v1).
MCP server (use it from Claude Code and other agents)
Add to your .mcp.json:
{
"mcpServers": {
"inventory-doctor": {
"type": "stdio",
"command": "npx",
"args": ["-y", "inventory-doctor", "mcp"],
"env": { "SHOPIFY_CLIENT_SECRET": "${SHOPIFY_CLIENT_SECRET}" }
}
}
}Three tools are registered:
diff_inventory(sourceA, sourceB, configPath?)— full diagnosis, returns the JSON reportexplain_sku(sku, sources, configPath?)— one SKU's raw values and findings across all sources (for follow-up questions)inventory_health(sources, configPath?)— lightweight health-score summary
Every source argument accepts either a CSV file path or store:<name> (a store from inventory-doctor.json, credentials resolved from env vars) — so an agent can diff two live stores, or a store against a CSV, in one call. configPath is only needed when the config file is not in a default location.
stdout is reserved for JSON-RPC; all logging goes to stderr.
Honest limitations
Snapshot diffing only. This compares two snapshots taken now. It does not do time-series detection (e.g. "this SKU gets silently zeroed every night") — that needs snapshot history and is planned for v2.
Client credentials = same org only, as described above. No OAuth flow in v1.
Amazon report headers vary by marketplace and report options; detection is best-effort via column aliases, and
--mapis the escape hatch.Product CSVs carry no per-location inventory; multi-location diagnosis needs the inventory CSV export or the API.
Development
npm test # vitest — rules, CSV adapters, token cache, throttle logic
npm run dev -- diff fixtures/shopify-store-a.csv fixtures/shopify-store-b.csv
npm run build # tsc + shebang
npm run check:stdout # guards the MCP stdout disciplineArchitecture: src/core/ is a pure-function diagnostic kernel ((records: InventoryRecord[]) => Finding[], zero I/O); src/adapters/ turn CSVs and the Shopify API into that intermediate representation; CLI and MCP layers only parse arguments and format output. Adding a new source (WooCommerce, BigCommerce, …) means adding one adapter, no refactor.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
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
Inventory, restock planning, and sales analytics for your Amazon FBA business.
Track price drops, stock-outs, restocks, and new/removed products across Shopify stores.
Check a product CSV, handles, variant matrices and metafield keys. 4 of 6 free.
Commerce intelligence for AI agents. Diagnose drop-offs, fix checkouts, optimize pricing.
Related MCP Servers
- AlicenseAqualityBmaintenanceMulti-channel inventory intelligence for Shopify and Amazon sellers. 28 tools for stockout risk, demand forecasts, purchase order management, and sales analytics — with human-in-the-loop safeguards.501632MIT
- FlicenseNot gradedqualityCmaintenanceAI-first CSV analysis tool that enables AI agents to analyze, query, and audit large CSV files directly within conversations, turning raw data into actionable insights.2-
- AlicenseAqualityDmaintenanceEnables Shopify store owners to get actionable business insights such as sales comparisons, inventory alerts, and recommendations, transforming raw data into meaningful decisions.1022MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to manage Shopify stores via natural language, with tools for products, orders, inventory, customers, and analytics.24MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/shidesheng0218/inventory-doctor'
If you have feedback or need assistance with the MCP directory API, please join our Discord server