Skip to main content
Glama
README.md
# SAP Commerce MCP Server

[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=commerce-cloud-integrations_sap-commerce-mcp-server&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=commerce-cloud-integrations_sap-commerce-mcp-server)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=commerce-cloud-integrations_sap-commerce-mcp-server&metric=coverage)](https://sonarcloud.io/summary/new_code?id=commerce-cloud-integrations_sap-commerce-mcp-server)
![SonarCloud](https://github.com/commerce-cloud-integrations/sap-commerce-mcp-server/actions/workflows/sonarcloud.yml/badge.svg?branch=master)
![Python](https://img.shields.io/badge/python-3.13%2B-blue)
![License](https://img.shields.io/badge/license-MIT-green)

This project exposes an MCP server for SAP Commerce Cloud focused on ASM employee workflows: search a customer, impersonate them, bind or manage a cart, and complete OCC-backed commerce actions through task-oriented MCP tools.

The repo is now treated as **local-first**: the expected default target is `https://localhost:9002`, with `SAP_BASE_URL` controlling the actual host. Remote tenants can still be used, but the docs, tests, and validation flow should make the local SAP Commerce runtime truth-first.

## What this server does now
- **ASM-first customer actions**: search a customer, impersonate a customer, and continue acting on their behalf
- **Session-aware cart management**: create, inspect, update, remove, and clear carts without manual cart juggling
- **Checkout flow**: delivery address, delivery mode, guest email, and order placement
- **Product and discovery tools**: search products, fetch details, inspect stock, browse base sites/stores/catalogs/categories
- **Two tool layers**: high-level agent-friendly tools plus low-level OCC/ASM wrappers
- **Session orientation**: `get_session_status` helps agents understand the current cart/user/base-site context
- **FastMCP transport**: stdio and SSE transports for local or remote MCP clients

## How a request flows

### 1. Architecture at a glance

![Architecture overview](docs/diagrams/architecture.png)

Source: [`docs/diagrams/architecture.mmd`](docs/diagrams/architecture.mmd)

### 2. Example request swimlane

This is the typical “agent impersonates a customer, then keeps shopping on their behalf” path.

![Example request swimlane](docs/diagrams/example-request.png)

Source: [`docs/diagrams/example-request.mmd`](docs/diagrams/example-request.mmd)

## MCP tools

### High-level tools
These are the main contract for ASM employee workflows.

**Discovery and products**
- `search_products` — keyword product discovery
- `get_product` — fetch one product detail
- `get_session_status` — inspect current session state

**Customer / ASM**
- `search_customer` — find a customer quickly
- `impersonate_customer` — start acting as customer
- `end_impersonation` — return to anonymous mode

**Cart and checkout**
- `add_to_cart` — add one product
- `get_cart` — read current cart
- `update_cart_entry` — change entry quantity
- `remove_from_cart` — delete one entry
- `clear_cart` — empty the cart
- `set_delivery_address` — attach shipping address
- `set_delivery_mode` — choose shipping method
- `get_delivery_modes` — list shipping options
- `set_guest_email` — set guest checkout email
- `place_order` — submit the order

### Low-level tools
These expose narrower OCC / ASM primitives for exact control.

- `basesites.list` — list available base sites
- `catalogs.list` — list catalogs for a site
- `catalogs.get` — fetch one catalog
- `catalogVersions.get` — fetch one catalog version
- `categories.products` — browse products by category
- `stores.list` — list stores for a site
- `stores.get` — fetch one base store
- `products.get` — fetch one OCC product
- `products.stock` — inspect stock data
- `products.stockCount` — count stock locations
- `asm.customer360` — fetch customer 360 fragments
- `asm.customers.create` — create a customer
- `asm.customers.search` — run ASM customer search
- `asm.customers.suggest` — get customer suggestions
- `carts.list` — list carts
- `carts.create` — create or restore cart
- `carts.get` — fetch one cart
- `carts.delete` — delete one cart
- `cartEntries.list` — list cart entries
- `cartEntries.add` — add one entry
- `cartEntries.get` — fetch one entry
- `cartEntries.update` — replace entry payload
- `cartEntries.patch` — partially update entry
- `cartEntries.delete` — delete one entry

## Configuration
1. Install dependencies:
   ```bash
   uv sync
   ```

2. Copy the environment template:
   ```bash
   cp .env.example .env
   ```

3. For the local SAP Commerce instance, set:
   ```bash
   SAP_BASE_URL=https://localhost:9002
   ```

4. Keep or adjust these path fragments if your SAP deployment differs:
   - `OCC_API_PATH=/occ/v2`
   - `OAUTH_PATH=/authorizationserver/oauth/token`
   - `ASM_PATH=/assistedservicewebservices`

5. Configure OAuth credentials for the local tenant or remote tenant you are validating against.
   For the stock local sample-data setup, these are the expected defaults:
   ```bash
   OAUTH_CLIENT_ID=mobile_android
   OAUTH_CLIENT_SECRET=secret
   OAUTH_USERNAME=asmagent
   OAUTH_PASSWORD=nimda
   OAUTH_SCOPE=basic
   ```

## Running
- Stdio:
  ```bash
  python -m app.server
  ```
- SSE:
  ```bash
  fastmcp serve app/server.py --sse :8080
  ```

## Testing
- Full verification suite:
  ```bash
  uv run ruff check app tests
  uv run mypy app
  uv run pytest -q
  ```
- Smoke checks:
  ```bash
  uv run pytest tests/integration/test_smoke.py -q
  ```
- Live discovery flow:
  ```bash
  uv run pytest tests/integration/test_integration_live.py -s
  ```

> **Note**
> Live tests are intended to validate the current contract against a real SAP Commerce runtime. When `SAP_BASE_URL=https://localhost:9002`, the local OCC/ASM instance should be the primary proof target. If OAuth or ASM data is misconfigured, diagnose it locally before broadening scope.

> **Local SAP caveat**
> Some SAP 2211 local stacks include `messagecentercsocc`, whose late `Oauth2UserFilter` can overwrite the `/users/{customerId}` on-behalf context with the authenticated agent again. If `asmagent` cart calls regress to `EmployeeModel -> CustomerModel` cast errors, patch that filter so it preserves the already-matched customer when the current OCC user differs from the OAuth principal.


## Quality gates
- **Ruff** for linting and import hygiene
- **Mypy** for a practical static type gate across `app/`
- **Pytest + coverage.xml** so SonarQube can consume the same local evidence used in CI

Local SonarQube analysis can be published with:

```bash
uv run pytest -q
sonar-scanner
```

`sonar-project.properties` is checked in so local and CI scans use the same project key/source layout.

## Documentation
- [Workflows](docs/WORKFLOWS.md) — practical tool-call sequences
- [Architecture Mermaid](docs/diagrams/architecture.mmd) — source for the system diagram
- [Request Mermaid](docs/diagrams/example-request.mmd) — source for the swimlane diagram
- MCP manifest and tool registration: `app/server.py`
- Contribution guide: `AGENTS.md`

## Future improvements
- add an optional external backing store only if the project later needs multi-process or horizontally scaled session persistence

## Supported OCC / ASM coverage
The current server covers the endpoints needed for the flows above, including base sites, catalogs, stores, products, carts, cart entries, checkout address/delivery operations, order placement, and ASM customer search / customer 360 / bind-cart style operations.