Facet UCP Shopping

The independent agent-commerce protocol for AI-agent checkout on any online store.

Should I use this

Quality & Safety

B
Description quality
97%
Schema completeness
92%
Naming quality
93%
Poisoning risk
20%
Permission match
100%
Protocol compliance
100%

Findings (6)

  • HIGHTool poisoning patterns detected
  • MEDIUMTool description contains URL to non-standard domainin discover_businesses
  • MEDIUMTool description contains URL to non-standard domainin discover_products
  • MEDIUMTool description contains URL to non-standard domainin get_quote
  • MEDIUMTool description contains URL to non-standard domainin post_delivery_refund
  • LOWTool 'lookup_catalog' description lacks action verbin lookup_catalog

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~3,986Tokens (tool definitions)
~1.0 KBTypical response size
Significant attention impact (3.11% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "ucp-shopping": {
      "url": "https://api.facet.llc/ucp/mcp"
    }
  }
}

Remote endpoints

https://api.facet.llc/ucp/mcpstreamable-http

What it can do

Tool inventory

Tools (23)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟢search_catalog(catalog)

Search the merchant catalog for products matching a free-text query.

Input Schema

{
  "type": "object",
  "properties": {
    "catalog": {
      "type": "object",
      "properties": {
        "query": {
          "type": "string",
          "description": "Free-text search query."
        },
        "pagination": {
          "type": "object",
          "properties": {
            "cursor": {
              "type": "string"
            },
            "limit": {
              "type": "integer",
              "minimum": 1
            }
          }
        }
      }
    }
  },
  "required": [
    "catalog"
  ]
}
⚪lookup_catalog(catalog)

Look up one or more products or variants by identifier (batch).

Input Schema

{
  "type": "object",
  "properties": {
    "catalog": {
      "type": "object",
      "required": [
        "ids"
      ],
      "properties": {
        "ids": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "minItems": 1,
          "maxItems": 100
        }
      }
    }
  },
  "required": [
    "catalog"
  ]
}
🟢get_product(catalog)

Get full product detail by product or variant identifier.

Input Schema

{
  "type": "object",
  "properties": {
    "catalog": {
      "type": "object",
      "required": [
        "id"
      ],
      "properties": {
        "id": {
          "type": "string"
        }
      }
    }
  },
  "required": [
    "catalog"
  ]
}
🟡discover_businesses(query, near, radius_km, limit)

Find businesses in the Facet Universal Business Index that an agent can transact with. Returns `featured` (claimed merchants with a live `terminal_url` — point your catalog and checkout calls there) and `results` (the wider directory). Use this first when you do not already know which merchant to talk to. REQUIRES IDENTITY: send a Facet KYA as `Authorization: Bearer <kya>` on the MCP request. A KYA is an ES256 JWT from Facet's default issuer https://issuer.facet.llc (or another issuer this Terminal trusts — see KYA-Issuers in its /.well-known/agents.txt). Calling without one returns 401 with a signup link.

Input Schema

{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "Free-text query, e.g. \"flowers\" or \"makeup brushes\"."
    },
    "near": {
      "type": "object",
      "description": "Optional geographic center to rank by proximity.",
      "properties": {
        "lat": {
          "type": "number",
          "description": "Latitude, decimal degrees."
        },
        "lng": {
          "type": "number",
          "description": "Longitude, decimal degrees."
        }
      },
      "required": [
        "lat",
        "lng"
      ]
    },
    "radius_km": {
      "type": "number",
      "description": "Search radius around `near`, km. Default 25."
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50,
      "description": "Max matches to return. Default 10, cap 50."
    }
  }
}
🟡discover_products(query, category, tags, limit)

Search products ACROSS every merchant in the Facet network that has opted into cross-merchant discovery. Returns matches each carrying the selling merchant's `terminal_url` (point your catalog and checkout calls there). Filter by free-text `query` (product name + description), exact `category`, and/or `tags` (all must be present); at least one filter is required. Use this when you know WHAT you want but not WHICH merchant sells it. REQUIRES IDENTITY: send a Facet KYA as `Authorization: Bearer <kya>` on the MCP request. A KYA is an ES256 JWT from Facet's default issuer https://issuer.facet.llc (or another issuer this Terminal trusts; see KYA-Issuers in its /.well-known/agents.txt). Calling without one returns 401 with a signup link.

Input Schema

{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "Free-text over product name + description, e.g. \"lavender soap\"."
    },
    "category": {
      "type": "string",
      "description": "Exact product category to match."
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Tags that must ALL be present on a matching product."
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50,
      "description": "Max matches to return. Default 10, cap 50."
    }
  }
}
🟡get_quote(product_id, qty, site_id, fulfillment)

Get the real landed cost of a product from this merchant: goods + shipping + tax for a specific destination, plus a signed `quote_token` the payment path binds to. Call this before paying — the token is what makes the price the MERCHANT's, not one you name. Physical products REQUIRE a `fulfillment` ship-to; without one you get FULFILLMENT_REQUIRED. An unserviceable destination returns UNDELIVERABLE (the merchant's own shipping zones, which Facet cannot waive). REQUIRES IDENTITY: send a Facet KYA as `Authorization: Bearer <kya>` (ES256 JWT from https://issuer.facet.llc, or another issuer in this Terminal's agents.txt KYA-Issuers).

Input Schema

{
  "type": "object",
  "properties": {
    "product_id": {
      "type": "string",
      "description": "Product or variant id, e.g. from search_catalog."
    },
    "qty": {
      "type": "integer",
      "minimum": 1,
      "description": "Quantity. Default 1."
    },
    "site_id": {
      "type": "string",
      "description": "Usually omitted — this Terminal's bound site is used."
    },
    "fulfillment": {
      "type": "object",
      "description": "Ship-to destination. REQUIRED for physical products.",
      "properties": {
        "mode": {
          "type": "string",
          "enum": [
            "inline",
            "ref"
          ],
          "description": "`inline` with a full address, or `ref` to reuse a prior fulfillment_ref."
        },
        "fulfillment_ref": {
          "type": "string",
          "description": "Opaque ref from a prior quote (mode `ref`)."
        },
        "address": {
          "type": "object",
          "description": "All six fields are required, including `region`.",
          "required": [
            "recipient",
            "line1",
            "locality",
            "region",
            "postal_code",
            "country"
          ],
          "properties": {
            "recipient": {
              "type": "string"
            },
            "line1": {
              "type": "string"
            },
            "line2": {
              "type": "string"
            },
            "locality": {
              "type": "string",
              "description": "City."
            },
            "region": {
              "type": "string",
              "description": "State/province. Required even where the country has none."
            },
            "postal_code": {
              "type": "string"
            },
            "country": {
              "type": "string",
              "description": "ISO 3166-1 alpha-2, e.g. US."
            },
            "phone": {
              "type": "string"
            }
          }
        }
      }
    }
  },
  "required": [
    "product_id"
  ]
}
🟢get_payment_capabilities

Which settlement rails this merchant actually accepts (e.g. coin/boson-escrow for escrowed funds that release on fulfilment, coin/usdc-base for direct). Call before get_payment_requirements so you pass a rail_id this merchant registers, rather than guessing. No identity required — this is discovery data.

Input Schema

{
  "type": "object",
  "properties": {}
}
🟢get_payment_requirements(product_id, qty, rail_id, amount, quote_token, ...)

Turn a `quote_token` from get_quote into a seller-signed payment offer to authorize. Returns `requirements` (escrow address, asset, exact atomic amount, network) — sign it LOCALLY with your own wallet (e.g. @bosonprotocol/x402-client handle402 for `coin/boson-escrow`, producing an X-PAYMENT string). Facet never holds your key and cannot sign for you, which is why paying is two steps and not one. The offer binds to the quote_token's sealed landed total and ship-to, so the amount is the merchant's, not one you name. REQUIRES IDENTITY: same Facet KYA as get_quote, and the SAME `aid` — the offer path rejects a quote_token issued to a different agent than the caller.

Input Schema

{
  "type": "object",
  "properties": {
    "product_id": {
      "type": "string",
      "description": "Must match the product the quote_token sealed."
    },
    "qty": {
      "type": "integer",
      "minimum": 1,
      "description": "Must match the quote_token. Default 1."
    },
    "rail_id": {
      "type": "string",
      "description": "Settlement rail, e.g. \"coin/boson-escrow\" (escrow: funds release on fulfilment) or \"coin/usdc-base\". See /v1/payments/capabilities for what this merchant registers."
    },
    "amount": {
      "type": "object",
      "required": [
        "amount",
        "currency"
      ],
      "description": "The landed total in ATOMIC units. Must equal the quote_token's sealed total.",
      "properties": {
        "amount": {
          "type": "integer",
          "description": "Atomic units, e.g. 16930000 for $16.93 USDC (6dp)."
        },
        "currency": {
          "type": "string",
          "description": "e.g. \"USDC\"."
        }
      }
    },
    "quote_token": {
      "type": "string",
      "description": "The signed token from get_quote."
    },
    "site_id": {
      "type": "string",
      "description": "Usually omitted — this Terminal's bound site is used."
    }
  },
  "required": [
    "product_id",
    "rail_id",
    "amount",
    "quote_token"
  ]
}
🟢get_order(order_id)

Read back one of YOUR orders on this merchant: status, amount, settlement state. Use the order_id returned when you paid. You can only read orders your own agent identity placed — another agent's order returns FORBIDDEN. REQUIRES IDENTITY: Facet KYA as `Authorization: Bearer <kya>`.

Input Schema

{
  "type": "object",
  "properties": {
    "order_id": {
      "type": "string",
      "description": "The order id returned at payment."
    }
  },
  "required": [
    "order_id"
  ]
}
🟢list_orders(limit, cursor)

List YOUR order history on this merchant, newest first. Scoped to your own agent identity — you never see another agent's orders. REQUIRES IDENTITY: Facet KYA as `Authorization: Bearer <kya>`.

Input Schema

{
  "type": "object",
  "properties": {
    "limit": {
      "type": "integer",
      "minimum": 1,
      "description": "Max orders to return."
    },
    "cursor": {
      "type": "string",
      "description": "Opaque cursor from a previous page."
    }
  }
}
🟡post_delivery_refund(order_id, reason, refund_line_items, receipt)

Request a refund or return on a DELIVERED order you placed on this merchant. Opens a merchant-approved refund ticket (status `requested`); it moves NO money on its own. The merchant reviews and approves it, and only then does the send-back sign from the merchant's OWN wallet (non-custodial). Amount and recipient are NOT inputs: the refund amount is derived and capped server-side, and the recipient is the order's stamped payer, never one you name. Pass `refund_line_items` to refund only part of the order; omit for the whole order. Owner-scoped: another agent's order returns FORBIDDEN. REQUIRES IDENTITY: a Facet KYA as `Authorization: Bearer <kya>` (an ES256 JWT from https://issuer.facet.llc, or another issuer in this Terminal's agents.txt KYA-Issuers). A wallet-bound KYA also authorizes a platform-originated order by its stamped payer.

Input Schema

{
  "type": "object",
  "properties": {
    "order_id": {
      "type": "string",
      "description": "The order id returned at payment (settle / checkout complete). A reservation id is not an order id."
    },
    "reason": {
      "type": "string",
      "description": "Why the refund or return is requested. Required."
    },
    "refund_line_items": {
      "type": "array",
      "description": "Optional PARTIAL selection: refund only these lines instead of the whole order. Advisory at request time; the merchant is authoritative and may adjust it at decide. Omit for a full-order refund.",
      "items": {
        "type": "object",
        "required": [
          "product_id",
          "qty"
        ],
        "properties": {
          "product_id": {
            "type": "string",
            "description": "A product id present in the order."
          },
          "qty": {
            "type": "integer",
            "minimum": 1,
            "description": "At most the ordered quantity for that line."
          }
        }
      }
    },
    "receipt": {
      "type": "object",
      "description": "Optional Ed25519-signed settlement receipt (the signed settle response you received). When valid and bound to this order it records receipt_verified on the ticket; it never gates the refund.",
      "properties": {
        "body": {
          "type": "string"
        },
        "signature": {
          "type": "string"
        },
        "trace_id": {
          "type": "string"
        },
        "path": {
          "type": "string"
        }
      }
    }
  },
  "required": [
    "order_id",
    "reason"
  ]
}
🟡wishlist_add(product_id, note)

Save a product to YOUR wishlist on this merchant for later. Idempotent: saving the same product again updates its note and keeps the original save time. Scoped to your own agent identity. REQUIRES IDENTITY: Facet KYA as `Authorization: Bearer <kya>`.

Input Schema

{
  "type": "object",
  "properties": {
    "product_id": {
      "type": "string",
      "description": "The product id to save."
    },
    "note": {
      "type": "string",
      "description": "Optional short note. No personal data."
    }
  },
  "required": [
    "product_id"
  ]
}
🟢wishlist_list(limit)

List YOUR saved items (wishlist) on this merchant, newest first. Scoped to your own agent identity, so you never see another agent's list. REQUIRES IDENTITY: Facet KYA as `Authorization: Bearer <kya>`.

Input Schema

{
  "type": "object",
  "properties": {
    "limit": {
      "type": "integer",
      "minimum": 1,
      "description": "Max items to return."
    }
  }
}
🔴wishlist_remove(product_id)

Remove a product from YOUR wishlist on this merchant. Idempotent: removing something not on your list succeeds with removed:false. Scoped to your own agent identity. REQUIRES IDENTITY: Facet KYA as `Authorization: Bearer <kya>`.

Input Schema

{
  "type": "object",
  "properties": {
    "product_id": {
      "type": "string",
      "description": "The product id to remove."
    }
  },
  "required": [
    "product_id"
  ]
}
🟡create_checkout(line_items, cart_id, fulfillment)

Open a checkout session for one or more catalog line items (or promote a cart with `cart_id`). Returns the session plus server-resolved `payment_handlers` (rail, pay_to, exact amount) to satisfy: the price and pay_to are the MERCHANT's, sealed here, never read from your request. Physical goods REQUIRE a `fulfillment` ship-to (else FULFILLMENT_REQUIRED), sealed at create. REQUIRES IDENTITY on a signature-required Terminal: a Facet KYA as `Authorization: Bearer <kya>`.

Input Schema

{
  "type": "object",
  "properties": {
    "line_items": {
      "type": "array",
      "description": "Items to buy, each `{ item: { id }, quantity }`. Omit when using cart_id.",
      "items": {
        "type": "object",
        "properties": {
          "item": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              }
            },
            "required": [
              "id"
            ]
          },
          "quantity": {
            "type": "integer",
            "minimum": 1
          }
        }
      }
    },
    "cart_id": {
      "type": "string",
      "description": "Promote an existing cart: its stored lines drive the checkout and any line_items are ignored (the business must use the cart contents)."
    },
    "fulfillment": {
      "type": "object",
      "description": "Ship-to destination. REQUIRED for physical products; sealed at create."
    }
  }
}
⚪complete_checkout(checkout_id, payment)

Complete a checkout you created and place the order by submitting the buyer-signed payment credential. This is the MONEY-MOVING leg: funds capture on-chain to the merchant's pay_to (x402) or into escrow (Boson). The amount is re-derived server-side from the reservation, never your request, and the buyer's signature is verified before any capture. A per-buyer refusal (FORBIDDEN, cap-exceeded, FULFILLMENT_REQUIRED) returns as an error result; a missing or invalid identity is a real 401. REQUIRES IDENTITY plus a signed Idempotency-Key on a signature-required Terminal.

Input Schema

{
  "type": "object",
  "properties": {
    "checkout_id": {
      "type": "string",
      "description": "The checkout id from create_checkout."
    },
    "payment": {
      "type": "object",
      "description": "The payment container `{ instruments: [{ credential: { type, ... } }] }`, where credential.type is `x402_authorization` or `boson_commit_authorization`. Sign the seller-signed offer LOCALLY with your own wallet; Facet never holds your key."
    }
  },
  "required": [
    "checkout_id",
    "payment"
  ]
}
🟢get_checkout(id)

Read back one of YOUR checkout sessions by id: status, totals, line items, payment_handlers. Owner-scoped, so another agent's id returns not_found. REQUIRES IDENTITY on a signature-required Terminal.

Input Schema

{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "The checkout session id."
    }
  },
  "required": [
    "id"
  ]
}
🟡update_checkout(id)

Return a checkout's CURRENT sealed snapshot. Facet seals price and items at create, so this is a no-op that reports the session plus a note: to change line items, update the cart and start a new checkout with create_checkout(cart_id). Owner-scoped.

Input Schema

{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "The checkout session id."
    }
  },
  "required": [
    "id"
  ]
}
🔴cancel_checkout(id)

Cancel a checkout session before completion, releasing its inventory hold. Idempotent, owner-scoped, and moves no money (distinct from an escrow refund). REQUIRES IDENTITY plus an Idempotency-Key on a signature-required Terminal.

Input Schema

{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "The checkout session id."
    }
  },
  "required": [
    "id"
  ]
}
🟡create_cart(line_items)

Create a pre-checkout cart from catalog line items. A cart is a mutable scratchpad: it moves no money and holds no inventory, so it carries estimated (server-derived) totals and NO payment_handlers. Assemble it, then create_checkout(cart_id) to convert. REQUIRES IDENTITY on a signature-required Terminal.

Input Schema

{
  "type": "object",
  "properties": {
    "line_items": {
      "type": "array",
      "description": "Items, each `{ item: { id }, quantity }`. Prices are catalog-derived, never yours.",
      "items": {
        "type": "object",
        "properties": {
          "item": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              }
            },
            "required": [
              "id"
            ]
          },
          "quantity": {
            "type": "integer",
            "minimum": 1
          }
        }
      }
    }
  }
}
🟢get_cart(id)

Read back one of YOUR carts by id: line items and estimated totals. Owner-scoped, so another agent's id returns not_found. REQUIRES IDENTITY on a signature-required Terminal.

Input Schema

{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "The cart id."
    }
  },
  "required": [
    "id"
  ]
}
🟡update_cart(id, line_items)

Replace a cart's line items (full replacement), re-priced server-side. Owner-scoped. REQUIRES IDENTITY on a signature-required Terminal.

Input Schema

{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "The cart id."
    },
    "line_items": {
      "type": "array",
      "description": "The new full set of items, each `{ item: { id }, quantity }`.",
      "items": {
        "type": "object",
        "properties": {
          "item": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              }
            },
            "required": [
              "id"
            ]
          },
          "quantity": {
            "type": "integer",
            "minimum": 1
          }
        }
      }
    }
  },
  "required": [
    "id"
  ]
}
🔴cancel_cart(id)

Cancel a cart. Idempotent, owner-scoped, and moves no money. REQUIRES IDENTITY plus an Idempotency-Key on a signature-required Terminal.

Input Schema

{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "The cart id."
    }
  },
  "required": [
    "id"
  ]
}

Recommended Prompts

search_research
Search for information about [topic] using Facet UCP Shopping
Expected tools: search_catalog
find_specific
Find [specific item] using Facet UCP Shopping
Expected tools: search_catalog
retrieve_data
Get details about [item] from Facet UCP Shopping
Expected tools: get_product
fetch_info
Fetch [information type] using Facet UCP Shopping
Expected tools: get_product
list_items
List all [items] available in Facet UCP Shopping
Expected tools: list_orders

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded23 tools
verifiedversion not recorded23 tools