# MCP server (https://prood.com/docs/apps/api/mcp)

The Commerce API exposes a **Model Context Protocol (MCP)** server at `/mcp`, allowing AI agents and LLM applications to interact with commerce data through standardized tools.

Free keys reach the 21 storefront tools, with three limits. `applyCartCoupon` and `removeCartCoupon` have nothing to act on, because no merchant can create coupons yet. `listOrders` returns an empty list here: it only lists a signed-in customer's orders, and that needs the REST route. Admin tools need a key with the Admin scope, which starts on Grow. Agent Auth starts on Grow. Paid plans are coming.

## Endpoint [#endpoint]

```
POST /mcp
Content-Type: application/json
Authorization: Bearer {jwt} | x-api-key: {key}
```

Uses streamable HTTP transport via `mcp-handler`.

## Available tools [#available-tools]

MCP tools mirror the REST API endpoints. Each tool maps to an OpenAPI `operationId`:

### Catalog tools [#catalog-tools]

| Tool | REST equivalent | Description |
| --- | --- | --- |
| `listProducts` | `GET /v1/products` | Search and list products |
| `getProduct` | `GET /v1/products/{id}` | Get product by ID |
| `getProductBySlug` | `GET /v1/products/by-slug/{slug}` | Get product by URL slug |
| `listCategories` | `GET /v1/categories` | List categories |
| `getStore` | `GET /v1/store` | Get store info |
| `listCountries` | `GET /v1/countries` | List countries |

### Cart tools [#cart-tools]

| Tool | REST equivalent | Description |
| --- | --- | --- |
| `createCart` | `POST /v1/carts` | Create a new cart |
| `getCart` | `GET /v1/carts/{id}` | Get cart details |
| `addCartItem` | `POST /v1/carts/{id}/items` | Add item to cart |
| `updateCartItem` | `PATCH /v1/carts/{id}/items/{itemId}` | Update item quantity |
| `removeCartItem` | `DELETE /v1/carts/{id}/items/{itemId}` | Remove item |
| `applyCartCoupon` | `POST /v1/carts/{id}/coupon` | Apply coupon. No merchant can create coupons yet |
| `removeCartCoupon` | `DELETE /v1/carts/{id}/coupon` | Remove coupon. No merchant can create coupons yet |
| `setCartShippingAddress` | `PUT /v1/carts/{id}/shipping-address` | Set shipping address |
| `setCartBillingAddress` | `PUT /v1/carts/{id}/billing-address` | Set billing address |
| `listCartShippingMethods` | `GET /v1/carts/{id}/shipping-methods` | List shipping options |
| `listCartPaymentMethods` | `GET /v1/carts/{id}/payment-methods` | List payment options |
| `setCartShippingMethod` | `PATCH /v1/carts/{id}/shipping-method` | Select shipping method |
| `placeOrder` | `POST /v1/carts/{id}/place-order` | Place order from cart |
| `listOrders` | `GET /v1/orders` | List customer orders. Returns an empty list over MCP |
| `getOrder` | `GET /v1/orders/{id}` | Get order |

### Admin tools [#admin-tools]

| Tool | REST equivalent | Description |
| --- | --- | --- |
| `adminListProducts` | `GET /v1/admin/products` | List all products |
| `adminCreateProduct` | `POST /v1/admin/products` | Create product |
| `adminGetProduct` | `GET /v1/admin/products/{id}` | Get product |
| `adminUpdateProduct` | `PATCH /v1/admin/products/{id}` | Update product |
| `adminDeleteProduct` | `DELETE /v1/admin/products/{id}` | Delete product |
| `adminCreateCategory` | `POST /v1/admin/categories` | Create category |
| `adminUpdateCategory` | `PATCH /v1/admin/categories/{id}` | Update category |
| `adminDeleteCategory` | `DELETE /v1/admin/categories/{id}` | Delete category |
| `adminListOrders` | `GET /v1/admin/orders` | List orders |
| `adminGetOrder` | `GET /v1/admin/orders/{id}` | Get order detail |
| `adminCancelOrder` | `POST /v1/admin/orders/{id}/cancel` | Cancel order |
| `adminGetOrderHistory` | `GET /v1/admin/orders/{id}/history` | Get order history |
| `adminFulfillOrder` | `POST /v1/admin/orders/{id}/fulfill` | Fulfill order |
| `adminRefundOrder` | `POST /v1/admin/orders/{id}/refund` | Refund order |
| `adminListCustomers` | `GET /v1/admin/customers` | List customers |
| `adminGetCustomer` | `GET /v1/admin/customers/{id}` | Get customer |
| `adminGetDashboard` | `GET /v1/admin/dashboard` | Dashboard statistics |
| `adminGetStore` | `GET /v1/admin/store` | Store settings |
| `adminUpdateStore` | `PATCH /v1/admin/store` | Update store settings |
| `adminUpdateInventory` | `POST /v1/admin/inventory` | Update inventory |

## Authentication [#authentication]

MCP requests use the same authentication as REST:

| Method | Header | Scopes |
| --- | --- | --- |
| Agent JWT | `Authorization: Bearer {jwt}` | From capability grants |
| API key | `x-api-key: {key}` | From key metadata |

The MCP handler resolves the caller via `resolve-caller.ts` and sets context in AsyncLocalStorage for tool execution.

## Implementation [#implementation]

Each tool in `apps/api/lib/mcp/tools.ts` calls the same `commerce-service.ts` functions as REST route handlers and returns both text content and `structuredContent`:

```ts
server.registerTool('listProducts', { inputSchema: searchProductsQuery.shape }, async (input) => {
  const orgId = requireScope('storefront')
  const data = await catalog.searchProducts(orgId, searchProductsQuery.parse(input))
  return {
    content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
    structuredContent: data,
  }
}
```

## Connecting an MCP client [#connecting-an-mcp-client]

### Cursor / Claude Desktop [#cursor--claude-desktop]

Add to your MCP config:

```json
{
  "mcpServers": {
    "prood-commerce": {
      "url": "https://prood.com/mcp",
      "headers": {
        "x-api-key": "pkAbC123..."
      }
    }
  }
}
```

### Programmatic [#programmatic]

Use the `@modelcontextprotocol/sdk` client:

```ts
import { Client } from '@modelcontextprotocol/sdk/client/index.js'

const client = new Client({ name: 'my-agent', version: '1.0.0' })
await client.connect(transport)

const result = await client.callTool({
  name: 'listProducts',
  arguments: { query: 'shirt', perPage: 5 },
})
```

## Related pages [#related-pages]

<Cards>
  <Card title="Agent Auth" href="/docs/apps/api/agent-auth" description="Agent registration and capability grants." />
  <Card title="Authentication" href="/docs/apps/api/authentication" description="Caller resolution for MCP and REST." />
  <Card title="OpenAPI reference" href="/docs/api" description="REST endpoint schemas." />
</Cards>
