Skip to main content
Glama
mukundjha-mj

commerce-operations-mcp

by mukundjha-mj

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.

Related MCP server: semley

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: not deployed yet. After deployment, document POST https://<elastic-ip>.sslip.io/mcp here and deliver the bearer token out of band.

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

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.

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.

  • Deployment, public URL, repository URL, and four-to-five-minute video still require operator-owned external accounts and are 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.

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Servers

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

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/mukundjha-mj/commerce-operations-mcp'

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