commerce-operations-mcp

commerce-operations-mcp

Helps a commerce operations analyst investigate stuck synthetic orders, diagnose blockers from stored facts, and create auditable human-review escalations without changing fulfillment state.

Category
Visit Server

README

Commerce Operations MCP

A focused MCP v2 service that helps a commerce operations analyst investigate a stuck synthetic order, explain the blocker from stored facts, and create an auditable human-review escalation without changing fulfillment state.

The repository was initialized with the official Turborepo generator and then reduced to three TypeScript workspaces:

  • apps/mcp-server: authenticated stateless Streamable HTTP MCP and health endpoints
  • packages/domain: deterministic diagnosis, validation schemas, and domain errors
  • packages/database: Drizzle schema/migrations, stable fixtures, queries, and serializable escalation transaction

Product scope

The MCP is deliberately read-heavy and exposes exactly one bounded write. It has three tools:

  • get_order_context reads the order, latest payment, required inventory lines, and latest fulfillment attempt.
  • diagnose_order_blocker selects exactly one diagnosis using documented deterministic precedence. It never mutates state.
  • create_order_escalation creates only a human-review escalation, and only with confirmed: true, the diagnosed order version, and a stable idempotency key. It never changes the order or fulfillment attempts.

No frontend, real commerce integration, automated remediation, arbitrary mutation, customer PII, or production payment/provider action is included. Retry, requeue, reroute, cancellation, and address modification are explicitly prohibited.

Architecture

MCP client -> HTTPS/Caddy -> TypeScript MCP v2 server -> Drizzle/pg -> Neon PostgreSQL
                                |
                                +-> deterministic domain policy

The domain policy is separate from MCP transport and persistence. Repository reads, joins, inserts, conflict handling, row locks, updates, transactions, fixture writes, and test assertions use Drizzle ORM against the schema definitions. The write transaction reserves the idempotency key, locks and rechecks the order and diagnosis, creates the escalation and audit event, and stores the replay result under SERIALIZABLE isolation. It contains no fulfillment-attempt insertion or order update. A failed transaction leaves no durable PENDING request. Raw SQL is limited to generated/custom migrations and PostgreSQL/operator controls such as SET LOCAL statement_timeout, transaction commands in CLI scripts, and schema teardown.

Prerequisites and setup

  • Node.js 22+ locally; the production image uses the maintained Node.js 24 Bookworm-slim tag
  • npm 10.9.8
  • A PostgreSQL/Neon connection containing synthetic data only

Oxlint provides the real TypeScript-aware lint stage. It was selected because current stable typescript-eslint does not yet declare compatibility with the pinned stable TypeScript 7 compiler; type correctness remains a separate npm run typecheck gate.

npm install
cp .env.example .env
npm run db:migrate
npm run db:seed
npm test
npm run test:integration
npm run test:mcp
npm run build
npm run dev

The .env values must include a random demo token of at least 32 characters and a UTC expiry no more than seven days ahead. For Neon, use sslmode=verify-full in DATABASE_URL. Never commit or publish the token.

Operator-only database commands:

  • npm run db:reset deterministically restores the five fixtures.
  • npm run db:fresh drops only this application's seven synthetic tables and Drizzle metadata, reapplies migrations, and seeds. It is destructive and is never exposed as an MCP tool.

HTTP and MCP usage

Local endpoint: POST http://127.0.0.1:3000/mcp

Hosted endpoint: POST https://mcp.mukundjha.dev/mcp

Source repository: https://github.com/mukundjha-mj/commerce-operations-mcp

The bearer token is delivered out of band and expires within seven days.

Every MCP POST requires:

  • Authorization: Bearer <demo-token>
  • MCP-Protocol-Version: 2026-07-28
  • Mcp-Method exactly matching the JSON-RPC method
  • Mcp-Name exactly matching params.name for tools/call, and omitted for discovery/listing

For Postman, import postman/commerce-operations-mcp.postman_collection.json, leave baseUrl as https://mcp.mukundjha.dev, and set its demoToken collection variable to the short-lived bearer token provided privately. The collection contains no token and is safe to commit.

Example tool listing:

curl -X POST http://127.0.0.1:3000/mcp \
  -H "Authorization: Bearer $DEMO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/list" \
  --data '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'

Health checks:

  • GET /health/live proves the process is running.
  • GET /health/ready runs a minimal database query and exposes no internals.

Stable fixtures

Order Expected diagnosis Escalation
ord_timeout_001 FULFILLMENT_PROVIDER_FAILURE Allowed after confirmation
ord_address_002 FULFILLMENT_NON_RETRYABLE_FAILURE Allowed after confirmation
ord_payment_003 PAYMENT_NOT_CAPTURED Allowed after confirmation
ord_done_004 FULFILLMENT_ALREADY_COMPLETE Refused
ord_inventory_005 INVENTORY_NOT_RESERVED Allowed after confirmation

Safety and operational behavior

  • Strict Zod objects reject malformed and unknown fields.
  • Required inventory comes from order items and left-joins reservations, so a missing reservation cannot disappear from the evidence.
  • Diagnosis never implies authorization. confirmed: true is caller attestation, not proof of a human identity.
  • Version checking refuses stale diagnoses; idempotency replay returns the original escalation and audit IDs.
  • Escalation is the only mutation. Tests assert that order version/status and fulfillment-attempt count remain unchanged.
  • Origin allow-listing, expiring bearer token, 64 KiB body limit, 10-second request limit, eight-request concurrency cap, and in-memory source-IP/auth throttles protect the demo boundary. Forwarded client addresses are trusted only when TRUST_PROXY=true; Compose enables it because the app port is private behind Caddy, while direct local runs default to the socket peer.
  • Pino logs include correlation IDs, timing, tool outcome, and structured error codes while redacting credentials. MCP tool failures are recorded as errors even though the protocol transports them in HTTP 200 responses. Tool errors never return SQL, stack traces, or connection details.
  • The app binds to loopback locally. In Compose it is private behind Caddy; only ports 80/443 are published.

Token rotation: replace DEMO_TOKEN and DEMO_TOKEN_EXPIRES_AT, then recreate the app container. Emergency shutdown: stop the Compose stack or revoke its inbound 443 rule. Neither procedure logs the token.

Verification

npm run typecheck
npm run lint
npm test
npm run test:integration
npm run test:mcp
npm run build

Unit/HTTP tests cover diagnosis precedence, inventory precedence, strict inputs including forbidden retry actions, configuration expiry, authentication, origins, limits, health, MCP metadata, mandatory server discovery, and the three-tool listing. The Neon repository suite verifies context, all fixture diagnoses, atomic escalation/audit creation, replay, concurrent replay, idempotency conflict, stale version, refusal, unchanged operational state, and absence of durable pending rows. The separate MCP suite exercises the complete workflow through the real HTTP handler and Neon.

Deployment

Dockerfile, compose.yaml, and Caddyfile provide a reproducible single-host deployment using Neon as requested. Set MCP_HOSTNAME to the public hostname and make ALLOWED_ORIGINS match approved browser origins. Keep the app port private and expose only Caddy on 80/443.

For the requested Ubuntu 24.04 EC2 deployment in Mumbai (ap-south-1), follow the AWS HTTPS deployment runbook. It includes Elastic IP/sslip.io, security-group, secret, smoke-test, rotation, rollback, and emergency-shutdown steps.

See AI_WORKLOG.md for the AI-assisted implementation approach, corrections, verification, and limitations.

Assumptions, exclusions, and limitations

  • Neon replaces the PRD's single-host PostgreSQL container by explicit project direction.
  • The shared token identifies a demo client, not an individual approver.
  • In-memory rate limits are per process and are not a distributed production control.
  • There is no queue, tenant isolation, real provider retry, user management, or high-availability/DR design.
  • The four-to-five-minute video remains an operator-owned submission item and is not claimed complete.
  • Remote Neon latency makes integration tests slower than local unit tests.
  • npm audit --omit=dev reports the pinned MCP Node adapter through its Hono dependency because Hono's Windows static-file helper has a path-traversal advisory. This service never mounts or calls that static-file helper, runs in Linux, and no compatible upstream MCP dependency update is currently available. The remaining audit findings are development-only Drizzle Kit/esbuild tooling and are pruned from the runtime image.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured