> ## Documentation Index
> Fetch the complete documentation index at: https://learn.orbexa.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Commerce MCP Server design patterns

> MCP Server design patterns for e-commerce — product search, inventory queries, order management, return processing, and OTR trust queries

# Commerce MCP Server

## 5.1 Tool Design for an E-Commerce MCP Server

A complete e-commerce MCP Server typically includes the following tools:

| Tool Name         | Function            | Input                                | Output                          |
| ----------------- | ------------------- | ------------------------------------ | ------------------------------- |
| `search_products` | Search products     | query, category, priceRange, limit   | Product list                    |
| `get_product`     | Get product details | productId or sku                     | Full product information        |
| `check_inventory` | Check inventory     | sku, warehouse (optional)            | Inventory quantity and location |
| `get_price`       | Get price           | sku, quantity, couponCode (optional) | Real-time price with discounts  |
| `get_order`       | Get order           | orderId                              | Order status and details        |
| `list_orders`     | List orders         | userId, status (optional), limit     | User's order list               |
| `create_return`   | Initiate return     | orderId, items, reason               | Return request number           |
| `get_shipping`    | Track shipping      | orderId or trackingNumber            | Shipping status and tracking    |
| `get_categories`  | Get categories      | parentId (optional)                  | Category tree                   |
| `get_promotions`  | Get promotions      | category (optional)                  | Current promotion list          |

## 5.2 Tool Design Principles

### Single Responsibility

Each tool should do one thing. Do not combine search and ordering in the same tool. The AI model will automatically compose multiple tools based on context.

### Clear Descriptions

A tool's `description` directly affects when the AI model chooses to use it. Be explicit about:

* What the tool does
* When it should be used
* What type of data it returns

```typescript theme={null}
// Good description
"Search the product catalog with support for keyword, category, and price range filters. Returns product name, price, and stock status."

// Poor description
"Search products"
```

### Sensible Parameter Design

* Keep required parameters minimal (lower the barrier to use)
* Provide defaults for optional parameters
* Write specific parameter descriptions

### Leverage structuredContent

For return data that needs programmatic processing (such as price calculations, inventory comparisons), provide both `content` (for LLM reading) and `structuredContent` (for programmatic processing):

```typescript theme={null}
return {
  content: [{
    type: "text",
    text: "Nike Air Max (SHOE-001): $89.90, In Stock\nAdidas Ultra Boost (SHOE-002): $129.90, Out of Stock"
  }],
  structuredContent: {
    products: [
      { name: "Nike Air Max", sku: "SHOE-001", price: 89.90, inStock: true },
      { name: "Adidas Ultra Boost", sku: "SHOE-002", price: 129.90, inStock: false }
    ],
    total: 42,
    page: 1
  }
};
```

### Use isError to Distinguish Business Errors

For business issues encountered during tool execution (e.g., product not found, insufficient inventory), use `isError: true` instead of throwing an exception:

```typescript theme={null}
if (!product) {
  return {
    content: [{ type: "text", text: `SKU ${sku} not found, please check the code` }],
    isError: true
  };
}
```

## 5.3 Complete E-Commerce MCP Server Example

```typescript theme={null}
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new McpServer({
  name: "my-store-server",
  version: "1.0.0"
});

// ---- Product Search ----
server.tool(
  "search_products",
  "Search products. Supports keyword and category filtering. Returns product name, price, and stock status.",
  {
    query: { type: "string", description: "Search keyword" },
    category: { type: "string", description: "Category name (optional)" },
    minPrice: { type: "number", description: "Minimum price (optional)" },
    maxPrice: { type: "number", description: "Maximum price (optional)" },
    limit: { type: "number", description: "Number of results, default 10, max 50" }
  },
  async ({ query, category, minPrice, maxPrice, limit = 10 }) => {
    const filters: any = {};
    if (category) filters.category = category;
    if (minPrice) filters.price = { $gte: minPrice };
    if (maxPrice) filters.price = { ...filters.price, $lte: maxPrice };

    const results = await db.products.search(query, filters, Math.min(limit, 50));

    return {
      content: [{
        type: "text",
        text: JSON.stringify({
          results: results.map(p => ({
            name: p.name,
            sku: p.sku,
            price: p.price,
            currency: "USD",
            inStock: p.inventory > 0,
            category: p.category,
            url: `https://mystore.com/product/${p.slug}`
          })),
          total: results.totalCount,
          query
        }, null, 2)
      }]
    };
  }
);

// ---- Product Details ----
server.tool(
  "get_product",
  "Get full details for a single product, including description, specifications, ratings, and inventory.",
  {
    sku: { type: "string", description: "Product SKU code" }
  },
  async ({ sku }) => {
    const product = await db.products.findBySku(sku);
    if (!product) {
      return {
        content: [{ type: "text", text: `SKU not found: ${sku}` }],
        isError: true
      };
    }

    return {
      content: [{
        type: "text",
        text: JSON.stringify({
          name: product.name,
          sku: product.sku,
          description: product.description,
          price: product.price,
          currency: "USD",
          brand: product.brand,
          category: product.category,
          inStock: product.inventory > 0,
          inventory: product.inventory,
          rating: product.averageRating,
          reviewCount: product.reviewCount,
          specs: product.specifications,
          images: product.images,
          url: `https://mystore.com/product/${product.slug}`
        }, null, 2)
      }]
    };
  }
);

// ---- Order Query ----
server.tool(
  "get_order",
  "Query order status and details. Requires order ID.",
  {
    orderId: { type: "string", description: "Order ID" }
  },
  async ({ orderId }) => {
    const order = await db.orders.findById(orderId);
    if (!order) {
      return {
        content: [{ type: "text", text: `Order not found: ${orderId}` }],
        isError: true
      };
    }

    return {
      content: [{
        type: "text",
        text: JSON.stringify({
          id: order.id,
          status: order.status,
          createdAt: order.createdAt,
          items: order.items.map(i => ({
            name: i.name, quantity: i.quantity, price: i.price
          })),
          total: order.total,
          shipping: {
            method: order.shippingMethod,
            trackingNumber: order.trackingNumber,
            estimatedDelivery: order.estimatedDelivery
          }
        }, null, 2)
      }]
    };
  }
);

// ---- OTR Trust Query (ORBEXA Integration) ----
server.tool(
  "otr_verify",
  "Query a merchant website's OTR trust score. Returns six-dimensional trust assessment results.",
  {
    domain: { type: "string", description: "Merchant domain, e.g. example.com" }
  },
  async ({ domain }) => {
    const response = await fetch(
      `https://${domain}/.well-known/otr/verify`
    );
    if (!response.ok) {
      return {
        content: [{ type: "text", text: `${domain} has not deployed the OTR protocol` }],
        isError: true
      };
    }
    const otr = await response.json();
    return {
      content: [{
        type: "text",
        text: JSON.stringify({
          domain: otr.domain,
          trustScore: otr.trustScore,
          dimensions: otr.dimensions,
          badges: otr.badges,
          lastScan: otr.lastScan
        }, null, 2)
      }]
    };
  }
);

// Start
const transport = new StdioServerTransport();
await server.connect(transport);
```

## 5.4 Commerce Resource Design

Beyond tools, an e-commerce Server can also expose static context as Resources, enabling AI agents to understand your business:

```typescript theme={null}
// Return policy
server.resource(
  "commerce://policies/return",
  "Return Policy",
  "text/markdown",
  async () => {
    return "## Return Policy\n\n- 7-day no-questions-asked returns\n- Original packaging must be intact\n- Custom products are non-returnable";
  }
);

// Shipping zones
server.resource(
  "commerce://shipping/zones",
  "Shipping Zones",
  "application/json",
  async () => {
    const zones = await db.shippingZones.getAll();
    return JSON.stringify(zones, null, 2);
  }
);
```

When an AI agent answers questions like "Do you accept returns?", it automatically reads the relevant resource as context.

## 5.5 Permissions and Security

Commerce Servers require special attention to access control:

| Tool              | Permission Required     | Notes                                                                |
| ----------------- | ----------------------- | -------------------------------------------------------------------- |
| `search_products` | No authentication       | Public information                                                   |
| `get_product`     | No authentication       | Public information                                                   |
| `check_inventory` | Optional authentication | Rough inventory is public; precise inventory requires authentication |
| `get_order`       | Authentication required | Users can only view their own orders                                 |
| `create_return`   | Authentication required | Involves refund operations                                           |
| `otr_verify`      | No authentication       | OTR is a public protocol                                             |

For remote deployment, use OAuth 2.1 authentication to ensure correct user identity and permissions. For tools that require authentication, you can request user login via Elicitation, or rely on the Host application's existing OAuth integration.

## 5.6 Commerce MCP Server and Its Relationship to Other Protocols

| Protocol | Purpose                       | Relationship to MCP                            |
| -------- | ----------------------------- | ---------------------------------------------- |
| **UCP**  | AI agent product discovery    | MCP Server can expose UCP data as a Resource   |
| **ACP**  | AI agent ordering and payment | MCP Server can wrap ACP workflows as a Tool    |
| **OTR**  | Merchant trust assessment     | MCP Server can integrate OTR queries as a Tool |

In a complete Agentic Commerce system, MCP serves as the "connection layer" between AI applications and your commerce systems, while UCP/ACP/OTR handle the specific commerce protocol logic.

***

**Next Chapter**: [Resources and Prompts](/en/book-5/ch6-resources-prompts) — Deep dive into Resources and Prompts
