Skip to main content
Glama
ritz541

ecommerce-mcp

by ritz541

ecommerce-mcp

MCP server for commerce-operations self-service. Lets an AI agent look up order details, search orders, and process refunds (with manager-approval escalation) without needing developer or SQL access.

Endpoint: https://mcp.chavanpatil.com/mcp

The server is already hosted. Point an MCP client at the endpoint above and it will discover and call the tools below.

Tools at a glance

Tool

Purpose

Key inputs

get_order

Full order details, plus payment status, customer risk score, carrier status, order age, and refund eligibility

orderId

search_orders

Filtered, paginated order search, newest first

optional filters, limit, offset

refund_order

Auto-refund when the order meets the policy, otherwise create a manager-approval escalation

orderId, reason

get_audit_log

Durable before/after trail of every refund/escalation action for an order

orderId

Detailed docs for each tool below.

Related MCP server: MCP E-Commerce Agent

Connecting an agent harness

Any MCP client that supports Streamable HTTP can connect. The flow is the same across harnesses (verified with oh-my-pi and Kimi Code):

  1. Open the harness and run its add-MCP-server command (e.g. /mcp add on oh-my-pi or Kimi Code).

  2. Give the server a name, e.g. ecommerce-mcp.

  3. Enter the endpoint URL: https://mcp.chavanpatil.com/mcp.

  4. The harness connects, detects that no authentication is required, and reads the available tools automatically.

Then ask the agent to use the tools, e.g.:

Use the ecommerce-mcp tools to look up order ORD-001 and summarize it.

MCP Tools

All tools return structured JSON (a JSON string in the MCP text content block). Tool results are the parsed JSON; never formatted prose.

Conventions

  • Null contract: fields are always present. When there is no value (e.g. tracking, notes), they are null — never omitted.

  • Errors: every error response is { "ok": false, "message": "..." } with the MCP isError flag set to true. On success isError is unset.

  • Unknown parameters: unrecognized arguments are silently ignored (never an error).

  • Sort order: search_orders results are sorted by created descending, with id descending as a tiebreaker — the sort is deterministic and stable for pagination.

  • IDs: order IDs look like ORD-001 (^ORD-\d{3}$); refund IDs REF-<hex> and escalation IDs ESC-<hex> are generated per action.

Rate limiting

The MCP endpoint is public, so POST /mcp is rate-limited per client IP to protect against abuse and runaway agent loops.

  • Default: 300 requests per minute (RATE_LIMIT_MAX, RATE_LIMIT_WINDOW_MS ms).

  • Over the limit returns HTTP 429 with a Retry-After header and a JSON-RPC error body.

  • Configure via environment variables (e.g. inline RATE_LIMIT_MAX=120 npm start, or Environment=RATE_LIMIT_MAX=120 in a systemd unit).

  • GET /health is intentionally not rate-limited (readiness polling).

get_order(orderId)

Look up a single order by ID.

Param

Type

Required

Notes

orderId

string

yes

e.g. ORD-001, matches ^ORD-\d{3}$

Response — a single order object:

Field

Type

id

string

customer

string

email

string

status

string — pending / processing / shipped / delivered / cancelled

items

array of { name: string, qty: number, price: number }

total

number

created

string (YYYY-MM-DD)

tracking

string | null

notes

string | null

Example request → response:

{ "orderId": "ORD-004" }
{
  "id": "ORD-004",
  "customer": "Dave Wilson",
  "email": "dave@example.com",
  "status": "pending",
  "items": [{ "name": "Laptop Stand", "qty": 1, "price": 44.99 }],
  "total": 44.99,
  "created": "2026-07-10",
  "tracking": null,
  "notes": "Awaiting payment"
}

Error example — get_order({ "orderId": "ORD-999" }):

{ "ok": false, "message": "Order ORD-999 not found." }

search_orders(filters)

Search orders, newest first. All filters are optional and combined with AND.

Param

Type

Required

Notes

status

string

no

enum: pending / processing / shipped / delivered / cancelled

customer

string

no

substring match

email

string

no

substring match

dateFrom

string

no

created >= date (YYYY-MM-DD)

dateTo

string

no

created <= date (YYYY-MM-DD)

limit

number

no

1–10, default 10 (silently clamped)

offset

number

no

default 0, for pagination

Response — a JSON array of order objects (list view: no items/notes):

Field

Type

id

string

customer

string

email

string

status

string

total

number

created

string

tracking

string | null

Example — page 2 of shipped orders:

{ "status": "shipped", "limit": 2, "offset": 2 }
[]

No matches returns an empty array (not an error).

refund_order(orderId, reason)

Process a refund request against the client's refund policy. Idempotent: retries never issue a duplicate refund or a duplicate escalation.

Param

Type

Required

Notes

orderId

string

yes

e.g. ORD-016, matches ^ORD-\d{3}$

reason

string

yes

non-empty; recorded in the audit log

The order is checked against the refund policy automatically. A refund is issued immediately only when all of these hold:

  • amount ≤ $150

  • amount ≤ the paid amount (payment captured as paid)

  • order created within the last 30 days

  • customer risk score below 70

  • the carrier exception is verified (carrier_status is exception)

  • no refund already exists for the order

Otherwise the request is flagged for manager approval (an escalation is created) with the failing conditions listed as reasons.

Response — mode is one of:

Field

Type

Notes

ok

boolean

always true on a handled outcome

mode

string

automatic | escalated | already_refunded

refundId / escalationId

string

only for automatic / escalated

amount

number

only for automatic

refundedAt

string

only for automatic (ISO timestamp)

reasons

string[]

only for escalated — why auto-refund was denied

status

string

only for escalatedpending_approval

refund

object

only for already_refunded — the existing refund

Example — eligible order refunded automatically:

{ "orderId": "ORD-016", "reason": "Damaged on delivery; carrier exception confirmed" }
{
  "ok": true,
  "mode": "automatic",
  "orderId": "ORD-016",
  "refundId": "REF-3f9a1c2d",
  "amount": 49.99,
  "refundedAt": "2026-07-31T14:02:11.000Z",
  "message": "Refund issued automatically."
}

Example — order too old, escalated to a manager:

{ "orderId": "ORD-017", "reason": "Customer requests refund" }
{
  "ok": true,
  "mode": "escalated",
  "orderId": "ORD-017",
  "escalationId": "ESC-7b4e209a",
  "status": "pending_approval",
  "reasons": ["Order is older than the 30-day window", "Carrier exception is not verified"],
  "message": "Refund requires manager approval."
}

Re-running refund_order on the same order returns the existing outcome (mode: "already_refunded" or the same escalation) instead of creating a second record.

get_audit_log(orderId)

Return the durable audit trail for an order — every refund/escalation action with before/after snapshots.

Param

Type

Required

Notes

orderId

string

yes

e.g. ORD-016, matches ^ORD-\d{3}$

Response — a JSON array of audit entries, newest first:

Field

Type

ts

string (ISO timestamp)

orderId

string

action

string — refund.automatic / refund.escalated

actor

string

reason

string

before

JSON string — payment snapshot before the action

after

JSON string — outcome snapshot (e.g. refundId, amount, escalation reasons)

outcome

string — refunded / escalated

Example — after refunding ORD-016:

{ "orderId": "ORD-016" }
[
  {
    "ts": "2026-07-31T14:02:11.000Z",
    "orderId": "ORD-016",
    "action": "refund.automatic",
    "actor": "ops_agent",
    "reason": "Damaged on delivery; carrier exception confirmed",
    "before": "{\"status\":\"paid\",\"amount\":49.99,\"method\":\"credit_card\"}",
    "after": "{\"paymentStatus\":\"refunded\",\"refundId\":\"REF-3f9a1c2d\",\"amount\":49.99}",
    "outcome": "refunded"
  }
]

Demo order map

The seed ships several orders that exercise each refund outcome, three per scenario. Use a fresh order each time you want to re-demo a path (no reset needed).

Scenario

Orders

refund_order result

Auto-eligible

ORD-101ORD-103

automatic

Over the $150 auto-refund limit

ORD-201ORD-203

escalated (amount limit)

Amount exceeds the paid amount

ORD-301ORD-303

escalated (paid amount)

Older than 30 days

ORD-401ORD-403

escalated (age)

High-risk customer

ORD-501ORD-503

escalated (risk score)

Carrier exception not verified

ORD-601ORD-603

escalated (carrier status)

Already refunded

ORD-701ORD-703

already_refunded

Each escalation order fails exactly one rule, so reasons contains a single entry. See DATA.md for the schema, seed rationale, and why certain records look inconsistent.


All data is synthetic. The server is exposed over Streamable HTTP (JSON-RPC POST /mcp).

License

ISC

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers