Skip to main content
Glama
aratan

ucp-mcp-server

by aratan
README.md
# ucp-mcp-server

**Let AI assistants shop.** An MCP server that gives Claude, Cursor, and any MCP-compatible AI the ability to interact with UCP-enabled merchants.

> **UCP** (Universal Commerce Protocol) is Google's new open standard for agentic commerce, backed by Shopify, Stripe, Visa, Mastercard, Target, Walmart, and 20+ partners.
>
> **MCP** (Model Context Protocol) is the standard for giving AI assistants access to tools.
>
> This project connects them.

---

## What Can It Do?

| Tool | Description |
|------|-------------|
| `ucp_discover` | Find out what a merchant supports (capabilities, payment methods) |
| `ucp_products_list` | List all products from a merchant's catalog |
| `ucp_products_search` | Search and filter products by color, category, location, price, specs |
| `ucp_checkout_create` | Start a purchase (add items to cart, set buyer info) |
| `ucp_checkout_update` | Apply discount codes to an existing checkout |
| `ucp_checkout_set_fulfillment` | Set up shipping (auto-selects address and delivery option) |
| `ucp_checkout_complete` | Complete the purchase by submitting payment |
| `ucp_order_get` | Get the current status of an order, including fulfillment |
| `ucp_testing_simulate_shipping` | Mark an order as shipped via the merchant's testing endpoint |

Your AI assistant gets structured, type-safe access to the entire UCP shopping flow. No scraping, no browser automation, no brittle hacks.

## Quick Start

### Install

```bash
pip install ucp-mcp-server
```

Or with [uv](https://docs.astral.sh/uv/):

```bash
uv pip install ucp-mcp-server
```

### Use with Claude Desktop

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "ucp-shopping": {
      "command": "ucp-mcp-server"
    }
  }
}
```

### Use with Cursor

Add to your `.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "ucp-shopping": {
      "command": "ucp-mcp-server"
    }
  }
}
```

### Run Directly

```bash
# As a module
python -m ucp_mcp_server

# Or via the entry point
ucp-mcp-server
```

## Tools Reference

### `ucp_discover`

Discover what a UCP merchant supports before shopping.

```
Arguments:
  merchant_url (str): Base URL of a UCP-enabled merchant

Returns:
  capabilities: List of supported UCP capabilities (checkout, discount, fulfillment)
  payment_handlers: Accepted payment methods (Shop Pay, Google Pay, etc.)
  ucp_version: Protocol version the merchant implements
```

### `ucp_products_list`

List all products from a merchant's catalog.

```
Arguments:
  merchant_url (str): Base URL of the merchant

Returns:
  products: List of products with id, title, price, and image_url
```

### `ucp_products_search`

Search and filter products from a merchant's catalog with advanced filtering.

```
Arguments:
  merchant_url (str): Base URL of the merchant
  query (str): Text search query to match against product titles
  color (str): Filter by color (e.g., "red", "blue", "black")
  category (str): Filter by category (e.g., "pc", "laptop", "monitor")
  location (str): Filter by location/availability (e.g., "Madrid", "Barcelona")
  max_price (int): Maximum price filter in cents (e.g., 200000 for 2000 EUR)
  min_price (int): Minimum price filter in cents
  sort_by (str): Sort results by "price_asc", "price_desc", or "name"
  specs (dict): Filter by specifications (e.g., {"use_case": "ai", "gpu": "RTX 4090"})

Returns:
  products: List of matching products with all fields
  total: Number of products found
  filters_applied: Summary of filters that were applied
```

**Example: Find a red PC for AI in Madrid under 2000 EUR**

```python
result = await ucp_products_search(
    merchant_url="http://localhost:8182",
    color="red",
    category="pc",
    location="Madrid",
    max_price=200000,  # 2000 EUR in cents
    specs={"use_case": "ai"},
    sort_by="price_asc",
)
# Returns: PC IA Rojo NVIDIA H100 at 1850 EUR
```

### `ucp_checkout_create`

Create a new shopping cart / checkout session.

```
Arguments:
  merchant_url (str): Base URL of the merchant
  items (list): Items to buy, each with "id" and "quantity"
  buyer_name (str): Full name of the buyer
  buyer_email (str): Email address
  currency (str): Currency code (default: "USD")

Returns:
  checkout_id: Session ID for tracking this purchase
  status: Current checkout status
  total: Total price in smallest currency unit (cents)
  subtotal: Subtotal before discounts
  line_items: What's in the cart
```

### `ucp_checkout_update`

Apply discount codes or modify an existing checkout.

```
Arguments:
  merchant_url (str): Base URL of the merchant
  checkout_id (str): The checkout session to update
  discount_codes (list[str]): Promo codes to apply

Returns:
  checkout_id: Session ID
  total: Updated total after discounts
  discount_applied: How much was saved
  discounts: Details of applied discounts
```

### `ucp_checkout_set_fulfillment`

Set up shipping for a checkout. Automatically selects the first available address and delivery option.

```
Arguments:
  merchant_url (str): Base URL of the merchant
  checkout_id (str): The checkout session

Returns:
  checkout_id: Session ID
  status: Current status
  total: Updated total (may include shipping costs)
  fulfillment: Details of selected shipping method
```

### `ucp_checkout_complete`

Complete a checkout by submitting payment. This finalizes the purchase and returns an order ID.

```
Arguments:
  merchant_url (str): Base URL of the merchant
  checkout_id (str): The checkout session to complete
  payment_handler_id (str): Payment handler to use (from ucp_discover)
  card_token (str): Payment token from the provider
  card_brand (str): Card brand (e.g., "Visa")
  card_last_digits (str): Last 4 digits of the card

Returns:
  checkout_id: Session ID
  status: "complete" or "completed"
  total: Final amount charged
  order_id: Order ID for tracking
  order_url: Permalink to the order
```

### `ucp_order_get`

Get the current status of an order, including fulfillment details.

```
Arguments:
  merchant_url (str): Base URL of the merchant
  order_id (str): The order to track

Returns:
  order_id: The order ID
  status: Current order status
  currency: Order currency
  total: Total amount charged
  fulfillment: Fulfillment details (method, tracking, status)
```

### `ucp_testing_simulate_shipping`

Simulate shipping an order via the merchant's testing endpoint. Useful for end-to-end tests and demos.

```
Arguments:
  merchant_url (str): Base URL of the merchant
  order_id (str): The order to mark as shipped

Returns:
  status: The result of the simulation (e.g., "shipped")
```

## Example Conversation

### Basic Shopping Flow

> **You:** "Find out what the flower shop at http://flowers.example.com supports"
>
> **Claude:** *calls ucp_discover* "This merchant supports checkout, discounts, and fulfillment tracking. They accept Shop Pay and Google Pay."
>
> **You:** "Buy 2 bouquets of roses for me"
>
> **Claude:** *calls ucp_checkout_create* "I've created a checkout for 2 Bouquet of Red Roses. Total: $70.00. Would you like to proceed?"
>
> **You:** "Try the code 10OFF first"
>
> **Claude:** *calls ucp_checkout_update* "Applied 10OFF - saved $7.00! New total: $63.00."

### Product Search Flow

> **You:** "I'm looking for a red PC for AI work in Madrid, budget under 2000 EUR"
>
> **Claude:** *calls ucp_products_search(color="red", category="pc", location="Madrid", max_price=200000, specs={"use_case": "ai"}, sort_by="price_asc")*
> "I found 1 matching PC: **PC IA Rojo NVIDIA H100** at **1,850 EUR**. It has 128GB RAM, AMD EPYC 9654 CPU, and NVIDIA H100 GPU. This is the cheapest option that meets your criteria. Would you like to proceed with checkout?"
>
> **You:** "Yes, add it to cart"
>
> **Claude:** *calls ucp_checkout_create* "Added to cart! Checkout session created. Total: 1,850 EUR. Ready to complete purchase?"

## Use Cases

### ๐Ÿ›’ E-commerce Personal Assistant

**Why:** Users want to shop naturally through conversation, not browse websites.

**How:** The AI acts as a personal shopper that understands preferences and finds the best deals.

```
User: "I need a gift for my mom, she loves gardening, budget 50 euros"
AI: ucp_products_search(query="garden", max_price=5000, sort_by="price_desc")
AI: "I found 3 gardening items. The Premium Pruning Set at โ‚ฌ45 has great reviews."
User: "Perfect, buy it"
AI: ucp_checkout_create โ†’ ucp_checkout_complete
```

**Value:** No app switching, no browser tabs, no remembering passwords. Just conversation.

---

### ๐Ÿข Enterprise Procurement

**Why:** Companies need to buy equipment across multiple vendors while tracking budgets.

**How:** The AI compares products across merchants and follows procurement rules.

```
User: "We need 10 laptops for the dev team, under 1500 EUR each, from approved vendors"
AI: ucp_products_search(category="laptop", max_price=150000, specs={"use_case": "development"})
AI: "Found 5 options across 3 merchants. Best value: ThinkPad X1 at โ‚ฌ1,299 from TechStore"
User: "Add 10 to cart and apply our corporate discount CORP20"
AI: ucp_checkout_create(quantity=10) โ†’ ucp_checkout_update(discount_codes=["CORP20"])
```

**Value:** Budget compliance, audit trail, no manual PO forms.

---

### ๐Ÿ” Price Comparison Shopping

**Why:** Users want the best price without checking 10 different websites.

**How:** The AI queries multiple UCP merchants and compares results.

```
User: "Find me the cheapest iPhone 15 Pro across all stores"
AI: [queries 5 merchants simultaneously]
AI: "Best price: โ‚ฌ899 at TechShop (โ‚ฌ50 cheaper than average). In stock in Madrid."
User: "Buy it from there"
AI: ucp_checkout_create(merchant_url="http://techshop.example.com")
```

**Value:** Save time and money without manual comparison.

---

### ๐ŸŽ Gift Purchasing with Constraints

**Why:** Gift buying involves multiple constraints (budget, preferences, occasion).

**How:** The AI filters products based on complex requirements.

```
User: "Find a red gaming PC under 2000 EUR for my son's birthday, needs RTX 4070 or better"
AI: ucp_products_search(
    color="red", category="pc", max_price=200000,
    specs={"use_case": "gaming", "gpu_min": "RTX 4070"},
    sort_by="price_asc"
)
AI: "Found 2 options. Best match: Gaming PC Rojo at โ‚ฌ1,850 with RTX 4070 Ti"
```

**Value:** Complex multi-criteria search in one conversation.

---

### ๐Ÿ“ฆ Order Tracking & Support

**Why:** Users want to know where their order is without logging into websites.

**How:** The AI tracks orders across merchants and provides updates.

```
User: "Where's my order from TechShop?"
AI: ucp_order_get(order_id="order-abc-123")
AI: "Your order shipped yesterday via DHL. Tracking: DH123456789. Expected delivery: Friday."
User: "Can I change the delivery address?"
AI: "Let me check... [calls merchant API] The order is already in transit, so address changes aren't possible. Would you like me to contact support?"
```

**Value:** Single point for all order tracking, no multiple logins.

---

### ๐Ÿงช Development & Testing

**Why:** Developers need to test e-commerce integrations without real payments.

**How:** Use the testing endpoints to simulate the full flow.

```python
# Full test flow without real money
result = await ucp_testing_simulate_shipping(merchant_url, order_id)
# Simulates: payment โ†’ fulfillment โ†’ shipping โ†’ delivery
```

**Value:** Test complete purchase flows in development environments.

---

### ๐Ÿค– Automated Reordering

**Why:** Businesses need to reorder supplies when stock is low.

**How:** The AI monitors inventory and triggers reorders automatically.

```
[Automated trigger: inventory low]
AI: ucp_products_search(category="office_supplies", query="paper")
AI: "Office paper running low. Reordering 50 reams from SuppliesCo at โ‚ฌ25/ream"
AI: ucp_checkout_create โ†’ ucp_checkout_complete
```

**Value:** Never run out of supplies, automatic procurement.

---

### ๐Ÿ’ณ Multi-Payment Method Support

**Why:** Different users prefer different payment methods.

**How:** The AI discovers and uses the user's preferred payment handler.

```
User: "Pay with Google Pay"
AI: ucp_discover() โ†’ finds google_pay handler
AI: ucp_checkout_complete(payment_handler_id="google_pay")
```

**Value:** Flexibility without merchant-side integration work.

## Why This Exists

Every AI app is going to need shopping capabilities. UCP standardizes how merchants expose commerce APIs. MCP standardizes how AI assistants use tools. This project is the bridge.

Without this, connecting AI to commerce means:
- Scraping websites (brittle, breaks constantly)
- Building custom integrations per merchant (doesn't scale)
- Browser automation (slow, unreliable, expensive)

With UCP + MCP:
- One protocol, every merchant
- Structured data in, structured data out
- Works with any MCP-compatible AI assistant

## Improvements Roadmap

### ๐Ÿ”ง Optimization (Protocol-Compliant)

| Area | Before | After | Why |
|------|--------|-------|-----|
| **HTTP Client** | New client per request | Connection pooling with `httpx.AsyncClient` reuse | Reduce latency, reuse TCP connections |
| **Response Caching** | No caching | Cache `ucp_discover` results (5min TTL) | Discovery rarely changes, saves round-trips |
| **Parallel Queries** | Sequential product search | `asyncio.gather()` for multi-merchant search | Search 5 merchants in time of 1 |
| **Retry Logic** | No retries | Exponential backoff (3 attempts) | Handle transient network failures |
| **Timeout Handling** | Default httpx timeout | Configurable per-tool timeouts (10s/30s/60s) | Prevent hanging on slow merchants |

### ๐Ÿ›ก๏ธ Robustness (UCP Protocol Compliance)

| Area | Current | Improvement | Why |
|------|---------|-------------|-----|
| **Error Messages** | Generic errors | UCP-compliant error codes + details | Merchants expect structured errors |
| **Input Validation** | Basic Pydantic | Field-level validators (URL format, price ranges) | Fail fast with clear messages |
| **Rate Limiting** | None | Client-side rate limiter (100 req/min) | Respect merchant limits |
| **Graceful Degradation** | Fail on first error | Partial results with warnings | Show what works, note what failed |

### ๐Ÿ’ป Code Quality

| Area | Current | Improvement | Why |
|------|---------|-------------|-----|
| **Type Hints** | Partial | Full typing with `py.typed` marker | Better IDE support, catch errors early |
| **Docstrings** | Minimal | Google-style docstrings on all public APIs | Auto-generate API docs |
| **Logging** | Print statements | Structured logging with `structlog` | Production observability |
| **Config** | Hardcoded defaults | Environment-based config (`UCP_*` env vars) | Deploy anywhere without code changes |
| **Metrics** | None | Prometheus metrics (request count, latency) | Monitor in production |

### ๐Ÿงช Testing

| Area | Current | Improvement | Why |
|------|---------|-------------|-----|
| **Mock Fidelity** | Static responses | Dynamic mocks from OpenAPI specs | Test against real merchant schemas |
| **Property Tests** | None | Hypothesis-based property testing | Find edge cases automatically |
| **Load Testing** | None | Locust scenarios for 100+ concurrent users | Verify production readiness |
| **Contract Tests** | None | UCP protocol compliance suite | Guarantee merchant compatibility |

## Configuration

All settings are configurable via environment variables:

| Variable | Default | Description |
|----------|---------|-------------|
| `UCP_TIMEOUT` | `30.0` | HTTP request timeout in seconds |
| `UCP_CONNECT_TIMEOUT` | `10.0` | Connection timeout in seconds |
| `UCP_MAX_CONCURRENT` | `10` | Max concurrent HTTP connections |
| `UCP_RATE_LIMIT` | `100` | Max requests per second to merchants |
| `UCP_MAX_RETRIES` | `3` | Max retry attempts on failure |
| `UCP_RETRY_BACKOFF_BASE` | `0.5` | Base backoff time in seconds |
| `UCP_RETRY_BACKOFF_MAX` | `10.0` | Max backoff time in seconds |
| `UCP_DISCOVERY_CACHE_TTL` | `300` | Discovery cache TTL in seconds |
| `UCP_LOG_LEVEL` | `INFO` | Logging level |

### Example: Production Configuration

```bash
export UCP_TIMEOUT=60
export UCP_RATE_LIMIT=50
export UCP_MAX_RETRIES=5
export UCP_LOG_LEVEL=WARNING
```

## Development

```bash
# Clone the repo
git clone https://github.com/nguthrie/ucp-mcp-server.git
cd ucp-mcp-server

# Install dependencies
uv sync --extra dev

# Run tests
uv run pytest -v

# Run integration tests (requires a live UCP server on port 8182)
uv run pytest -v -m integration --run-integration
```

### End-to-end functional tests

The repository also ships with self-contained end-to-end scripts that start the sample UCP merchant and exercise the full shopping flow via the MCP stdio client.

```bash
# Run a single end-to-end flow against a freshly started sample merchant
uv run python scripts/test_mcp_e2e.py

# Run all built-in scenarios (single items, multiple items, discounts, out-of-stock, ...)
uv run python scripts/test_mcp_scenarios.py

# Use an already running merchant (e.g., on localhost:8182)
uv run python scripts/test_mcp_e2e.py --skip-merchant
uv run python scripts/test_mcp_scenarios.py --skip-merchant --merchant-url http://localhost:8182

# Generate a sample scenarios file to customize
uv run python scripts/test_mcp_scenarios.py --generate-sample scenarios.json
```

### Project Structure

```
ucp-mcp-server/
โ”œโ”€โ”€ src/ucp_mcp_server/
โ”‚   โ”œโ”€โ”€ __init__.py        # Package version
โ”‚   โ”œโ”€โ”€ __main__.py        # python -m entry point
โ”‚   โ”œโ”€โ”€ server.py          # MCP server + tool definitions
โ”‚   โ”œโ”€โ”€ ucp_client.py      # HTTP client for UCP APIs
โ”‚   โ””โ”€โ”€ models.py          # Pydantic models for UCP data
โ””โ”€โ”€ tests/
    โ”œโ”€โ”€ conftest.py         # Test fixtures with mock UCP responses
    โ”œโ”€โ”€ test_discovery.py   # Discovery tool tests
    โ”œโ”€โ”€ test_products.py    # Product listing tests
    โ”œโ”€โ”€ test_product_search.py # Product search/filter tests
    โ”œโ”€โ”€ test_checkout.py    # Checkout tool tests
    โ”œโ”€โ”€ test_order.py       # Order tracking tool tests
    โ”œโ”€โ”€ test_errors.py      # Error handling tests
    โ”œโ”€โ”€ test_e2e_user_journey.py # End-to-end user journey tests
    โ””โ”€โ”€ test_integration.py # Live server integration tests
```

## Architecture

### System Overview

```mermaid
flowchart LR
    subgraph AI["AI Assistant"]
        A1[Claude / Cursor / MCP Client]
    end

    subgraph MCP["MCP Server Layer"]
        B1[FastMCP Server]
        B2[ucp_discover]
        B3[ucp_products_list]
        B4[ucp_products_search]
        B5[ucp_checkout_create]
        B6[ucp_checkout_update]
        B7[ucp_checkout_set_fulfillment]
        B8[ucp_checkout_complete]
        B9[ucp_order_get]
        B10[ucp_testing_simulate_shipping]
    end

    subgraph Client["HTTP Client Layer"]
        C1[UCPClient]
        C2[httpx AsyncClient]
    end

    subgraph Models["Data Models (Pydantic)"]
        D1[UCPDiscoveryResponse]
        D2[CheckoutSession]
        D3[LineItem]
        D4[PaymentHandler]
    end

    subgraph External["UCP Merchant API"]
        E1[/.well-known/ucp]
        E2[/checkout-sessions]
        E3[/checkout-sessions/:id/complete]
    end

    A1 -->|"MCP Protocol (stdio)"| B1
    B1 --> B2 & B3 & B4 & B5 & B6 & B7 & B8 & B9 & B10
    B2 & B3 & B4 & B5 & B6 & B7 & B8 & B9 & B10 --> C1
    C1 --> C2
    C2 -->|"HTTPS"| E1 & E2 & E3
    C1 --> D1 & D2 & D3 & D4
```

| Layer | Package | Purpose |
|-------|---------|---------|
| **AI Assistant** | External | MCP-compatible client (Claude, Cursor, etc.) |
| **MCP Server** | `server.py` | Tool definitions, input/output transformation |
| **HTTP Client** | `ucp_client.py` | Async HTTP calls to UCP merchant APIs |
| **Data Models** | `models.py` | Pydantic validation for requests/responses |
| **UCP Merchant** | External | Google UCP-compliant commerce server |

### Class Diagram

```mermaid
classDiagram
    class FastMCP {
        +tool() decorator
        +run(transport)
    }

    class UCPClient {
        -timeout: float
        -_client: AsyncClient
        +__aenter__()
        +__aexit__()
        +discover(merchant_url) UCPDiscoveryResponse
        +create_checkout(...) CheckoutSession
        +update_checkout(...) CheckoutSession
        +setup_fulfillment(...) dict
        +complete_checkout(...) CheckoutSession
        +get_checkout(...) dict
        +raw_update_checkout(...) dict
    }

    class UCPClientError {
        +message: str
    }

    class UCPDiscoveryResponse {
        +ucp_version: str
        +capabilities: list~UCPCapability~
        +payment_handlers: list~PaymentHandler~
    }

    class UCPCapability {
        +name: str
        +version: str
        +spec: str
    }

    class PaymentHandler {
        +id: str
        +name: str
        +version: str
        +config: dict
    }

    class CheckoutSession {
        +id: str
        +status: str
        +currency: str
        +line_items: list~LineItem~
        +totals: list~CheckoutTotals~
        +discounts: dict
        +order: OrderInfo
        +total: int
        +subtotal: int
        +discount_amount: int
    }

    class LineItem {
        +id: str
        +item: dict
        +quantity: int
        +totals: list
    }

    class CheckoutTotals {
        +type: str
        +amount: int
    }

    class DiscountApplied {
        +code: str
        +title: str
        +amount: int
        +automatic: bool
    }

    class OrderInfo {
        +id: str
        +permalink_url: str
    }

    FastMCP --> UCPClient : uses
    UCPClient --> UCPDiscoveryResponse : returns
    UCPClient --> CheckoutSession : returns
    UCPClient --> UCPClientError : throws
    UCPDiscoveryResponse *-- UCPCapability : contains
    UCPDiscoveryResponse *-- PaymentHandler : contains
    CheckoutSession *-- LineItem : contains
    CheckoutSession *-- CheckoutTotals : contains
    CheckoutSession *-- OrderInfo : contains
    LineItem --> CheckoutTotals : has
```

### Shopping Flow (Sequence)

```mermaid
sequenceDiagram
    actor User
    participant AI as AI Assistant
    participant MCP as MCP Server
    participant Client as UCPClient
    participant Merchant as UCP Merchant

    User->>AI: "Buy 2 roses from flower shop"
    
    AI->>MCP: ucp_discover(merchant_url)
    MCP->>Client: discover()
    Client->>Merchant: GET /.well-known/ucp
    Merchant-->>Client: capabilities, handlers
    Client-->>MCP: UCPDiscoveryResponse
    MCP-->>AI: capabilities + payment_handlers
    AI-->>User: "Merchant supports checkout, Shop Pay"

    AI->>MCP: ucp_checkout_create(items, buyer)
    MCP->>Client: create_checkout()
    Client->>Merchant: POST /checkout-sessions
    Merchant-->>Client: CheckoutSession
    Client-->>MCP: CheckoutSession
    MCP-->>AI: checkout_id, total
    AI-->>User: "Cart ready: $35.00"

    AI->>MCP: ucp_checkout_update(discount_codes=["10OFF"])
    MCP->>Client: update_checkout()
    Client->>Merchant: PUT /checkout-sessions/:id
    Merchant-->>Client: CheckoutSession (updated)
    Client-->>MCP: CheckoutSession
    MCP-->>AI: total, discount_applied
    AI-->>User: "Applied 10OFF: $31.50"

    AI->>MCP: ucp_checkout_set_fulfillment()
    MCP->>Client: setup_fulfillment()
    Client->>Merchant: PUT /checkout-sessions/:id (3 steps)
    Merchant-->>Client: CheckoutSession
    Client-->>MCP: fulfillment details
    MCP-->>AI: shipping selected
    AI-->>User: "Shipping configured"

    AI->>MCP: ucp_checkout_complete(payment)
    MCP->>Client: complete_checkout()
    Client->>Merchant: POST /checkout-sessions/:id/complete
    Merchant-->>Client: Order confirmed
    Client-->>MCP: OrderInfo
    MCP-->>AI: order_id, order_url
    AI-->>User: "Order placed! ๐ŸŽ‰"

    User->>AI: "Has my order shipped?"
    AI->>MCP: ucp_order_get(order_id)
    MCP->>Client: get_order()
    Client->>Merchant: GET /orders/:id
    Merchant-->>Client: Order + fulfillment status
    Client-->>MCP: Order details
    MCP-->>AI: status, fulfillment
    AI-->>User: "Your order is still being prepared"
```

## Roadmap

### โœ… Completed

- [x] Merchant capability discovery (`ucp_discover`)
- [x] Product catalog listing (`ucp_products_list`)
- [x] Product search and filtering (`ucp_products_search`)
- [x] Checkout session creation (`ucp_checkout_create`)
- [x] Discount code application (`ucp_checkout_update`)
- [x] Fulfillment / shipping setup (`ucp_checkout_set_fulfillment`)
- [x] Purchase completion / payment submission (`ucp_checkout_complete`)
- [x] Order fulfillment tracking (`ucp_order_get`, `ucp_testing_simulate_shipping`)
- [x] End-to-end user journey tests
- [x] UCP protocol compliance tests

### ๐Ÿšง In Progress

- [ ] Returns and exchanges

### ๐Ÿ“‹ Planned

- [ ] Multi-merchant comparison shopping
- [ ] Hosted managed version (so you don't have to self-host)

## Resources

- [UCP Specification](https://ucp.dev) - The Universal Commerce Protocol
- [UCP GitHub](https://github.com/universal-commerce-protocol/ucp)
- [UCP Python SDK](https://github.com/Universal-Commerce-Protocol/python-sdk)
- [MCP Documentation](https://modelcontextprotocol.io) - Model Context Protocol
- [Google's UCP Blog Post](https://developers.googleblog.com/under-the-hood-universal-commerce-protocol-ucp/)

## License

MIT