Skip to content
Last updated

Using the Norce Commerce MCP Server

This guide explains how to use the Norce Commerce MCP Server to power conversational agents that search for products and manage baskets in Norce Commerce.

The MCP Server is designed to be a thin layer on top of Norce Commerce Services. It exposes a small set of tools that follow the same principles as the regular APIs: clear responsibilities, OAuth2-based authentication, and explicit control over assortments, price lists and markets.


When to use the MCP Server

Use the MCP Server when you are:

  • Building conversational shopping agents that:

    • help customers find, filter and compare products,
    • propose a small set of recommended items,
    • and add items to a basket on behalf of the shopper.
  • Integrating with LLM platforms (for example OpenAI, first-party MCP clients, or custom MCP-capable clients) and you want:

    • a stable tool surface on top of Norce Commerce,
    • without exposing the full ProductService and ShoppingService directly.

If you are building a traditional frontend or system integration, you should still use the regular Norce Commerce APIs as described in the Developer Portal and API Reference.


Endpoint and protocol

The MCP Server is exposed per customer on this URL:

https://[customer-slug].api-se.norce.tech/mcp/commerce
  • Replace [customer-slug] with the same slug you use for other Norce Commerce APIs.

  • The endpoint uses HTTPS and the Model Context Protocol (MCP) – Streamable HTTP transport.

  • Requests are JSON-RPC 2.0 messages with MCP-specific methods such as:

    • initialize
    • tools/list
    • tools/call

In most cases you should not construct these messages manually. Instead, use:

  • an MCP-aware client (for example an LLM integration that understands MCP), or
  • the official MCP Inspector for testing.

If you implement your own MCP client, see the Model Context Protocol specification for details on the transport and message formats.


Authentication and headers

The MCP Server reuses the same OAuth2 mechanism as other Norce Commerce APIs. Accessing OAuth2 accounts.

1. Create an OAuth2 account and token

  1. In Norce Admin, create an OAuth2 integration user with access to:

    • the correct Applications,
    • the correct Resources (currently Norce API)
  2. Follow the normal OAuth2 flow to obtain an access token, as described in: Accessing APIs with OAuth2 accounts

You can reuse the same token for both direct API calls and the MCP Server, as long as the scopes and environment match.

2. Required headers

Every request to the MCP endpoint must include:

  • Authorization: Bearer <access_token> The OAuth2 access token created via the standard Norce authentication flow.

  • application-id: <application-id> Identifies which Application is calling the MCP Server. This should match how you configure Applications for direct API access (for example the same Application used by your storefront).

The MCP Server validates the token locally using the IDP’s signing keys and forwards the token to Norce Commerce Services. If the token is invalid or expired you will receive 401 Unauthorized.


Concepts: tools, filters and context

The MCP Server exposes a small set of tools. A tool is a structured operation that an agent can call, for example product.search or cart.addItem.

Tools

In version 1.0, the MCP Server exposes tools in two main categories:

  • Product tools

    • product.search – search and list products.
    • product.get – fetch details for a single product.
  • Cart tools

    • cart.addItem – create/update a basket and add a line.
    • cart.removeItem – remove a line from a basket.
    • cart.setItemQuantity – update the quantity of a basket line.
    • cart.get – (optional) fetch the current state of a basket.

You can see the exact set of tools available for a specific MCP Server by calling tools/list via an MCP client.

Filters

The filters parameter is used by product.search to narrow down the result set. It mirrors how you typically filter products in a storefront:

  • by category,
  • by manufacturer,
  • by flags (for example “campaign products”),
  • by price range.

The filters object is optional. If you omit it, the search will only use the free-text query together with your assortment configuration.

Example filters object:

{
  "categoryIds": [1001, 1002],
  "manufacturerIds": [25],
  "flagIds": [10],
  "minPrice": 500,
  "maxPrice": 2000
}

Under the hood, the MCP Server maps these values to the corresponding ListProducts2 parameters on the ProductService.

Context

The context parameter describes where and for whom the request is made:

  • language / culture,
  • currency and price lists,
  • customer and company,
  • sales area / market.

It plays the same role as when you call ProductService or ShoppingService directly and choose:

  • which price lists to use,
  • which customer-specific conditions to apply,
  • which sales area to target.

Example context object:

{
  "cultureCode": "sv-SE",
  "currencyCode": "SEK",
  "priceListIds": [1, 5],
  "salesAreaId": 10,
  "customerId": 12345,
  "companyId": 123
}

The agent is responsible for supplying the correct context, in the same way your frontend does when calling the APIs directly. The MCP Server does not guess the market or price lists; it forwards the context to Norce Commerce.


Tool reference

product.search

Purpose

Search and list products based on a user query and optional filters, so the agent can propose a small curated list of products.

Underlying API

Parameters

The tool expects a JSON object with:

  • query (string, required) Free-text search string. Passed to searchString in ListProducts2.

  • page (number, optional) 1-based page index. Default is 1.

  • pageSize (number, optional) Number of products per page. Default is 20. Values above 50 may be rejected.

  • sort (string, optional) Sort order. Common values:

    • "relevance"
    • "price_asc"
    • "price_desc"
    • "name_asc"
    • "name_desc"
    • "popularity"
  • filters (object, optional) See Filters above. Typical fields:

    • categoryIds: array of category IDs.
    • manufacturerIds: array of manufacturer IDs.
    • flagIds: array of flag IDs.
    • minPrice, maxPrice: numeric price limits.
  • context (object, optional but recommended) See Context above. Typical fields:

    • cultureCode
    • currencyCode or currencyId
    • priceListIds
    • salesAreaId
    • customerId
    • companyId

Example call payload (for MCP Inspector)

When testing in MCP Inspector, you would paste this JSON into the tool’s input field:

{
  "query": "dining table oak",
  "page": 1,
  "pageSize": 12,
  "sort": "relevance",
  "filters": {
    "categoryIds": [1001],
    "minPrice": 2000,
    "maxPrice": 8000
  },
  "context": {
    "cultureCode": "sv-SE",
    "currencyCode": "SEK",
    "priceListIds": [1],
    "salesAreaId": 10
  }
}

Response shape

product.search returns a normalized structure, typically:

{
  "total": 123,
  "page": 1,
  "pageSize": 12,
  "products": [
    {
      "productId": 4567,
      "uniqueName": "oak-dining-table-180",
      "partNo": "TABLE-180-OAK",
      "name": "Oak Dining Table 180 cm",
      "subHeader": "Solid oak with metal legs",
      "shortDescription": "Sturdy dining table for 6–8 people.",
      "thumbnailImageUrl": "https://cdn.example.com/...",
      "mainImageUrl": "https://cdn.example.com/...",
      "priceIncVat": 5990,
      "priceExVat": 4792,
      "currencyCode": "SEK",
      "manufacturerName": "Norce Furniture",
      "categoryIds": [1001],
      "flags": ["campaign"]
    }
  ]
}

Values are based on the underlying ProductItem model returned by ProductService.

How agents should use it

  • Start with product.search to get a broader list.
  • Use LLM logic to narrow down the selection.
  • Only call product.get for a small number of candidates (1–3) when more detail is needed.

product.get

Purpose

Retrieve detailed information for a single product, suitable for product pages or final recommendations.

Underlying APIs

  • ProductService.GetProduct (by product ID).
  • GetProductByUniqueName or GetProductByPartNo may be used internally if the agent only has those identifiers. (ByUniqueName, ByPartNo)

Parameters

Exactly one product identifier must be provided:

  • productId (number, preferred)
  • uniqueName (string)
  • partNo (string)

Optional context object as described earlier (culture, currency, price lists, sales area, customer, company).

Example input

{
  "productId": 4567,
  "context": {
    "cultureCode": "sv-SE",
    "currencyCode": "SEK",
    "priceListIds": [1],
    "salesAreaId": 10
  }
}

Response shape

Typical structure:

{
  "productId": 4567,
  "uniqueName": "oak-dining-table-180",
  "partNo": "TABLE-180-OAK",
  "name": "Oak Dining Table 180 cm",
  "subHeader": "Solid oak with metal legs",
  "description": "...",
  "longDescription": "...",
  "images": [
    { "type": "primary", "url": "https://cdn.example.com/..." }
  ],
  "priceIncVat": 5990,
  "priceExVat": 4792,
  "currencyCode": "SEK",
  "manufacturerName": "Norce Furniture",
  "attributes": {
    "width": 180,
    "height": 75,
    "material": "Oak"
  },
  "variants": [
    {
      "productId": 4568,
      "uniqueName": "oak-dining-table-220",
      "partNo": "TABLE-220-OAK",
      "name": "Oak Dining Table 220 cm"
    }
  ]
}

How agents should use it

  • Prefer productId when calling product.get after product.search.
  • Use uniqueName or partNo only when the product ID is not known.
  • Avoid calling product.get for every search result; call it only when the user is close to making a decision.

cart.addItem

Purpose

Create (if needed) and update a basket, and add a line for the specified product.

Underlying APIs

Parameters

  • basketId (number, optional)

    • If provided, the item is added to the existing basket.
    • If omitted, a new basket is created.
  • partNo (string, required) The product’s part number.

  • quantity (number, required) Quantity to add.

  • clientIp (string, required when basketId is omitted)

    • Used only when creating a new basket.
    • Should be the end customer’s IP address, typically as seen by your storefront or API gateway.
  • context (object, optional but recommended) Same structure as for product.search. Common fields:

    • currencyCode / currencyId
    • priceListIds
    • salesAreaId
    • customerId
    • companyId
    • cultureCode

If no customerId is provided, the MCP server will use a configured system account (SYSTEM_USER_ID) as createdBy when creating the basket.

Example input

Create a new basket and add a product:

{
  "partNo": "TABLE-180-OAK",
  "quantity": 1,
  "clientIp": "203.0.113.25",
  "context": {
    "currencyCode": "SEK",
    "priceListIds": [1],
    "salesAreaId": 10
  }
}

Response shape

{
  "basketId": 9876,
  "basket": {
    "basketId": 9876,
    "currencyCode": "SEK",
    "totalIncVat": 5990,
    "totalExVat": 4792,
    "items": [
      {
        "lineNo": 1,
        "partNo": "TABLE-180-OAK",
        "name": "Oak Dining Table 180 cm",
        "quantity": 1,
        "priceIncVat": 5990,
        "priceExVat": 4792
      }
    ]
  }
}

How agents should use it

  • On the first add-to-cart action, call cart.addItem without basketId and with clientIp.
  • Remember the returned basketId in the conversation or client state.
  • Use the same basketId for subsequent cart operations.

cart.removeItem

Purpose

Remove a specific line from an existing basket.

Underlying API

Parameters

  • basketId (number, required)
  • lineNo (number, required)

Response

Returns an updated basket summary with the same structure as cart.addItem.

How agents should use it

  • Use cart.get (if available) or previously stored basket data to find the lineNo of the item to remove.
  • Call cart.removeItem with the correct basketId and lineNo.

cart.setItemQuantity

Purpose

Update the quantity of a specific basket line.

Underlying API

Parameters

  • basketId (number, required)
  • lineNo (number, required)
  • partNo (string, required)
  • quantity (number, required)

Response

Returns an updated basket summary with the same structure as cart.addItem.

How agents should use it

  • Use this when the user wants to change the quantity of an existing item.
  • If the quantity is set to 0, the underlying API may remove the item; the agent should be prepared to handle that.

cart.get (if available)

Purpose

Fetch the current state of an existing basket.

Underlying API

Parameters

  • basketId (number, required)

Response

Same basket structure as in cart.addItem / cart.removeItem / cart.setItemQuantity.

How agents should use it

  • Use it to:

    • display the current cart,
    • refresh totals after multiple changes,
    • verify the basket before checkout.

End-to-end example workflow

A typical conversational flow in an agent using the MCP Server:

  1. User: “I’m looking for a 180 cm oak dining table for 6 people.”

  2. Agent:

    • Calls product.search with:

      • query = "dining table oak 180 cm 6 people"
      • filters.categoryIds for “dining tables” (if known)
      • context with correct culture, currency, price lists and sales area.
    • Receives a page of products[].

  3. Agent:

    • Uses LLM logic to pick 3–5 relevant options based on size, material and price.
    • Optionally calls product.get for 1–2 products if more details are needed.
  4. User: “Let’s go with the second one, and add two chairs that match.”

  5. Agent:

    • Calls cart.addItem with:

      • partNo of the selected table,
      • quantity = 1,
      • clientIp (first call),
      • same context as in search.
    • Receives basketId.

    • Calls product.search again with filters for matching chairs (category, manufacturer, flags, etc.).

    • Calls cart.addItem with basketId to add the chairs.

  6. Agent:

    • Optionally calls cart.get to present the basket summary back to the user.

Testing with MCP Inspector

The MCP Inspector is an interactive developer tool for testing and debugging MCP servers. It provides a graphical interface to connect to the MCP Server, discover available tools, and execute tool calls without writing any client code.

Starting the Inspector

The Inspector runs directly through npx without requiring installation:

npx @modelcontextprotocol/inspector

This opens a web-based interface where you can configure the connection to the MCP Server.

Connecting to the Norce Commerce MCP Server

Since the Norce Commerce MCP Server uses Streamable HTTP transport (not stdio), you need to configure the Inspector to connect over HTTP:

  1. Start the Inspector with npx @modelcontextprotocol/inspector.
  2. In the Server connection pane, select the Streamable HTTP transport.
  3. Enter the MCP Server URL:
    https://[customer-slug].api-se.norce.tech/mcp/commerce
  4. Configure the required headers:
    • Authorization: Bearer <your-oauth2-token>
    • application-id: <your-application-id>

Using the Inspector

Once connected, the Inspector provides several tabs for interacting with the MCP Server:

  • Tools tab – Lists all available tools (product.search, product.get, cart.addItem, etc.) with their input schemas. You can test tools by entering JSON input and viewing the results.

  • Resources tab – Shows any resources exposed by the server (if applicable).

  • Prompts tab – Displays prompt templates (if applicable).

  • Notifications pane – Shows logs and notifications from the server, useful for debugging.

Example: Testing product.search

  1. Open the Tools tab.
  2. Select product.search from the list.
  3. Enter the tool input as JSON:
    {
      "query": "dining table",
      "pageSize": 5,
      "context": {
        "cultureCode": "sv-SE",
        "currencyCode": "SEK",
        "priceListIds": [1],
        "salesAreaId": 10
      }
    }
  4. Click Execute to run the tool.
  5. View the response in the results pane.

Best practices for development

  • Verify connectivity first – Use the Inspector to confirm that authentication and headers are correctly configured before integrating with your agent.
  • Test edge cases – Try invalid inputs, missing parameters, and boundary conditions to understand error responses.
  • Monitor notifications – Keep an eye on the notifications pane for server-side logs that can help diagnose issues.
  • Iterate quickly – The Inspector allows rapid testing without deploying client code, making it ideal for exploring the tool surface.

For more information about the MCP Inspector, see the official documentation at modelcontextprotocol.io/docs/tools/inspector.


Troubleshooting and common pitfalls

  • 401 Unauthorized

    • Check that your OAuth2 token is valid, not expired, and has access to the correct Application and Environment, OAuth access.
    • Verify that you send Authorization: Bearer <token> on every MCP request.
  • 400 Bad Request – missing application-id

    • Make sure you include application-id header.
    • The value should match an Application configured in Norce Admin.
  • Empty search results

    • Check that your context matches your storefront setup:

      • price lists,
      • sales area,
      • customer/company (if needed).
    • Try removing filters to verify that the products are available at all.

  • Basket not created

    • If you call cart.addItem without basketId, you must provide clientIp.
    • Ensure the IP value is a valid IPv4 or IPv6 address string.
  • Unexpected prices

    • Verify that:

      • currencyCode / currencyId matches the storefront.
      • priceListIds correspond to the same lists used in your frontend.
      • You are using the correct sales area.

For details on the underlying ProductService and ShoppingService endpoints, see the Norce Commerce API Reference.

Use this guide together with your existing knowledge of Norce Commerce product, variant and basket models to design agents that behave consistently with your storefront implementation.